Fork me on GitHub

Codis3.1 集群安装部署

Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有显著区别, 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务。

环境说明

codis架构图




分配角色

主机名 IP地址 操作系统 用途
codis-1 10.16.20.62 CentOS 6.5 codis-dashboard、codis-fe、codis-ha、codis-proxy1、codis_group1_M(6379)、codis_group3_S(6380)
codis-2 10.16.20.63 CentOS 6.5 codis-proxy2、codis_group2_M(6379)、codis_group1_S(6380)
codis-3 10.16.20.64 CentOS 6.5 codis-proxy3、codis_group3_M(6379)、codis_group2_S(6380)

软件版本

codis3.x组件说明

  • Codis Server:基于 redis-2.8.21 分支开发。增加了额外的数据结构,以支持 slot 有关的操作以及数据迁移指令,具体的修改可以参考文档 redis的修改。

  • Codis Proxy:客户端连接的 Redis 代理服务, 实现了 Redis 协议。除部分命令不支持以外,表现的和原生的 Redis 没有区别(就像 Twemproxy)。 对于同一个业务集群而言,可以同时部署多个codis-proxy实例,不同 codis-proxy 之间由 codis-dashboard 保证状态同步。

  • Codis Dashboard:集群管理工具,支持 codis-proxy、codis-server 的添加、删除以及数据迁移等操作。在集群状态发生改变时,codis-dashboard 维护集群下所有 codis-proxy 的状态一致性。 对于同一个集群而言,同一个时刻 codis-dashboard 只能有 0个或者1个,所有对集群的修改都必须通过 codis-dashboard 完成。

  • Codis Admin:集群管理的命令行工具,可用于控制codis-proxy、codis-dashboard状态以及访问外部存储。

  • Codis FE:集群管理界面。多个集群可以共享同一个前端展示页面,通过配置文件管理后端 codis-dashboard 列表,配置文件可自动更新。

  • Codis HA:为集群提供高可用,依赖 codis-dashboard 实例,自动抓取集群各个组件的状态,会根据当前集群状态自动生成主从切换策略,并在需要时通过 codis-dashboard 完成主从切换。

  • Storage:为集群状态提供外部存储,提供Namespace概念,不同集群会按照不同product name进行组织;目前仅提供了Zookeeper 和Etcd两种实现,但是提供了抽象的interface可自行扩展。

环境准备


codis集群的搭建,需要依赖zookeeper集群

zookeeper集群


而zookeeper是需要依赖java jdk的

jdk 1.8安装

这里直接去官网下载jdk 1.8的rpm包,http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
1
2
3
4
5
6
7
8
9
yum -y install jdk-8u112-linux-x64.rpm
# 下载完安装jdk即可
vim /etc/profile.d/java.sh
# 修改java环境变量
export JAVA_HOME=/usr/java/jdk1.8.0_11
export PATH=$JAVA_HOME/bin:$PATH
source /etc/profile.d/java.sh
# 重载环境变量

zookeeper集群安装

下载完zookeeper之后,解压
1
2
3
4
5
6
7
8
9
10
11
12
13
14
tar -xvf zookeeper-3.4.8.tar.gz
mv zookeeper-3.4.8 /usr/local/
cd /usr/local/zookeeper-3.4.8/conf/
mv zoo_sample.cfg{,.bak}
vim zoo.cfg
lientCnxns=50
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/work/zookeeper/
clientPort=2181
server.1=10.16.20.63:2888:3888
server.2=10.16.20.64:2888:3888
server.3=10.16.20.62:2888:3888

说明:server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。

创建数据存储目录,并设置当前zk的结点ID
服务器1

1
2
mkdir -pv /work/zookeeper
echo "1" > /work/zookeeper/myid

服务器2

1
2
mkdir -pv /work/zookeeper
echo "2" > /work/zookeeper/myid

服务器3

1
2
mkdir -pv /work/zookeeper
echo "3" > /work/zookeeper/myid

启动zookeeper,分别在三台机器上启动zookeepe

