Codis安装部署2台服务器没有HA版本


项目地址: 

https://github.com/wandoulabs/codis 

中文说明文档: 

https://github.com/wandoulabs/codis/blob/master/doc/tutorial_zh.md 


参考地址:


http://0xffff.me/blog/2014/11/11/codis-de-she-ji-yu-shi-xian-part-2/


http://www.cnblogs.com/xuanzhi201111/p/4425194.html


http://blog.csdn.net/freewebsys/article/details/44100919


个人:广州-李惟忠 


架构图:

Codis安装部署2台服务器没有HA版本-LMLPHP




Codis 并不太适合 key 少,但是 value 特别大的应用, 而且你的 key 越少, value 越大,最后就会退化成单个 redis 的模型 (性能还不如 raw redis),所以 Codis 更适合海量 Key, 


value比较小 (<= 1 MB) 的应用。


机器与应用列表:

操作系统:CentOS6.5


IP: 172.17.3.133    hostname: codis-133  apps: zookeeper, codis_proxy_1, codis_config, codis_server_master,slave 

IP: 172.17.3.134    hostname: codis-134  apps: codis_server_master,slave


备注:由于是仿真测试,一台机器跑多个应用,如生产环境,只需把应用分开部署即可,另外zookeeper需要3台搭建集群环境,还需要2台搭建keepalived+haproxy。




一,安装zookeeper


1,配置hosts文件 (所有机器上配置)

vim /etc/hosts

172.17.3.133    codis-133

172.17.3.134    codis-134



2,安装java环境

ZooKeeper 要求 JAVA 的环境才能运行,并且需要 JAVA6 以上的版本,可以从 SUN 官网上下载,并对 JAVA 环境变量进行设置。

yum -y install java-1.7.0-openjdk-devel

java -version

java version "1.7.0_75"

OpenJDK Runtime Environment (rhel-2.5.4.0.el6_6-x86_64 u75-b13)

OpenJDK 64-Bit Server VM (build 24.75-b04, mixed mode)

3,安装zookeeper

wget http://mirrors.cnnic.cn/apache/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz

tar zxvf zookeeper-3.4.6.tar.gz

mv zookeeper-3.4.6 /usr/local/zookeeper

mkdir -p /data/zookeeper/{data,logs}

配置zoo.cfg

vim /usr/local/zookeeper/conf/zoo.cfg 

tickTime=2000

initLimit=10

syncLimit=5

dataDir=/data/zookeeper/data

dataLogDir=/data/zookeeper/logs

clientPort=2181



4,启动zookeeper

/usr/local/zookeeper/bin/zkServer.sh start

JMX enabled by default

Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg

Starting zookeeper ... STARTED

[root@localhost conf]# /usr/local/zookeeper/bin/zkServer.sh status

JMX enabled by default

Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg

Mode: standalone


设置开机启动

vim /etc/rc.local

/usr/local/zookeeper/bin/zkServer.sh start




二,安装codis集群



1,安装go

设置环境变量

vim /etc/profile

export GOROOT=/usr/local/go

export PATH=$PATH:$GOROOT/bin

export GOPATH=/usr/local/codis

source /etc/profile

下载安装go

cd /usr/local/


wget http://golangtc.com/static/go/go1.4.2.linux-amd64.tar.gz


tar -zxvf go1.4.2.linux-amd64.tar.gz                                                                             

go version

go version go1.4.2 linux/amd64



2,安装依赖环境

yum groupinstall "Development Tools"



3,安装codis

yum install -y git

go get github.com/wandoulabs/codis  #这个需要几分钟下载共30M文件

package github.com/wandoulabs/codis

imports github.com/wandoulabs/codis

imports github.com/wandoulabs/codis: no buildable Go source files in /usr/local/codis/src/github.com/wandoulabs/codis

cd $GOPATH/src/github.com/wandoulabs/codis

[root@localhost codis]# pwd

/usr/local/codis/src/github.com/wandoulabs/codis

#执行编译测试脚本,编译go和reids。 

./bootstrap.sh #这个需要十几分钟共下载50M文件

make gotest

# 将编译好后,把bin目录和一些脚本复制过去/usr/local/codis目录下:

mkdir -p /usr/local/codis/{logs,conf,scripts}

mkdir -p /data/codis_server/{logs,conf,data}

cp -rf bin /usr/local/codis/

cp sample/config.ini /usr/local/codis/conf/

cp sample/redis_conf/6381.conf /data/codis_server/conf/

