Redis系列7-cluster(1)

  1. redis集群模式解决的问题

  • 并发量的瓶颈。

  • 内存的瓶颈

  • 网络带宽的瓶颈。

  1. 分布式数据库-数据分区

  • 常用的分区策略

  • 顺序分布

  • 哈希分布(例如节点取模)

  • 节点取余(客户端分区)

  • 一致性哈希(客户端分区)

  • 虚拟槽分区(服务端分区)

  • 顺序分布于哈希分区优缺点对比

  1. 哈希分区-节点取余详解

节点取余属于客户端分区,实现简单,但是在增加和删除节点时需要大量的数据迁移工作。

  • 添加节点

  • 多倍扩容

  • 如果在选用该方案时,在做扩容时建议多倍扩容,数据迁移量会减少到50%

  1. 哈希分区-一致性哈希详解

一致性哈希分布同样属于客户端分区,相对于根据节点取余的方式,一致性哈希算法会在增加或者删除节点时减少数据迁移的数量。

  • 什么是一致性哈希

  • 将0~2^32范围看成一个token环,给不同的node节点定义不同的值平均分配到该环上,根据hash算法计算出的hash值在0~2^32内,并且从该hash值开始按顺时针方向寻找,找到的第一个node节点就是该hash值存储的节点。

  • 添加节点

  • 添加n5节点时只有n1和n2的数据受到影响,当群中的节点较多时,影响的数据范围就会更小,memcache就使用的该算法实现的客户端分区。

  1. 虚拟槽分区

虚拟槽分区属于服务端分区。

  • 预设虚拟槽,每个槽映射一个数据子集,一般槽数比节点数大很多。

  • 良好的hash函数,例如CRC16。

  • 以redis-cluster为例进行讲解。redis-cluster将虚拟槽的个数设置为0~16383,实际为16384个。key经过CRC16 hash函数并且对16384取余,此时可以确定其所属的槽范围,在根据集群的节点与槽的映射关系,来确定数据的处理节点。

  • 虚拟槽的好处

  • 在增加节点时,必须由原有的node节点将其处理的槽节点分配给新node节点,并且将其数据同步给新node节点,才可以使用。这样就会减少大量的数据回源。删除node节点时也是如此。

  1. redis-cluster的基本架构

  • 回顾下redis单机架构

  • redis分布式架构

  • 节点与节点之间是互相通信的,也就保证了每个节点都会知道集群中虚拟槽的分配,当client访问任意一个节点时,node节点可以判断出是否应该是当前节点进行处理,如果不是则返回应处理的节点。如果client每次都随机访问redis-cluster集群中的节点时,这样会有性能问题,大概率会进行两次请求,所以后续引入的智能客户端的概念,client也会维护redis-cluster集群node与虚拟槽的映射关系。

  • redis-cluster安装的关键因素

  • node节点

  • 需要设置配置,cluster-enabled yes。

  • meet操作

  • 节点间互相通信的基础

  • 指派槽

  • 当上述操作完成后,需要给node指派对应的槽信息。

  1. 原生搭建redis-cluster集群

  • 整体结构图

  • 7100、7101、7102为主节点。

  • 7103、7104、7105为从节点。

  • 各节点配置

  • 7100

port 7100
pidfile /var/run/redis_7100.pid
logfile "7100.log"
dbfilename dump-7100.rdb
dir /Users/xiaosa/learning/redis/data/7100-data
cluster-enabled yes
cluster-config-file nodes-7100.conf
cluster-require-full-coverage no
  • 7101

port 7101
pidfile /var/run/redis_7101.pid
logfile "7101.log"
dbfilename dump-7101.rdb
dir /Users/xiaosa/learning/redis/data/7101-data
cluster-enabled yes
cluster-config-file nodes-7101.conf
cluster-require-full-coverage no
  • 7102

port 7102
pidfile /var/run/redis_7102.pid
logfile "7102.log"
dbfilename dump-7102.rdb
dir /Users/xiaosa/learning/redis/data/7102-data
cluster-enabled yes
cluster-config-file nodes-7102.conf
cluster-require-full-coverage no
  • 7103

port 7103
pidfile /var/run/redis_7103.pid
logfile "7103.log"
dbfilename dump-7103.rdb
dir /Users/xiaosa/learning/redis/data/7103-data
cluster-enabled yes
cluster-config-file nodes-7103.conf
cluster-require-full-coverage no
  • 7104

port 7104
pidfile /var/run/redis_7104.pid
logfile "7104.log"
dbfilename dump-7104.rdb
dir /Users/xiaosa/learning/redis/data/7104-data
cluster-enabled yes
cluster-config-file nodes-7104.conf
cluster-require-full-coverage no
  • 7105

