目录
场景
原理
首页 数据库 Redis 深入了解Redis中的Codis

深入了解Redis中的Codis

Jan 06, 2022 am 09:54 AM
redis

本篇文章带大家了解一下Redis中的Codis,介绍一下Codis原理,希望对大家有所帮助!

深入了解Redis中的Codis

场景

在大数据高并发场景下,使用单个redis实例,即使redis的性能再高,也会变的非常吃力,

首先,数据量越大,redis占用内存就越大,进一步导致rdb文件过大,这种情况会使的主从全量同步时间过长,同时实例重启时,加载过大的rdb也会让启动时间变长。【相关推荐:Redis视频教程

其次在CPU的使用上,单个实例的Redis只能使用一个CPU核心,一个核心应多过多的数据,也会显得力不从心,

因此需要一个集群方案,将巨大的数据量由一台实例分散到多台实例上,从Redis流行到官方支持自己的Cluster方案之间,第三方也在自己开发支持集群的组件,Codis就是其中之一,

Codis使用Go语言开发,在Redis与客户端中间充当代理的角色,使用Redis协议,所以客户端直接连接Codis,向其发送指令即可,Codis负责转发指令给Redis,最后接收返回结果再返回给客户端,

1.png

Codis代理的Redis实例构成一个Redis集群,当集群空间也不足以使用时,可以动态扩容,继续增加Redis实例,与此同时,客户端使用的sdk不需要做任何改动,只需由原来的连接redis改成连接codis即可,

Codis自身也可以采取一个集群,来保证自身的高可用,由于其本身就是无状态的,只负责转发内容,增加多个Codis没有副作用还可以保证QPS的提高,当其中一个Codis挂掉时,还可以使用别的。

2.png

原理

Codis将特定的Key转发到特定的Redis实例,集群中每个实例都保存一部分Key,降低其他实例的压力,同时所有实例的数据加起来,就是一份完整的信息。

Codis默认划分了1024个槽位(slot),集群中的每个Redis实例对应一部分槽位,Codis会在内存中维护槽位与Redis实例的对应关系,

槽位的数量默认是1024,可以更改,如果集群节点比较多,可以将数字调大。

3.png

当接收到客户端发送过来的key时,Codis对该key进行 crc32 运算得出一个 hash 值,

再将 hash 后的整数值对 1024(槽位数量) 进行取模得到一个余数,该余数就是Key将被保存到的槽位,有了槽位就可以找到这个key该发到哪个redis实例上了。

伪代码:

hash = crc32(command.key) # 计算hash值
slot = hash % 1024 # 取模得到槽位
redisInstance = slots[slot].redis # 得到redis实例
redis.do(command) # 执行命令复制代码
登录后复制

集群槽位同步

Redis与槽位的映射关系存在Codis的内存当中,因此Codis集群需要考虑保证每个节点中的槽位映射关系同步,所以Codis采用 Zookeeper、Etcd 分布式配置存储中间件来持久化槽位映射关系,保证Codis集群之间的数据同步,

如下图,Codis将槽位关系存在Zookeeper中,并提供了一个Dashboard 观察与修改槽位关系,当发生改变时,Codis Proxy 监听到变化并重新同步槽位关系。

4.png

拓容

当现有集群也不满足业务需求时,就需要新增实例加入到的集群中,此时槽位映射关系需要进行重新分配,需要分配一部分的槽位给新节点。

Codis新增了一个 SLOTSSCAN 指令,可以遍历指定slot下的所有key,通过该指令扫描出待迁移槽位的所有key,然后挨个遍历每个key迁移到新节点中,

迁移过程中,Codis继续对外提供服务,此时来了一个请求打在了正在迁移的槽位上,由于该槽位现在对应新老两个节点,此时 Codis 无法判断该 key 有没有从旧节点中迁移到新节点上,

因此这种情况 Codis 会立即强制对当前的 key 进行单个迁移,迁移完成后,将请求转发给新的Redis实例上。

伪代码:

slot_index = crc32(command.key) % 1024
if slot_index in migrating_slots:
    doMigratingKey(command.key)
    redis = slots[slot_index].new_redis
else:
    redis = slots[slot_index].redis复制代码
登录后复制

SLOTSSCAN 与 Redis自身的Scan指令一样,无法避免扫描出来的数据重复,但这不会影响到迁移的正确性,因为单个key迁移之后,就立刻从旧实例中删除了,无法再被扫描出来。

自动均衡槽位

每次新增实例,如果都需要人工维护slot的映射关系太麻烦,Codis提供自动均衡,该功能会在系统比较空闲的时候观察每个Redis实例对应的slot数量,如果不平衡,就进行自动均衡,迁移数据的操作。

缺点

Codis给Redis带来扩容好处,但也造成了一些副作用。

不支持事务

一个事务可能对多个key做了操作,但事务只能在单个实例中完成,但是由于key分散在不同的实例中,因此Codis无法支持事务操作。

不支持rename

rename将一个key命名成另一个key,但是这两个key可能hash出来的槽位并不是同一个,而是在不同实例的槽位上,因此rename也不被支持。

官方提供的不支持的指令列表:https://github.com/CodisLabs/codis/blob/master/doc/unsupported_cmds.md

扩容卡顿

Codis在扩容过程中,对数据的迁移是将整个key直接迁移过去的,例如一个hash结构,Codis会直接 hgetall 拉取所有的内容,使用 hmset 放到 新节点中,

