早期Redis分布式集群的部署方案:
- 客户端分区:由客户端程序决定key写分配和写入的redis node,但是需要客户端自己处理写入分配、高可用管理和 故障转移等
- 代理方案:基于三方软件实现redis proxy,客户端先连接之代理层,由代理层实现key的写入分配,对客户端来说 是有比较简单,但是对于集群管节点增减相对比较麻烦,而且代理本身也是单点和性能瓶颈。
哨兵主要解决了主从切换问题,但是还存在redis单机写入的瓶颈问题。
此redis官方在redis 3.0版本之后推出了无中心架构的redis cluster机制,在无中心的redis集群当中,其每个节点保存当前节点数据和整个集群状态,每个节点都和其他所有节点连接,特点如下:
- 所有Redis节点使用(PING机制)互联
- 集群中某个节点的失效,是整个集群中超过半数的节点监测都失效才算真正的失效
- 客户端不需要proxy即可直接连接redis,应用程序需要写全部的redis服务器IP。
- redis cluster把所有的redis node映射到 0-16383个槽位(slot)上,读写需要到指定的redis node上进行 操作,因此有多少个reids node相当于redis 并发扩展了多少倍。
- Redis cluster预先分配16384个(slot)槽位,当需要在redis集群中写入一个key -value的时候,会使用 CRC16(key) mod 16384之后的值,决定将key写入值哪一个槽位从而决定写入哪一个Redis节点上,从而有效解决单 机瓶颈。
一、Redis Cluster 架构
假如三个主节点分别是:A, B, C 三个节点,采用哈希槽 (hash slot)的方式来分配16384个slot 的话,它们三个节点分别承担的slot 区间是:
使用 CRC16(key) mod 16384 之后的值跟以下三个节点进行匹配
节点A覆盖 0-5460
节点B覆盖 5461-10922
节点C覆盖 10923-16383
二、配置Redis Cluster前的注意事项
- 每个redis node节点采用相同的硬件配置、相同的密码、相同的redis版本。
- 每个节点必须开启的参数
cluster-enabled yes #开启集群状态
cluster-config-file nodes-6370.conf #指定集群配置文件名称,该文件自动创建和维护,无需手动操作
- 所有redis服务器必须没有任何数据,不能有任何key
- 先启动为单机redis且没有任何key value
三、创建Redis Cluster集群
3.1 Redis 版本 3 和 4
需要使用到集群管理工具redis-trib.rb,这个工具是redis官方推出的管理redis集群的工具,集成在redis的源码src目录下,是基于redis提供的集群命令封装成简单、便捷、实用的操作工具,redis-trib.rb是redis作者用ruby开发完成的,centos 系统yum安装的ruby存在版本较低问题。
root@ubuntu1804:~# cp /usr/local/src/redis-4.0.14/src/redis-trib.rb /usr/bin/
root@ubuntu1804:~# redis-trib.rb -h
/usr/bin/env: ‘ruby’: No such file or directory
提示说没有安装ruby,需要我们去手动安装
ruby版本需要大于等于2.3.0
[root@s1 src]# gem install redis
Fetching: redis-4.1.2.gem (100%)
ERROR: Error installing redis:
redis requires Ruby version >= 2.3.0.
Ubuntu安装ruby
root@ubuntu1804:~# apt-cache madison ruby
ruby | 1:2.5.1 | https://mirrors.aliyun.com/ubuntu bionic/main amd64 Packages
apt -y install ruby
gem install redis
Centos安装ruby
yum remove ruby rubygems -y #先卸载较低版本的ruby
cd /usr/local/src
wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.5.tar.gz
tar xf ruby-2.5.5.tar.gz
cd ruby-2.5.5
./configure
make -j 2
make install
gem install redis
#如果无法在线安装,可以下载reids模块安装包离线安装
https://rubygems.org/gems/redis #先下载redis模块安装包
gem install -l redis-3.3.0.gem #安装redis模块
安装完成之后,验证命令是否可用
root@ubuntu1804:~# redis-trib.rb
Usage: redis-trib <command> <options> <arguments ...>
create host1:port1 ... hostN:portN #指定IP:Port,创建集群
--replicas <arg> #指定master的副本数量,一个master下面有一个slave,应该写"1"
check host:port #检查集群信息
info host:port #检查集群主机信息
fix host:port #修复集群
--timeout <arg>
reshard host:port #在线热迁移集群指定主机的slots数据
--from <arg>
--to <arg>
--slots <arg>
--yes
--timeout <arg>
--pipeline <arg>
rebalance host:port #平衡集群中各主机的slot数量
--weight <arg>
--auto-weights
--use-empty-masters
--timeout <arg>
--simulate
--pipeline <arg>
--threshold <arg>
add-node new_host:new_port existing_host:existing_port #添加主机到集群
--slave
--master-id <arg>
del-node host:port node_id #删除主机
set-timeout host:port milliseconds #设置节点的超时时间
call host:port command arg arg .. arg #在集群上的所有节点上执行命令
import host:port #导入外部redis服务器的数据到当前集群
--from <arg>
--copy
--replace
help (show this help)
For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
修改redis的登陆密码,password为123456
root@ubuntu1804:~# find / -name client.rb
root@ubuntu1804:~# vim /var/lib/gems/2.5.0/gems/redis-4.3.1/lib/redis/client.rb
创建集群,其中前三个为master,后三个为slave
redis-trib.rb create --replicas 1 10.0.0.31:6379 10.0.0.32:6379 10.0.0.33:6379 10.0.0.34:6379 10.0.0.35:6379 10.0.0.36:6379
记得在redis的slave配置文件中配置主从的认证密码,不然集群中的主从起不来。
Node A Master:10.0.0.31
Node A Slave:10.0.0.35
Node B Master:10.0.0.32
Node B Slave:10.0.0.36
Node C Master:10.0.0.33
Node C Slave:10.0.0.34
3.2 Redis 版本 5
redis-cli -a 123456 --cluster create 192.168.7.101:6379 192.168.7.101:6380 192.168.7.102:6379 192.168.7.102:6380 1 92.168.7.103:6379 192.168.7.103:6380 --cluster-replicas 1
四、验证Redis Cluster集群
4.1 查看集群信息
cluster_state:ok 表示集群正常
root@ubuntu1804:~# redis-cli
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:1401
cluster_stats_messages_pong_sent:1448
cluster_stats_messages_sent:2849
cluster_stats_messages_ping_received:1443
cluster_stats_messages_pong_received:1400
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:2848
4.2 查看集群node对应关系
127.0.0.1:6379> CLUSTER NODES
f44add80c6b2179d93eb68c4169238da94d66476 10.0.0.34:6379@16379 slave 159eadcb486b6b2b5956281ddf47d9d75b0a22be 0 1626445236464 4 connected
159eadcb486b6b2b5956281ddf47d9d75b0a22be 10.0.0.33:6379@16379 master - 0 1626445237481 3 connected 10923-16383
3eef4279bf52a4b4085cb87de75b8e3dd173e4c5 10.0.0.32:6379@16379 master - 0 1626445238507 2 connected 5461-10922
11236eab81bdde236455a16494537a6b83e0fc78 10.0.0.35:6379@16379 slave 0d3ba938ff620d3ddf909698f383757e4e311ebf 0 1626445236000 5 connected
5d48beb1ce78346849178cf060e3b08a7ddd7100 10.0.0.36:6379@16379 slave 3eef4279bf52a4b4085cb87de75b8e3dd173e4c5 0 1626445235444 6 connected
0d3ba938ff620d3ddf909698f383757e4e311ebf 10.0.0.31:6379@16379 myself,master - 0 1626445236000 1 connected 0-5460
4.3 确认slave状态为up
master_link_status:up 表示已连接到master
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:10.0.0.33
master_port:6379
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:798
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:2581792646c52617e9ffadec7e30d9e2f6c25690
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:798
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:798