带你走进Redis的世界 - 分布式环境下Redis的挑战

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 带你走进Redis的世界 - 分布式环境下Redis的挑战

前言

Redis作为存储系统,不论数据存储在内存中,还是我们之前聊过的,以快照或者AOF日志文件形式持久化到磁盘,作为单实例,会面临很多问题:

  • 数据量伸缩

单实例Redis存储k-v数量受限于内存和磁盘容量。长期运行的生产环境,会有很大瓶颈。

  • 访问量伸缩

单实例的Redis单线程执行客户端请求,吞吐量依赖于单机能够处理的数量

  • 单点故障

Redis持久化机制一定程度上,缓解了宕机/重启带来的数据安全性问题。但是对于单机系统应用,故障难以解决,会造成很大的生产问题

针对上述问题,对于数据存储系统,分布式环境下解决方案基本上通用的,如下:

  • 水平拆分 sharding
  • 主备复制 replication
  • 故障转移 failover


水平拆分

为了解决数据量和访问量增加带来的单机局限问题,采用水平拆分数据,将数据按照规则,拆分分散到不同节点处理。水平拆分后的每个节点存储的数据原则上没有交集,节点间相互独立。

image.png

具体的拆分策略一般如下所示:

hash映射

对应业务数据key,采用hash算法,映射到有限值域(hash值)上,映射尽量均匀,然后将均匀分布的hash值映射到Redis实例上。

image.png

范围映射

直接按照业务数据key进行选择,对应的实例存放。比如,0<= key <100 存放到Redis 实例0上;当大于100,存放在redis其他实例上。按照一定的规则去存放

hash和范围结合

典型的实现方式就是一致性hash。先对业务数据key进行hash求值,然后根据有限值域hash值,进行范围映射,进行存放。

按照一定的策略进行数据拆分存放,但对于客户端对于数据的请求,需要按照对应的规则,去请求到对应的实例上,称为请求路由。

对于只读的跨实例请求,按照拆分的规则进行路由到对应的实例即可。

对于跨实例的读写请求,需要特殊注意。比如,一个客户端请求需要先进行读取实例A中数据,根据获得的数据,再对实例B实施写操作,此时整个业务请求就失去了原子性。如果没有采用集群方案之前,可以通过proxy 代理层处理sharding逻辑。如独立的实例:Twemproxy


主备复制

为了解决单机性能瓶颈,引入数据拆分,将数据分发至多个redis节点,多个节点数据独立。

但是,当出现宕机问题,还是没法避免数据丢失问题。因此,引用主备复制机制,解决宕机数据安全问题。

主备复制流程

Redis包含master slave两类节点,master对外提供数据读写服务;slave节点作为master的数据备份,拥有master的全量数据,对外不提供写服务,可以读。

image.png

  1. slave节点刚启动,向master节点,发起SYNC命令,master被动将新进的slave节点加入自己的主备复制集群中
  2. master收到SYNC命令之后,开启BGSAVE操作,进行快照操作
  3. master完成BGSAVE之后,将快照信息发送给slave
  4. 在发送期间,master收到其他请求的写命令,除了正常响应之外,会存储到back-log
  5. 快照信息传送完毕,会继续传送back-log,等于追加增加的指令。
  6. 后续所有的对于master的写操作,master会同时同步给slave。保持实时异步复制


对于slave来讲,处理逻辑如下:

  • 发送完SYNC指令,对外提供读服务
  • 接收到master的快照信息,此时将slave的现有数据清空,将master的快照写入内存
  • 接受back-log执行

如多个slave节点发送SYNC命令到master,那么只要master没有完成BGSAVE操作,slave节点收到的快照信息和back-log是一致的。

断点续传

当slave节点发送SYNC指令到master,master会dump全部数据,进行异步复制。当一个已经和master完成了同步,且持续保持了很长时间的slave节点,突然断开重连,那么如果仍执行SYNC指令,就会再重发一遍。会造成不必要的开销,其中可能改变的数据没有或者很少。

