前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis读写分离和分布式缓存算法原理

Redis读写分离和分布式缓存算法原理

作者头像
丁D
发布2022-08-12 21:39:00
4650
发布2022-08-12 21:39:00
举报
文章被收录于专栏:老铁丁D

读写分离、主从复制

当启动一个slave node的时候,它会发送一个PSYNC命令给master node

如果这是slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据; 否则如果是slave node第一次连接master node,那么会触发一次full resynchronization

开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。

slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。

2、主从复制的断点续传 https://www.jianshu.com/p/532149db7650

从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份

master node会在内存中常见一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制

但是如果没有找到对应的offset,那么就会执行一次resynchronization

3、无磁盘化复制

master在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了

repl-diskless-sync repl-diskless-sync-delay,等待一定时长再开始复制,因为要等更多slave重新连接过来

4、过期key处理

slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。

哨兵基础知识

从之前学习到的知识我们知道,读写分离能提高读的吞吐量,提高高的QPS,但是却不能保证主节点的高可用。sentinal(哨兵)是redis集群中非常重要的组件,能保证集群的高可用。

哨兵作用: 1.集群检测,检查redis master和slave是否正常工作 2.消息通知,当检测到redis实例有故障,可以通过api通知管理员 3.故障转移,当发现master节点挂了,会提拔一个slave当作master。

哨兵本身也是分布式的,作为一个哨兵集群去运行; 一般来说至少需要3个哨兵实例,来保证自身的健壮性; 哨兵不能保证redis数据的0丢失,只能保证redis集群的高可用。

经典的哨兵集群(3个)

代码语言:javascript
复制
+----+ 
| M1 | 
| S1 | 
+----+ 
| 
+----+ | +----+ 
| R2 |----+----| R3 | 
| S2 | | S3 | 
+----+ +----+ 

为什么哨兵需要部署两个节点以上? 要进行主从切换要满足下面两个条件 1.Configuration: quorum = 1

当master宕机的时候至少需要quorum个哨兵几点认为master宕机才可以进行主从切换

2.majority 需要majority,也就是大多数哨兵都是运行的,2个哨兵的majority就是2(2的majority=2,3的majority=2,5的majority=3,4的majority=2),2个哨兵都运行着,就可以允许执行故障转移

slave->master选举算法

https://www.cnblogs.com/codecheng99/p/12383589.html#slave-master-%E9%80%89%E4%B8%BE%E7%AE%97%E6%B3%95 如果一个master被认为odown了,而且majority哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个slave来

会考虑slave的一些信息

(1)跟master断开连接的时长 (2)slave优先级 (3)复制offset (4)run id

如果一个slave跟master断开连接已经超过了down-after-milliseconds的10倍,外加master宕机的时长,那么slave就被认为不适合选举为master

