Redis3.0 stable版本已经释放出来了,其最大的特点就是有了cluster的能力。估计尝鲜的人不少,但也不会多,它真正要在生成环境中被人熟练应用起来,估计还的两年之久。去年年底本人就玩过一段时间的cluster,这些罗列一些cluster的特点,以备日后精进之用。
1 cluster
cluster有三个feature:
1 数据可以在cluster的多个node之间进行共享;
2 一次请求处理多批key的命令将不再被支持,因为这些命令处理的key可能在不同的node之间,使用了它们反而会降低cluster的性能;
3 提供高HA,即某个node failed后cluster依旧提供高可用性。
cluster提供如下能力保证:
1 在cluster内自动把数据划分到不同的set上;
2 当集群中一小群机器出现网络故障时或者其他种类的failure时,cluster要保证系统继续可用;
redis的每个node启动后占用两个port 6379 & 16379。redis通过port 6379继续对client提供服务,client通过redis独有的文本协议与node进行通信,所以这个port被成为client port or command port。redis node通过port 16379与cluster内部的其他node进行二进制形式的通信,所以被称为data port or bus port。通过port 16379,node之间进行 failure detection(探活)、configure update(配置更新)、failure authorization(失败确认)。如果node使用别的端口作为command port,那么data port 一定是command port + 10000。
两个不同的cluster之间也可以通过data port进行data migration。
2 sharding
redis cluster内部没用提供一致性hash算法来保证集群的可伸缩能力,而是通过简单的crc16 hash算法来进行sharding,所以它最多提供16384个slot。如果cluster有三个node,分别为 A and B and C,则A负责0 - 5500 slots,B负责5501 - 11000 slots,C负责11001 - 16383 slots。进行扩容的时候,就得在不同的node之间进行slots的迁移,不需要关机,也不会出现服务不可用现象。
cluster内部每个node(也成为一个instance)由一个master和多个slave构成,当master fail的时候,可以通过选举机制选出一个slave代替master。
Redis Cluster不提供强一致性。例如cluster接受了一个写请求,给client返回ok,这个写请求的内容也可能丢失。因为其写流程如下:
1 master B接受了一个写请求;
2 B写成功,返回ok给client;
3 B把数据广播给slaves(B1、B2、B3)
如果第二步执行完毕后,B crash了,则会发生数据不一致现象。这与传统的DBMS类似,它们接收了写请求后,每隔1S才会把数据写入disk,这么做也是在性能和一致性之间做一个平衡。
如果用户对数据的一致性要求比较高,Redis可能也会兼顾这种需求,将来会提供相应的选项,让redis中的slave没用成功的接受数据之前不会给client返回ok给client。即先执行step 3,然后再执行step 2。
一致性还有一种场景。假设有client Z,与cluster内各个node A and B and C,以及各个node的replica A1 and B1 and C1,Z与B之间连接正常,但是B与B1以及cluster内其他nodes连接失败。如果Z发起write request,那么B会给他返回ok,但是B1无法获取到相应的数据,这就要求写的时候也要把node与cluster内其他的成员的探活也要考虑在内。基本要求就是,写时间周期要大于探活时间周期(node timeout)。当node B timeout之后,master B会自动进入failing状态,拒绝外部client的连接请求,而cluster则会选出slave B1来代替B。
上面的写请求流程中,如果是master A接受了一个写请求,则A会把写请求转发给B,写成功之后给client返回OK。但是,如果是master A接受了一个读请求,则A只会给client返回master B的地址。