cp -rf /usr/local/codis/src/github.com/wandoulabs/codis/sample/*.sh /usr/local/codis/scripts/

cp -rf /usr/local/codis/src/github.com/wandoulabs/codis/sample/usage.md /usr/local/codis/scripts/

cp /usr/local/codis/src/github.com/wandoulabs/codis/extern/redis-2.8.13/src/redis-cli /usr/local/codis/bin/redis-cli-2.8.13

cp /usr/local/codis/src/github.com/wandoulabs/codis/extern/redis-2.8.21/src/redis-cli /usr/local/codis/bin/redis-cli-2.8.21

ln -s /usr/local/codis/bin/redis-cli-2.8.21 /usr/local/codis/bin/redis-cli



4. 配置codis_proxy_1  ( codis-133 机器上配置)

cd /usr/local/codis

vim config.ini 

zk=localhost:2181

product=bitauto-codis

proxy_id=proxy_1

net_timeout=5

dashboard_addr=localhost:18087

coordinator=zookeeper



5. 修改配置文件,启动codis-server服务.

cd /data/codis_server/conf/

mv 6381.conf 6379.conf.bak

grep -Ev "^#|^$" 6379.conf.bak >6379.conf

vim 6379.conf

修改如下参数: (生产环境,参数适当进行调整)

daemonize yes

timeout 300

pidfile /var/run/redis_6379.pid

port 6379

logfile "/data/codis_server/logs/codis_6379.log"

save 900 1

save 300 10

save 60 10000

dbfilename 6379.rdb

dir /data/codis_server/data

appendfilename "6379_appendonly.aof"

appendfsync everysec


具体配置文件如下:

daemonize yes

pidfile /var/run/redis_6379.pid

port 6379

tcp-backlog 511

timeout 300

tcp-keepalive 0

loglevel notice

logfile "/data/codis_server/logs/redis_6379.log"

databases 16

stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

dbfilename 6379.rdb

dir /data/codis_server/data

slave-serve-stale-data yes

slave-read-only yes

repl-disable-tcp-nodelay no

slave-priority 100

maxclients 10000

maxmemory 2gb

maxmemory-policy allkeys-lru

appendonly no

appendfilename "6379_appendonly.aof"

appendfsync everysec

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

lua-time-limit 5000

slowlog-log-slower-than 10000

slowlog-max-len 128

latency-monitor-threshold 0

notify-keyspace-events ""

hash-max-ziplist-entries 512

hash-max-ziplist-value 64

list-max-ziplist-entries 512

list-max-ziplist-value 64

set-max-intset-entries 512

zset-max-ziplist-entries 128

zset-max-ziplist-value 64

hll-sparse-max-bytes 3000

activerehashing yes

client-output-buffer-limit normal 0 0 0

client-output-buffer-limit slave 256mb 64mb 60

client-output-buffer-limit pubsub 32mb 8mb 60

hz 10

aof-rewrite-incremental-fsync yes




复制6380配置文件

cp 6379.conf 6380.conf

sed -i 's/6379/6380/g' 6380.conf


添加内核参数

echo "vm.overcommit_memory = 1" >>  /etc/sysctl.conf

sysctl -p

内核参数说明如下:                                                                                                                                       

overcommit_memory文件指定了内核针对内存分配的策略,其值可以是0、1、2。                               

0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。 

1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。

2, 表示内核允许分配超过所有物理内存和交换空间总和的内存


启动codis-server服务

nohup  /usr/local/codis/bin/codis-server /data/codis_server/conf/6379.conf &

nohup  /usr/local/codis/bin/codis-server /data/codis_server/conf/6380.conf &

[root@localhost conf]#nohup  /usr/local/codis/bin/codis-server /data/codis_server/conf/6379.conf &

[1] 15944

[root@localhost conf]#                 _._                                                  

           _.-``__ ''-._                                             

      _.-``    `.  `_.  ''-._           Redis 2.8.21 (575eed4b/0) 64 bit

  .-`` .-```.  ```\/    _.,_ ''-._                                   

 (    '      ,       .-`  | `,    )     Running in stand alone mode

 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379

 |    `-._   `._    /     _.-'    |     PID: 15944

  `-._    `-._  `-./  _.-'    _.-'                                   

 |`-._`-._    `-.__.-'    _.-'_.-'|                                  

 |    `-._`-._        _.-'_.-'    |           http://redis.io        

  `-._    `-._`-.__.-'_.-'    _.-'                                   

 |`-._`-._    `-.__.-'    _.-'_.-'|                                  

 |    `-._`-._        _.-'_.-'    |                                  

  `-._    `-._`-.__.-'_.-'    _.-'                                   

      `-._    `-.__.-'    _.-'                                       

          `-._        _.-'                                           

              `-.__.-'                                               


[15944] 24 Jun 18:23:22.255 # Server started, Redis version 2.8.21

[15944] 24 Jun 18:23:22.256 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with 


Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the 


setting after a reboot. Redis must be restarted after THP is disabled.

[15944] 24 Jun 18:23:22.256 * The server is now ready to accept connections on port 6379




6. 查看一下启动流程:

cat /usr/local/codis/scripts/usage.md

0. start zookeeper       //启动zookeeper服务

1. change config items in config.ini  //修改codis配置文件

2. ./start_dashboard.sh    //启动 dashboard

3. ./start_redis.sh        //启动redis实例

4. ./add_group.sh          //添加redis组,一个redis组只能有一个master

5. ./initslot.sh          //初始化槽

6. ./start_proxy.sh        //启动proxy

7. ./set_proxy_online.sh    //上线proxy项目

8. open browser to http://localhost:18087/admin     //访问web

这只是一个参考,有些顺序不是必须的,但启动dashboard前,必须启动zookeeper服务,这是必须的,后面有很多操作,都可以在web页面完成,例如添加/删除组,添加/删除redis实例等



7. 修改脚本,启动 dashboard。( 只需在一台机器上启动即可。172.17.3.133上启动 ,后续大部分操作都可以在面板上操作)

cat /usr/local/codis/scripts/start_dashboard.sh

#!/bin/sh

CODIS_HOME=/usr/local/codis 


nohup $CODIS_HOME/bin/codis-config -c $CODIS_HOME/conf/config.ini -L $CODIS_HOME/logs/dashboard.log dashboard --addr=:18087 --http-log=$CODIS_HOME/logs/requests.log 


&>/dev/null &


启动dashboard

cd /usr/local/codis/scripts/

sh start_dashboard.sh



8. 修改脚本,初始化槽 ( 172.17.3.133 机器上配置 )

cat /usr/local/codis/scripts/initslot.sh

#!/bin/sh

CODIS_HOME=/usr/local/codis

echo "slots initializing..."

$CODIS_HOME/bin/codis-config -c $CODIS_HOME/conf/config.ini slot init -f

echo "done"


执行初始化槽脚本:

sh initslot.sh 

slots initializing...

{

    "msg": "OK", 

    "ret": 0 

}

done



9. 启动codis-server master , slave 实例 ,以上步骤已经启动,不在描述(在第5步,此时还没有分主从,只是分别在3.133和3.134上启动2个实例6379和6380)。



10. 通过管理页面添加组ID,为组添加主从实例,一个组里只能有一个redis-master:

http://172.17.3.133:18087(最好用Firefox浏览器或者谷歌浏览器)

登录http://172.17.3.133:18087/admin/,添加2个组,组里面有2个实例,一个主一个从,默认每个组里面第一个实例是主

group_1

172.17.3.133:6379   master

172.17.3.134:6380   slave

group_2

172.17.3.134:6379   master

172.17.3.133:6380   slave



11.测试一下redis-master和redis-slave是否正常同步数据了:

这个需要用redis-cli测试:

[root@localhost conf]# /usr/local/codis/src/github.com/wandoulabs/codis/extern/redis-2.8.13/src/redis-cli -h 172.17.3.133 -p 6379

172.17.3.133:6379> ping

PONG

172.17.3.133:6379> set name foo

OK

172.17.3.133:6379> get name

"foo"

172.17.3.133:6379> quit

[root@localhost conf]# /usr/local/codis/src/github.com/wandoulabs/codis/extern/redis-2.8.13/src/redis-cli -h 172.17.3.134 -p 6380

172.17.3.134:6380> get name

"foo"

172.17.3.134:6380> set test 123

(error) READONLY You can't write against a read only slave.

172.17.3.134:6380> quit

[root@localhost conf]# 

也可以通过日志查看

root@localhost conf]# [15825] 24 Jun 18:59:42.717 * SLAVE OF 172.17.3.133:6379 enabled (user request)

[15825] 24 Jun 18:59:43.199 * Connecting to MASTER 172.17.3.133:6379

[15825] 24 Jun 18:59:43.199 * MASTER <-> SLAVE sync started

[15825] 24 Jun 18:59:43.200 * Non blocking connect for SYNC fired the event.

[15825] 24 Jun 18:59:43.202 * Master replied to PING, replication can continue...

[15825] 24 Jun 18:59:43.203 * Partial resynchronization not possible (no cached master)

[15825] 24 Jun 18:59:43.204 * Full resync from master: 65c0b5c071fab1b52892a5efe7fd422bbf84f391:1

[15825] 24 Jun 18:59:43.289 * MASTER <-> SLAVE sync: receiving 18 bytes from master

[15825] 24 Jun 18:59:43.289 * MASTER <-> SLAVE sync: Flushing old data

[15825] 24 Jun 18:59:43.290 * MASTER <-> SLAVE sync: Loading DB in memory

[15825] 24 Jun 18:59:43.290 * MASTER <-> SLAVE sync: Finished with success



12. 配置codis-ha服务,主从自动切换。( 随便找个节点机器上配置即可,此环境中在172.17.3.134机器上配置 )

cd /usr/local

go get github.com/ngaut/codis-ha  #ngaut大概3M左右

cd /usr/local/codis/src/github.com/ngaut

cp -r codis-ha /usr/local/

cd /usr/local/codis-ha

go build


创建启动脚本,启动codis-ha服务

vim start_codis_ha.sh

codis-ha --codis-config=172.17.3.133:18087 -log-level="info" --productName=bitauto-codis &> ./logs/codis-ha.log &


mkdir logs

sh start_codis_ha.sh


13. 修改start_proxy.sh,启动codis-proxy服务 ( 在172.17.3.133上配置)

[root@codis-133 scripts]# cat start_proxy.sh 

#!/bin/sh


CODIS_HOME=/usr/local/codis


echo "shut down codis_proxy_1..."

$CODIS_HOME/bin/codis-config -c $CODIS_HOME/conf/config.ini proxy offline codis_proxy_1

echo "done"


echo "start new codis_proxy_1..."

nohup $CODIS_HOME/bin/codis-proxy --log-level info -c $CODIS_HOME/conf/config.ini -L $CODIS_HOME/logs/codis_proxy_1.log  --cpu=4 --addr=0.0.0.0:19000 --http-


addr=0.0.0.0:11000 &

echo "done"


echo "sleep 3s"

sleep 3

tail -n 30 $CODIS_HOME/logs/codis_proxy_1.log


cat set_proxy_online.sh 

#!/bin/sh


CODIS_HOME=/usr/local/codis

echo "set codis_proxy_1 online"

$CODIS_HOME/bin/codis-config -c $CODIS_HOME/conf/config.ini proxy online codis_proxy_1

echo "done"


启动codis-proxy

./start_proxy.sh


上线codis_proxy_1

./set_proxy_online.sh



14,最后设置开机启动

172.17.3.133上配置如下

vim /etc/rc.local

/usr/local/zookeeper/bin/zkServer.sh start

/usr/local/codis/bin/codis-server /data/codis_server/conf/6379.conf 

/usr/local/codis/bin/codis-server /data/codis_server/conf/6380.conf 

/usr/local/codis/scripts/start_dashboard.sh

/usr/local/codis/scripts/initslot.sh(一次性的,开机不需要启动)

/usr/local/codis/scripts/start_proxy.sh

/usr/local/codis/scripts/set_proxy_online.sh


172.17.3.134上配置如下

vim /etc/rc.local

/usr/local/zookeeper/bin/zkServer.sh start

/usr/local/codis/bin/codis-server /data/codis_server/conf/6379.conf 

/usr/local/codis/bin/codis-server /data/codis_server/conf/6380.conf 

/usr/local/codis-ha/start_codis_ha.sh



15,附加文件redis服务启动脚本

#!/bin/sh

#Configurations injected by install_server below....


EXEC=/usr/local/codis/bin/codis-server

CLIEXEC=/usr/local/codis/bin/redis-cli

PIDFILE=/var/run/redis_6379.pid

CONF="/data/codis_server/conf/6379.conf"

REDISPORT="6379"

###############

# SysV Init Information

# chkconfig: - 58 74

# description: redis_6379 is the redis daemon.

### BEGIN INIT INFO

# Provides: redis_6379

# Required-Start: $network $local_fs $remote_fs

# Required-Stop: $network $local_fs $remote_fs

# Default-Start: 2 3 4 5

# Default-Stop: 0 1 6

# Should-Start: $syslog $named

# Should-Stop: $syslog $named

# Short-Description: start and stop redis_6379

# Description: Redis daemon

### END INIT INFO



case "$1" in

    start)

        if [ -f $PIDFILE ]

        then

            echo "$PIDFILE exists, process is already running or crashed"

        else

            echo "Starting Redis server..."

            $EXEC $CONF

        fi

        ;;

    stop)

        if [ ! -f $PIDFILE ]

        then

            echo "$PIDFILE does not exist, process is not running"

        else

            PID=$(cat $PIDFILE)

            echo "Stopping ..."

            $CLIEXEC -p $REDISPORT shutdown

            while [ -x /proc/${PID} ]

            do

                echo "Waiting for Redis to shutdown ..."

                sleep 1

            done

            echo "Redis stopped"

        fi

        ;;

    status)

        PID=$(cat $PIDFILE)

        if [ ! -x /proc/${PID} ]

        then

            echo 'Redis is not running'

        else

            echo "Redis is running ($PID)"

        fi

        ;;

    restart)

        $0 stop

        $0 start

        ;;

    *)

        echo "Please use start, stop, restart or status as first argument"

        ;;

esac


09-07 14:22