码迷,mamicode.com
首页 > 其他好文 > 详细

Codis 高可用负载均衡群集的搭建与使用

时间:2015-04-29 07:27:17      阅读:1340      评论:0      收藏:0      [点我收藏+]

标签:codis   codis群集搭建   codis配置   

 

项目地址:
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 并不太适合 key 少,但是 value 特别大的应用, 而且你的 key 越少, value 越大,最后就会退化成单个 redis 的模型 (性能还不如 raw redis),所以 Codis 更适合海量 Key, value比较小 (<= 1 MB) 的应用。

实验环境:

System version: CentOS 6.5

网络拓扑图参考项目地址架构图。

机器与应用列表:

IP: 192.168.43.130    hostname: iaround-130  apps: zookeeper_1, codis_proxy_1, codis_config, codis_server_master,slave
IP: 192.168.43.131    hostname: iaround-131  apps: zookeeper_2, codis_proxy_2, codis_server_master,slave
IP: 192.168.43.132    hostname: iaround-132  apps: zookeeper_3, codis_proxy_3, codis_server_master,slave

IP: 192.168.43.120    hostname: iaround-120  apps: keepalived+haproxy Master
IP: 192.168.43.121    hostname: iaround-121  apps: keepalived+haproxy Slave

VIP: 192.168.43.100  Port: 6379

备注:由于是测试,一台机器跑多个应用,如生产环境,只需把应用分开部署即可。

 

一、部署Zookeeper群集

1.配置hosts文件 (所有机器上配置)
vim /etc/hosts
192.168.43.130    iaround-130
192.168.43.131    iaround-131
192.168.43.132    iaround-132
192.168.43.120    iaround-120
192.168.43.121    iaround-121

2.安装java 坏境  (所有机器上配置)
cd /data/packages
chmod 755 jdk-6u27-linux-x64.bin
./jdk-6u27-linux-x64.bin
mv jdk1.6.0_27 /usr/local/
cd /usr/local
ln -s jdk1.6.0_27 java


3. 安装Zookeeper  ( 所有节点机器上配置 )
cd /data/packages
wget http://apache.fayea.com/zookeeper/zookeeper-3.4.6/zookeeper-3.4.6.tar.gz
tar zxvf zookeeper-3.4.6.tar.gz -C /usr/local
ln -s zookeeper-3.4.6 zookeeper
cd /usr/local/zookeeper/


4.设置环境变量  ( 所有节点机器上配置 )
vim /etc/profile
JAVA_HOME=/usr/local/java
JRE_HOME=$JAVA_HOME/jre
ZOOKEEPER_HOME=/usr/local/zookeeper
JAVA_FONTS=/usr/local/java/jre/lib/fonts
CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$ZOOKEEPER_HOME/bin
export JAVA_HOME PATH CLASSPATH JRE_HOME ZOOKEEPER_HOME

#生效
source /etc/profile


5. 修改zookeeper配置文件 ( 所有zookeeper节点机器上配置 )
vi /usr/local/zookeeper/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
clientPort=2181
autopurge.snapRetainCount=500
autopurge.purgeInterval=24
dataDir=/data/zookeeper/data
dataLogDir=/data/zookeeper/logs
server.1=192.168.43.131:2888:3888
server.2=192.168.43.132:2888:3888
server.3=192.168.43.133:2888:3888

#创建数据目录和日志目录
mkdir -p /data/zookeeper/data
mkdir -p /data/zookeeper/logs


6.节点创建myid文件,节点对应id
在43.130机器上创建myid,并设置为1与配置文件zoo.cfg里面server.1对应。
echo "1" > /data/zookeeper/data/myid

在43.131机器上创建myid,并设置为1与配置文件zoo.cfg里面server.2对应。
echo "2" > /data/zookeeper/data/myid

在43.132机器上创建myid,并设置为1与配置文件zoo.cfg里面server.3对应。
echo "3" > /data/zookeeper/data/myid


7. 启动zookeeper服务, 以iaround-130为例:
[root@iaround-130 ~]# zkServer.sh start
JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED


8.检查状态
[root@iaround-130 ~]# zkServer.sh status
JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: follower

[root@iaround-131 ~]# zkServer.sh status
JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: follower

[root@iaround-132 ~]# zkServer.sh status
JMX enabled by default
Using config: /usr/local/zookeeper/bin/../conf/zoo.cfg
Mode: leader


二、部署 Codis群集

1. 安装 go 语言环境
/data/packages
wget http://golangtc.com/static/go/go1.4.2.linux-amd64.tar.gz
tar zxvf zkServer.sh status -C /usr/local

