博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实战Centos系统部署Codis集群服务
阅读量:7234 次
发布时间:2019-06-29

本文共 14881 字,大约阅读时间需要 49 分钟。

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

Codis 是 Wandoujia Infrastructure Team 开发的一个分布式 Redis 服务, 用户可以看成是一个无限内存的 Redis 服务, 有动态扩/缩容的能力. 对偏存储型的业务更实用, 如果你需要 SUBPUB 之类的指令, Codis 是不支持的. 时刻记住 Codis 是一个分布式存储的项目. 对于海量的 key, value不太大( <= 1M ), 随着业务扩展缓存也要随之扩展的业务场景有特效.

Codis github地址:https://github.com/CodisLabs/codis

Codis FAQ:https://github.com/CodisLabs/codis/blob/master/doc/FAQ_zh.md

二、Codis架构图
1、组件说明

Codis 由四部分组成:

Codis Proxy (codis-proxy)

Codis Dashboard (codis-config)

Codis Redis (codis-server)

ZooKeeper/Etcd

codis-proxy:是客户端连接的Redis代理服务,codis-proxy 本身实现了Redis协议,表现得和一个原生的Redis没什么区别(就像Twemproxy),对于一个业务来说,可以部署多个codis-proxy,codis-proxy本身是没状态的。

codis-config:是Codis的管理工具,支持包括,添加/删除Redis节点,添加/删除Proxy节点,发起数据迁移等操作,codis-config本身还自带了一个http server,会启动一个dashboard,用户可以直接在浏览器上观察Codis集群的状态。

codis-server:是Codis项目维护的一个Redis分支,基于2.8.13开发,加入了slot的支持和原子的数据迁移指令,Codis上层的codis-proxy和codis-config只能和这个版本的Redis交互才能正常运行。

ZooKeeper:用来存放数据路由表和codis-proxy节点的元信息,codis-config发起的命令都会通过ZooKeeper同步到各个存活的codis-proxy

注:Codis支持按照Namespace区分不同的产品,拥有不同的product name 的产品,各项配置都不会冲突。

2、实验环境
主机名 IP地址 角色
linux-node1 10.1.1.148 Zookeeper、redis_master,redis_slave
linux-node2 10.1.1.149 Zookeeper、redis_master,redis_slave
linux-node3 10.1.1.150 zookeeper,codis-proxy、redis_master,redis_slave

注:生产环境建议redis放到单独的服务器上面

3、安装配置

注:部署单个codis-proxy节点的环境,建议相关的安装包本地下载完上传到服务器上面。

#在codis-proxy(linux-node3)服务器上面操作

yum install -y git gcc make g++ gcc-c++ automake openssl-devel zlib-devel
3.1、安装GO

Go下载地址:http://www.golangtc.com/download

cd /usr/local/src/tar zxvf go1.7.linux-amd64.tar.gz -C /opt

注意:Zookeeper已搭建完成的下面安装JDK和zookeeper的步骤可以跳过。

3.2、安装JDK

JDK下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html

rpm -ivh jdk-8u65-linux-x64.rpm
3.3、安装zookeeper

Zookeeper下载地址:http://zookeeper.apache.org/releases.html#download

wget http://mirrors.cnnic.cn/apache/zookeeper/zookeeper-3.4.8/zookeeper-3.4.8.tar.gztar zxvf zookeeper-3.4.8.tar.gz -C /opt/
3.4、环境变量设置

修改环境变量:vim /etc/profile 在最后添加以下内容

#codis pathexport GOROOT=/opt/goexport GOPATH=/opt/codisJAVA_HOME=/usr/java/jdk1.8.0_101CLASS_PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/libexport PATH=$PATH:$GOROOT/bin:$JAVA_HOME/bin:

#测试环境变量设置

#执行source /etc/profile是环境变量生效,测试go是否正常安装:

cat hello.gopackage mainimport "fmt"func main(){fmt.Printf("hello,world\n")}
[root@linux-node-2 ~]# go run hello.gohello,world!
三、安装codis
[root@linux-node-3 ~]# yum -y install git[root@linux-node-3 opt]# go get -u -d github.com/CodisLabs/codis

