.png)
1.切片集群(分片集群)
1.1.概念
启动多个redis实例组成一个集群,其中数据按照规则划分到每个实例
牢记:RDB中fork子进程的耗时是和当前数据量成正比的,并且fork的过程会阻塞主进程
1.2.数据分片和实例的对应分布关系
Redis 3.0官方提供了一个Redis Cluster的方案。
哈希槽(Hash Slot):一个切片集群有16384个哈希槽,每个哈希槽会分配给不同的实例
数据:根据键值的key,按照CRC16算法计算一个16bit的值,然后再用这个16bit的值对16384取模
实例:使用cluster create
命令创建集群,这个时候会把槽均匀分配到实例上 16384/实例树=N(每个实例的槽数),也可以使用
cluster meet
命令手动建立实例连接,再使用cluster addslots
命令指定实例的槽数,在手动分配哈希槽时,需要把16384个槽都分配完,否则Redis集群无法正常工作
例如:
redis-cli -h 172.16.19.3 –p 6379 cluster addslots 0,1
redis-cli -h 172.16.19.4 –p 6379 cluster addslots 2,3
redis-cli -h 172.16.19.5 –p 6379 cluster addslots 4
1.3.客户端如何定位数据
(1)如何获得哈希槽分配信息
当客户端与集群建立连接时候,会获得哈希槽与实例的映射信息,客户端并且会将映射信息缓存到本地(这样就能够通过key取模得到槽,去请求对应的实例了),其中实例之间相互连接后,会将哈希槽的信息同步给其他实例
(2)实例的增删改引发的哈希槽重新分配
增删实例后,会将哈希槽再实例中重新分配,这个时候实例之间是能够知道哈希槽的分配信息的,但是客户端本地缓存的信息可能就与当前信息出现不一致的场景,这个时候客户端再次读写请求会发生什么呢?
重定向:
-
第一步:当客户端通过缓存的哈希槽映射信息向实例发送读写请求
-
第二步:此时key不在这个实例上,该实例就会返回Moved
命令响应,其中包含了该key所在实例的地址
GET hello:key (error)
MOVED 13320 172.16.19.5:6379
-
第三步:客户端拿到新地址后,再次发起同样的读写请求,并更新本地缓存
重定向(数据未全部迁移完成场景):
当slot槽的数据并未全部迁移完成时,此时客户端发送读写请求会出现其他结果
-
第一步:当客户端通过缓存的哈希槽映射信息向实例发送读写请求
-
第二步:此时key未迁移到新的实例,则返回正常数据,若此时key已迁移到新的实例,就会返回ASK
命令响应,其中包含key所在实例信息
GET hello:key (error)
ASK 13320 172.16.19.5:6379
-
第三步(接收到ASK命令):接收到ASK命令代表数据所在的哈希槽正在迁移,此时需要客户端发送ASKING命令(让该实例允许客户端所发送的读写请求)给ASK所返回的新实例地址,然后客户端再发送具体的命令给实例。此时客户端并不会更新本地缓存