1
2
3
4
/usr/local/zookeeper-3.4.8/bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.4.8/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

确保zookeeper集群是否启动成功

1
2
3
4
/usr/local/zookeeper-3.4.8/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/zookeeper-3.4.8/bin/../conf/zoo.cfg
Mode: follower

go语言环境搭建


下载go语言包,由于国内的特殊情况,有些网站是访问不了的。所以还是要自行去网站下载,网址:http://www.golangtc.com/download/ , 下载完毕后解压到/usr/local如下:
1
2
3
4
5
6
7
8
9
10
tar -zxf go1.6.2.linux-amd64.tar.gz -C /usr/local/
vim /etc/profile.d/go.sh
# 设置go语言环境变量
export GOROOT=/usr/local/go
export GOPATH=/usr/local/codis
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
source /etc/profile.d/go.sh
# 重载环境变量
go version
go version go1.6.2 linux/amd64

codis集群安装

codis安装

设置编译环境

添加 $GOPATH/bin 到 $PATH,安装 godep 工具
1
2
go get -u github.com/tools/godep && which godep
/usr/local/codis/bin/godep

下载 Codis 源代码

Codis 源代码需要下载到 $GOPATH/src/github.com/CodisLabs/codis
1
2
mkdir -p $GOPATH/src/github.com/CodisLabs
cd $_ && git clone https://github.com/CodisLabs/codis.git -b release3.1

编译 Codis 源代码

Codis 编译过程使用了 godep,请确定编译之前 godep 能正常工作
直接通过 make 进行编译
1
2
3
4
5
6
7
8
9
cd $GOPATH/src/github.com/CodisLabs/codis
make
make -j -C extern/redis-2.8.21/
... ...
go build -i -o bin/codis-dashboard ./cmd/dashboard
go build -i -o bin/codis-proxy ./cmd/proxy
go build -i -o bin/codis-admin ./cmd/admin
go build -i -o bin/codis-ha ./cmd/ha
go build -i -o bin/codis-fe ./cmd/fe

编译成功后在codis下面的bin目录下会有assets codis-admin codis-dashboard codis-fe codis-ha codis-proxy codis-server redis-benchmark redis-cli version等文件,assets是codis-dashboard http服务需要的前端资源,需要和codis-dashboard放置在同一目录下。

编辑redis配置文件


每台codis服务器上,要启动两个redis实例(也可以启动多个redis实例),先配置两个实例,从redis实例的配置文件中找到下列参数选项并按如下进行修改:
1
2
3
4
5
6
7
8
9
mkdir -pv /work/codis
mkdir -pv /var/log/redis
vim /usr/local/codis/src/github.com/CodisLabs/codis/extern/redis-test/conf/6379.conf
daemonize yes
pidfile /var/run/redis6379.pid
port 6379
logfile /var/log/redis/6379.log
dbfilename dump6379.rdb
dir /work/codis

配置第二个redis实例6380.conf同上设置。
每台codis服务器上redis配置完毕后,启动redis实例,如下:

1
2
3
4
5
cd /usr/local/codis/src/github.com/CodisLabs/codis/bin/
./codis-server ../extern/redis-test/conf/6379.conf &
./codis-server ../extern/redis-test/conf/6380.conf &
ps -ef |grep codis-server
# 确认6379和6380两个进程正在跑

Codis Dashboard


Coddis3.0的dashboard与codis 2.0有所不同,作为集群管理工具,它支持codis-proxy,codis-server的添加、删除以及数据迁移等操作。在集群状态发生改变时,codis-dashboard 维护集群下所有 codis-proxy 的状态一致性。有以下两点注意事项:

  1. 对于同一个业务集群而言,同一个时刻codis-dashboard只能有0个或者1个;
  2. 所有对集群的修改都必须通过codis-dashboard完成。

默认配置文件dashboard.toml可由codis-dashboard生成。

