一、redis集群介绍
本文档是Redis集群的一般介绍,没有涉及复杂难懂的分布式概念的赘述,只是提供了从用户角度来如何搭建测试以及使用的方法。
本教程试图提供最终用户一个简单的关于集群和一致性特征的描述
请注意,本教程使用于Redis3.0(包括3.0)以上版本
如果你计划部署集群,那么我们建议你从阅读这个文档开始。
本文两种安装方法后都附录一些各个方法安装时常遇到的问题及其解决方法,以及第一种部署方法有有命令集成,可以快速部署。希望对您有所帮助。
1.1、Redis集群介绍
Redis 集群是一个提供在多个Redis间节点间共享数据的程序集。
Redis集群并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误.
Redis 集群通过分区来提供一定程度的可用性,在实际环境中当某个节点宕机或者不可达的情况下继续处理命令. Redis 集群的优势:
1.2、Redis 集群的数据分片
Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:
这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我像移除节点A,需要将A中得槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.
1.3、Redis 集群的主从复制模型
为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品.
在我们例子中具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用.
然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了
不过当B和B1 都失败后,集群是不可用的.
1.4、Redis 一致性保证
Redis 并不能保证数据的强一致性. 这意味这在实际中集群在特定的条件下可能会丢失写操作.
第一个原因是因为集群是用了异步复制. 写操作过程:
主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。 注意:Redis 集群可能会在将来提供同步写的方法。 Redis 集群另外一种可能会丢失命令的情况是集群出现了网络分区, 并且一个客户端与至少包括一个主节点在内的少数实例被孤立。
举个例子 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, A1 、B1 、C1 为A,B,C的从节点, 还有一个客户端 Z1 假设集群中发生网络分区,那么集群可能会分为两方,大部分的一方包含节点 A 、C 、A1 、B1 和 C1 ,小部分的一方则包含节点 B 和客户端 Z1 .
Z1仍然能够向主节点B中写入, 如果网络分区发生时间较短,那么集群将会继续正常运作,如果分区的时间足够让大部分的一方将B1选举为新的master,那么Z1写入B中得数据便丢失了.
注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项:
Redis集群部署(方法一:redis-tribe.rb方式)
一、本文集群说明
本文在五台服务器上部署由5个节点组成的redis集群,每个主节点有4个从节点。每台服务器上部署了一个主节点和4个其余主节点的一个从节点()。具体结构如图:
二、集群准备
1.安装ruby,安装包在下面
从windows将包导入linux虚拟机
rz
解压、编译、安装
tar -zxvf ruby-2.3.6.tar.gz
cd ./ruby-2.3.6
sudo make && make install
查看ruby
ruby -v
2.安装redis-trib.rb运行依赖的ruby的包redis-3.2.2.gem
gem install redis-3.2.2.gem
二、集群步骤
3.1、搭建集群的第一件事情我们需要一些运行在 集群模式的Redis实例. 这意味这集群并不是由一些普通的Redis实例组成的,集群模式需要通过配置启用,开启集群模式后的Redis实例便可以使用集群特有的命令和特性了.
下面是一个最少选项的集群的配置文件:
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no
文件中的 cluster-enabled 选项用于开实例的集群模式, 而 cluster-conf-file 选项则设定了保存节点配置文件的路径, 默认值为 nodes.conf.节点配置文件无须人为修改, 它由 Redis 集群在启动时创建, 并在有需要时自动进行更新。
在158.222.14.123~158.222.14.127.五台服务器上分别执行如下操作,这里以158.222.14.123为例,其余四个服务器同样操作。
首先,在/opt/redis 里 让我们进入一个新目录, 并创建五个以端口号为名字的子目录,一个主节点和4个其余主节点的从节点。 稍后我们在将每个目录中运行一个 Redis 实例: 命令如下:
mkdir redis-clusters
cd redis-clusters
mkdir 7000 7001 7002 7003 7004
在文件夹 7000 至 7004 中, 各创建一个 redis.conf 文件, 文件的内容可以使用上面的示例配置文件, 但记得将配置中的端口号从 7000 改为与文件夹名字相同的号码。
本文redis安装在redis-clusters的同级目录下, 使用类似以下命令, 在每个标签页中打开一个实例:
cd 7000
../../redis-3.2.9/bin/redis-server ./redis.conf &
3.2、现在我们已经有了25个正在运行中的 Redis 实例, 接下来我们需要使用这些实例来创建集群, 并为每个节点编写配置文件。
通过使用 Redis 集群命令行工具 redis-trib , 编写节点配置文件的工作可以非常容易地完成: redis-trib 位于 Redis 源码的 src 文件夹中, 它是一个 Ruby 程序, 这个程序通过向实例发送特殊命令来完成创建新集群, 检查集群, 或者对集群进行重新分片(reshared)等工作。
在redis的安装目录下执行:
./bin/redis-trib.rb create --replicas 4 158.222.14.123:7000 158.222.14.124:7001 158.222.14.125:7002 158.222.14.126:7003 158.222.14.127:7004
158.222.14.124:7000 158.222.14.125:7000 158.222.14.126:7000 158.222.14.127:7000
158.222.14.123:7001 158.222.14.125:7001 158.222.14.126:7001 158.222.14.127:7001
158.222.14.123:7002 158.222.14.124:7002 158.222.14.126:7002 158.222.14.127:7002
158.222.14.123:7003 158.222.14.124:7003 158.222.14.125:7003 158.222.14.127:7003
158.222.14.123:7004 158.222.14.124:7004 158.222.14.125:7004 158.222.14.126:7004
这个命令在这里用于创建一个新的集群, 选项–replicas 4 表示我们希望为集群中的每个主节点创建四个从节点(redis规定后面紧跟着的五个是主节点)。
之后跟着的其他参数则是这个集群实例的地址列表5个master20个slave redis-trib 会打印出一份预想中的配置给你看, 如果你觉得没问题的话, 就可以输入 yes , redis-trib 就会将这份配置应用到集群当中,让各个节点开始互相通讯,最后可以得到如下信息:
[OK] All 16384 slots covered
这表示集群中的 16384 个槽都有至少一个主节点在处理, 集群运作正常。
三、集群测试
测试 Redis 集群比较简单的办法就是使用 redis-rb-cluster 或者 redis-cli , 接下来我们将使用 redis-cli 为例来进行演示:
$ redis-cli -c -p 7000
redis 158.222.14.123:7000> set foo bar
-> Redirected to slot [12182] located at 158.222.14.123:7002
OK
redis 158.222.14.123:7002> set hello world
-> Redirected to slot [866] located at 158.222.14.123:7000
OK
redis 158.222.14.123:7000> get foo
-> Redirected to slot [12182] located at 158.222.14.123:7002
"bar"
redis 158.222.14.123:7000> get hello
-> Redirected to slot [866] located at 158.222.14.123:7000
"world"
注意: 如果redis-cli 忘带-c会出现像(error)moved 158.222.14.123这样的错误。
redis-cli 对集群的支持是非常基本的, 所以它总是依靠 Redis 集群节点来将它转向(redirect)至正确的节点。一个真正的(serious)集群客户端应该做得比这更好: 它应该用缓存记录起哈希槽与节点地址之间的映射(map), 从而直接将命令发送到正确的节点上面。这种映射只会在集群的配置出现某些修改时变化, 比如说, 在一次故障转移(failover)之后, 或者系统管理员通过添加节点或移除节点来修改了集群的布局(layout)之后, 诸如此类。
四、福利:快速部署方法(shell脚本集成命令部署)!!!
1.rz命令上传上面的redis-clusters.tar压缩包到/opt/redis/下(这里必须压缩到这里,否则需要更改压缩包里文件的/opt/redis/为自己的压缩目录)
2.解压
tar -xvf ./redis-clusters.tar
cd ./redis-clusters
3.执行3.1的步骤
./initcluster.sh
4.执行3.2的步骤
注意因为最后一台服务器不仅要启动节点还要将节点添加到集群和分slots槽,所以运行的不一样
全部先启动节点
./startclusters
最后一台运行:
./start-cluster-meet-all
完成!!!
Redis集群部署二:(非redis-tribe.rb)方式
一、说明
同部署方法一的说明
二、准备
本文使用Redis 3.2.9版本,服务器158.222.14.123~158.222.14.127.
预习:redis cluster命令行
//集群(cluster)
CLUSTER INFO 打印集群的信息
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
//节点(node)
CLUSTER MEET 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
CLUSTER FORGET 从集群中移除 node_id 指定的节点。
CLUSTER REPLICATE 将当前节点设置为 node_id 指定的节点的从节点。
CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。
//槽(slot)
CLUSTER ADDSLOTS [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。
CLUSTER DELSLOTS [slot ...] 移除一个或多个槽对当前节点的指派。
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
CLUSTER SETSLOT NODE 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
CLUSTER SETSLOT MIGRATING 将本节点的槽 slot 迁移到 node_id 指定的节点中。
CLUSTER SETSLOT IMPORTING 从 node_id 指定的节点中导入槽 slot 到本节点。
CLUSTER SETSLOT STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。
//键 (key)CLUSTER KEYSLOT 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT 返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT 返回 count 个 slot 槽中的键。
这些命令是集群所独有的。执行上述命令要先登录
三、创建集群步骤
3.1 在158.222.14.123~158.222.14.127.服务器分别执行如下操作,这里以158.222.14.123为例,其余四个服务器同样操作。
3.1.1创建配置文件目录,使用的端口分别为7000,7001,7003,7004和7005。
[root@xxx ~]# cd /opt/redis
[root@xxx redis-3.2.9]# mkdir clusters-test
[root@xxx redis-3.2.9]# mkdir ./clusters-test/7000 7001 7002 7003 7004
3.1.2 分别在上述创建的目录创建对应的配置文件
[root@xxx 7000]# vi redis.conf (第一个编辑,后面的复制更改)
编辑内容:
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no
文件中的 cluster-enabled 选项用于开实例的集群模式, 而 cluster-conf-file 选项则设定了保存节点配置文件的路径, 默认值为 nodes.conf.节点配置文件无须人为修改, 它由 Redis 集群在启动时创建, 并在有需要时自动进行更新。protected-mode 为no才能跨服务器集群,单机集群可忽略。
[root@xxx 7000]# cp redis.conf ../7001
[root@xxx 7000]# cp redis.conf ../7002
[root@xxx 7000]# cp redis.conf ../7003
[root@xxx 7000]# cp redis.conf ../7004
3.1.3 分别修改各个配置文件使用对应的端口.例如redis_7001.conf
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
3.1.4 分别启动各个Redis instance
[root@xxx clusters-test]# cd 7000
[root@xxx7000]# ../../redis-3.2.9/bin/redis-server ./redis.conf &
[root@xxx 7000]# cd ../7001
[root@xxx 7001]# ../../redis-3.2.9/bin/redis-server ./redis.conf&
[root@xxx 7001]# cd ../7002
[root@xxx7002]# ../../redis-3.2.9/bin/redis-server ./redis.conf&
[root@xxx 7002]# cd ../7003
[root@xxx7003]# ../../redis-3.2.9/bin/redis-server ./redis.conf&
[root@xxx 7003]# cd ../7004
[root@xxx7004]# ../../redis-3.2.9/bin/redis-server ./redis.conf &
3.2 连接集群,在一个Redis instance执行连接25个节点(必须25个,自己也要连,否则默认自己为127.0.0.1就会和其他节点连接不上)就行
[root@xxx redis-3.2.9]# ./bin/redis-cli -c -p 7000 CLUSTER MEET 158.222.13.123 7000
[root@xxx redis-3.2.9]# ./bin/redis-cli -c -p 7000 CLUSTER MEET 158.222.13.123 7001
[root@xxx redis-3.2.9]# ./bin/redis-cli -c -p 7000 CLUSTER MEET 158.222.13.123 7003
[root@xxx redis-3.2.9]# ./bin/redis-cli -c -p 7000 CLUSTER MEET 158.222.13.123 7004
[root@xxx redis-3.2.9]# ./bin/redis-cli -c -p 7000 CLUSTER MEET 158.222.13.123 7005
。。。。。。。
。。。。。
。。。
[root@xxx redis-3.2.9]# ./bin/redis-cli -c -p 7000 CLUSTER MEET 158.222.13.127 7005
总共25个!!!!!!!!!!!!!!!!!!
3.3 连接完集群所有的节点都为主节点,且都没有分配槽slot,接下来是分配从节点(即将主节点改为从节点)和分配槽,先给选定的主节点(主节点的选择请看最上图)分配槽,平均分,共16384个,分为五份每分3277个即:0~3277,3278~6554,6555~9831,9832~13108,13109~16384。分配槽的过程需在各个服务器的相同目录执行!!!。
3.1.1因为绑定从节点需要主节点的id,先找到主节点的ld
[root@xxx redis-3.2.9]# ./bin/redis-cli -c -p 7000 CLUSTER NODES
可以看到各个节点位于第一列的id。
3.1.2分配槽和从节点
服务器158.222.14.123:
主节点 7000 分配槽
[root@xxx redis-3.2.9]# ./bin/redis-cli -c -p 7000 CLUSTER ADDSLOTS {0..3277}
从节点7001~7004 变为其相同接口的主节点的从节点
[root@xxx redis-3.2.9]# ./bin/redis-cli -c -p 7001 REPLICATE 3fc783611028b1707fd65345e763befb36454d73
(3fc783611028b1707fd65345e763befb36454d73为7000主节点的id)
。。。
。。。。。
。。。。。。
共4个从节点’
其余4台服务器除了主节点和从节点不一样,其余同上操作。
四、集群测试
同方法一。