复制的问题
由于复制中,每个数据库都是拥有完整的数据,因此复制的总数据存储量受限于内存最小的数据库节点,如果数据量过大,复制就无能为力了。
分片
分片(Patitioning)就是将数据拆分到多个redis实例的过程,这样每个Redis实例将只包含完整数据的一部分。
分片场景
常见的分片方式:
1、按照范围分片
2、哈希分片,例如一致性哈希
常见的分片的实现:
①客户端分片
②通过代分片,比如:twemproxy
③查询路由:就是发送查询到一个随机实例,这个实例会保证转发你的查询到正确的节点,redis集群在客户端的帮助下,实现了查询路由的一种混合形式,请求不是直接从redis实例转发到另一个实例,而是客户端收到重定向到正确的节点
④在服务端进行分片,Redis采用哈希槽(hash slot)的方式在服务器端进行分片:
Redis集群有16384个哈希槽,使用健CrC16对16384取模来计算一个键所属的哈希槽
Redis分片的缺点
1、不支持涉及多建的操作,如mget,如果所操作的健都在同一个节点,就正常执行,否则会提示报错
2、分片的粒度是健,因此每个键对应的值不要太大
3、数据备份会比较麻烦,备份数据时你需要聚合多个实例和主机的持久化文件
4、扩容的处理比较麻烦
5、故障的恢复的处理会比较麻烦,可能需要重新梳理Master和Slave的关系,并调整每个复制集里面的数据
Redis集群
由于数据量过大,单个复制集难以承担,因此需要对多个复制集进行集群,形成水平扩展,每个复制集只负责存储数据集的一部分,这就是Redis的集群
1、在以前版本中,Redis的集群是依靠客户端分片来完成,但是这样会有很多缺点,比如维护成本高,需要客户端编码解决;增加、移除节点都比较繁琐等
2、Redis3.0新增的一大特性就是支持集群,在不降低性能的情况下,还提供了网络分区的可访问性和支持对主数据库故障的恢复。
3、使用集群后,都只能使用默认的0号数据库
4、每个redis集群节点需要两个TCP连接打开,正常的TCP端口用来服务客户端,例如6379,家10000的端口用作数据端口,必须保证防火墙打开这两个端口
5、Redis集群不保证强一致性,这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请求命令(Master传播命令返回OK后挂掉,slave还没有收到广播)
集群的架构
1、所有的Redis节点彼此互联,内部使用二进制协议优化传输速度和宽带
2、节点的fail是通过集群中超过半数的节点检测失效时才生效
3、客户端与redis节点直连,不需要中间的proxy层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
4、集群把所有的物理节点映射到【0-16383】插槽上,集群负责维护:节点—插槽—值 的关系
集群操作的基本命令
CLUSTER INFO
CLUSTER NODES
CLUSTER MEET <IP> <PORT>
CLUSTER FORGET <NODE_ID>
CLUSTER REPLICATE <NODE_ID>
CLUSTER SAVECONFIG
CLUSTER ADDSLOTS <SLOT>
CLUSTER DELSLOTS <SLOT>
CLUSTER FLUSHSLOTS <SLOT>
CLUSTER SETSLOT <SLOT> NODE <NODE_ID>
CLUSTER SETSLOT <SLOT> MIGRATING <NODE_ID>
CLUSTER SETSLOT <SLOT> IMPORTING <NODE_ID>
CLUSTER SETSLOT <SLOT> STABLE
CLUSTER KEYSLOT <KEY>
CLUSTER COUNTKEYSINSLOT <SLOT>
CLUSTER GETKEYSINSLOT <SLOT> <COUNT>
MIGRATE 目的节点<ip> 目的节点<port> 键名 数据库号码 超时时间 [copy] [replace]