Redis的PSYNC用来替代SYNC指令,可以实现断点续传。master slave维护一个offset记录当前已经同步过的指令,当出现断点重连之后,比较offset,只进行同步没有执行过的命令内容。

故障转移

当主备复制被正确使用之后,组成的集群,就具有一定的高可用,当master存在宕机或者故障,slave会自动切换为master,对外提供读写服务,这种机制称为failover(故障转移)。

针对如何发现故障,一般解决方案为采用一个daemon进程,监控所有的master-slave节点,观察可用性,并提供切换方案。image.png

但是单机的daemon又会出现单点问题,需要引入多个daemon,才进行集群管理。

image.png多个daemon集群方案,又会出现新的问题,要解决集群数据一致性问题。

Redis的sentinel提供了一套多daemon的交互机制,解决故障发现、故障转移决策协商机制等问题。

image.png

sentinel的互相感知

通过发布订阅模式来实现互相感知。

Master节点发布一个sentinel频道channel,所有的sentinel需要订阅master上的同channel,并发布自己的信息到channel,因此当新的sentinel增加,能够及时订阅到channel信息,并感知到当前所有订阅该channel的节点的信息。

master的故障发现

sentinel节点通过心跳检测的方式,定期向master发送心跳包判断是否存活。一旦没有收到正确响应,当前sentinel节点,判断master为主观不可用态,此时没有最终的决议,只有当前节点的判断。

随后所有的sentinel节点进行确定,当确定不可用的节点数大于配置的阈值,则判断不可用,进行failover故障转移流程。

failover决策

Redis的sentinel机制采用的是Raft数据一致性协议,那可以Paxos的最强有力的颠覆者。如果不了解Raft的可以参考我之前的文章,深入分布式缓存-Raft,相关的介绍。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
11天前
|
NoSQL Redis
Redis分布式锁如何实现 ?
Redis分布式锁通过SETNX指令实现,确保仅在键不存在时设置值。此机制用于控制多个线程对共享资源的访问,避免并发冲突。然而,实际应用中需解决死锁、锁超时、归一化、可重入及阻塞等问题,以确保系统的稳定性和可靠性。解决方案包括设置锁超时、引入Watch Dog机制、使用ThreadLocal绑定加解锁操作、实现计数器支持可重入锁以及采用自旋锁思想处理阻塞请求。
47 16
|
1月前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
61 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
|
1月前
|
NoSQL Redis 数据库
计数器 分布式锁 redis实现
【10月更文挑战第5天】
48 1
|
1月前
|
NoSQL 算法 关系型数据库
Redis分布式锁
【10月更文挑战第1天】分布式锁用于在多进程环境中保护共享资源,防止并发冲突。通常借助外部系统如Redis或Zookeeper实现。通过`SETNX`命令加锁,并设置过期时间防止死锁。为避免误删他人锁,加锁时附带唯一标识,解锁前验证。面对锁提前过期的问题,可使用守护线程自动续期。在Redis集群中,需考虑主从同步延迟导致的锁丢失问题,Redlock算法可提高锁的可靠性。
76 4
|
1月前
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
55 3
|
1月前
|
SQL NoSQL 安全
分布式环境的分布式锁 - Redlock方案
【10月更文挑战第2天】Redlock方案是一种分布式锁实现,通过在多个独立的Redis实例上加锁来提高容错性和可靠性。客户端需从大多数节点成功加锁且总耗时小于锁的过期时间,才能视为加锁成功。然而,该方案受到分布式专家Martin的质疑,指出其在特定异常情况下(如网络延迟、进程暂停、时钟偏移)可能导致锁失效,影响系统的正确性。Martin建议采用fencing token方案,以确保分布式锁的正确性和安全性。
44 0
|
1月前
|
缓存 NoSQL 算法
面试题:Redis如何实现分布式锁!
面试题:Redis如何实现分布式锁!
|
1月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
77 6
|
10天前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
下一篇
无影云桌面