redis 集群搭建

 

本文是redis学习系列的第四篇,前面咱们学习了redis的数据结构和一些高级特性,点击下面连接可回看node

《详细讲解redis数据结构(内存模型)以及经常使用命令》git

《redis高级应用(主从、事务与锁、持久化)》redis

本文咱们继续学习redis的高级特性——集群。本文主要内容包括集群搭建、集群分区原理和集群操做的学习。算法

 

Redis集群简介

Redis 集群是3.0以后才引入的,在3.0以前,使用哨兵(sentinel)机制(本文将不作介绍,你们可另行查阅)来监控各个节点之间的状态。Redis 集群可谓是让不少人久等了。缓存

Redis 集群是一组能进行数据共享的Redis 实例(服务或者节点)的设施,集群可使用的功能是普通单机 Redis 所能使用的功能的一个子集;Redis 集群一般具备高可用、可扩展性、分布式、容错等特性。了解redis的集群后,这些晦涩的概念可结合redis的主从、集群分区和集群运维等角度理解体会。ruby

Redis集群搭建

建立集群文件夹

在/usr/local/下新建redis-cluster目录并在redis-cluster下新建7031~7036共6个文件夹,这6个文件夹表明建立redis集群的6个节点。以下数据结构

[root@localhost local]# mkdir -p /usr/local/redis-clusterapp

[root@localhost redis-cluster]# mkdir 7031 7032 7033 7034 7035 7036运维

拷贝修改配置文件

将已有的/usr/local/redis/etc/下的redis.conf拷贝到新建立的7031目录中

[root@localhost etc]# cp redis.conf /usr/local/redis-cluster/7031

[root@localhost 7031]# vi redis.conf

修改项以下:

(1)绑定端口,port 7031

(2)绑定IP,bind 192.168.2.128

(3)指定数据存放路径,dir /usr/local/redis-cluster/7031

(4)启动集群模式,cluster-enabled yes

(5)指定集群节点配置文件,cluster-config-file nodes-7031.conf

(6)后台启动,daemonize yes

(7)指定集群节点超时时间,cluster-node-timeout 5000

(8)指定持久化方式,appendonly yes

上面红色项目最好所有设置,否则会出意想不到的错误,703x最好与节点文件夹保持一致。

将7031的redis.conf改完后再拷贝到剩下的5个目录中,而后只要全局替换redis.conf中的7031为相应的节点便可。

安装ruby

因为Redis 集群客户端实现不多,redis集群的启动须要用到ruby实现的redis-trib.rb,因此咱们须要先安装ruby。

[root@localhost redis-cluster]# yum install ruby

[root@localhost redis-cluster]# yum install rubygems

[root@localhost redis-cluster]# gem install redis

启动redis实例

[root@localhost redis-cluster]# 

/usr/local/redis/bin/redis-server /usr/local/redis-cluster/7031/redis.conf

 

分别启动6个redis实例。也能够用脚本循环启动,这样更方便省时

 

[root@localhost redis-cluster]#

for((i=1;i<=6;i++)); do /usr/local/redis/bin/redis-server /usr/local/redis-cluster/703$i/redis.conf; done

 

查看redis实例是否启动成功

 

[root@localhost redis-cluster]# netstat -tunpl | grep redis-server

#或者

[root@localhost redis-cluster]# ps -ef | grep redis-server

 

 

建立并启动集群

进入redis安装目录的bin目录下

[root@localhost ~]# cd /usr/local/redis/bin/

[root@localhost bin]#./redis-trib.rb create --replicas 1 192.168.2.128:7031 192.168.2.128:7032 192.168.2.128:7033 192.168.2.128:7034 192.168.2.128:7035 192.168.2.128:7036 

 

命令的意义以下:

给定 redis-trib.rb 程序的命令是 create,表示建立一个新的集群。选项 --replicas 1 表示为集群中的每一个主节点建立一个从节点。以后跟着的其余参数则是实例的地址列表, 指定使用这些地址所指示的实例来建立新集群。

 

>>> Creating cluster

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

Using 3 masters:

192.168.2.128:7031

192.168.2.128:7032

192.168.2.128:7033

Adding replica 192.168.2.128:7034 to 192.168.2.128:7031

Adding replica 192.168.2.128:7035 to 192.168.2.128:7032

Adding replica 192.168.2.128:7036 to 192.168.2.128:7033

......

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

 

