前言
在开发环境中,大家应该都用的是redis单点吧,但是在生产环境中我相信没有人敢用单点的,应该都是用的cluster,因为万一单点挂掉的话,我们的应用也就自然而然的ConnectionException。那么,接下来我就记录一下我自己用docker搭建redis-cluster吧!
基本概念
每个Redis集群中的节点都需要打开两个TCP连接。一个连接用于正常的给Client提供服务,比如6379,还有一个额外的端口(通过在这个端口号上加10000)作为数据端口,比如16379。第二个端口(本例中就是16379)用于集群总线,这是一个用二进制协议的点对点通信信道。这个集群总线(Cluster bus)用于节点的失败侦测、配置更新、故障转移授权,等等。客户端从来都不应该尝试和这些集群总线端口通信,它们只应该和正常的Redis命令端口进行通信。注意,确保在你的防火墙中开放着两个端口,否则,Redis集群节点之间将无法通信。命令端口和集群总线端口的偏移量总是10000。
Redis集群不同一致性哈希,它用一种不同的分片形式,在这种形式中,每个key都是一个概念性(hash slot)的一部分。Redis集群中的每个节点负责一部分hash slots,并允许添加和删除集群节点。比如,如果你想增加一个新的节点D,那么久需要从A、B、C节点上删除一些hash slot给到D。同样地,如果你想从集群中删除节点A,那么会将A上面的hash slots移动到B和C,当节点A上是空的时候就可以将其从集群中完全删除。因为将hash slots从一个节点移动到另一个节点并不需要停止其它的操作,添加、删除节点以及更改节点所维护的hash slots的百分比都不需要任何停机时间。也就是说,移动hash slots是并行的,移动hash slots不会影响其它操作。
为了保持可用,Redis集群用一个master-slave模式,这样的话每个hash slot就有1到N个副本。而redis-cluster规定,至少需要3个master和3个slave,即3个master-slave对。当我们给每个master节点添加一个slave节点以后,我们的集群最终会变成由A、B、C三个master节点和A1、B1、C1三个slave节点组成,这个时候如果B失败了,系统仍然可用。节点B1是B的副本,如果B失败了,集群会将B1提升为新的master,从而继续提供服务。然而,如果B和B1同时失败了,那么整个集群将不可用。
Redis集群不能保证强一致性。换句话说,Redis集群可能会丢失一些写操作,原因是因为它用异步复制。为了使用redis-cluster,需要配置以下几个参数:
- cluster-enabled <yes/no>: 如果是yes,表示启用集群,否则以单例模式启动
- cluster-config-file <filename>: 可选,这不是一个用户可编辑的配置文件,这个文件是Redis集群节点自动持久化每次配置的改变,为了在启动的时候重新读取它。
- cluster-node-timeout <milliseconds>: 超时时间,集群节点不可用的最大时间。如果一个master节点不可到达超过了指定时间,则认为它失败了。注意,每一个在指定时间内不能到达大多数master节点的节点将停止接受查询请求。
- cluster-slave-validity-factor <factor>: 如果设置为0,则一个slave将总是尝试故障转移一个master。如果设置为一个正数,那么最大失去连接的时间是node timeout乘以这个factor。
- cluster-migration-barrier <count>: 一个master和slave保持连接的最小数量(即:最少与多少个slave保持连接),也就是说至少与其它多少slave保持连接的slave才有资格成为master。
- cluster-require-full-coverage <yes/no>: 如果设置为yes,这也是默