2. 添加GO环境变量,
vim /etc/profile
GOROOT=/usr/local/go
GOPATH=/usr/local/codis
PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$ZOOKEEPER_HOME/bin:$GOROOT/bin
export JAVA_HOME PATH CLASSPATH JRE_HOME ZOOKEEPER_HOME GOROOT GOPATH
source /etc/profile

3. 安装codis
yum install -y git
go get github.com/wandoulabs/codis
cd $GOPATH/src/github.com/wandoulabs/codis

#执行编译测试脚本,编译go和reids。
./bootstrap.sh
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/


4. 配置codis_proxy_1  ( iaround-130 机器上配置)
cd /usr/local/codis
vim config.ini
zk=iaround-130:2181,iaround-131:2181,iaround-132:2181                             
product=iAround-codis                                        
proxy_id=codis_proxy_1                                  
net_timeout=5
dashboard_addr=192.168.43.130:18087        
coordinator=zookeeper
配置codis_proxy_1  ( iaround-131 机器上配置)
cd /usr/local/codis
vim config.ini
zk=iaround-130:2181,iaround-131:2181,iaround-132:2181                             
product=iAround-codis                                        
proxy_id=codis_proxy_2                                  
net_timeout=5
dashboard_addr=192.168.43.130:18087        
coordinator=zookeeper

配置codis_proxy_1  ( iaround-132 机器上配置)
cd /usr/local/codis
vim config.ini
zk=iaround-130:2181,iaround-131:2181,iaround-132:2181                             
product=iAround-codis                                        
proxy_id=codis_proxy_3                                  
net_timeout=5
dashboard_addr=192.168.43.130:18087        
coordinator=zookeeper


5. 修改配置文件,启动codis-server服务.
cd /data/codis_server/conf/
mv 6381.conf 6379.conf
vim 6379.conf
修改如下参数: (生产环境,参数适当进行调整)
daemonize yes
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

复制6380配置文件
cp 6379.conf 6380.conf
sed -i ‘s/6379/6380/g‘ 6380.conf

添加内核参数
echo "vm.overcommit_memory = 1" >>  /etc/sysctl.conf
sysctl -p

启动codis-server服务
/usr/local/codis/bin/codis-server /data/codis_server/conf/6379.conf
/usr/local/codis/bin/codis-server /data/codis_server/conf/6380.conf


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。( 只需在一台机器上启动即可。43.130上启动 )
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. 修改脚本,初始化槽 ( 43.130 机器上配置 )
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 实例 ,以上步骤已经启动,不在描述。

10. 通过管理页面添加组ID,为组添加主从实例,一个组里只能有一个redis-master,设置slot分片数据等。

http://192.168.43.130:18087(最好用Firefox浏览器或者谷歌浏览器,别的浏览器比较坑爹!!!)

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


12. 配置codis-ha服务,主从自动切换。( 随便找个节点机器上配置即可,此环境中在43.131机器上配置 )
go get github.com/ngaut/codis-ha
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=192.168.43.130:18087 -log-level="info" --productName=iAround-Codis &> ./logs/codis-ha.log &

mkdir logs
sh start_codis_ha.sh

