redis之cluster集群部署

一、redis cluster简介

Redis在3.0版正式引入了集群这个特性。

Redis集群是一个提供在多个Redis间节点间共享数据的程序集。

Redis集群是一个分布式(distributed)、容错(fault-tolerant)的Redis内存K/V服务,集群可以使用的功能是普通单机Redis所能使用的功能的一个子集(subset),比如Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误。还有比如set里的并集(unions)和交集(intersections)操作,就没有实现。通常来说,那些处理命令的节点获取不到键值的所有操作都不会被实现。在将来,用户或许可以通过使用MIGRATE COPY命令,在集群上用计算节点(Computation Nodes) 来执行多键值的只读操作, 但Redis集群本身不会执行复杂的多键值操作来把键值在节点间移来移去。

Redis集群不像单机版本的Redis那样支持多个数据库,集群只有数据库0,而且也不支持SELECT命令。

Redis集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令。

Redis集群的优点:

无中心架构,分布式提供服务。

数据按照slot存储分布在多个redis实例上。

增加slave做standby数据副本,用于failover,使集群快速恢复。

实现故障auto failover,节点之间通过gossip协议交换状态信息;投票机制完成slave到master角色的提升。

支持在线增加或减少节点。

降低硬件成本和运维成本,提高系统的扩展性和可用性。

Redis集群的缺点:

client实现复杂,驱动要求实现smart client,缓存slots mapping信息并及时更新。

目前仅JedisCluster相对成熟,异常处理部分还不完善,比如常见的“max redirect exception”。

客户端的不成熟,影响应用的稳定性,提高开发难度。

节点会因为某些原因发生阻塞(阻塞时间大于clutser-node-timeout),被判断下线。这种failover是没有必要,sentinel也存在这种切换场景。


二、环境说明:

1、操作系统:CentOS Linux release 7.3.1611

2、redis版本:redis-4.0.6

3、服务器共3台:

192.168.10.91

192.168.10.92

192.168.10.93


三、安装redis(3台服务器都需要安装)

1、下载redis源码包:

wget http://download.redis.io/releases/redis-4.0.6.tar.gz

2、解压源码包:

tar zxvf redis-4.0.6.tar.gz

3、编译安装:

make

make PREFIX=/app/redis install


四、集群部署

1、创建集群需要的目录(三台机器都要创建)

mkdir -p /data/redis/cluster-6379/{conf,data,log,pid}

mkdir -p /data/redis/cluster-6380/{conf,data,log,pid}

mkdir -p /data/redis/cluster-6381/{conf,data,log,pid}

2、为每个实例创建配置文件(三台机器都要配置),以端口6379为例,其他实例省略

cat /data/redis/cluster-6379/conf/redis.conf

port 6379

bind 0.0.0.0

daemonize yes

protected-mode yes

cluster-enabled yes

cluster-config-file /data/redis/cluster-6379/nodes.conf

cluster-node-timeout 5000

appendonly yes

dir /data/redis/cluster-6379/data

3、启动各实例并查看

./redis-server /data/redis/cluster-6379/conf/redis.conf

./redis-server /data/redis/cluster-6380/conf/redis.conf

./redis-server /data/redis/cluster-6381/conf/redis.conf

现在我们已经有了9个正在运行中的Redis实例, 接下来我们需要使用这些实例来创建集群。通过使用Redis集群命令行工具redis-trib,编写节点配置文件的工作可以非常容易地完成:redis-trib位于Redis源码的src文件夹中,它是一个Ruby程序,这个程序通过向实例发送特殊命令来完成创建新集群, 检查集群, 或者对集群进行重新分片(reshared)等工作。但是redis-trib是Ruby程序,所以需要解决Ruby依赖。

4、安装集群依赖环境

4.1、安装ruby2.4.1

curl -L get.rvm.io | bash -s stable

source /usr/local/rvm/scripts/rvm

rvm list known

rvm install 2.4.1

ruby --version

4.2、安装gem redis

gem install redis

5、创建集群

