Redis对象共享池,性能优化小细节
如果你仔细研究过 Redis 中各种实现细节,你会发现为了性能,Redis 真的是不遗余力。
作为一种高性能的键值存储系统,Redis 广泛用于缓存、会话管理、消息队列等多种场景。
为了提高 Redis 在处理大量数据时的性能和效率,Redis 设计并实现了对象共享池(Shared Object Pool)这一内部机制。
那么接下来松哥就和大家详细说一说 Redis 中的对象共享池。
一 设计目的
Redis 的对象共享池主要用于复用一些常用的数据对象,以减少内存的开销。
在 Redis 中,一些常用的数据对象,主要是小整数(如 0 到 9999)等,是不会被改变的,因此可以安全地共享使用而无需重复创建。
例如你设置 set k1 99
和 set k2 99
,这时 k1 和 k2 其实指向的是同一个对象。
通过共享这些对象,Redis 能够显著降低内存的使用量,并减少对象的创建和销毁时间,从而提升整体性能。
二 工作原理
在 Redis 服务器启动时,会预先创建并存储一些常用的对象到一个全局的哈希表中,这个哈希表就是对象共享池。
当 Redis 需要处理一个键值对时,会首先检查这个键值对中的值是否已经在对象共享池中。如果已存在,Redis 将直接引用该对象,而不是创建一个新的对象。
三 支持的对象类型
目前主要是支持小整型,也就是 0~9999 之间的整数,浮点型数据不支持。
四 应用场景
对象共享池在多种场景下都能显著提升 Redis 的性能和效率,特别是在处理大量重复数据时。例如,在 Web 应用中,许多缓存的键值对可能包含相同的值,通过对象共享池,这些值可以被多个键值对共享,从而节省大量内存。
注意事项
- 只读性:对象共享池中的对象是只读的,不可修改。如果应用程序需要修改这些对象,Redis 会将其复制并创建一个新的对象进行操作。因此,在使用共享对象时,需要注意对象的可修改性。
- 内存策略:当 Redis 设置了最大内存值(maxmemory)并启用了 LRU(最近最少使用)等相关淘汰策略时,对象共享池可能会被禁用。这是因为在内存紧张的情况下,共享对象可能不再是最优选择。
五 实际案例
为了通过实际案例证明 Redis 中对象共享池的存在,我们可以结合 Redis 的内部机制和一些实际操作来进行分析。虽然 Redis 的官方文档没有直接提及"对象共享池"这一术语,但我们可以从 Redis 如何处理整数对象的共享中看到其背后的共享机制。
假设我们有一个 Redis 服务器,它用于存储和访问大量的键值对。在这些键值对中,有一部分键对应的值是常见的小整数。
我们来执行以下命令:
SET k1 1 OBJECT REFCOUNT k1 SET k2 1 OBJECT REFCOUNT k1
这里我要跟大家解释下。
OBJECT REFCOUNT 命令理论上可以查看某一个 key 对应的 value 被引用的次数。
所以我们期望第一次执行 OBJECT REFCOUNT k1
的时候返回 1,第二次执行 OBJECT REFCOUNT k1
的时候返回 2,但是实际上却并非如此,每次都是返回 2^31-1。
虽然这里并没有返回我们想要的值,但是大家可以看到,
OBJECT REFCOUNT k1
返回的值确实和 value 为字符串的 key 的返回值是不同的。
松哥来解释下原因。
通过分析 Redis 源码,松哥发现新版本的 redis 中 OBJ_SHARED_INTEGERS 变量定义了共享整数 10000,并且定义不被销毁的全局对象的引用数量 OBJ_SHARED_REFCOUNT 为 INT_MAX,INT_MAX = 2^31 - 1 =2147483647。
源码位置在:https://github.com/redis/redis/blob/unstable/src/server.h#L903。
并且从源码中可以看到当把一个对象设置为共享时候就会把 refcount 设置为 INT_MAX。
源码位置在:https://github.com/redis/redis/blob/unstable/src/object.c#L56。
从这里就能看出,如果某个对象的引用次数是 2^31-1,那么就说明这个对象是一个引用对象。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
课程实录 | 借助 F5 NGINX 交付极致用户体验(上)
原文作者:廖健雄 - F5 资深解决方案顾问 转载来源: NGINX 中文官网 NGINX 唯一中文官方社区 ,尽在 nginx.org.cn 编者按——本文为 NGINX 线上讲座“借助 F5 NGINX 交付极致用户体验”的课程实录的上篇。关注本号,接收本次课程实录的下篇. 在本节课程中,廖健雄老师详细介绍了用户访问体验的内容和量化,以及如何通过 Brotli 压缩、动态 webp 转换、HTTP/2 部署优化等具有可实操性的方式来提升用户访问体验。 本次分享主要分为三部分。首先,介绍什么是用户体验。其次,从技术角度分享提升用户体验的手段和方法。最后,廖健雄老师将与大家分享在某股份制商业银行的案例,详细介绍如何帮助客户提升和交付极致用户体验。 用户体验概览 首先,我们来探讨一下苹果、京东和招商银行这三家企业。不论苹果、京东或是招商银行,他们共同点是追求极致的用户体验。 先看苹果,从 iPod、iPhone、iPad 到 Mac 等一系列电子产品,苹果的出现改变了我们的生活方式。 再来看京东,他们用户体验做的非常好。京东的 CEO 说,他们内部有一个倒三角表,主要围绕三方面进行:用户...
- 下一篇
问 MySQL 非唯一索引等值查询加什么锁?
可重复读、读已提交两种隔离级别下,非唯一索引的等值查询会加什么锁?为什么这么加锁? > 作者:操盛春,爱可生技术专家,公众号『一树一溪』作者,专注于研究 MySQL 和 OceanBase 源码。 > 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 > 本文基于 MySQL 8.0.32 源码,存储引擎为 InnoDB。 1. 准备工作 创建测试表: CREATE TABLE `t2` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `i1` int DEFAULT '0', `i2` int DEFAULT '0', PRIMARY KEY (`id`) USING BTREE, KEY `idx_i1` (`i1`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; 插入测试数据: INSERT INTO `t2` (`id`, `i1`, `i2`) VALUES (1, 11, 21), (2, 12, 22),(3, 13, 23), (4, 14, 24...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池