13. 修改start_proxy.sh,启动codis-proxy服务 ( 以130机器配置为例,其余codis-proxy只需修改下名称即可。)
[root@iaround-130 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=8 --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

[root@iaround-130 scripts]# 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

备注:其他codis_proxy只需修改start_proxy.sh和set_proxy_online.sh启动脚本里面的codis_proxy_1名称即可。

 

三、部署Keepalived + haproxy 高可用负载均衡
安装haproxy、keepalived (43.120、43.121 机器上操作)
1.查看系统内核是否支持 tproxy
[root@iaround-120 ~]# grep TPROXY /boot/config-`uname -r`
CONFIG_NETFILTER_TPROXY=m
CONFIG_NETFILTER_XT_TARGET_TPROXY=m
内核为2.6.32-220.el6.x86_64,支持TPROXY;

2.源码安装pcre-8.01
[root@iaround-120 ~]# rpm -qa|grep pcre
pcre-7.8-6.el6.x86_64
pcre-devel-7.8-6.el6.x86_64
系统已经rpm形式安装了pcre,但安装haproxy时,提示找不到pcre的库文件,看了haproxy的Makefile文件,指定pcre的为/usr/local下,故再源码安装一个pcre-8.01,如下(如果不重新安装,可以改makefile文件或把库文件软链到makefile文件指定的路径)
tar -zxf pcre-8.01.tar.gz && cd pcre-8.01
./configure --disable-shared --with-pic
make && make install
编译过程中可能缺少一个gcc make 之类的,缺少xxx就yum install -y xxx。

3.安装 haproxy-1.4.22
cd /data/packages
tar xf haproxy-1.4.22.tar.gz
cd haproxy-1.4.22
make TARGET=linux26 CPU=x86_64 USE_STATIC_PCRE=1 USE_LINUX_TPROXY=1
make install target=linux26
mkdir -p /usr/local/haproxy/sbin
mkdir -p /data/haproxy/{conf,run,logs}
ln -s /usr/local/sbin/haproxy /usr/local/haproxy/sbin

4. 创建haproxy启动脚本
[root@iaround-130 ~]# vim /etc/init.d/haproxy
#!/bin/sh
# haproxy
# chkconfig: 35 85 15
# description: HAProxy is a free, very fast and reliable solution \
# offering high availability, load balancing, and \
# proxying for TCP and HTTP-based applications
# processname: haproxy
# config: /data/haproxy/conf/haproxy.cfg
# pidfile: /data/haproxy/run/haproxy.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

config="/data/haproxy/conf/haproxy.cfg"
exec="/usr/local/haproxy/sbin/haproxy"
prog=$(basename $exec)

[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog

lockfile=/var/lock/subsys/haproxy

check() {
    $exec -c -V -f $config
}

start() {
    $exec -c -q -f $config
    if [ $? -ne 0 ]; then
        echo "Errors in configuration file, check with $prog check."
        return 1
    fi
 
    echo -n $"Starting $prog: "
    # start it up here, usually something like "daemon $exec"
    daemon $exec -D -f $config -p /data/haproxy/run/$prog.pid
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    # stop it here, often "killproc $prog"
    killproc $prog
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    $exec -c -q -f $config
    if [ $? -ne 0 ]; then
        echo "Errors in configuration file, check with $prog check."
        return 1
    fi
    stop
    start
}

reload() {
    $exec -c -q -f $config
    if [ $? -ne 0 ]; then
        echo "Errors in configuration file, check with $prog check."
        return 1
    fi
    echo -n $"Reloading $prog: "
    $exec -D -f $config -p /data/haproxy/run/$prog.pid -sf $(cat /data/haproxy/run/$prog.pid)
    retval=$?
    echo
    return $retval
}

force_reload() {
    restart
}

fdr_status() {
    status $prog
}

case "$1" in
    start|stop|restart|reload)
        $1
        ;;
    force-reload)
        force_reload
        ;;
    checkconfig)
        check
        ;;
    status)
        fdr_status
        ;;
    condrestart|try-restart)
      [ ! -f $lockfile ] || restart
    ;;
    *)
        echo $"Usage: $0 {start|stop|status|checkconfig|restart|try-restart|reload|force-reload}"
        exit 2
esac

备注:此脚本stop的时候有问题,待解决。

#添加haproxy服务
echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/rsysctl.conf
sysctl -p
chmod 755 /etc/init.d/haproxy
chkconfig --add haproxy
chkconfig haproxy on


5.安装keepalived
cd /data/packages
tar zxvf keepalived-1.2.16.tar.gz
cd keepalived-1.2.16
./configure --sysconf=/data/keepalived/conf --with-kernel-dir=/usr/src/kernels/2.6.32-504.16.2.el6.x86_64/
\\若/usr/src/kernels/目录下为空,那么安装kernel-headers和kernel-devel包 yum install -y kernel-header kernel-devel
make && make install


6.配置keepalived,添加keepalived 服务
cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
mkdir -p /data/keepalived/{conf,scripts}
cp /usr/local/sbin/keepalived /usr/sbin/

chkconfig --add keepalived
chkconfig keepalived on

7. 配置haproxy.cfg配置文件,启用日志( 43.120, 43.121 配置,haproxy.cfg配置文件完全一样 )
[root@iaround-120 ~]# vim /usr/local/haproxy/conf/haproxy.cfg
########### 全局配置 #########
global
log 127.0.0.1 local0 err
chroot /usr/local/haproxy
daemon
nbproc 1
group nobody
user nobody
pidfile /usr/local/haproxy/run/haproxy.pid
ulimit-n 65536
#spread-checks 5m
#stats timeout 5m
#stats maxconn 100


######## 默认配置 ############
defaults
mode tcp                     #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
retries 3                    #两次连接失败就认为是服务器不可用,也可以通过后面设置
option redispatch            #当serverId对应的服务器挂掉后,强制定向到其他健康的服务器
option abortonclose          #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
maxconn 32000                #默认的最大连接数
timeout connect 5000ms       #连接超时
timeout client 30000ms       #客户端超时
timeout server 30000ms       #服务器超时
#timeout check 2000          #心跳检测超时
log 127.0.0.1 local3 err     #[err warning info debug]
 
