Redis集群

Posted LinBupt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis集群相关的知识,希望对你有一定的参考价值。

集群架构:就是使用网络将若干台计算机连通起来,并提供统一的管理方式,使其对外呈现单机的服务效果

集群作用==》

分散单台服务器的访问压力,实现负载均衡;

分散单台服务器的存储压力,实现可扩展性;

降低单台服务器宕机带来的业务灾难

 

Redis集群结构设计:key-->CRC16-->%16384

数据存储设计:通过算法设计,计算出key应该保存的位置;将所有的存储空间计划切割成16384份,每台主机保存一部分,每份代表的是一个存储空间,不是一个key的保存空间;将key按照计算出的结果放到对应的存储空间

增强可扩展性:增节点/去节点,改变槽的地方  增加节点-->其他节点给该节点部分槽

 

集群内部通讯设计:各个数据库相互通信,保存各个库中槽的编号数据;一次命中,直接返回;一次未命中,告知具体位置

 

cluster集群搭建  修改配置文件

cluster-enabled yes

cluster-node-timeout 1000000000

redis-trib.rb  create  --replicas count ip

 

连接客户端 redis-cli -c

 

 

 

 

 

主从下线与主从切换

 

----------------------------

16384个槽-->https://zhuanlan.zhihu.com/p/99037321

Redis集群:

Redis Sentinal==》高可用,在master宕机时会自动将slave提升为master,继续提供服务

Redis Cluster==》扩展性,在单个redis内存不足时,使用Cluster进行分片存储

 

数据分片策略==》Sharding。为了使得集群能够水平扩展,首要解决的问题就是如何将整个数据集按照一定的规则分配到多个节点上,常用的数据分片的方法:范围分片哈希分片一致性哈希算法虚拟哈希槽

范围分片==》假设数据集是有序,将顺序相临近的数据放在一起,可以很好的支持遍历操作。范围分片的缺点是面对顺序写时,会存在热点。比如日志类型的写入,一般日志的顺序都是和时间相关的,时间是单调递增的,因此写入的热点永远在最后一个分片。对于关系型的数据库,因为经常性的需要表扫描或者索引扫描,基本上都会使用范围的分片策略

哈希分片==》为了将不同的key分散放置到不同的redis节点,通常获取key的哈希值,然后根据节点数来求模。缺点是当需要增加或减少一个节点时,会造成大量的key无法命中

一致性哈希==》均衡性:哈希的结果能够尽可能分布到所有的节点中去,这样可以有效的利用每个节点上的资源;单调性:当节点数量变化时哈希的结果应尽可能的保护已分配的内容不会被重新分派到新的节点;分散性和负载:对key哈希避免重复

 

Redis的分片机制==》Redis集群没有使用一致性hash,而是引入了哈希槽的概念

Redis Cluster采用虚拟哈希槽分区,所有的键根据哈希函数映射到0~16383整数槽内,每个key通过CRC16校验后对16384取模来决定放置哪个槽(Slot),每一个节点负责维护一部分槽以及槽所映射的键值数据

计算公式:slot=CRC16(key)&16383

这种结构很容易添加或者删除节点,并且无论是添加删除或者修改某一个节点,都不会造成集群不可用的状态。使用哈希槽的好处就在于可以方便的添加或移除节点

当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了

当需要移出节点时,只需要把移除节点上的哈希槽挪到其他节点就行了

 

Redis虚拟槽分区的特点

解耦数据和节点之间的关系,简化了节点扩容和收缩难度

节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据

支持节点、槽和键之间的映射查询,用于数据路由,在线集群伸缩等场景

 

Redis集群伸缩的原理

Redis集群提供了灵活的节点扩容和收缩方案。在不影响集群对外服务的情况下,可以为集群添加节点进行扩容也可以下线部分节点进行缩容。槽是Redis集群管理数据的基本单位,集群伸缩就是槽和数据在节点之间的移动

 

集群扩容==》当一个 Redis 新节点运行并加入现有集群后,我们需要为其迁移槽和数据。首先要为新节点指定槽的迁移计划,确保迁移后每个节点负责相似数量的槽,从而保证这些节点的数据均匀。

 

为什么RedisCluster会设计成16384个槽==》

https://github.com/antirez/redis/issues/2576

1.如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大。

如上所述,在消息头中,最占空间的是 myslots[CLUSTER_SLOTS/8]。 当槽位为65536时,这块的大小是: 65536÷8÷1024=8kb因为每秒钟,redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65536,这个ping消息的消息头太大了,浪费带宽。

2.redis的集群主节点数量基本不可能超过1000个。

如上所述,集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。因此redis作者,不建议redis cluster节点数量超过1000个。 那么,对于节点数在1000以内的redis cluster集群,16384个槽位够用了。没有必要拓展到65536个。

3.槽位越小,节点少的情况下,压缩率高

Redis主节点的配置信息中,它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中,会对bitmap进行压缩,但是如果bitmap的填充率slots / N很高的话(N表示节点数),bitmap的压缩率就很低。 如果节点数很少,而哈希槽数量很多的话,bitmap的压缩率就很低。

以上是关于Redis集群的主要内容,如果未能解决你的问题,请参考以下文章

java怎么从多台redis集群取数据库

我在工作中遇到的redis集群使用

redis集群概念

python连接redis,redis集群

Python3 redis集群连接 (带密码验证)

c#程序怎么调用redis集群