Codis部署和跨机房迁移详细步骤
Codis是一个Redis分布式集群解决方案...
作者简介
刘少波:UCloud高级技术专家,在Postfix、数据库、HTTP应用优化等领域,拥有丰富的经验。技术爱好者,热衷于高可用系统和自动化运维。正文
1.Codis简介
Redis 是一个高性能的key-value数据库,但是Redis容量受限于内存,如果想让Redis变成一个具有水平扩展的功能,之前只有Twtter开源的Twemproxy方案(后面Redis-3.0官方自带了Cluster功能),但是Twemproxy无法做到平滑扩容、缩容。
下面介绍的是
),实现平滑扩容、缩容,迁移过程对业务无感知(Codis性能测试请参考官方的测试文档)。数据迁移是通过修改Redis(2.8.21),加入了slot的支持和原子的数据迁移指令。
Codis的跨IDC迁移,我没有写详细的步骤,只是写了迁移的思路,因为前面几章的部署基本覆盖了迁移。
Codis 2.x由下面四个部分组成(Codis 3.x 变化较大,目前在github上面master版本是2.x):
1.1.codis-proxy
客户端连接的Redis代理服务,,就像 Twemproxy,可以部署多个codis-proxy,codis-proxy本身是无状态的。
1.2.codis-config
Codis的管理工具, 可以添加/删除Redis节点, 添加/删除Proxy节点, 发起数据迁移等。 还自带了一个dashboard,可以在浏览器上观察codis集群的运行状态。
1.3.codis-server
Codis项目维护的一个Redis分支,基于2.8.21开发,加入了slot的支持和原子的数据迁移指令。codis-proxy和codis-config只能和这个版本的Redis交互才能正常运行。
1.4.ZooKeeper
Codis依赖ZooKeeper来存放数据路由表和codis-proxy节点的元信息,codis-config发起的命令都会通过ZooKeeper同步到各个存活的codis-proxy。
1.4.1.备注:
Codis vs Twemproxy 性能测试,请根据自己业务的情况做测试。
https://github.com/CodisLabs/codis/blob/master/doc/benchmark.md
2.
节点规划
2.1.hosts文件规划
10.13.36.135 zk-1
10.13.46.83 zk-2
10.13.62.57 zk-3
10.13.63.112 codis-proxy-1
10.13.52.147 codis-server-1
10.13.50.113 codis-server-2
10.13.50.214 codis-server-3
10.13.43.144 codis-server-4
2.2.codis-server端口规划(6379为主、6380为从)
10.13.52.147:6379 10.13.50.113:6380
10.13.50.113:6379 10.13.52.147:6380
10.13.50.214:6379 10.13.43.144:6380
10.13.43.144:6379 10.13.50.214:6380
3.
部署ZooKeeper
3.1.安装JDK
zookeeper依赖java环境,所以要先安装JDK。
# wget --no-cookies --no-check-certificate --header "Cookie: oraclelicense=accept-securebackup-cookie" rpm" -O jdk-7u65-linux-x64.rpm
# rpm -ivh jdk-7u65-linux-x64.rpm
3.2.安装ZooKeeper
# wget http://mirror.bit.edu.cn/apache/zookeeper/zk-3.4.8/zk-3.4.8.tar.gz
# mkdir /usr/local/zookeeper && tar -xzvf zk-3.4.8.tar.gz -C /usr/local/zookeeper --strip-components 1
# cp /usr/local/zookeeper/conf/zoo_sample.cfg /usr/local/zookeeper/conf/zoo.cfg
# mkdir -p /data/zookeeper
3.3.配置ZooKeeper
# vim /usr/local/zookeeper/conf/zoo.cfg
修改文件如下:
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/zookeeper
clientPort=2181
maxClientCnxns=60
server.1=zk-1:2888:3888
server.2=zk-2:2888:3888
server.3=zk-3:2888:3888
设置zk-1的Server ID
# echo "1" > /data/zookeeper/myid
设置zk-2的Server ID
# echo "2" > /data/zookeeper/myid
设置zk-3的Server ID
# echo "3" > /data/zookeeper/myid
查看zookeeper状态
# ./zkServer.sh status
3.4.备注:
三种类型的节点:
Leader : 处理写请求,最终更新状态;
Follower : 处理客户端请求,参与投票;
Observer : 不参加投票,只处理客户端请求,主要是为提升zookeeper的性能;
当leader重启或宕机后,通过paxos算法,重新选出Leader,并以Leader为准,进行数据同步;
关于为Server ID,是标识host机器在集群中的机器序号,在每个ZK机器上,需要在dataDir目录下创建一个myid文件,myid中就是这个Server ID的数字。
3.5.启动zookeeper
# /usr/local/zookeeper/bin/zkServer.sh start
# /usr/local/zookeeper/bin/zkServer.sh status
# echo "/usr/local/zookeeper/bin/zkServer.sh start" >> /etc/rc.local
4.
部署Codis
4.1.启动流程
启动 dashboard
初始化 slots
启动 Codis Redis
添加 Redis Server Group
设置 server group 的slot范围
启动 Codis proxy
4.2.安装go
# wget https://storage.googleapis.com/golang/go1.5.2.linux-amd64.tar.gz
# tar -zxvf go1.5.2.linux-amd64.tar.gz -C /usr/local/
4.3.设置环境变量
# vim /etc/profile
新增如下内容:
export GOROOT="/usr/local/go"
export GOPATH="/opt/gopath"
export CODISPATH="/usr/local/codis"
export CODISCONF="/usr/local/codis/conf"
export PATH="$PATH:$GOROOT/bin:$GOPATH/bin:$CODISPATH/bin"
加载变量
# source /etc/profile
4.3.1.备注:
$GOPATH是本机所有go项目(包括项目依赖的第三方库)的目录,而非单纯codis的所在目录。
4.4.安装codis
# yum install -y git
# go get -u -d github.com/CodisLabs/codis
# cd $GOPATH/src/github.com/CodisLabs/codis
# make
# make gotest
4.4.1.备注:
安装后会在bin目录内生成codis-config、codis-proxy、codis-server三个可执行文件,另外bin/assets 目录是codis-config的dashboard 服务需要的前端资源,需要和codis-config放在同一目录下。
4.5.启动dashboard (codis-proxy-1上操作)
# mkdir -p /usr/local/codis/conf
# cp -r $GOPATH/src/github.com/CodisLabs/codis/bin /usr/local/codis/
# vim /usr/local/codis/conf/config.ini
修改文件如下:
coordinator=zookeeper
zk=zk-1:2181,zk-2:2181,zk-3:2181
product=codis
dashboard_addr=10.13.63.112:18087
password=
backend_ping_period=5
session_max_timeout=1800
session_max_bufsize=131072
session_max_pipeline=1024
zk_session_timeout=30000
proto=tcp4
proxy_id=codis-proxy-1 ##如果有多个proxy,proxy_id 需要唯一。
# codis-config -c $CODISCONF/config.ini -L /tmp/codis_dashboard.log dashboard --http-log=/tmp/codis_requests.log &
# echo "codis-config -c /usr/local/codis/conf/config.ini -L /tmp/codis_dashboard.log dashboard --http-log=/tmp/codis_requests.log" >> /etc/rc.local
4.6.初始化slots (codis-proxy-1主机上操作)
# codis-config -c $CODISCONF/config.ini slot init
{
"msg": "OK",
"ret": 0
}
5.
部署codis-server
(所有codis-server主机上操作)
5.1.调整内存分配策略
# echo "1" > /proc/sys/vm/overcommit_memory
# echo "512" > /proc/sys/net/core/somaxconn
# vim /etc/sysctl.conf
修改如下参数:
vm.overcommit_memory = 1
net.core.somaxconn = 512
让sysctl生效
# sysctl -p
禁用大内存页面
# echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
加入开机自启
# vim /etc/rc.local
加入如下参数:
if test -f /sys/kernel/mm/transparent_hugepage/enabled ; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi
5.2.复制codis-server所需的文件
(从codis-server主机操作)
# mkdir -p /usr/local/codis_server/{bin,conf}
(从codis-proxy-1主机操作,负载所有下面文件到所有codis-server主机)
# scp $CODISPATH/bin/codis-server codis-server-1:/usr/local/codis_server/bin/
# scp $GOPATH/src/github.com/CodisLabs/codis/extern/redis-2.8.21/src/redis-cli codis-server-1:/usr/local/codis_server/bin/
# scp $GOPATH/src/github.com/CodisLabs/codis/extern/redis-2.8.21/redis.conf codis-server-1:/usr/local/codis_server/conf/redis_6379.conf
5.3.启动codis-server(所有codis-server主机上操作)
5.4.配置redis-server
# mkdir -p /data/codis_server/data
# vim /usr/local/codis_server/conf/redis_6379.conf
修改如下参数:
pidfile /var/run/redis_6379.pid
dbfilename dump_6379.rdb
dir /data/codis_server/data
修改环境变量
# vim /etc/profile
添加如下内容:
export CODISPATH="/usr/local/codis_server"
export CODISCONF="/usr/local/codis_server/conf"
export PATH="$PATH:$GOROOT/bin:$CODISPATH/bin"
# source /etc/profile
# cp $CODISCONF/redis_6379.conf $CODISCONF/redis_6380.conf
# sed -i 's/6379/6380/g' $CODISCONF/redis_6380.conf
5.5.启动redis-server
# redis-server $CODISCONF/redis_6379.conf
# redis-server $CODISCONF/redis_6380.conf
# echo "redis-server /usr/local/codis_server/conf/redis_6379.conf" >> /etc/rc.local
# echo "redis-server /usr/local/codis_server/conf/redis_6380.conf" >> /etc/rc.local
5.5.1.备注:
codis不是不负责维护主从,而是不会自动持续维护主从状态。在手动添加slave的时候会发送slave of指令,如果redis的slave of不写在配置文件里,重启会被重置。
6.
配置 Redis Server Group
(codis-proxy-1主机上操作)
6.1.添加server group
group id分别为(1、2、3),每group有2个redis实例,为一主一从。
添加redis master和slave到group 1
# codis-config -c $CODISCONF/config.ini server add 1 10.13.52.147:6379 master
# codis-config -c $CODISCONF/config.ini server add 1 10.13.50.113:6380 slave
添加redis master和slave到group 2
# codis-config -c $CODISCONF/config.ini server add 2 10.13.52.147:6379 master
# codis-config -c $CODISCONF/config.ini server add 2 10.13.50.214:6380 slave
添加redis master和slave到group 3
# codis-config -c $CODISCONF/config.ini server add 3 10.13.50.214:6379 master
# codis-config -c $CODISCONF/config.ini server add 3 10.13.43.144:6380 slave
6.1.1.备注:
添加 Redis Server Group,只允许有一个master,可以有多个slave,group id需要是大于等于1的整数。
6.2.设置 server group 服务的 slot 范围
# codis-config -c $CODISCONF/config.ini slot range-set 0 255 1 online
# codis-config -c $CODISCONF/config.ini slot range-set 256 511 2 online
# codis-config -c $CODISCONF/config.ini slot range-set 512 1023 3 online
6.2.1.备注:
Codis 采用 Pre-sharding 的技术来实现数据的分片,默认分成1024个slots (0-1023),每一个slot都会有一个特定的server group id,后端最多支持1024个Codis Server,路由信息保存在ZooKeeper中。
6.3.启动codis-proxy
# codis-proxy -c $CODISCONF/config.ini -L /tmp/codis.log --cpu=4 --addr=0.0.0.0:19000 --http-addr=0.0.0.0:11000 &
# echo "codis-proxy -c /usr/local/codis/conf/config.ini -L /tmp/codis.log --cpu=4 --addr=0.0.0.0:19000 --http-addr=0.0.0.0:11000" >> /etc/rc.local
6.3.1.备注:
--cpu 是codis-proxy 使用的CPU核数,根据主机的情况设置;
--addr是codis-proxy的redis server监听地址;
--http-addr是codis-proxy启动的http server,显示的调试信息可以访问 http://server_addr:port/debug/vars ;
启动dashboard时,codis管理界面端口为18087,10086的端口,实际上用不到;
6.4.测试插入数据
#/bin/bash
for i in {1..1000}
do
echo $i
redis-cli -h 10.13.63.112 -p 19000 set name$i $i
done
7.
在线增加分片
(codis-proxy-1主机上操作)
7.1.添加redis master和slave到group 4
# codis-config -c $CODISCONF/config.ini server add 4 10.13.43.144:6379 master
# codis-config -c $CODISCONF/config.ini server add 4 10.13.50.214:6380 slave
7.2.数据迁移
将slot id为[768-1023]的slot数据,迁移到 server group 4上,执行完命令后,数据会在后台迁移,web页面中可以看到迁移的状态。
# codis-config -c $CODISCONF/config.ini slot migrate 768 1023 4
8.
通过NGINX代理认证访问dashboard
8.1.配置nginx
# yum install -y nginx httpd
# vim /etc/nginx/conf.d/codis.conf
修改如下参数:
server {
listen 80;
server_name 10.13.63.112;
location / {
auth_basic "codis auth";
auth_basic_user_file /etc/nginx/passwd.db;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://10.13.63.112:18087;
}
}
8.2.启动nginx
# htpasswd -c /etc/nginx/passwd codis
# service nginx start
# chkconfig nginx on
# chkconfig httpd off
8.2.1.备注:
因为codis的dashboard不支持认证访问,可以通过nginx代理做认证访问(htpasswd的apache的一个命令工具,用于生成http 基本认证的密码文件 ),可以用防火墙关闭18087端口。通过URL浏览器访问codis的dashboard。
9.
Codis跨机房迁移思路
1、广州BGP机房和北京BGP机房的主机数量、系统版本、环境变量、软件版本保持一样;
2、启动北京BGP机房的zookeeper主机,并加入广州BGP机房的zookeeper集群(机器数量为奇数);
3、启动北京BGP机房的codis-server主机,在广州BGP主机执行命令并加入Redis Server Group;
4、数据从广州BGP机房迁移到北京BGP机房的codis-server,执行如下命令codis-config slot migrate
5、启动北京BGP机房的codis-proxy主机,注意config.ini的proxy_id参数;
6、停止广州BGP机房的codis-proxy主机;
7、停止广州BGP机房的dashboard,启动北京BGP机房的dashboard;
8、在广州BGP机房执行codis-config添加北京BGP机房的codis-server后,在dashboard显示公网IP,如何把公网IP改成内网IP?比较简单的方法是用codis-config slot migrate重新迁移一次;
10.
Codis dashboard使用
Dashboard不仅仅是管理页面,还可以负责Proxy的负载分配,添加和删除Codis组,加和删除Codis-server,迁移数据等。
10.1.dashboard每秒钟去proxy取的值
10.2.添加Server Groups
10.3.添加codis-server地址
10.4.设置slot范围到Group
10.5.迁移slot
10.6.codis-proxy状态
10.7.codis-server状态
运维帮近期活动预告,点击了解详情
运维帮技术沙龙《架构之美》 (3.26@成都站)
《应用性能管理大讲堂》沙龙报名啦!(3.26@北京)
51CTO《 WOT2016运维大会》(4.14@北京)
运维帮技术沙龙《架构之美》 (3.26@成都站)
《应用性能管理大讲堂》沙龙报名啦!(3.26@北京)
51CTO《 WOT2016运维大会》(4.14@北京)
欢迎加入运维帮QQ技术讨论群:542812110
点我加入运维帮会员,沙龙举办城市你说了算
快乐分享,快乐生活
商务合作,请加微信yunweibang008
关注 运维帮
微信扫一扫关注公众号