port 7105
pidfile /var/run/redis_7105.pid
logfile "7105.log"
dbfilename dump-7105.rdb
dir /Users/xiaosa/learning/redis/data/7105-data
cluster-enabled yes
cluster-config-file nodes-7105.conf
cluster-require-full-coverage no
  • 启动各节点

./redis-server /Users/xiaosa/learning/redis/config/7100.conf &
./redis-server /Users/xiaosa/learning/redis/config/7101.conf &
./redis-server /Users/xiaosa/learning/redis/config/7102.conf &
./redis-server /Users/xiaosa/learning/redis/config/7103.conf &
./redis-server /Users/xiaosa/learning/redis/config/7104.conf &
./redis-server /Users/xiaosa/learning/redis/config/7105.conf &
xiaosa@XIAOSAdeMacBook-Pro bin % ps -ef | grep redis                                           
  501  4925   556   0  7:13下午 ttys000    0:00.06 ./redis-server *:7100 [cluster] 
  501  4928   556   0  7:13下午 ttys000    0:00.03 ./redis-server *:7101 [cluster] 
  501  4929   556   0  7:13下午 ttys000    0:00.03 ./redis-server *:7102 [cluster] 
  501  4930   556   0  7:13下午 ttys000    0:00.03 ./redis-server *:7103 [cluster] 
  501  4931   556   0  7:13下午 ttys000    0:00.02 ./redis-server *:7104 [cluster] 
  501  4932   556   0  7:13下午 ttys000    0:00.02 ./redis-server *:7105 [cluster] 
  501  4934   556   0  7:13下午 ttys000    0:00.00 grep redis
  • 7100上执行cluster nodes

xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -c -h 127.0.0.1 -p 7100 cluster nodes
adac00d83f36f8b10fb486c3f962de8a65a31173 :7100@17100 myself,master - 0 0 0 connected
  • meet操作

  • 7100 meet 7101

./redis-cli -h 127.0.0.1 -p 7100 cluster meet 127.0.0.1 7101
OK
  • 再次7100上执行cluster nodes

  • 已和7101建立起通信

xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -c -h 127.0.0.1 -p 7100 cluster nodes
3bd08fe7370a2bbaefab2d9b66f00aba065e2c74 127.0.0.1:7101@17101 master - 0 1678188635068 1 connected
adac00d83f36f8b10fb486c3f962de8a65a31173 127.0.0.1:7100@17100 myself,master - 0 0 0 connected
  • 与其他节点meet

./redis-cli -h 127.0.0.1 -p 7100 cluster meet 127.0.0.1 7102
./redis-cli -h 127.0.0.1 -p 7100 cluster meet 127.0.0.1 7103
./redis-cli -h 127.0.0.1 -p 7100 cluster meet 127.0.0.1 7104
./redis-cli -h 127.0.0.1 -p 7100 cluster meet 127.0.0.1 7105
  • 再次7100上执行cluster nodes

  • 所有节点间均已建立通信

xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -c -h 127.0.0.1 -p 7100 cluster nodes           
adac00d83f36f8b10fb486c3f962de8a65a31173 127.0.0.1:7100@17100 myself,master - 0 1678188785000 3 connected
72675e1ac5d367a7b6f144b129e1ea89a278d982 127.0.0.1:7104@17104 master - 0 1678188784471 4 connected
48ce710e293b9aa28c44ac72d3fa4961f76f160d 127.0.0.1:7105@17105 master - 0 1678188785000 5 connected
3bd08fe7370a2bbaefab2d9b66f00aba065e2c74 127.0.0.1:7101@17101 master - 0 1678188783463 1 connected
f94d4a0e2ca950cd441250c47289034c820138a0 127.0.0.1:7103@17103 master - 0 1678188785482 0 connected
9fa8e721e932d620fff84643ceccc208bdbd8bed 127.0.0.1:7102@17102 master - 0 1678188784000 2 connected
  • 执行cluster info查看集群状态

xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -c -h 127.0.0.1 -p 7100 cluster info 
cluster_state:fail
cluster_slots_assigned:0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
cluster_current_epoch:5
cluster_my_epoch:3
cluster_stats_messages_ping_sent:280
cluster_stats_messages_pong_sent:292
cluster_stats_messages_meet_sent:5
cluster_stats_messages_sent:577
cluster_stats_messages_ping_received:292
cluster_stats_messages_pong_received:285
cluster_stats_messages_received:577
total_cluster_links_buffer_limit_exceeded:0
  • 分配槽

  • 经过上述操作后,需要给master节点分配虚拟槽redis-cluster集群才可以正常的提供服务。

  • 编写分配slot的shell脚本addslots.sh