######## proxy 配置#################
listen proxy_status
bind 0.0.0.0:45001
mode tcp
balance roundrobin
server codis_proxy_1 192.168.43.130:19000 weight 1 maxconn 10000 check inter 10s
server codis_proxy_2 192.168.43.131:19000 weight 1 maxconn 10000 check inter 10s
server codis_proxy_3 192.168.43.132:19000 weight 1 maxconn 10000 check inter 10s
 
######## 统计页面配置 ########
listen admin_stats
bind 0.0.0.0:8099     #监听端口
mode http             #http的7层模式
option httplog        #采用http日志格式
#log 127.0.0.1 local0 err
maxconn 10
stats refresh 30s     #统计页面自动刷新时间
stats uri /stats      #统计页面url
stats realm XingCloud\ Haproxy     #统计页面密码框上提示文本
stats auth admin:admin             #统计页面用户名和密码设置
stats hide-version                 #隐藏统计页面上HAProxy的版本信息
stats admin if TRUE

8. 配置keepalived.conf配置文件 (43.120 上配置,43.121备用配置主要修改参数已经标注)
[root@iaround-120 ~]# vim /data/keepalived/conf/keepalived.conf
! Configuration File for keepalived 
 
global_defs { 
   notification_email { 
         lwz_benet@163.com
   } 
   notification_email_from lwz_benet@1163.com
   smtp_connect_timeout 30 
   smtp_server 127.0.0.1 
   router_id HAProxy_DEVEL

vrrp_script chk_haproxy { 
    script "killall -0 haproxy" 
    interval 2 

vrrp_instance HAProxy_HA { 
    state BACKUP    
    interface eth0 
    virtual_router_id 80  
    priority 100      #备用为90
    advert_int 2
    nopreempt        #设置不强占,防止业务来回切换。

    authentication { 
        auth_type PASS 
        auth_pass KJj23576hYgu23IP 
    } 
    track_interface { 
       eth0 
    } 
    virtual_ipaddress { 
        192.168.43.100
    } 
    track_script { 
        chk_haproxy 
    } 
 
    #状态通知 
    notify_master "/data/keepalived/scripts/mail_notify.py master" 
    notify_backup "/data/keepalived/scripts/mail_notify.py backup" 
    notify_fault  "/data/keepalived/scripts/mail_notify.py fault" 
}
\\拷贝主上面的keepalived.conf到从上,只需修改priority值参数即可。

创建/data/keepalived/scripts/mail_notify.py邮件通知程序:

详细请访问:http://liweizhong.blog.51cto.com/1383716/1639917

# 配置haproxy日志
vim /etc/rsyslog.d/haproxy.conf
$ModLoad imudp
$UDPServerRun 514
local3.* /data/haproxy/logs/haproxy.log
local0.* /data/haproxy/logs/haproxy.log

vim /etc/sysconfig/rsyslog
SYSLOGD_OPTIONS="-c 2 -r -m 0"

service rsyslog restart

9. 启动haproxy、keepalived服务。
service haproxy start   ( 先启动 haproxy 服务 )
service keepalived start


10.keepalived+haproxy群集故障测试
一,停止haproxy-master ,  观察/var/log/message日志
二,恢复haproxy-master, 观察/var/log/message日志,看是否被抢占,正常情况主haproxy恢复后,不会进行切换,防止业务来回切换。。。
三,停止haproxy-backup, 观察 /var/log/message日志,是否进行切换。


11. 测试redis-cli客户端访问

redis-cli -h 192.168.43.100 -p 45001 info

 


Codis架构测试

1.停止zookeeper节点,检查codis-proxy,dashboard是否正常.

检查zookeeper其他节点是否重新选取 leader。
redis客户端是否能正常访问到codis-proxy。
dashboard管理界面是否正常。


2.停止group master,检查group slave是否自动切换主

停止codis-master,检查codis-ha日志,是否有主从自动切换日志。
redis客户端写入新数据,切换后的主是否有新key增加。

备注:当master挂掉时候,redis-ha检测到自动将slave切换为master,但是master恢复后,仍为offline,需要将其删除在添加,就可以成为slave.

3.通过dashboard管理界面添加codis-server组,在线迁移、扩展等。

添加新组,添加master,slave .
Migrate Slot(s) 迁移slot

4.codis性能测试
redis-benchmark -h 192.168.1.130 -p 45001 -c 500 -n 5000000 -P 100 -r 10000 -t get,set


5.Slot Control  分配组槽的范围。( 0-1023 )
range set(set new group) 重新设置slot到新组,之后客户端访问的为新分配的组。

 

 

 

本文出自 “李惟忠的技术博客” 博客,转载请与作者联系!

Codis 高可用负载均衡群集的搭建与使用

标签:codis   codis群集搭建   codis配置   

原文地址:http://liweizhong.blog.51cto.com/1383716/1639918

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!