Redis分布式解决方案 codis

embedded/2024/10/19 6:19:31/

引言

在大数据高并发场景下,单个Redis实例往往会显得捉襟见肘。首先体现在内存上,单个Redis的内存不宜过大,内存太大会导致rdb文件过大,进一步导致主从同步时全量同步时间过长,在实例重启恢复时也会消耗很长的时间加载数据。其次,体现在CPU利用率上,单个Redis实例只能利用单个核心,单个核心要完成海量数据的存取和管理工作压力会很大。

正是在这样的大数据高并发需求之下,Redis集群方案应运而生。他可以将多个众多小内存的Redis实例综合起来,将分布在多台机器上的众多CPU核心的计算能力聚集到一起,完成海量数据存储和高并发读写操作。
在这里插入图片描述

Codis上挂接的 所有Redis实例构成一个Redis集群,当集群空间不足时,可以通过动态增加Redis实例来实现扩容需求。

客户端操作Codis同操作Redis几乎没有区别,还是可以使用相同的客户端SDK,不需要任何变化。

因为Codis是无状态的,他只是一个转发代理中间件,意味着我们可以启动多个Codis实例,供客户端使用,每个Codis节点都是对等的。因为单个Codis代理能支撑的QPS比较有限,通过启动多个Codis代理可以显著增加整体的QPS需求,还能起到容灾功能。
在这里插入图片描述

分片原理

Codis要负责将特定的key转发到特定的Redis实例,Codis将所有的key默认划分为1024个槽位(slot),他首先将客户端传来的key进行crc32运算计算哈希值,再将hash后的整数值对1024这个整数进行取模得到一个余数,这个余数就是对应key的槽位,每个槽位都会唯一映射到后面的多个Redis实例之一,Codis会在内存维护槽位和Redis实例的映射关系。

在这里插入图片描述

不同的Codis实例之间槽位关系如何同步

如果Codis的槽位映射关系只存储在内存里,那么不同的Codis实例之间的槽位关系就无法得到同步。所以,Codis需要一个分布式配置存储数据库专门用来持久化槽位关系。
在这里插入图片描述
Codis将槽位关系存储在zk中,并且提供了一个Dashboard可以用来观察和修改槽位关系,当槽位关系变化时,Codis Proxy会监听到变化并重新同步槽位关系。从而实现多个Codis Proxy之间共享相同的槽位关系配置。

扩容

刚开始Codis后端只有一个Redis实例,1024个槽位全部指向同一个Redis。然后一个Redis实例内存不够了,所以又加了一个Redis实例,这时候需要对槽位关系进行调整,将一半的槽位划分到新的节点。这意味着需要对这一半的槽位对应的所有key进行迁移,迁移到新的Redis实例。

Codis对Redis进行了改造,增加了slotsscan指令,可以遍历指定slot下所有的key。然后迁移每个key到新的Redis节点。

在迁移过程中,Codis还是会接收到新的请求落在当前正在迁移的槽位上,因为当前槽位的数据同时存在于新旧两个槽位中,Codis无法判定迁移过程中的key究竟在哪个实例中,所以采用了另一种完全不同的思路。当 Codis接收到位于正在迁移槽位中的key后,会立即强制对当前的单个key进行迁移,迁移完成后,再将请求转发到新的Redis实例

在这里插入图片描述

Codis的代价

Codis给Redis带来了扩容的同时,也损失了一些其他特性。因为Codis中所有的key分散在不同的Redis实例中,所以事务就不再支持。事务只能在单个Redis实例中完成。

同时,为了支持扩容,单个key对应的value不宜过大,因为集群的最小迁移单位是key。对于一个hash结构,他会一次性使用hgetall拉取所有内容,然后使用hmset放置到另一个节点。如果hash内部的kv太多,容易带来迁移卡顿。

Codis因为增加了Proxy作为中转层,所以在网络开销上要比Redis 大,整体性能上比单个Redis性能有所下降。

Codis集群配置中心使用zk来实现,在部署上增加了zk运维的代价。

Mget指令的操作过程

在这里插入图片描述
mget指令用于批量获取多个key的值,这些key 可能会分布在多个Redis实例中。Codis的策略是将key按照所分配的实例打散分组,然后依次对每个实例调用mget方法,最后将结果进行汇总,返回给客户端。


http://www.ppmy.cn/embedded/58687.html

相关文章

C#中AsMemory方法

1、效率&#xff1a;Memory<T>和Span<T>有助于避免不必要的分配&#xff0c;对频繁操作数组或字符串时起到提高其性能。 2、安全&#xff1a;类型都提供了安全和经过边界检查的内存访问&#xff0c;能降低常见编程错误风险。 3、灵活性&#xff1a;Memory<T&g…

45、tomcat+课后实验

tomcat 1、tomcat tomcat和php一样&#xff0c;都是用来处理动态页面的。 tomcat也可以作为web应用服务器&#xff0c;开源的。 php .php tomcat .jsp nginx .html tomcat 是用Java代码写的程序&#xff0c;运行的是Java的web应用程序。 tomcat的特点和功能&#xff1a…

C#开发单实例应用程序并响应后续进程启动参数

C#默认的WinForm模板是不支持设置单实例的&#xff0c;也没有隔壁大哥VB.NET那样有个“生成单个实例应用程序”的勾选选项&#xff08;VB某些时候要比C#更方便&#xff09;&#xff0c;实现单实例可以有多种方法&#xff1a; 检测同名进程&#xff1a;Process.GetProcessesByNa…

Redis 中的跳跃表是什么

Redis 中的跳跃表&#xff08;Skiplist&#xff09;是一种可以替代平衡树的数据结构&#xff0c;它主要用于实现有序集合&#xff08;Sorted Set&#xff09;功能。跳跃表通过在多个层级的链表上增加索引来提高查询效率&#xff0c;其效率可以与平衡树相媲美&#xff0c;但实现…

【数据结构】栈

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

SAP与易链SRM系统集成案例

一、项目环境 重庆润通控股&#xff08;集团&#xff09;有限公司成立于2007年&#xff0c;是一家集合汽柴油动力及终端、摩托车、储能电源、汽车零部件、金融服务等产业的多元化集团公司。现拥有员工超4000人&#xff0c;业务遍布全球80多个国家及地区&#xff0c;2021年营…

LangChain —— Prompt Templates

文章目录 一、什么是 Prompt Templates1、String PromptTemplates2、ChatPromptTemplates3、MessagesPlaceholder 留言占位符 二、如何使用 Prompt Templates 一、什么是 Prompt Templates 提示模板有助于将用户输入和参数转换为语言模型的指令。这可用于指导模型的响应&#x…

python操作SQLite3数据库进行增删改查

python操作SQLite3数据库进行增删改查 1、创建SQLite3数据库 可以通过Navicat图形化软件来创建: 2、创建表 利用Navicat图形化软件来创建: 存储在 SQLite 数据库中的每个值(或是由数据库引擎所操作的值)都有一个以下的存储类型: NULL. 值是空值。 INTEGER. 值是有符…