(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state

接下来会对slave进行排序

(1)按照slave优先级进行排序,slave priority越低,优先级就越高 (2)如果slave priority相同,那么看replica offset,哪个slave复制了越多的数据,offset越靠后,优先级就越高 (3)如果上面两个条件都相同,那么选择一个run id比较小的那个slave

哨兵主备切换,数据丢失,脑裂问题

数据丢失两种情况

(1)异步复制导致的数据丢失 因为redis 主从复制的异步的,所以当master宕机了,但是数据还没来得及复制到slave节点,哨兵当slave提拔为master这时候数据的丢失了。

(2)脑裂导致的数据丢失

当网络原因或者其他原因,master与slave和哨兵集群连接不上;这个时候哨兵会认为master宕机了,会提拔一个slave当作master,而实际上master没有宕机还在为客户端提供服务,某个slave被切换成了master,但是可能client还没来得及切换到新的master,还继续写向旧master的数据可能也丢失了

因此旧master再次恢复的时候,会被作为一个slave挂到新的master上去,自己的数据会清空,重新从新的master复制数据

解决异步复制和脑裂导致的数据丢失

代码语言:javascript
复制
min-slaves-to-write  
min-slaves-max-lag 10 

要求至少有1个slave,数据复制和同步的延迟不能超过10秒

如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了

上面两个配置可以减少异步复制和脑裂导致的数据丢失

(1)减少异步复制的数据丢失

有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延时太长,就认为可能master宕机后损失的数据太多了,那么就拒绝写请求,这样可以把master宕机时由于部分数据未同步到slave导致的数据丢失降低的可控范围内

(2)减少脑裂的数据丢失

如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求

这样脑裂后的旧master就不会接受client的新数据,也就避免了数据丢失

上面的配置就确保了,如果跟任何一个slave丢了连接,在10秒后发现没有slave给自己ack,那么就拒绝新的写请求

因此在脑裂场景下,最多就丢失10秒的数据

redis主从复制+高可用,横向扩展1T的数据

读写分离的架构,对于每个master来说,写就写到master,然后读就从mater对应的slave去读,这个时候master能存多少数据就受到master节点物理机的限制,假设master的内存只有64G那么master就只能缓存64G的数据,当超过一定数量,redis会通过淘汰算法来删除即将过期的数据等。

所以这个时候我们就可以需要支持多个master来横向扩展,提高缓存能支撑的数据量。这种方式叫redis cluster

我们只要基于redis cluster去搭建redis集群即可,不需要手工去搭建replication复制+主从架构+读写分离+哨兵集群+高可用

redis cluster vs. replication + sentinal如何选择?

如果你的数据量很少,主要是承载高并发高性能的场景,比如你的缓存一般就几个G,单机足够了

replication,一个mater,多个slave,要几个slave跟你的要求的读吞吐量有关系,然后自己搭建一个sentinal集群,去保证redis主从架构的高可用性,就可以了

redis cluster,主要是针对海量数据+高并发+高可用的场景,海量数据,如果你的数据量很大,那么建议就用redis cluster

redis数据分布算法

当redis要处理海量数据的时候,需要多个master来对redis集群进行扩容,从而支撑海量的数据,而这里主要介绍当多个master的时候数据存储在哪个master中。

hash算法 对存活的master求余数 假设master有3个节点 hash算法只要是指当一个key请求过来的时候,计算key的hash值,并对master的节点数(3个)求余, 从而将key请求到某一个节点。

当一个master宕机的时候,一个key请求过来,同样对key计算hash值,然后对master节点数求余数(2个),这时候发现求出来的余数跟之前对应不上,导致请求的节点没有数据需要到数据库去查询,这种算法只要有一个节点宕机就需要对缓存数据重新分布。

一致性hash算法 环形结构,将节点放在环上(可以搞几个虚拟节点,让其分散得均匀)。 将key计算hash放在环上,顺时针找到对应得节点,,这样如果有一台机器gg,,只是需要移动一小部分数据。。。

hash solt算法 槽slot 16384 redis cluster每个实例分一些slot(可以平分。。具体要自己计算) 将key计算映射到对应得slot中,当一个请求过来,到任意一个redis实例的时候, redis实例发现不是对应自己的slot将会返回 真实的redis实例,,客户端然后在去请求真实的服务器获取数据。

Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽 (hash slot)的方式来分配的。redis cluster 默认分配了 16384 个slot,当我们set一个key 时,会用CRC16算法来取模得到所属的slot,然后将这个key 分到哈希槽区间的节点上,具体算法就是:CRC16(key) % 16384。

gossip https://stor.51cto.com/art/201912/608491.htm

为什么redis是16384个slot? https://blog.csdn.net/fujiandiyi008/article/details/100147553

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-05-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 读写分离、主从复制
  • 哨兵基础知识
  • 哨兵主备切换,数据丢失,脑裂问题
  • redis主从复制+高可用,横向扩展1T的数据
  • redis数据分布算法
相关产品与服务
云数据库 Redis®
腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档