redis集群方案与redis cluster集群实现
一:redis集群与高可用有多重方式可以实现,比如高可用可以使用哨兵或者redis主从+keepalived的方式实现,redis集群支持多重方式,比如客户端分片、代理方式、redis cluster以及Coodis,每个实现方式都有自己的优缺点,具体方案及实现如下:
1.1:客户端分片:
mysql、memcached以及redis等都可以通过客户端分片实现,其中mysql还可以通过客户端实现分库分表,客户端分片是在客户端将key进行hash按照不同的值保存到不同的redis 服务器,读取的话也是按照不同的位置进行读取,优势是比较灵活,不存在单点故障,缺点是添加节点需要重新配置分片算法,并且需要手动同步数据,在缓存场景客户端分片最适用于使用memcached,因为缓存是可以丢失一部分数据的,但是memcached可以做集群进行数据同步。
1.2:Redis Cluster:
在3.0版本以后支持,无中心,在某种情况下会造成数据丢失,其也是通过算法将数据分片保存至某个redis服务器,即不再通过客户端计算key保存的redis服务器,redis服务器需要提前设置好自己所负责的槽位,比如redis A负责处理0-5000的哈希槽位数据,redis B负责处理5001-10000的hash槽位数据,redis C负责处理10001-16384的hash槽位数据,redis cluster需要特定的客户端,要求客户端必须支持集群协议 ,但是目前还没有比较好的客户端。
这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说:
如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。
与此类似, 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。
因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。
redis cluster需要专门的客户端,比如python当中引入的redis模块也不能使用了, 目前官方的客户端也不是很多,需要自己开发,
1.3:代理:
例如Twemproxy,由proxy代替客户端换和服务端实现分片,可以使用在缓存场景中允许数据丢失的场景,其还支持memcached,可以为proxy配置算法,缺点为twemproxy是瓶颈,不支持数据迁移,官方github地址https://github.com/twitter/twemproxy/
1.4:Codis:豌豆荚的开源方案,目前redis集群比较稳定的方案,豌豆荚gitlab地址https://github.com/pingcap:
豌豆荚codis项目官方github地址https://github.com/CodisLabs/codis
可以动态扩容和缩容
多业务完全透明,业务不知道运行的是codis
支持多核心CPU,twemproxy只能单核
codis是有中心基于proxy的设计,是客户端像连接单机一样操作proxy
有部分命令不能支持,比如keys *等
支持group划分,组内可以设置一个主多个从,通过sentinel 监控redis主从,当主down了自动将从切换为主
设置的进程要最大等于CPU的核心,不能超过CPU的核心数
其基于zookeeper,里面保存的是key保存的redis主机位置,因此zookeeper要做高可用
监控可以使用接口和dashboard
tidb豌豆荚团队实现的分布式mysql数据库,github地址https://github.com/pingcap/tidb
二:实现redis cluster:
2.1:环境:
操作系统:Centos 7.2-1511
服务器数量:2 台,启动8个redis服务
redis 版本:3.2.6
2.2:部署redis cluster集群,并实现动态增加主机:
2.2.1:服务器分别下载并安装redis:
# cd /opt
# wget http://download.redis.io/releases/redis-3.2.6.tar.gz
# tar xvf redis-3.2.6.tar.gz
# ln -sv /opt/redis-3.2.6 /usr/local/redis
# cd /usr/local/redis/
# make && make install
2.2.2:需要服务器启动6个redis 服务做集群,实现3主3从,另外在准备2个服务做动态集群的主机添加,一个主一个从,一共是每个服务器启动8个redis 服务,因此需要准备8个不通的redis 配置文件:
[root@redis1 redis]# pwd
/usr/local/redi
# mkdir conf.d && cd conf.d
# mkdir `seq 6381 6388`
# cp /usr/local/redis/redis.conf /usr/local/redis/conf.d/6381/
# vim /usr/local/redis/conf.d/6381/redis.conf #主要修改以下地方,将各服务的端口、PID、日志文件以及数据持久保存的路径进行单独保存:
bind 0.0.0.0
port 6381
daemonize yes
pidfile /var/run/redis_6381.pid
loglevel notice
logfile "/usr/local/redis/conf.d/6381/6381.log"
dir /usr/local/redis/conf.d/6381/
maxmemory 512M
appendonly yes
appendfilename "6381.aof"
appendfsync everysec
cluster-enabled yes #必须打开cluster功能,否则集群创建不成功
cluster-config-file 6381.conf #每个主机一个配置文件,有集群创建和管理,集群内的各主机不能重名
2.2.3:服务器批量生成redis配置文件:
# cp /usr/local/redis/conf.d/6381/redis.conf /opt/ #复制配置文件为模板,通过sed批量生成reids 配置文件
# sed 's/6381/6382/g' /opt/redis.conf >> /usr/local/redis/conf.d/6382/redis.conf
# sed 's/6381/6383/g' /opt/redis.conf >> /usr/local/redis/conf.d/6383/redis.conf
# sed 's/6381/6384/g' /opt/redis.conf >> /usr/local/redis/conf.d/6384/redis.conf
# sed 's/6381/6385/g' /opt/redis.conf >> /usr/local/redis/conf.d/6385/redis.conf
# sed 's/6381/6386/g' /opt/redis.conf >> /usr/local/redis/conf.d/6386/redis.conf
# sed 's/6381/6387/g' /opt/redis.conf >> /usr/local/redis/conf.d/6387/redis.conf
# sed 's/6381/6388/g' /opt/redis.conf >> /usr/local/redis/conf.d/6388/redis.conf
2.2.4:服务器批量启动redis 服务并验证端口存在:
# for i in `seq 6381 6388`;do /usr/local/redis/src/redis-server /usr/local/redis/conf.d/$i/redis.conf;done
2.2.5:服务器验证redis 命令可以连接到redis服务:
# redis-cli -h 192.168.10.101 -p 6388
192.168.10.101:6388>
2.3:安装ruby 管理工具:
2.3.1:配置ruby源并安装redis管理工具:
# yum install ruby rubygems -y
# gem install redis
# gem sources -l #当前使用的源为国外,但是连接很慢而且经常连接不上,因此将其删除并添加阿里的ruby源
*** CURRENT SOURCES ***
https://rubygems.org/
# gem source -r https://rubygems.org/ #删除默认的国外ruby源
# gem sources --add https://ruby.taobao.org/ #添加淘宝的ruby源
# gem sources -l #验证ruby源已经更换
*** CURRENT SOURCES ***
https://ruby.taobao.org/
# gem sources -u #更新缓存
# gem install redis #安装redis 工具
Fetching: redis-3.3.2.gem (100%)
Successfully installed redis-3.3.2
Parsing documentation for redis-3.3.2
Installing ri documentation for redis-3.3.2
1 gem installed
2.3.2:复制ruby的管理脚本:
# cp /usr/local/redis/src/redis-trib.rb /usr/local/bin/redis-trib
2.3.3:redis-trib命令介绍:
# redis-trib help
Usage: redis-trib <command> <options> <arguments ...>
help (show this help)
del-node host:port node_id #删除节点
reshard host:port #重新分片
--timeout <arg>
--pipeline <arg>
--slots <arg>
--to <arg>
--yes
--from <arg>
fix host:port
--timeout <arg>
create host1:port1 ... hostN:portN #创建集群
--replicas <arg>
rebalance host:port
--timeout <arg>
--simulate
--pipeline <arg>
--threshold <arg>
--use-empty-masters
--auto-weights
--weight <arg>
call host:port command arg arg .. arg
add-node new_host:new_port existing_host:existing_port #添加节点
--slave
--master-id <arg>
check host:port #检测节点
import host:port
--replace
--copy
--from <arg>
set-timeout host:port milliseconds
info host:port
2.4:在单机部署redis cluster集群:
2.4.1:创建redis cluster:
# redis-trib create --replicas 1 192.168.10.101:6381 192.168.10.101:6382 192.168.10.101:6383 192.168.10.101:6384 192.168.10.101:6385 192.168.10.101:6386
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.10.101:6381
192.168.10.101:6382
192.168.10.101:6383
Adding replica 192.168.10.101:6384 to 192.168.10.101:6381 #前三个节点主主,后三个节点是从
Adding replica 192.168.10.101:6385 to 192.168.10.101:6382
Adding replica 192.168.10.101:6386 to 192.168.10.101:6383
M: fc3b44c6d18abbf7191338a8a7fafdc516b6d758 192.168.10.101:6381 #主
slots:0-5460 (5461 slots) master #master的分片位置
M: b3f5ba5a3b1f53e358f438c923f9591055510b96 192.168.10.101:6382 #主
slots:5461-10922 (5462 slots) master #master 的分片位置
M: 8fe3c52b352a1209dfc3b9f2f9fa1be9bc2e69a5 192.168.10.101:6383 #主
slots:10923-16383 (5461 slots) master #master的分片位置
S: b786bd3a567634a7087aa289714063ed6e53bb47 192.168.10.101:6384 #从
replicates fc3b44c6d18abbf7191338a8a7fafdc516b6d758
S: 7d2da4da536003b2c25c8599526c1c937d071e1e 192.168.10.101:6385 #从
replicates b3f5ba5a3b1f53e358f438c923f9591055510b96
S: cc76054bf257f9bbfec868b86880e22f04fab96e 192.168.10.101:6386 #从,可见后三个节点是前三个节点的从
replicates 8fe3c52b352a1209dfc3b9f2f9fa1be9bc2e69a5
Can I set the above configuration? (type 'yes' to accept): yes #输入yes继续,no退出
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join......
>>> Performing Cluster Check (using node 192.168.10.101:6381)
M: fc3b44c6d18abbf7191338a8a7fafdc516b6d758 192.168.10.101:6381 #当前redis服务的ID即主机IP短裤呢
slots:0-