本博文翻译自Redis官网:http://redis.io/topics/cluster-tutorial
不管怎么样,本教程尝试从最终用户的角度来提供关于Redis 集群 可用性和一致性的信息。
注意:本教程需要Redis 3.0版本或者更高.
如果你计划运行一个重要的Redis 集群部署,更多的正规说明书建议阅读下,虽然不严格要求. 不管怎样,这是一个好的建议从本文档开始玩转Redis 集群一段时间,稍后阅读Redis 集群详细说明书.
一、Redis集群101
Redis集群提供一个将数据通过多个Redis节点自动分片的方式来安装Redis.
Redis集群也通过分区提供可用性程度,那就是在实践中当一些节点down掉或失去联系,仍然可以继续工作的能力. 不管怎样,大量节点出现故障时(例如当大多数的主节点不可用)Redis集群会停止工作.
- 在多个节点中数据自动分片的能力.
- 当一部分节点失败或者不能与集群其余节点通信 ,集群仍然可以工作的能力.
二、Redis集群TCP端口
每个Redis集群节点需要开通两个TCP 连接。正常的Redis TCP端口被用作服务端的端口,例如6379,服务端口加上10000得到的作为数据端口,例如16379。
- 命令行端口对需要访问集群的客户端可达, 加上所有其余的集群节点(使用命令行端口做keys转移)。
- 集群总线端口(命令行端口+10000)对集群中的所有节点可达.
三、Redis集群和Docker
networking mode ),请在Docker文档是查看更多关于--net=host选项的信息.
四、Redis集群数据分片
每个Redis集群节点负责hash
slots总数的的一个子集,举个例子,你拥有三个节点的Redis集群:
- 节点A包含0~5500个hash slots.
- 节点B包含5501~11000个hash slots.
- 节点C包含11001~16383个hash slots.
这使得添加和和删除节点在Redis集群中变得容易.例如,如果我想加个节点D,我需要从节点A、B、C移动一些hash slot到D节点上. 同样的,如果我想从集群中移除节点A,我只需要把服务于A节点的hash slot移动到B和C.当节点A没有任何的hash slot时,就可以完全的删除节点A了.
因为从一个节点移动hash slots到另一个节点不需要停止操作、添加和删除节点、或者改变节点间持有hash slot的百分比,也不需要任何的服务停止.
五、Redis集群主从模型
六、Redis集群一致性保证
- 你的客户端写数据到主节点B.
- 主节点B回应你的客户端一切OK.
- 主节点复制写的数据到副节点B1、B2、B3.
七、Redis集群配置参数
-
cluster-enabled <yes/no>
:如果是设置为yes,Redis集群将支持一个指定的Redis实例;否则这个实例将作为一个普通单独的实例。
-
cluster-config-file <filename>:注意不要管这个选项的名称,这不是一个用户编辑的配置文件,而是Redis集群自动存留的Redis配置(状态,基本的)每当集群发生变化时,为了在启动时再次读取. 这个文件列出了其他节点在集群中的状态、持久性变化等等。这个文件常常在磁盘上重写、刷新作为一些消息接收的结果.
- cluster-node-timeout <milliseconds>:Redis集群中的点不用,被认为失败节点的的最大等待时间。如果一个主节点在指定的时间段内不可达,就会被他的副节点做失败处理. 这个参数控制Redis集群中其它重要事情。尤其,每个节点不能在指定时间内与主节点中的大多数通信,该节点将会停止查询。
-
cluster-slave-validity-factor <factor>:如果设置成0,一个副节点总是尝试FailOver主节点,不管主节点和副节点保持断开连接多长时间。如果这个值设置为正数,一个最大失联时间将会被计算出来,node-timeout 乘以这个选项配置的factor,
如果这个节点是副节点,它将不会启动Failover当失联超过计算出的指定时间。 例如,如果node-timeoutt设置为5秒,validity factor 设置为10,一个副节点与主节点失去联系超过50秒后,副节点将不会尝试Failover它的主节点。注意,任何不同于0的值将导致集群不可用,当一个主节点失败后, 没有副节点可以替换它。在那个例子中,集群将返回可用,只要原始的主节点重新加入到集群中. - cluster-migration-barrier <count>: 一个主节点最少副节点连接数目,另一个移动到一个不被任何副节点覆盖的主节点。阅读本教程更多关于对于副本迁移恰当分区的信息.
- cluster-require-full-coverage <yes/no>:如果设置为yes,默认的,如果一定比例的key空间不被任何节点覆盖,集群将停止消息的写入;如果设置为no,集群仍然支持查询服务即使只有一部分key处理请求.
八、创建和使用一个Redis集群
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
就你所知,使集群模式工作只需要一个简单的cluster-enabled指令。每个实例也包含该节点配置信息被存储的文件的路径,默认是nodes.conf。 该配置文件不会被手动更改,它仅仅在Redis 集群实例启动的时候生成,每次需要的时候更新这个文件。
注意期望最小集群工作,要求至少三个主节点。对于你第一次测试,强烈建议你开启一个6个节点的集群,包含3个主节点和3个副节点。
mkdir cluster-test
cd cluster-test
mkdir 7000 7001 7002 7003 7004 7005
cd 7000
../redis-server ./redis.conf
你可以看见每个实例的日志,由于nodes.conf
文件不存在,每个节点分配一个新的ID.
[82462] 26 Nov 11:56:55.329 * No cluster configuration found, I'm 97a3a64667477371c4479320d683e4c8db5858b1
这个ID将被指定的Redis 实例永远使用,为了让这个实例在Redis上下文中有一个唯一的名字. 每一个节点都是通过ID来记录其余的节点,而不是通过IP地址或端口。 IP地址和端口可以改变,但是这个节点唯一的节点标识在节点生命周期内永远不会改变。我们把这个标识简单的称之为节点ID.
1、创建集群
gem install redis
创建集群的简单类型
./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
这里使用的命令是creat,因为我们想创建一个新的Redis集群。 --replicas 1这个选项的意思是我们想要为每个master节点创建一个slave节点,其余参数是我想创建集群实例要使用的地址列表。
Redis-trib将会提出一个配置,输入yes,集群将会被配置和加入,这意味着,Redis实例将会被引导至互相交互。最后,你将看到一个信息:
[OK] All 16384 slots covered
上面这条信息意味着,至少有一个master节点实例服务于16384 slot 中的每一个。
2、使用create-cluster脚本创建Redis集群
1、create-cluster start
2、create-cluster create
第二步的时候,当redis-trib工具想让你接受redis集群布局时,请输入yes。
create-cluster stop.
请阅读目录下面的README 文件查看更多关于运行该脚本的信息.
3、玩转Redis集群(Playing with the cluster)
redis-rb-cluster is a Ruby implementation written by me (@antirez) as a reference for other languages. It is a simple wrapper around the original redis-rb, implementing the minimal semantics to talk with the cluster efficiently.
redis-py-cluster A port of redis-rb-cluster to Python. Supports majority of redis-py functionality. Is in active development.
The popular Predis has support for Redis Cluster, the support was recently updated and is in active development.
The most used Java client, Jedis recently added support for Redis Cluster, see the Jedis Cluster section in the project README.
StackExchange.Redis offers support for C# (and should work fine with most .NET languages; VB, F#, etc)
thunk-redis offers support for Node.js and io.js, it is a thunk/promise-based redis client with pipelining and cluster.
redis-go-cluster is an implementation of Redis Cluster for the Go language using the Redigo library client as the base client. Implements MGET/MSET via result aggregation.
The redis-cli utility in the unstable branch of the Redis repository at GitHub implements a very basic cluster support when started with the -c switch.
一个简单的方式来测试你的集群是使用上面任何一种客户端或者简单的命令行工具redis-cli。
$ redis-cli -c -p 7000
redis 127.0.0.1:7000> set foo bar
-> Redirected to slot [12182] located at 127.0.0.1:7002
OK
redis 127.0.0.1:7002> set hello world
-> Redirected to slot [866] located at 127.0.0.1:7000
OK
redis 127.0.0.1:7000> get foo
-> Redirected to slot [12182] located at 127.0.0.1:7002
"bar"
redis 127.0.0.1:7000> get hello
-> Redirected to slot [866] located at 127.0.0.1:7000
"world"