start=$1
end=$2
port=$3
for slot in `seq ${start} ${end}`
do
  echo "slot:${slot}"
  /usr/local/bin/redis-cli -p ${port} cluster addslots ${slot}
done
  • 虚拟槽规划

  • 0~5461 7100

  • 5462~10922 7101

  • 10923~16383 7102

  • 执行addslots.sh脚本

./addslots.sh 0 5461 7100
./addslots.sh 5462 10922 7101
./addslots.sh 10923 16383 7102
  • 7100上执行cluster info

  • 虚拟槽已分配完成,cluster_state:ok

xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -c -h 127.0.0.1 -p 7100 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:5
cluster_my_epoch:3
cluster_stats_messages_ping_sent:1574
cluster_stats_messages_pong_sent:1563
cluster_stats_messages_meet_sent:5
cluster_stats_messages_sent:3142
cluster_stats_messages_ping_received:1563
cluster_stats_messages_pong_received:1579
cluster_stats_messages_received:3142
total_cluster_links_buffer_limit_exceeded:0
  • 配置从节点

  • 主从关系

  • 7100 <- 7103

  • 7101 <- 7104

  • 7102 <- 7105

  • 查看集群状态

  • 此时7103、7104、7105没有分配虚拟槽,并且状态是master。

xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -c -h 127.0.0.1 -p 7100 cluster nodes
adac00d83f36f8b10fb486c3f962de8a65a31173 127.0.0.1:7100@17100 myself,master - 0 1678190471000 3 connected 0-5461
72675e1ac5d367a7b6f144b129e1ea89a278d982 127.0.0.1:7104@17104 master - 0 1678190469539 4 connected
48ce710e293b9aa28c44ac72d3fa4961f76f160d 127.0.0.1:7105@17105 master - 0 1678190469000 5 connected
3bd08fe7370a2bbaefab2d9b66f00aba065e2c74 127.0.0.1:7101@17101 master - 0 1678190470000 1 connected 5462-10922
f94d4a0e2ca950cd441250c47289034c820138a0 127.0.0.1:7103@17103 master - 0 1678190470551 0 connected
9fa8e721e932d620fff84643ceccc208bdbd8bed 127.0.0.1:7102@17102 master - 0 1678190471560 2 connected 10923-16383
  • 执行配置从节点命令

./redis-cli -h 127.0.0.1 -p 7103 cluster replicate adac00d83f36f8b10fb486c3f962de8a65a31173
./redis-cli -h 127.0.0.1 -p 7104 cluster replicate 3bd08fe7370a2bbaefab2d9b66f00aba065e2c74
./redis-cli -h 127.0.0.1 -p 7105 cluster replicate 9fa8e721e932d620fff84643ceccc208bdbd8bed
  • 再次查询集群状态

xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -c -h 127.0.0.1 -p 7100 cluster nodes                                          
adac00d83f36f8b10fb486c3f962de8a65a31173 127.0.0.1:7100@17100 myself,master - 0 1678190628000 3 connected 0-5461
72675e1ac5d367a7b6f144b129e1ea89a278d982 127.0.0.1:7104@17104 slave 3bd08fe7370a2bbaefab2d9b66f00aba065e2c74 0 1678190627000 1 connected
48ce710e293b9aa28c44ac72d3fa4961f76f160d 127.0.0.1:7105@17105 slave 9fa8e721e932d620fff84643ceccc208bdbd8bed 0 1678190625000 2 connected
3bd08fe7370a2bbaefab2d9b66f00aba065e2c74 127.0.0.1:7101@17101 master - 0 1678190627993 1 connected 5462-10922
f94d4a0e2ca950cd441250c47289034c820138a0 127.0.0.1:7103@17103 slave adac00d83f36f8b10fb486c3f962de8a65a31173 0 1678190629006 3 connected
9fa8e721e932d620fff84643ceccc208bdbd8bed 127.0.0.1:7102@17102 master - 0 1678190626000 2 connected 10923-16383

至此集群已成功搭建完成。

  • 验证

  • 7100设置hello

xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -c -h 127.0.0.1 -p 7100
127.0.0.1:7100> set hello world
OK
127.0.0.1:7100> get hello
"world"
  • 7101上获取进行了跳转

xiaosa@XIAOSAdeMacBook-Pro bin % ./redis-cli -c  -h 127.0.0.1 -p 7101
127.0.0.1:7101> get hello
-> Redirected to slot [866] located at 127.0.0.1:7100
"world"
127.0.0.1:7100> 

来源:https://coding.imooc.com/learn/list/151.html