./redis-trib.rb create --replicas 2 192.168.10.91:6379 192.168.10.91:6380 192.168.10.91:6381 192.168.10.92:6379 192.168.10.92:6380 192.168.10.92:6381 192.168.10.93:6379 192.168.10.93:6380 192.168.10.93:6381

>>> Creating cluster

>>> Performing hash slots allocation on 9 nodes...

Using 3 masters:

192.168.10.91:6379

192.168.10.92:6379

192.168.10.93:6379

Adding replica 192.168.10.92:6380 to 192.168.10.91:6379

Adding replica 192.168.10.93:6380 to 192.168.10.91:6379

Adding replica 192.168.10.91:6380 to 192.168.10.92:6379

Adding replica 192.168.10.91:6381 to 192.168.10.92:6379

Adding replica 192.168.10.92:6381 to 192.168.10.93:6379

Adding replica 192.168.10.93:6381 to 192.168.10.93:6379

M: f0ddd134da674ac6f7d2805c5b6a59c346df9c80 192.168.10.91:6379

  slots:0-5460 (5461 slots) master

S: cd1520b19c7374d82b9712c6f42b8ec3b599d04f 192.168.10.91:6380

  replicates fb843114f6e4d7988971422be3f370bfce2c1fb9

S: 8728bc5408f9b305fbd0354ba7eaf74e71f00128 192.168.10.91:6381

  replicates fb843114f6e4d7988971422be3f370bfce2c1fb9

M: fb843114f6e4d7988971422be3f370bfce2c1fb9 192.168.10.92:6379

  slots:5461-10922 (5462 slots) master

S: c899a39d04a287e0a65b649a88b1369eb1916b97 192.168.10.92:6380

  replicates f0ddd134da674ac6f7d2805c5b6a59c346df9c80

S: f7c4e797a02f75d9e4e0f26dae448cde3be864d7 192.168.10.92:6381

  replicates 724c6c355513dabd8f017817443a4631fbcf72fe

M: 724c6c355513dabd8f017817443a4631fbcf72fe 192.168.10.93:6379

  slots:10923-16383 (5461 slots) master

S: 8096d93d8b2b00810cf528554d6a17981547183a 192.168.10.93:6380

  replicates f0ddd134da674ac6f7d2805c5b6a59c346df9c80

S: 4236e756d7df651956895c608153233230e8bb9e 192.168.10.93:6381

  replicates 724c6c355513dabd8f017817443a4631fbcf72fe

Can I set the above configuration? (type 'yes' to accept): yes

>>> 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.91:6379)

M: f0ddd134da674ac6f7d2805c5b6a59c346df9c80 192.168.10.91:6379

  slots:0-5460 (5461 slots) master

  2 additional replica(s)

S: 8728bc5408f9b305fbd0354ba7eaf74e71f00128 192.168.10.91:6381

  slots: (0 slots) slave

  replicates fb843114f6e4d7988971422be3f370bfce2c1fb9

M: 724c6c355513dabd8f017817443a4631fbcf72fe 192.168.10.93:6379

  slots:10923-16383 (5461 slots) master

  2 additional replica(s)

M: fb843114f6e4d7988971422be3f370bfce2c1fb9 192.168.10.92:6379

  slots:5461-10922 (5462 slots) master

  2 additional replica(s)

S: c899a39d04a287e0a65b649a88b1369eb1916b97 192.168.10.92:6380

  slots: (0 slots) slave

  replicates f0ddd134da674ac6f7d2805c5b6a59c346df9c80

S: 4236e756d7df651956895c608153233230e8bb9e 192.168.10.93:6381

  slots: (0 slots) slave

  replicates 724c6c355513dabd8f017817443a4631fbcf72fe

S: 8096d93d8b2b00810cf528554d6a17981547183a 192.168.10.93:6380

  slots: (0 slots) slave

  replicates f0ddd134da674ac6f7d2805c5b6a59c346df9c80

S: cd1520b19c7374d82b9712c6f42b8ec3b599d04f 192.168.10.91:6380

  slots: (0 slots) slave

  replicates fb843114f6e4d7988971422be3f370bfce2c1fb9