如果该hash的内容过大,将会引起卡顿,官方建议单个集合结构的总大小不超过1MB,在业务上可以通过分桶存储等,将大型数据拆成多个小的,做一个折中。

网络开销

由于 Codis 在 客户端与Redis实例之间充当网络Proxy,多了一层,网络开销自然多一些,比直接连接Redis的性能要稍低一些。

中间件运维开销

Codis集群配置需要使用Zk或Etcd,这意味着引入Codis集群又要引入其他中间件,增加运维机器资源成本。

优点

Codis将分布式一致性的问题交给了第三方(ZK或Etcd)负责,省去了这方面的维护工作,降低实现代码的复杂性,

Redis官方的Cluster为了实现去中心化,引入了Raft与Gossip协议,以及大量需要调优的配置参数,复杂度骤增。

批量获取

对于批量操作,例如使用 mget 获取多个key的值,这些key可能分散在多个实例中,Codis将key按照所在的实例进行分组,然后对每个实例挨个调用 mget,最后汇总返回给客户端。

5.png

其他功能

Codis 提供 Dashboard 界面化,以及 Codis-fe 对集群进行管理,还可以进行增加分组、节点、执行自动均衡等操作,查看 slot 状态以及 slot 对应的 redis 实例,这些功能使的运维更加方便轻松。

6.png

7.png

8.png

9.png

走向历史

Codis是为了弥补Redis官方没有提供集群这一概念时出现的,现在Redis官方提供Cluster功能,官方的支持自然比第三方的更有优势,

同时第三方软件还需要实时关注官方发布的新特性各种,而Cluster肯定是实时兼容新特性,因此更推荐使用官方的Cluster,Codis作为曾经的一个知识点了解,某些思想与Cluster是有重合的。

更多编程相关知识,请访问:编程入门!!

以上是深入了解Redis中的Codis的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

redis集群模式怎么搭建 redis集群模式怎么搭建 Apr 10, 2025 pm 10:15 PM

Redis集群模式通过分片将Redis实例部署到多个服务器,提高可扩展性和可用性。搭建步骤如下:创建奇数个Redis实例,端口不同;创建3个sentinel实例,监控Redis实例并进行故障转移;配置sentinel配置文件,添加监控Redis实例信息和故障转移设置;配置Redis实例配置文件,启用集群模式并指定集群信息文件路径;创建nodes.conf文件,包含各Redis实例的信息;启动集群,执行create命令创建集群并指定副本数量;登录集群执行CLUSTER INFO命令验证集群状态;使

redis指令怎么用 redis指令怎么用 Apr 10, 2025 pm 08:45 PM

使用 Redis 指令需要以下步骤:打开 Redis 客户端。输入指令(动词 键 值)。提供所需参数(因指令而异)。按 Enter 执行指令。Redis 返回响应,指示操作结果(通常为 OK 或 -ERR)。

redis数据怎么清空 redis数据怎么清空 Apr 10, 2025 pm 10:06 PM

如何清空 Redis 数据:使用 FLUSHALL 命令清除所有键值。使用 FLUSHDB 命令清除当前选定数据库的键值。使用 SELECT 切换数据库,再使用 FLUSHDB 清除多个数据库。使用 DEL 命令删除特定键。使用 redis-cli 工具清空数据。

redis怎么使用单线程 redis怎么使用单线程 Apr 10, 2025 pm 07:12 PM

Redis 使用单线程架构,以提供高性能、简单性和一致性。它利用 I/O 多路复用、事件循环、非阻塞 I/O 和共享内存来提高并发性,但同时存在并发性受限、单点故障和不适合写密集型工作负载的局限性。

redis怎么读源码 redis怎么读源码 Apr 10, 2025 pm 08:27 PM

理解 Redis 源码的最佳方法是逐步进行:熟悉 Redis 基础知识。选择一个特定的模块或功能作为起点。从模块或功能的入口点开始,逐行查看代码。通过函数调用链查看代码。熟悉 Redis 使用的底层数据结构。识别 Redis 使用的算法。

redis怎么查看所有的key redis怎么查看所有的key Apr 10, 2025 pm 07:15 PM

要查看 Redis 中的所有键,共有三种方法:使用 KEYS 命令返回所有匹配指定模式的键;使用 SCAN 命令迭代键并返回一组键;使用 INFO 命令获取键的总数。

redis怎么读取队列 redis怎么读取队列 Apr 10, 2025 pm 10:12 PM

要从 Redis 读取队列,需要获取队列名称、使用 LPOP 命令读取元素,并处理空队列。具体步骤如下:获取队列名称:以 "queue:" 前缀命名,如 "queue:my-queue"。使用 LPOP 命令:从队列头部弹出元素并返回其值,如 LPOP queue:my-queue。处理空队列:如果队列为空,LPOP 返回 nil,可先检查队列是否存在再读取元素。

redis底层怎么实现 redis底层怎么实现 Apr 10, 2025 pm 07:21 PM

Redis 使用哈希表存储数据,支持字符串、列表、哈希表、集合和有序集合等数据结构。Redis 通过快照 (RDB) 和追加只写 (AOF) 机制持久化数据。Redis 使用主从复制来提高数据可用性。Redis 使用单线程事件循环处理连接和命令,保证数据原子性和一致性。Redis 为键设置过期时间,并使用 lazy 删除机制删除过期键。

See all articles