可以看到no buildable Go source files in /opt/codis/src/github.com/wandoulabs/codis,我们在上面环境就是设置GOAPTH=/opt/codis,所以只要执行上面的获取命令,就会下载在/opt/codis下:

我们进到提示的路径进行安装,安装过程比较久,耐心等待:

[root@linux-node-3 ~]# cd /opt/codis/src/github.com/CodisLabs/codis

目录执行make命令编译代码,并执行make gotest来跑测试

make
make gotest

建议只通过go get命令来下载codis,除非你非常熟悉go语言的目录引用形式从而不会导致代码放错地方。该命令会下载master分支的最新版,我们会确保master分支的稳定。

执行全部指令后,会在 bin 文件夹内生成 codis-config、codis-proxy、codis-server三个可执行文件。另外, bin/assets 文件夹是 codis-config 的 dashboard http 服务需要的前端资源, 需要和 codis-config 放置在同一文件夹下)

通过git方式安装codis
git clone https://github.com/CodisLabs/codis.git

git仓库下载完毕后,我们接下来进行如下的操作。如下:

mkdir -p /opt/codis /src/github.com/CodisLabs/cp -r codis /opt/codis/src/github.com/CodisLabs/cd /opt/codis/src/github.com/CodisLabs/codis/

#以上操作完毕后,就和通过go下载安装方式一样,执行make命令进行编译,然后执行make gotest命令进行测试

通过源码包安装
wget https://github.com/CodisLabs/codis/archive/3.0.3.tar.gz -P /usr/local/srctar zxvf 3.0.3.tar.gz && cd codis-3.0.3 && make && make gotest
codis相关配置文件详解

#codis安装完成之后codis-config主要的使用方法

# ./bin/codis-config -h (master)usage: codis-config [-c ] [-L ] [--log-level=] [...] options: -c 配置文件地址 -L 日志输出文件地址 --log-level= 输出日志级别 (debug < info (default) < warn < error < fatal)commands:server redis 服务器组管理slot slot 管理dashboard 启动 dashboard 服务action 事件管理 (目前只有删除历史事件的日志)proxy proxy 管理
# ./bin/codis-proxy -husage: codis-proxy [-c ] [-L ] [--log-level=] [--cpu=] [--addr=] [--http-addr=]options:-c 配置文件地址-L 日志输出文件地址--log-level= 输出日志级别 (debug < info (default) < warn < error < fatal)--cpu= proxy占用的 cpu 核数, 默认1, 最好设置为机器的物理cpu数的一半到2/3左右--addr= proxy 的 redis server 监听的地址, 格式 :, 如: localhost:9000, :9001--http-addr= proxy 的调试信息启动的http server, 可以访问 http://debug_http_server_addr/debug/vars
四、配置codis集群

codis安装完毕后,我们现在来配置codis集群,在正式配置集群之前,先创建相关的目录,然后复制相关文件到新的目录下。

1、codis集群配置

使用如下命令:

cd /opt/codis/src/github.com/CodisLabs/codis/mkdir -p /opt/codis/{log,redis_conf}cp -rf bin/ /opt/codis/cp config.ini /opt/codis/cp extern/redis-test/conf/6379.conf /opt/codis/redis_conf/cp extern/redis-test/conf/6380.conf /opt/codis/redis_conf/
2、编辑codis配置文件
[root@linux-node3 codis]# egrep -v "^#|^$" config.ini
coordinator=zookeeperzk=192.168.1.148:2181,192.168.1.149:2181,192.168.1.150:2181product=testdashboard_addr=192.168.1.150:18087password=backend_ping_period=5session_max_timeout=1800session_max_bufsize=131072session_max_pipeline=1024zk_session_timeout=30000proxy_id=proxy_3

该配置文件中,我们需要注意三个参数:zk、dashboard_addr、proxy_id。

其中zk是表示zookeeper集群的服务器IP地址,dashboard_addr表示codis web管理的IP地址及端口,proxy_id表示codis的id,注意每台codis服务器该值要唯一。