S: f7c4e797a02f75d9e4e0f26dae448cde3be864d7 192.168.10.92:6381

  slots: (0 slots) slave

  replicates 724c6c355513dabd8f017817443a4631fbcf72fe

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

这个命令在这里用于创建一个新的集群(create),选项–replicas 2表示我们希望为集群中的每个主节点创建2个从节点。之后跟着的其他参数则是这个集群实例的地址列表,3个master6个slave。redis-trib会打印出一份预想中的配置给你看,如果你觉得没问题的话,就可以输入yes ,redis-trib就会将这份配置应用到集群当中,让各个节点开始互相通讯,最后可以得到如下信息:

6、集群状态查看

/app/redis/bin/redis-cli -c -p 6379

6.1、集群节点信息查看命令“cluster nodes”

127.0.0.1:6379> CLUSTER nodes

8728bc5408f9b305fbd0354ba7eaf74e71f00128 192.168.10.91:6381@16381 slave fb843114f6e4d7988971422be3f370bfce2c1fb9 0 1515492930073 4 connected

724c6c355513dabd8f017817443a4631fbcf72fe 192.168.10.93:6379@16379 master - 0 1515492930000 7 connected 10923-16383

fb843114f6e4d7988971422be3f370bfce2c1fb9 192.168.10.92:6379@16379 master - 0 1515492931075 4 connected 5461-10922

f0ddd134da674ac6f7d2805c5b6a59c346df9c80 192.168.10.91:6379@16379 myself,master - 0 1515492931000 1 connected 0-5460

c899a39d04a287e0a65b649a88b1369eb1916b97 192.168.10.92:6380@16380 slave f0ddd134da674ac6f7d2805c5b6a59c346df9c80 0 1515492932080 5 connected

4236e756d7df651956895c608153233230e8bb9e 192.168.10.93:6381@16381 slave 724c6c355513dabd8f017817443a4631fbcf72fe 0 1515492930074 9 connected

8096d93d8b2b00810cf528554d6a17981547183a 192.168.10.93:6380@16380 slave f0ddd134da674ac6f7d2805c5b6a59c346df9c80 0 1515492930074 8 connected

cd1520b19c7374d82b9712c6f42b8ec3b599d04f 192.168.10.91:6380@16380 slave fb843114f6e4d7988971422be3f370bfce2c1fb9 0 1515492931000 4 connected

f7c4e797a02f75d9e4e0f26dae448cde3be864d7 192.168.10.92:6381@16381 slave 724c6c355513dabd8f017817443a4631fbcf72fe 0 1515492931578 7 connected

第一个参数:节点ID;

第二个参数:IP和端口;

第三、四个参数:节点状态,会有master, slave, myself, fail, …这几种;如果是个从节点, 这里是它的主节点的NODE ID;

第五、六个参数:集群最近一次向节点发送PING命令之后,过去了多长时间还没接到回复;

第七、八个参数:节点最近一次返回PONG回复的时间节点的配置纪元(configuration epoch),详细信息请参考Redis集群规范;

第九、十个参数:本节点的网络连接情况,例如connected。

第十一个参数:节点目前包含的槽,例如10.99.73.11:6551目前包含号码为0至5460的哈希槽。

6.2、集群状态信息查看命令“cluster info”

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:9

cluster_size:3

cluster_current_epoch:9

cluster_my_epoch:1

cluster_stats_messages_ping_sent:622

cluster_stats_messages_pong_sent:614

cluster_stats_messages_sent:1236

cluster_stats_messages_ping_received:606

cluster_stats_messages_pong_received:622

cluster_stats_messages_meet_received:8

cluster_stats_messages_received:1236


五、集群测试

Redis集群现阶段的一个问题是客户端实现很少,以下是官网给出的目前Redis集群仅有的客户端的实现:

redis-rb-cluster,是作者编写的Ruby实现,用于作为其他实现的参考。该实现是对redis-rb的一个简单包装,高效地实现了与集群进行通讯所需的最少语义(semantic)。