#bin/codis-dashboard –default-config | tee dashboard.toml(就是dashboard.conf)
生成dashboard.toml文件,可自行配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
vim dashboard.toml
coordinator_name = "zookeeper"
coordinator_addr = "10.16.20.62:2181,10.16.20.63:2181,10.16.20.64:2181"
# Set Codis Product Name/Auth.
product_name = "codis-demo"
product_auth = ""
# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:18080"
# coordinator_name 外部存储类型,接受 zookeeper/etcd
# coordinator_addr 外部存储地址
# product_name 集群名称,满足正则 \w[\w\.\-]*
# product_auth 集群密码,默认为空
# admin_addr RESTful API 端口
```bash
启动dashboard
```bash
nohup bin/codis-dashboard --ncpu=4 --config=dashboard.toml --log=dashboard.log --log-level=WARN &

1
2
3
4
5
6
7
8
9
10
Usage:
codis-dashboard [--ncpu=N][--config=CONF] [--log=FILE] [--log-level=LEVEL] [--host-admin=ADDR]
codis-dashboard --default-config
codis-dashboard --version
说明:
--ncpu=N 最大使用 CPU 个数
-c CONF, --config=CONF 指定启动配置文件
-l FILE, --log=FILE 设置 log 输出文件
--log-level=LEVEL 设置log输出等级:INFO,WARN,DEBUG,ERROR;默认INFO,推荐WARN
正常关闭dashboard命令: bin/codis-admin --dashboard=192.168.33.6:18080 --shutdown

Codis Proxy


对于同一个业务集群而言,可以同时部署多个codis-proxy 实例;
不同 codis-proxy 之间由 codis-dashboard 保证状态同步。
默认配置文件 proxy.toml 可由 codis-proxy 生成
1
bin/codis-proxy --default-config | tee proxy.toml

生成proxy.toml可自行配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
vim proxy.toml
# Set Codis Product {Name/Auth}.
product_name = "codis-demo"
product_auth = ""
# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:11080"
# Set bind address for proxy, proto_type can be "tcp","tcp4", "tcp6", "unix" or "unixpacket".
proto_type = "tcp4"
proxy_addr = "0.0.0.0:19000"
# Set jodis address & session timeout.
jodis_addr = ""
jodis_timeout = 10
# Proxy will ping-pong backend redis periodly to keep-alive
backend_ping_period = 5
# If there is no request from client for a long time, the connectionwill be droped. Set 0 to disable.
session_max_timeout = 1800
# Buffer size for each client connection.
session_max_bufsize = 131072
# Number of buffered requests for each client connection.
# Make sure this is higher than the max number of requests for eachpipeline request, or your client may be blocked.
session_max_pipeline = 1024
# Set period between keep alives. Set 0 to disable.
session_keepalive_period = 60
#product_name 集群名称,参考dashboard参数说明
#product_auth 集群密码,默认为空
#admin_addr RESTfulAPI 端口
#proto_type Redis 端口类型,接受tcp/tcp4/tcp6/unix/unixpacket
#proxy_addr Redis 端口地址或者路径
#jodis_addr Jodis注册zookeeper地址
#jodis_timeout Jodis注册sessiontimeout时间,单位second
#jodis_compatible Jodis注册 zookeeper 的路径
#backend_ping_period 与codis-server 探活周期,单位second,0表示禁止
#session_max_timeout 与client 连接最大读超时,单位second,0表示禁止
#session_max_bufsize 与client 连接读写缓冲区大小,单位byte
#session_max_pipeline 与client 连接最大的pipeline大小
#session_keepalive_period 与client 的 tcp keepalive周期,仅tcp有效,0表示禁止

启动proxy

1
nohup bin/codis-proxy --ncpu=4 --config=proxy.toml --log=proxy.log --log-level=WARN &

codis-proxy启动后,处于 waiting 状态,监听proxy_addr 地址,但是不会accept连接。添加到集群并完成集群状态的同步,才能改变状态为online。添加的方法有以下两种:
通过codis-fe添加:通过Add Proxy按钮,将admin_addr加入到集群中;(这个我们稍后再说)
通过codis-admin命令行工具添加,方法如下:

1
2
3
bin/codis-admin --dashboard=10.16.20.62:18080 --create-proxy -x 10.16.20.62:11080
bin/codis-admin --dashboard=10.16.20.62:18080 --create-proxy -x 10.16.20.63:11080
bin/codis-admin --dashboard=10.16.20.62:18080 --create-proxy -x 10.16.20.64:11080

其中10.16.20.62:18080 以及10.16.20.63:11080 分别为dashboard和proxy的admin_addr 地址。
添加过程中,dashboard会完成如下一系列动作:

  1. 获取 proxy 信息,对集群name以及auth进行验证,并将其信息写入到外部存储中;
  2. 同步slots状态;
  3. 标记proxy状态为online,此后proxy开始accept连接并开始提供服务。
1
2
3
4
5
6
7
8
9
10
11
12
#bin/codis-proxy -h
Usage:
codis-proxy [--ncpu=N][--config=CONF] [--log=FILE] [--log-level=LEVEL] [--host-admin=ADDR]
[--host-proxy=ADDR] [--ulimit=NLIMIT]
codis-proxy --default-config
codis-proxy --version
Options:
--ncpu=N 最大使用 CPU 个数
-c CONF, --config=CONF 指定启动配置文件
-l FILE, --log=FILE 设置 log 输出文件
--log-level=LEVEL 设置 log 输出等级:INFO,WARN,DEBUG,ERROR;默认INFO,推荐WARN
--ulimit=NLIMIT 检查ulimit -n的结果,确保运行时最大文件描述不少于NLIMIT

Codis FE


集群管理界面:

  • 多个集群实例可以共享同一个前端展示页面
  • 通过配置文件管理后端codis-dashboard列表,配置文件可自动更新

配置codis-fe
配置文件codis.json(fe.conf)可以手动编辑,也可以通过codis-admin从外部存储中拉取

1
2
3
4
5
6
7
8
9
10
11
12
bin/codis-admin --dashboard-list --zookeeper=10.16.20.62:2181 | tee codis.json
2016/12/20 16:51:50 zkclient.go:23: [INFO] zookeeper - zkclient setup new connection to 10.16.20.62:2181
2016/12/20 16:51:50 zkclient.go:23: [INFO] zookeeper - Connected to 10.16.20.62:2181
2016/12/20 16:51:50 zkclient.go:23: [INFO] zookeeper - Authenticated: id=97138763315609600, timeout=40000
[
{
"name": "codis-demo",
"dashboard": "10.16.20.62:18080"
}
]
2016/12/20 16:51:50 zkclient.go:23: [INFO] zookeeper - Recv loop terminated: err=EOF
2016/12/20 16:51:50 zkclient.go:23: [INFO] zookeeper - Send loop terminated: err=<nil>

启动codis-fe

1
2
nohup bin/codis-fe --ncpu=4 --log=fe.log --log-level=WARN --dashboard-list=codis.json --listen=0.0.0.0:18090 &
# 这里指定端口号为18090是为了防止和codis-dashboard的端口号18080冲突

1
2
3
4
5
6
7
8
9
10
#bin/codis-fe -h
Usage:
codis-fe [--ncpu=N][--log=FILE] [--log-level=LEVEL] --dashboard-list=LIST --listen=ADDR
codis-fe --version
Options:
--ncpu=N 最大使用 CPU 个数
-d LIST,--dashboard-list=LIST 配置文件,能够自动刷新
-l FILE, --log=FILE 设置 log 输出文件
--log-level=LEVEL 设置 log 输出等级:INFO,WARN,DEBUG,ERROR;默认INFO,推荐WARN
--listen=ADDR HTTP 服务端口

打开浏览器,在地址栏里输入http://192.168.4.157:18090/,通过管理界面操作Codis

除了图形界面进行如上操作外,还可以通过命令进行操作。
创建组:

1
2
#bin/codis-admin --dashboard=192.168.33.6:18080 --create-group --gid=1
#bin/codis-admin --dashboard=192.168.33.6:18080 --create-group --gid=2

组添加服务器:

