Redis Cluster
在redis集群,比如有三个redis实例,redis集群会把key按照一定的算法,分布到这三个redis实例中,达到了水平扩展的功能,同时,也支持在这三个redis中配置slave节点,在master出现故障的时候,自动的切换到slave节点,所以他集合了主从和哨兵的两个功能,同样的,redis集群也不保证数据的一致性,数据从master到slave的过程的异步的,这个和redis - 哨兵(数据丢失的处理)一样。
每个集群除了正常的TCP端口,比如6379,还需要另外一个端口,正常是在前面的端口加1000,也就是16379端口,这个端口是用来故障检测、配置更新、故障转移授权等,为了让redis集群的正常运行,这个端口的访问权限是需要开放的。
数据分片
在redis中,并没有用一致性哈希来做数据分片的,而是用哈希槽。redis中有16384个哈希槽,所以每个key通过CRC16计算后,对16384进行取模,然后落入相应的哈希槽,redis集群的每个节点都有对应的哈希槽集合,比如节点A包含从0到5500的哈希槽,节点B包含从5501到11000的哈希槽,节点C包含从11001到16383的哈希槽。
通过这种方式,新增或者移除节点就非常方便了。比如想加一个节点D,我们只需要移动相应的哈希槽就好了。同样的,当我们减少一个节点时,只要把他的哈希槽移动到其他的节点就好了。因为将哈希槽从一个节点移动到另一个节点不需要停止操作,所以添加和删除节点,或者改变节点持有哈希槽的百分比,不需要任何停机时间。
简单示例
配置信息如下:
port 7000 #端口
cluster-enabled yes #开启集群
cluster-config-file nodes_7000.conf#存储此节点配置的文件
cluster-node-timeout 5000 # 超时时间
另外还有7100,7200,7001,7101,7201的配置,跟上面的配置一样,改了相应的端口和cluster-config-file的文件名。
进入src目录,执行以下目录,启动每个节点。
./redis-server ../conf/cluster_7000.conf &
./redis-server ../conf/cluster_7001.conf &
./redis-server ../conf/cluster_7100.conf &
./redis-server ../conf/cluster_7101.conf &
./redis-server ../conf/cluster_7200.conf &
./redis-server ../conf/cluster_7201.conf &
成功后打印信息如下:
由于没有node.conf文件,每个节点都创建了自己的id,比如上面截图的id为7f466898761e66fdf84cac1e73660766e22d32c8。这个ID将被这个特定的实例永远使用,以便该实例在集群上下文中具有唯一的名称。每个节点记住使用这个id的其他节点,而不是通过IP或端口。IP地址和端口可能会改变,但是唯一的节点标识符在节点的整个生命周期中不会改变。我们称这个标识符为节点ID。
我当前的版本是6.0.8,所以直接使用redis-cli开启集群功能,如果是3或4版本,就需要使用redis-trib.rb命令。create后面是6个地址,由于设置cluster-replicas为1,所以是一主一从,那六个地址中,前面3个就是master,后面是对应的slave,比如7000对应着7001,后面以此类推。
./redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7100 \
127.0.0.1:7200 127.0.0.1:7001 127.0.0.1:7101 127.0.0.1:7201 \
--cluster-replicas 1
我们也可以不用上面那样,启动每个节点,然后再用redis-cli开启集群功能,比如使用下面这些命令:
`create-cluster start`
`create-cluster create`
`create-cluster stop`.
使用redis-cli命令,进入7000端口的redis,开始执行其他命令
./redis-cli -c -p 7000
第一次set name的时候,由于对应的槽是5798,所以会到7100里执行。
第二次set hello的时候,由于对应的槽是866,所以会到7000里执行。
第三次get name的时候,由于对应的槽是5798,所以会到7100里执行。
127.0.0.1:7000> set name zhangsan
-> Redirected to slot [5798] located at 127.0.0.1:7100
OK
127.0.0.1:7100> set hello world
-> Redirected to slot [866] located at 127.0.0.1:7000
OK
127.0.0.1:7000> get name
-> Redirected to slot [5798] located at 127.0.0.1:7100
"zhangsan"
重新分片
重新分片,我们可以用以下的命令,比如我们想给7000这个节点多1000个槽,那2的位置就输入1000,说明要移动1000个槽,3的位置输入的是7000的id,说明这1000的目标是7000,4这个有两种,这边是all,说明其他所以节点都分一些槽出来给7000。第四个步骤执行完输入yes。
./redis-cli --cluster reshard 127.0.0.1:7000
./redis-cli --cluster check 127.0.0.1:7000
此时7000有6501的槽,7200有4889的槽,7100有4994的槽。
输入以下命令查看当前各个节点的情况
./redis-cli --cluster check 127.0.0.1:7000
其他命令
除了重新分片,还有其他命令如下(还是已6.0.8版本为例):
新增节点
新增master节点,第一个地址是新增的节点,第二个地址是已经在集群中的随机节点。
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
新增slave节点,第一个地址是新增的节点,第二个地址是已经在集群中的随机节点。此时并没有他指定master节点,redis集群将从slave节点较少的master作为新增slave的master节点。
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000 --cluster-slave
当然也可以直接指定master节点:
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 --cluster-slave --cluster-master-id 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e
为某个master新增slave还有其他方式,新增新的slave节点,在这个节点中执行以下命令:
cluster replicate 3c3a0c74aae0b56170ccb03a76b60cfe7dc1912e
移除节点
第一个参数只是集群中的一个随机节点,第二个参数是要删除的节点的ID。在删除之前,要确保他的槽是空的。
redis-cli --cluster del-node 127.0.0.1:7000 ``