“All 16384 slots covered.”表示集群中的 16384 个槽都有至少一个主节点在处理, 集群运做正常。从打印出来的信息也能够看出,7031,7032,7033是主节点,其它三个是从节点。

客户端链接集群

集群启动成功后,咱们就能够用任意一个客户端链接集群了,以下

 

[root@localhost bin]# /usr/local/redis/bin/redis-cli -c -h 192.168.2.128 -p 7031

192.168.2.128:7031> info

# Server

redis_version:3.2.0

redis_git_sha1:00000000

redis_git_dirty:0

redis_build_id:f8fcffd133fe3364

redis_mode:cluster

os:Linux 2.6.32-504.el6.x86_64 x86_64

arch_bits:64

 

可使用 cluster info命令查看集群信息,cluster nodes命令查看集群节点信息。

集群关闭

关闭集群须要逐个关闭

[root@localhost redis-cluster]#

for((i=1;i<=6;i++)); do /usr/local/redis/bin/redis-cli -c -h 192.168.2.128 -p 703$i shutdown; done

 

若是从新启动集群报如下错误

 

[ERR] Node 192.168.2.128:7031 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

 

须要清除杀掉redis实例,而后删除每一个节点下的临时数据文件appendonly.aof,dump.rdb,nodes-703x.conf,而后再从新启动redis实例便可启动集群。

 

[root@localhost redis-cluster]#for((i=1;i<=6;i++)); do cd 703$i; rm -rf appendonly.aof; rm -rf dump.rdb; rm -rf nodes-703$i.conf; cd ..; done

 

集群测试

下面咱们先来体验一下集群的set,get简单操做,后面咱们会进一步学习集群的更多操做。

 

192.168.2.128:7031> set name "zhangsan"

-> Redirected to slot [5798] located at 192.168.2.128:7032

OK

192.168.2.128:7032> set age 20

-> Redirected to slot [741] located at 192.168.2.128:7031

OK

192.168.2.128:7031> set sex "man"

OK

192.168.2.128:7031>

 

若是在链接客户端的时候不加-c选项set key时则会报MOVED 的错误:

 

[root@localhost bin]# /usr/local/redis/bin/redis-cli -h 192.168.2.128 -p 7031

192.168.2.128:7031> set name "zhangsan"

(error) MOVED 5798 192.168.2.128:7032

192.168.2.128:7031> set age 20

OK

192.168.2.128:7031> set sex "man"

OK

192.168.2.128:7031>

 

来看看取值又是怎么样

 

192.168.2.128:7031> get name

-> Redirected to slot [5798] located at 192.168.2.128:7032

"zhangsan"

192.168.2.128:7032> get age

-> Redirected to slot [741] located at 192.168.2.128:7031

"20"

192.168.2.128:7031> get sex

"man"

192.168.2.128:7031>

 

能够看到,客户端链接加-c选项的时候,存储和提取key的时候不断在7031和7032之间跳转,这个称为客户端重定向。之因此发生客户端重定向,是由于Redis Cluster中的每一个Master节点都会负责一部分的槽(slot),存取的时候都会进行键值空间计算定位key映射在哪一个槽(slot)上,若是映射的槽(slot)正好是当前Master节点负责则直接存取,不然就跳转到其余Master节点负的槽(slot)中存取,这个过程对客户端是透明的。继续看下文的集群分区原理。

Redis集群分区原理

槽(slot)的基本概念

从上面集群的简单操做中,咱们已经知道redis存取key的时候,都要定位相应的槽(slot)。

Redis 集群键分布算法使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 它们的编号为0、一、二、3……1638二、16383,这个槽是一个逻辑意义上的槽,实际上并不存在。redis中的每一个key都属于这 16384 个哈希槽的其中一个,存取key时都要进行key->slot的映射计算。

下面咱们来看看启动集群时候打印的信息:

 

>>> Creating cluster

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

Using 3 masters:

192.168.2.128:7031

192.168.2.128:7032

192.168.2.128:7033

Adding replica 192.168.2.128:7034 to 192.168.2.128:7031

Adding replica 192.168.2.128:7035 to 192.168.2.128:7032

Adding replica 192.168.2.128:7036 to 192.168.2.128:7033

M: bee706db5ae182c5be9b9bdf94c2d6f3f8c8ec5c 192.168.2.128:7031

   slots:0-5460 (5461 slots) master

