带你走进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
目录
相关文章
|
5月前
|
NoSQL 关系型数据库 Redis
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
mall在linux环境下的部署(基于Docker容器),docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongodb、minio详细教程,拉取镜像、运行容器
mall在linux环境下的部署(基于Docker容器),Docker安装mysql、redis、nginx、rabbitmq、elasticsearch、logstash、kibana、mongo
|
8月前
|
存储 缓存 NoSQL
Redis是一种高性能的内存数据库,常用于高并发环境下的缓存解决方案
【6月更文挑战第18天】**Redis摘要:** 高性能内存数据库,擅长高并发缓存。数据存内存,访问迅速;支持字符串、列表等多元数据类型;具备持久化防止数据丢失;丰富命令集便于操作;通过节点集群实现数据分片与负载均衡,增强可用性和扩展性。理想的缓存解决方案。
103 1
|
8月前
|
NoSQL 关系型数据库 MySQL
Linux搭建mysql以及Redis环境
Linux搭建mysql以及Redis环境
|
8月前
|
存储 缓存 负载均衡
【Redis】 String类型的内部编码与使用环境
【Redis】 String类型的内部编码与使用环境
|
9月前
|
NoSQL Linux 测试技术
如何在Linux环境下安装Redis呢?
如何在Linux环境下安装Redis呢?
134 1
|
9月前
|
缓存 运维 NoSQL
面试分享:Redis在大数据环境下的缓存策略与实践
【4月更文挑战第10天】探索Redis在大数据缓存的关键作用,本文分享面试经验及必备知识点。聚焦Redis数据结构(String、List、Set、Hash、Sorted Set)及其适用场景,缓存策略(LRU、LFU、TTL)与过期机制,集群和数据分片,以及性能优化和运维技巧。通过代码示例深入理解,助你面试成功,构建高效缓存服务。
229 4
|
9月前
|
NoSQL 关系型数据库 MySQL
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
Docker安装详细步骤及相关环境安装配置(mysql、jdk、redis、自己的私有仓库Gitlab 、C和C++环境以及Nginx服务代理)
762 0
|
9月前
|
NoSQL Linux Redis
在Linux环境如何启动和redis数据库?
在Linux环境如何启动和redis数据库?
|
9月前
|
NoSQL 数据可视化 Redis
redis在window环境下的安装教程
redis在window环境下的安装教程
97 0
|
9月前
|
存储 NoSQL Redis
docker compose搭建Redis Cluster集群环境
docker compose搭建Redis Cluster集群环境
285 0