3、编辑redis配置文件

每台codis服务器上,启动两个redis实例(也可以启动多个redis实例),配置两个redis,如下:

daemonize nopidfile /var/run/redis.pidport 6379tcp-backlog 511timeout 0tcp-keepalive 0loglevel noticelogfile /var/log/redis/6379.logdatabases 16stop-writes-on-bgsave-error yesrdbcompression yesrdbchecksum yesdbfilename dump6379.rdbdir /opt/codis/slave-serve-stale-data yesslave-read-only yesrepl-disable-tcp-nodelay noslave-priority 100appendonly noappendfilename "appendonly.aof"appendfsync everysecno-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mblua-time-limit 5000slowlog-log-slower-than 10000slowlog-max-len 128latency-monitor-threshold 0notify-keyspace-events ""hash-max-ziplist-entries 512hash-max-ziplist-value 64list-max-ziplist-entries 512list-max-ziplist-value 64set-max-intset-entries 512zset-max-ziplist-entries 128zset-max-ziplist-value 64hll-sparse-max-bytes 3000activerehashing yesclient-output-buffer-limit normal 0 0 0client-output-buffer-limit slave 256mb 64mb 60client-output-buffer-limit pubsub 32mb 8mb 60hz 10aof-rewrite-incremental-fsync yes

#注意红线标注的一个参数,配置第二个redis实例

\cp /opt/codis/redis_conf/6379.conf 6380.confsed -i 's/6379/6380/g' /opt/codis/redis_conf/6380.confmkdir -p /var/log/redis/

#上面操作需要在每台codis服务上面都执行。

echo 512 > /proc/sys/net/core/somaxconnsysctl vm.overcommit_memory=1

注:优化系统的参数

4、 初始化 slots

执行 bin/codis-config slot init,该命令会在zookeeper上创建slot相关信息

/opt/codis/bin/codis-config -c /opt/codis/config.ini slot init

#linux-node3、linux-node1、linux-node2

/opt/codis/bin/codis-server /opt/codis/redis_conf/6379.conf &/opt/codis/bin/codis-server /opt/codis/redis_conf/6380.conf &ps -ef | grep codis-server

#在三台codis-proxy上面分别启动redis实例

5、启动codis dashboard

#尽量在redis安装目录或者让redi的log目录下启动dashboard,这样方便查看启动产生的日志,nohup.out

nohup /opt/codis/bin/codis-config -c /opt/codis/config.ini dashboard &

#从图中可以看出dashboard已经启动完成,然后去web页面访问,codis dashboard访问端口是18087

#查看codis dashboard,浏览器访问http://192.168.1.150:18087/,如下:

#codis dashboard启动完成之后默认页面如上图所示,我们可以通过web页面新建redis_group,把刚刚启动好的redis实例加到不同的组当中、也可以通过命令行执行创建redis_group的操作。

6、添加 Redis Server Group

# 每一个 Server Group 作为一个Redis服务器组存在, 只允许有一个master, 可以有多个slave, group id仅支持大于等于1的整数

#在codis dashboard上使用命令新建server group

[root@linux-node3 ~]# cd /opt/codis/[root@linux-node3 codis]# ./bin/codis-config server -husage:codis-config server listcodis-config server addcodis-config server removecodis-config server promotecodis-config server add-groupcodis-config server remove-group

#如: 添加三个 server group, 每个 group 有两个 redis 实例,group的id分别为1和2, redis实例为一主一从。

#注:这里我把linux-node3,linux-node2,linux-node1上面的两个redis实例分别加到不同的server group当中,详细如下:

group_1: linux-node3 redis_6379 linux-node2 redis_6380group_2: linux-node2 redis_6379 linux-node1 redis_6380group_3: linux-node1 redis_5379 linux-node3 redis_6380

其中redis的6379端口作为redis master,6380作为slave

#添加一个group,group的id为1, 并添加一个redis master(192.168.1.150:6379)到该group

./bin/codis-config server add 1 192.168.1.150:6379 master

#添加一个redis slave(192.168.1.149:6380)到该group