1
2
#bin/codis-admin --dashboard=192.168.33.6:18080 --group-add --gid=1 --addr=192.168.33.6:6379
#bin/codis-admin --dashboard=192.168.33.6:18080 --group-add --gid=1 --addr=192.168.33.6:6380

把从库跟主库同步(同一组的两个实例都要执行):

1
2
#bin/codis-admin --dashboard=192.168.33.6:18080 --sync-action --create --addr=192.168.33.6:6379
#bin/codis-admin --dashboard=192.168.33.6:18080 --sync-action --create --addr=192.168.33.6:6380

若从库需要提升为master,操作如下:

1
#bin/codis-admin --dashboard=192.168.33.6:18080 --promote-server --gid=1 --addr=192.168.33.6:6380(从库ip和端口)

初始化 slots并设置 server group服务的slot范围((只在一节点执行一次)sid是slot的编号。Codis采用Pre-sharding技术来实现数据的分片, 默认分成1024个slots (0-1023), 对于每个key来说,通过以下公式确定所属的Slot Id : SlotId = crc32(key) % 1024每一个slot都会有一个且必须有一个特定的server group id来表示这个slot的数据由哪个server group来提供。

1
2
#bin/codis-admin --dashboard=192.168.33.6:18080 --slot-action --create-range --beg=0 --end=300 --gid=1
#bin/codis-admin --dashboard=192.168.33.6:18080 --slot-action --create-range --beg=301 --end=601 --gid=2

Codis HA


注意:Codis HA工具仅仅是Codis 集群HA 的一部分,单独工作能力有限。

  • 默认以 5s为周期,codis-ha会从codis-dashboard中拉取集群状态,并进行主从切换;

codis-ha 在以下状态下会退出:

  • 从 codis-dashboard 获取集群状态失败时;
  • 向codis-dashboard发送主从切换指令失败时。

odis-ha在以下状态下不会进行主从切换:

  • 存在proxy状态异常:因为提升主从需要得到所有proxy的确认,因此必须确保操作时所有proxy都能正常响应操作指令;
  • 网络原因造成的master异常:若存在slave满足slave.master_link_status == up,通常可以认为master并没有真的退出,而是由于网络原因或者响应延迟造成的master状态获取失败,此时codis-ha不会对该group进行操作;
    n没有满足条件的slave时。提升过程会选择满足slave.master_link_status == down,并且slave.master_link_down_since_seconds最小的进行操作。这就要求被选择的slave至少在过去一段时间内与master是成功同步状态,这个时间间隔是2d+5,其中d是codis-ha检查周期默认5秒。

注意:应用codis-ha时还需要结合对codis-proxy和codis-server的可用性监控,否则codis-ha无法保证可靠性。

需要注意:codis-ha将其中一个slave升级为master时,该组内其他slave是不会自动改变状态的,这些slave仍将试图从旧的master上同步数据,因而会导致组内新的master和其他slave之间的数据不一致。因为redis的slaveof命令切换master时会丢弃slave上的全部数据,从新master完整同步,会消耗资源。因此,当出现主从切换时,需要管理员手动创建新的sync action来完成新master与slave之间的数据同步。

启动codis-ha

1
nohup bin/codis-ha --log=ha.log --log-level=WARN --dashboard=10.16.20.62:18080 &

1
2
3
4
5
6
Usage:
codis-ha [--log=FILE][--log-level=LEVEL] --dashboard=ADDR
codis-ha --version
Options:
-l FILE, --log=FILE 设置 log 输出文件
--log-level=LEVEL 设置 log 输出等级:INFO,WARN,DEBUG,ERROR;默认INFO,推荐WARN


    本文标题   :   Codis3.1 集群安装部署

    文章作者   :   火柴

    发布时间   :   2016年12月20日 - 14时12分

    本文链接   :   http://www.chen-hao.com.cn/Codis3-1-集群安装部署.html

    本文字数   :   本文一共有3,980字

    许可协议   :   Attribution-NonCommercial 4.0

    © 转载请保留以上信息,谢谢合作。