M: 72826f06dbf3be163f2f456ca24caed76a15bdf4 192.168.2.128:7032

   slots:5461-10922 (5462 slots) master

M: ab6e9d1dfc471225eef01e57be563157f81d26b3 192.168.2.128:7033

   slots:10923-16383 (5461 slots) master

......

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

 

从上面信息能够看出,建立集群的时候,哈希槽被分配到了三个主节点上,从节点是没有哈希槽的。7031负责编号为0-5460 共5461个 slots,7032负责编号为 5461-10922共5462 个 slots,7033负责编号为10923-16383 共5461个 slots。

键-槽映射算法

和memcached同样,redis也采用必定的算法进行键-槽(key->slot)之间的映射。memcached采用一致性哈希(consistency hashing)算法进行键-节点(key-node)之间的映射,而redis集群使用集群公式来计算键 key 属于哪一个槽:

 

HASH_SLOT(key)= CRC16(key) % 16384

 

其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。key通过公式计算后获得所对应的哈希槽,而哈希槽被某个主节点管理,从而肯定key在哪一个主节点上存取,这也是redis将数据均匀分布到各个节点上的基础。

 

 

 

 

键-槽-节点(key->slot->node)映射示意图

集群分区好处

不管是memcached的一致性哈希算法,仍是redis的集群分区,最主要的目的都是在移除、添加一个节点时对已经存在的缓存数据的定位影响尽量的降到最小。redis将哈希槽分布到不一样节点的作法使得用户能够很容易地向集群中添加或者删除节点, 好比说:

l 若是用户将新节点 D 添加到集群中, 那么集群只须要将节点 A 、B 、 C 中的某些槽移动到节点 D 就能够了。

l 与此相似, 若是用户要从集群中移除节点 A , 那么集群只须要将节点 A 中的全部哈希槽移动到节点 B 和节点 C , 而后再移除空白(不包含任何哈希槽)的节点 A 就能够了。

由于将一个哈希槽从一个节点移动到另外一个节点不会形成节点阻塞, 因此不管是添加新节点仍是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会形成集群下线,从而保证集群的可用性。下面咱们就来学习下集群中节点的增长和删除。

集群操做

集群操做包括查看集群信息,查看集群节点信息,向集群中增长节点、删除节点,从新分配槽等操做。

查看集群信息

cluster info 查看集群状态,槽分配,集群大小等,cluster nodes也可查看主从节点。

 

192.168.2.128:7031> 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_sent:119

cluster_stats_messages_received:119

192.168.2.128:7031>

新增节点

(1)新增节点配置文件

执行下面的脚本建立脚本配置文件

 

[root@localhost redis-cluster]# mkdir /usr/local/redis-cluster/7037 && cp /usr/local/redis-cluster/7031/redis.conf /usr/local/redis-cluster/7037/redis.conf && sed -i "s/7031/7037/g" /usr/local/redis-cluster/7037/redis.conf

 

(2)启动新增节点

 

[root@localhost bin]# /usr/local/redis/bin/redis-server /usr/local/redis-cluster/7037/redis.conf

 

(3)添加节点到集群

如今已经添加了新增一个节点所需的配置文件,可是这个这点尚未添加到集群中,如今让它成为集群中的一个主节点

 

[root@localhost redis-cluster]# cd /usr/local/redis/bin/

[root@localhost bin]# ./redis-trib.rb add-node 192.168.2.128:7037 192.168.2.128:7036

>>> Adding node 192.168.2.128:7037 to cluster 192.168.2.128:7036

>>> Performing Cluster Check (using node 192.168.2.128:7036)

S: 2c8d72f1914f9d6052065f7e9910cc675c3c717b 192.168.2.128:7036

   slots: (0 slots) slave

   replicates 6dbb4aa323864265c9507cf336ef7d3b95ea8d1b

M: 6dbb4aa323864265c9507cf336ef7d3b95ea8d1b 192.168.2.128:7033

   slots:10923-16383 (5461 slots) master

   1 additional replica(s)

S: 791a7924709bfd7ef5c36d9b9c838925e41e3c2e 192.168.2.128:7034

   slots: (0 slots) slave

   replicates d9e3c78a7c49689c29ab67a8a17be9d95cb08452

M: d9e3c78a7c49689c29ab67a8a17be9d95cb08452 192.168.2.128:7031

   slots:0-5460 (5461 slots) master

   1 additional replica(s)