./bin/codis-config server add 1 192.168.1.149:6380 slave

#添加一个group,group的id为2, 并添加一个redis master(192.168.1.149:6379)到该group

./bin/codis-config server add 2 192.168.1.149:6379 master

#添加一个redis slave(192.168.1.148:6380)到该group

./bin/codis-config server add 2 192.168.1.148:6380 slave

#添加一个group,group的id为3, 并添加一个redis master(192.168.1.148:6379)到该group

./bin/codis-config server add 3 192.168.1.148:6379 master

#添加一个redis slave(192.168.1.150:6380)到该group

./bin/codis-config server add 3 192.168.1.150:6380 slave

注意:每组添加的第一个redis实例不能被删除,因为codis默认把该redis实例设置为master。

#从图中我们可以看出server group 已经创建成功,到codis dashboard上面查看:

7、设置 server group 服务的 slot 范围,
https://github.com/CodisLabs/codis/blob/master/doc/FAQ_zh.md

Codis 采用 Pre-sharding 的技术来实现数据的分片, 默认分成 1024 个 slots (0-1023), 对于每个key来说, 通过以下公式确定所属的 Slot Id : SlotId = crc32(key) % 1024 每一个 slot 都会有一个且必须有一个特定的 server group id 来表示这个 slot 的数据由哪个 server group 来提供.

[root@linux-node3 codis]# ./bin/codis-config slot -husage:codis-config slot init [-f]codis-config slot infocodis-config slot setcodis-config slot range-setcodis-config slot migrate [--delay=]codis-config slot rebalance [--delay=]

#设置编号为[0, 340]的 slot 由 server group 1 提供服务, 编号 [341, 682] 的 slot 由 server group 2 提供服务,编号[683, 1023] 的 slot 由 server group 3 提供服务

./bin/codis-config slot range-set 0 340 1 online./bin/codis-config slot range-set 341 682 2 online./bin/codis-config slot range-set 683 1023 3 online

#查看slot的信息
/opt/codis/bin/codis-config -c /opt/codis/config.ini slot info 1/opt/codis/bin/codis-config -c /opt/codis/config.ini slot info 2/opt/codis/bin/codis-config -c /opt/codis/config.ini slot info 3

#slot操作完成可以到codis dashboard查看状态。如下:

8、启动 codis-proxy
./bin/codis-proxy -c config.ini -L ./log/proxy.log --cpu=1 --addr=0.0.0.0:19000 --http-addr=0.0.0.0:11000

nohup /opt/codis/bin/codis-proxy -c /opt/codis/config.ini --log-level=error -L /opt/codis/log/proxy.log --cpu=1 --addr=0.0.0.0:19000 --http-addr=0.0.0.0:11000 &

#下面对以上命令中的参数进行解释:

-c 配置文件地址。-L 日志输出文件地址。–log-level= 输出日志级别(debug –cpu= proxy占用的cpu核数,默认1,最好设置为机器的物理cpu数的一半到2/3左右。–addr= proxy的redis server监听的地址, 格式:, 如: localhost:9000, :9001。–http-addr= proxy的调试信息启动的http server,可以访问 http://debug_http_server_addr/debug/vars。

#codis-proxy启动后,我们可以在dashboard上进行查看,如下:

#到此codis集群搭建完毕,为了性能需求,建议redis实例和codis-proxy放到不同的服务器上面。

9、连接codis集群

codis集群搭建完毕后,测试连接codis集群。要连接codis集群,我们只需要连接codis-proxy即可。codis-proxy服务器地址:192.168.1.150,然后加19000端口。使用redis-cli命令连接,如下:

#在某台已安装redis实例的服务器上面测试:

8-28-23

通过上图,我们可以很明显的看到连接codis集群是ok的。

10、codis集群压测

我们现在对codis集群做一些压力测试,同时在dashboard上观察键值对的情况。如下:

./redis-benchmark -h 192.168.1.150 -p 19000 -c 1000 -d 1000 -t set -n 100000 -r 100000

上述命令的意思是,使用redis-benchmark压力测试命令连接codis集群,同时并发10000个(-c),测试set操作(-t),每个测试数据集是100字节(-d),请求数是100000(-n),使用使用随机数插入数值(-r)

11、数据迁移

安全和透明的数据迁移是 Codis 提供的一个重要的功能, 也是 Codis 区别于 Twemproxy 等静态的分布式 Redis 解决方案的地方

数据迁移的最小单位是 key, 我们在 codis redis 中添加了一些指令, 实现基于key的迁移, 如 SLOTSMGRT等 (命令列表), 每次会将特定 slot 一个随机的 key 发送给另外一个 codis redis 实例, 这个命令会确认对方已经接收, 同时删除本地的这个 k-v 键值, 返回这个 slot 的剩余 key 的数量, 整个操作是原子的.

在 codis-config 管理工具中, 每次迁移任务的最小单位是 slot

如: 将slot id 为 [0-340] 的slot的数据, 迁移到 server group 2上, --delay 参数表示每迁移一个 key 后 sleep 的毫秒数, 默认是 0, 用于限速.

#codis dashboard上面查看每个组中的数据状态,

#可以看出刚刚我们做过压测之后,每个redis组处理的key基本一致,然后我们把group_1中slot上的数据迁移到group_2上,--delay 参数表示每迁移一个 key 后 sleep 的毫秒数, 默认是 0, 用于限速.

$ bin/codis-config slot migrate 0 511 2 --delay=10

/opt/codis/bin/codis-config -c /opt/codis/config.ini slot migrate 0 340 2 --delay=10

#查看codis dashboard上,group状态:

#再次刷新,3s后

#对比group中两次的key变化,我们可以看出group_1中的slot数据正在向group_2迁移。

迁移的过程对于上层业务来说是安全且透明的, 数据不会丢失, 上层不会中止服务.

注意, 迁移的过程中打断是可以的, 但是如果中断了一个正在迁移某个slot的任务, 下次需要先迁移掉正处于迁移状态的 slot, 否则无法继续 (即迁移程序会检查同一时刻只能有一个 slot 处于迁移状态).

Auto Rebalance

Codis 支持动态的根据实例内存, 自动对slot进行迁移, 以均衡数据分布.

$ bin/codis-config slot rebalance

要求:

所有的codis-server都必须设置了maxmemory参数所有的 slots 都应该处于 online 状态, 即没有迁移任务正在执行所有 server group 都必须有 Master
五、Codis集群架构模拟故障测试

Server group实现主从切换,当同一个组中的某一台redis实例停止的时候,组中的其它redis实例自动切换为master角色,提供服务。

需要安装codis-ha插件,codis-ha可以安装在任意节点即可,只需要在一个节点上面安装。(本实验安装在linux-node2上)

go get github.com/ngaut/codis-ha[root@linux-node2 ~]# cd /opt/codis/src/github.com/ngaut/[root@linux-node2 ngaut]# cp -r codis-ha /opt/[root@linux-node2 ngaut]# cd /opt/codis-ha/[root@linux-node2 codis-ha]# go build
1、启动codis-ha服务
nohup $codis_ha_home/codis-ha -codis-config=192.168.1.150:18087 -log-level=info -productName=test &> /opt/codis-ha/codis-ha.log

注:-codis-config后跟dashboard所在服务器ip

重新启动codis-proxy服务

注:(以150机器配置为例,其余codis-proxy只需要修改下名称即可)

先停掉codis-proxy

[root@linux-node3 ~]# /opt/codis/bin/codis-config -c /opt/codis/config.ini proxy offline codis_proxy_3

#不同的机器只需要更改codis_proxy即可(本实验之重启了一台codis-proxy,且codis-ha服务已生效)

重新启动codis-proxy

nohup /opt/codis/bin/codis-proxy -c /opt/codis/config.ini --log-level=error -L /opt/codis/log/proxy.log --cpu=1 --addr=0.0.0.0:19000 --http-addr=0.0.0.0:11000 &

设置codis-proxy状态为online

[root@linux-node3 ~]# /opt/codis/bin/codis-config -c /opt/codis/config.ini proxy online codis_proxy_3

注:如果重启一台codis-proxy之后codis-ha服务没生效,需要重启三台codis-proxy

停止任意节点的zookeeper,检查codis-proxy,dashboard是否正常>

以zookeeper状态为leader那台服务器测试(linux-node2)

查看zookeeper状态确认是否为leader

[root@linux-node2 ~]# /opt/zookeeper/bin/zkServer.sh status

停止linux-node2上面的zookeeper节点,让其他zookeeper节点自动选择leader节点并提供服务

[root@linux-node2 ~]# /opt/zookeeper/bin/zkServer.sh stop

#随机检测其他节点的zookeeper状态,检测到linux-node2的zookeeper节点已经被选为leader,开始提供服务

#重启刷新codis dashboard可以看到dashboard是正常的。

检测redis客户端是否能正常访问codis-proxy

以linux-node3为例:

[root@linux-node3 ~]# cd /opt/codis/src/github.com/CodisLabs/codis/extern/redis-2.8.21/src/

#新建scripts目录,存放redis常用命令

[root@linux-node3 src]# mkdir -p /opt/codis/scripts/[root@linux-node3 src]# cp redis-cli redis-server redis-benchmark redis-check-dump /opt/codis/scripts/

从上面可以看出我之前set的两个key都能正常get到

停止任意group中的redis master实例,检查redis slave是否自动切换为master模拟linux-node1(192.168.1.148)上面的redis-master 6379端口挂掉

登录到codis-ha所在的节点(linux-node2)查看codis-ha日志,打印如下

打开dashbard界面,可以看到如下:

从图中可以看到group_3的salve节点已经自动切换到master状态

客户端写入数据,检查切换后的redis master实例是否有新key增加

#linux-nod3新增key

重新刷新dashboard界面,查看key变化

#恢复linux-node1上的redis实例的6379端口

[root@linux-node1 ~]# /opt/codis/bin/codis-server /opt/codis/redis_conf/6379.conf &[root@linux-node1 ~]# ps -ef | grep -v grep | grep codis-serverroot     16620 13759  0 Aug27 pts/0    00:04:52 /opt/codis/bin/codis-server *:6380root     27574 13759  2 19:40 pts/0    00:00:00 /opt/codis/bin/codis-server *:6379

刷新dashboard界面查看group中redis实例状态变化

可以看到linux-node1上面的端口为6379的redis实例已经启动并自动成为group_3中的slave

备注:假如当maste挂掉是,redis-ha检测自动将slave切换为master,但是master恢复后,如果状态仍为offline,可以把这个redis节点从group中移出,再重新添加。

2、报错解决:
/opt /bin/zkCli.shdelete /zk/codis/db_test/dashboard

#重启codis dashboard

 

ard &

本文转自Linux就该这么学博客园博客,原文链接:http://www.cnblogs.com/linuxprobe/p/5860937.html,如需转载请自行联系原作者

你可能感兴趣的文章
tomcat 403错误和ls: cannot open directory '.': Permission denied
查看>>
pfsense 2.2RC版本应用
查看>>
图像处理与机器视觉网络资源收罗——倾心大放送
查看>>
Fiddler 实现手机的抓包
查看>>
浅谈C++多态性
查看>>
[翻译] GVUserDefaults
查看>>
Openlayer跨域问题解决
查看>>
Windows7下的免费虚拟机(微软官方虚拟机)
查看>>
Hibernate Criterion
查看>>
AFNetworking 使用方法(2.0)
查看>>
React Canvas:高性能渲染 React 组
查看>>
Mono产品生命周期
查看>>
FetchType与FetchMode的区别
查看>>
GCD &amp;&amp; Run Loops学习笔记
查看>>
SQLite Learning、SQL Query Optimization In Multiple Rule
查看>>
[ios]sqlite轻量级数据库学习连接
查看>>
它们的定义ListView,实现Item除去滑动和滑出菜单效果
查看>>
2015第我35周三
查看>>
Web前端研发工程师编程能力飞升之路
查看>>
C#编程总结(十)字符转码
查看>>