为什么要做redis集群
为了提高响应速度,将热点数据保存在缓存中。
因为内存资源的限制,scale up并不是好办法,需要scale out,既分布式多个redis协同运作。
而且,Redis单线程,只运行一个redis实例很浪费,通常一台机器上同时跑多个redis实例。
方案1:redis官方集群方案 redis cluster
Redis cluster是一种服务器sharding技术,3.0开始正式提供。
Redis cluster Sharding采用slot概念(槽),一共16384个,每个进入redis的值对,根据key进行散列,分配到16384中的某一个,使用hash算法,CRC16后16384取模。
Redis中每一个node节点负责分摊这16384个slot中的一部分。每个slot对应在一个node上。当节点加减,需要将16384个slot再分配,slot中的键值也要迁移,目前属于半自动,需要人工介入。
Redis集群,要保证每个node都正常工作,如果某个node故障,他负责的slots也就失效。
为了增加集群的可访问性,官方推出将node配置主从结构,即一个master主节点,n个slave节点,如果主节点挂掉,redis cluster 会选择一个slave节点上升为主节点。
Redis cluster 每个节点相互通信(cluster bus)可以识别,判断故障,故障转移。他们采用特殊的端口号,即对外端口号+10000。例如某个node端口3001,那与它通信的nodes端口号13001,node之间采用二进制通信协议。
方案2:redis sharding 集群
多redis实例服务,比单redis实例要复杂的多,设计定位,协同,容错,扩容等难题。
Redis sharding是采用哈希算法将redis数据的key进行散列,通过hash函数,特定的key会映射到特定的redis节点上。
扩容问题:
redis sharding,服务端的redis 还是一个个相对独立的redis实例节点。要增加redis节点时,尽管采用一致性的hash,但还是会有key匹配不到而丢失,这时需要键值移植。
Presharding,预先根据系统规模尽量部署多个redis实例,让他们参与sharding,当需要扩容时,选中一个实例做主节点,新加入的redis 实例作为从节点进行拷贝。数据同步后,修改sharding配置,让指向原实例的shard指向新机器上扩容后的redis节点,调整新redis节点为主节点,原实例可不再使用。
方案3:利用代理中间件实现大规模redis集群
Twemproxy 中间件做sharding技术,处于客户端和服务端之间,客户端发送请求,进行一定的处理后,再转发给真正的redis服务器。
Twemproxy支持redis,同时也支持memcached。可以通过共享与后端系统的链接,降低客户端直接链接后端服务器的链接数量。同时它也提供sharding功能,支持后端服务器集群水平扩展。
使用中间件性能上会有所损耗,测试结果大约降低20%左右。