redis-py-cluster,看上去是redis-rb-cluster的一个Python版本, 这个项目有一段时间没有更新了(最后一次提交是在好几个月之前), 不过可以将这个项目用作学习集群的起点。

Jedis,Jedis最近添加了对集群的支持,使用最多的是java客户端,详细请查看项目README中Jedis Cluster部分。

StackExchange.Redis,提供对C#的支持(并且包括大部分 .NET 下面的语言,比如: VB, F#等等)。

thunk-redis,提供对Node.js和io.js的支持。

测试Redis集群比较简单的办法就是使用redis-rb-cluster或者redis-cli ,接下来我们将使用redis-cli为例来进行演示:

我们输入redis-cli -h 127.0.0.1 -p 6551 -c命令,切忌要加入-c,否则我们进入的不是集群环境。进入客户端以后,我们输入set a 100发现他会进行跳转,这就是因为他经过计算以后,要存储100的hash槽在7003实例上。这样就表示我们的集群成功了!

#/app/redis/bin/redis-cli -c -p 6379

127.0.0.1:6379> set name WADE

OK

127.0.0.1:6379> set address shenzhen

-> Redirected to slot [3680] located at 192.168.10.91:6379

OK

192.168.10.91:6379> get name

-> Redirected to slot [5798] located at 192.168.10.92:6379

"WADE"

192.168.10.92:6379> get address

-> Redirected to slot [3680] located at 192.168.10.91:6379

"shenzhen"

redis-cli对集群的支持是非常基本的,所以它总是依靠 Redis 集群节点来将它转向(redirect)至正确的节点。一个真正的(serious)集群客户端应该做得比这更好: 它应该用缓存记录起哈希槽与节点地址之间的映射(map), 从而直接将命令发送到正确的节点上面。这种映射只会在集群的配置出现某些修改时变化, 比如说, 在一次故障转移(failover)之后, 或者系统管理员通过添加节点或移除节点来修改了集群的布局(layout)之后, 诸如此类。

另外关闭redis集群不能直接kill掉进程,或者关机,我们要通过命令:

# redis-cli -p -c 6379 shutdown

进行关闭,这样在关闭之前,数据才能够进行保存。

一般应用程序端在操作redis cluster的时候只需要把集群节点都添加进配置文件即可,但是一般填写5-6个节点即可。在操作上,不管是主节点操作还是从节点操作都是可以进行一次操作的成功,因为就算在从节点进行写入,他也会重定向到主节点上进行操作的。


六、集群常见操作命令

1、集群状态

CLUSTER INFO    #打印集群的信息;

CLUSTER NODES    #列出集群当前已知的所有节点(node),以及这些节点的相关信息;

2、节点(nodes)

CLUSTER MEET    #将ip和port所指定的节点添加到集群当中,让它成为集群的一份子;

CLUSTER FORGET    #从集群中移除指定的节点;

CLUSTER REPLICATE    #将当前节点设置为指定的节点的从节点;

CLUSTER SAVECONFIG    #将节点的配置文件保存到硬盘里面;

3、槽(slot)

CLUSTER ADDSLOTS [slot ...]    #将一个或多个槽(slot)指派(assign)给当前节点;

CLUSTER DELSLOTS [slot ...]    #移除一个或多个槽对当前节点的指派;

CLUSTER FLUSHSLOTS    #移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点;

CLUSTER SETSLOT NODE    #将槽指派给指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派;

CLUSTER SETSLOT MIGRATING     #将本节点的槽迁移到指定的节点中;

CLUSTER SETSLOT IMPORTING     #从指定的节点中导入槽到本节点中;  

CLUSTER SETSLOT STABLE    #取消对槽的导入(import)或者迁移(migrate);

4、键(key)

CLUSTER KEYSLOT    #计算键key应该被放置在哪个槽上;  

CLUSTER COUNTKEYSINSLOT    #返回槽slot目前包含的键值对数量;  

CLUSTER GETKEYSINSLOT    #返回count个slot槽中的键;

你可能感兴趣的:(redis之cluster集群部署)