还是有很多问题的,希望以后的自己能够作出解答。
好处: 简单直接
坏处: 单机数据过大,fork时可能阻塞主线程过长,成本
需要解决的问题就是数据放在哪里如何分布,客户端怎么知道访问哪里
Redis提供了Redis Cluster方案 如下:
采用Hash槽处理集群与数据的映射关系,默认16384个,根据key用CRC16算法取模。
使用cluster create
建立集群时需要指定这台节点关注的hash槽 (所有节点的hash槽之和必须等于16384)
hash槽分配结束后节点之间会同步hash槽信息。每个实例存储一份hash槽节点映射。
负责0~5460个槽 redis-cli -h 172.16.19.1 –p 6379 cluster addslots 0,5460 redis-cli -h 172.16.19.2 –p 6379 cluster addslots 5461,10922 redis-cli -h 172.16.19.3 –p 6379 cluster addslots 10923,16383
自动分配Hash槽
CLUSTER MEET <ip> <port>
邀请ip:port
节点组为集群,Redis会自动分配Hash槽
客户端如何知道一个Key在哪个节点?
注意:当节点新增/删除时需要重新分配hash槽,故而数据也需要重新分配
(重新分配怎么做的?有哪些资源开销?分配期间服务是否不可用?)
3. 重新分配后客户端的hash槽映射关系还是旧的就会导致访问到了没有数据的实例。。
Redis Cluster 提供了一种重定向机制:数据可分为俩种:1. 已迁移到新实例 2. 数据还在迁移中。
针对1: 节点没有相应数据,返回(MOVED 槽 key所在节点地址)客户端就可以拿到MOVED去拉取数据了 (怎么发现的是在本库中查一遍还是带了槽过来?)
针对2: 部分数据迁移完成时拉取数据会返回ASK 槽 key所在节点地址
消息,标识当前槽在这个节点上,但是槽正在迁移 (如果已经迁移到新的节点那为什么不用MOVED直接去新节点拉取数据,如果还没迁移到为什么不直接返回数据??还要引入一个ASK操作)
ASK: 不会修改客户端缓存,也就是说下次访问这个槽还是这个节点。
MOVED: 会修改客户端缓存。