M: 69b63d8db629fa8a689dd1ed25ed941c076d4111 192.168.2.128:7032

   slots:5461-10922 (5462 slots) master

   1 additional replica(s)

S: e669a91866225279aafcac29bf07b826eb5be91c 192.168.2.128:7035

   slots: (0 slots) slave

   replicates 69b63d8db629fa8a689dd1ed25ed941c076d4111

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

>>> Send CLUSTER MEET to node 192.168.2.128:7037 to make it join the cluster.

[OK] New node added correctly.

[root@localhost bin]#

 

./redis-trib.rb add-node 命令中,7037 是新增的主节点,7036 是集群中已有的从节点。再来看看集群信息

 

192.168.2.128:7031> cluster info

cluster_state:ok

cluster_slots_assigned:16384

cluster_slots_ok:16384

cluster_slots_pfail:0

cluster_slots_fail:0

cluster_known_nodes:7

cluster_size:3

cluster_current_epoch:6

cluster_my_epoch:1

cluster_stats_messages_sent:11256

cluster_stats_messages_received:11256

 

 

 

(4)分配槽

从添加主节点输出信息和查看集群信息中能够看出,咱们已经成功的向集群中添加了一个主节点,可是这个主节尚未成为真正的主节点,由于尚未分配槽(slot),也没有从节点,如今要给它分配槽(slot)

 

[root@localhost bin]# ./redis-trib.rb reshard 192.168.2.128:7031

>>> Performing Cluster Check (using node 192.168.2.128:7031)

M: 1a544a9884e0b3b9a73db80633621bd90ceff64a 192.168.2.128:7031

   ......

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

How many slots do you want to move (from 1 to 16384)? 1024

What is the receiving node ID?

 

系统提示要移动多少个配槽(slot),而且配槽(slot)要移动到哪一个节点,任意输入一个数,如1024,再输入新增节点的ID cf48228259def4e51e7e74448e05b7a6c8f5713f.

 

What is the receiving node ID? cf48228259def4e51e7e74448e05b7a6c8f5713f

Please enter all the source node IDs.

  Type 'all' to use all the nodes as source nodes for the hash slots.

  Type 'done' once you entered all the source nodes IDs.

Source node #1:

 

而后提示要从哪几个节点中移除1024个槽(slot),这里输入‘all’表示从全部的主节点中随机转移,凑够1024个哈希槽,而后就开始重新分配槽(slot)了。重新分配完后再次查看集群节点信息

 

 

 

可见,0-340 5461-5802 10923-11263的槽(slot)被分配给了新增长的节点。三个加起来恰好1024个槽(slot)。

(5)指定从节点

如今从节点7036的主节点是7033,如今咱们要把他变为新增长节点(7037)的从节点,须要登陆7036的客户端

[root@localhost bin]#  /usr/local/redis/bin/redis-cli -c -h 192.168.2.128 -p 7036

192.168.2.128:7036> cluster replicate cf48228259def4e51e7e74448e05b7a6c8f5713f

OK

 

再来查看集群节点信息

 

 

 

可见,7036成为了新增节点7037的从节点。

删除节点

指定删除节点的ID便可,以下

[root@localhost bin]#

./redis-trib.rb del-node 192.168.2.128:7037 'a56461a171334560f16652408c2a45e629d268f6'

>>> Removing node a56461a171334560f16652408c2a45e629d268f6 from cluster 192.168.2.128:7037

>>> Sending CLUSTER FORGET messages to the cluster...

>>> SHUTDOWN the node.

[root@localhost bin]#

 

集群操做小结

从上面过程能够看出,添加节点、分配槽、删除节点的过程,不用中止集群,不阻塞集群的其余操做。命令小结

 

#向集群中添加节点,7037是新增节点,7036是集群中已有的节点

./redis-trib.rb add-node 192.168.2.128:7037 192.168.2.128:7036

#从新分配槽

./redis-trib.rb reshard 192.168.2.128:7031

#指定当前节点的主节点

cluster replicate cf48228259def4e51e7e74448e05b7a6c8f5713f

#删除节点

./redis-trib.rb del-node 192.168.2.128:7037 'a56461a171334560f16652408c2a45e629d268f6'

 

到此,redis的集群搭建、分区原理、集群增长节点以及删除节点的主要内容已经简要介绍完毕。

 

 

https://www.cnblogs.com/hjwublog/p/5681700.html

相关文章
相关标签/搜索