Redis核心技术及实战(九.解决大数据量问题)

九:cluster集群——解决大数据量问题

原文:《09丨切片集群:数据增多了,是该加内存还是加实例?》

Redis要保存大量数据怎么办?

  • 纵向扩展:升级单个Redis实例的资源配置,如增加内存容量、高配置CPU等。但是,当数据量特别大时,硬盘会很难支撑,而且,一个实例中的数据太多,在fork子进程保存快照时就会严重阻塞主线程。
  • 横向扩展:切片集群,使用多个Redis实例存储数据。这时,会有两个问题:数据切片后,怎么在多个实例间分布?客户端怎么确定想要访问的数据在哪个实例上?

1. 数据切片和实例的对应分布关系

在Redis 3.0之前,并没有官方的集群方法,可以使用一致性哈希方法(哈希环)部署集群。

在Redis 3.0之后,官方集群采用**哈希槽(Hash Slot)**方法来处理数据和实例之间的映射关系。

**哈希槽:**一个切片集群共有16384个槽,把这些槽分给所有实例,读写数据时,每一个键值都会根据它的key被映射到一个槽中(对key使用CRC16算法计算得到一个值,然后对16384取余,得到的结果就是槽号)。

那么槽是怎么分给实例呢?

  • 平均分配
  • 如果每个实例的配置不同,可以手动给各个实例分配槽的数量(注意一定要把所有槽都给分配完)

2. 客户端如何定位数据

在定位键值位置的时候,可以计算得到槽号,但是怎么知道这个槽号是在哪个实例呢? => 最开始创建集群的时候,每个实例只知道自己有哪些槽,然后各个实例之间会互相发送槽信息,这样所有实例都拥有全部的槽分布信息,然后客户端和Redis实例建立连接后,Redis实例会把哈希槽的分配信息发给客户端,客户端把哈希槽信息给缓存起来,之后就知道该去哪里读写数据了。

但是,在集群中,如果有实例的增删,Redis集群为了负载均衡就要重新分配哈希槽。集群实例之间互相传递消息获得最新的哈希槽信息,但是客户端是无法主动感知到这些变化的,这就导致客户端缓存的分配信息和最新的分配信息不一致了。 => 重定向机制

重定向机制:客户端在给实例发送数据读写操作请求的时候,这个实例并没有相应数据,会返回给客户端MOVED/ASK命令,客户端要再给新的实例发送数据。

  • MOVED命令,原本位于该实例的数据所在槽已经全部移到了新的实例,MOVED会包含该数据所在槽号以及新实例的ip地址,客户端收到MOVED命令后,就会给新实例发送请求,并把缓存中的分配信息给更新过来
  • ASK命令,原文位于该实例的数据所在的槽只有一部分转移到了新实例,另一部分还没有转移过去,ASK命令会包含该槽号和新实例的ip地址,客户端会给新实例发送请求,但是并不会更新缓存(因为还有部分数据仍再原来实例中)。

你可能感兴趣的:(Java,redis,缓存,数据库)