当前位置: 首页 > article >正文

Redis对象共享池,性能优化小细节

如果你仔细研究过 Redis 中各种实现细节,你会发现为了性能,Redis 真的是不遗余力。

作为一种高性能的键值存储系统,Redis 广泛用于缓存、会话管理、消息队列等多种场景。

为了提高 Redis 在处理大量数据时的性能和效率,Redis 设计并实现了对象共享池(Shared Object Pool)这一内部机制。

那么接下来松哥就和大家详细说一说 Redis 中的对象共享池。

一 设计目的

Redis 的对象共享池主要用于复用一些常用的数据对象,以减少内存的开销。

在 Redis 中,一些常用的数据对象,主要是小整数(如 0 到 9999)等,是不会被改变的,因此可以安全地共享使用而无需重复创建。

例如你设置 set k1 99set 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,那么就说明这个对象是一个引用对象。


http://www.kler.cn/news/365697.html

相关文章:

  • Java应用程序的测试覆盖率之设计与实现(三)-- jacoco cli 客户端
  • 鸿蒙next之导航组件跳转携带参数
  • TensorFlow面试整理-TensorFlow 数据处理
  • arcgis中dem转模型导入3dmax
  • 未来汽车驾驶还会有趣吗?车辆动力学系统简史
  • goalng框架Gin解析
  • 设计模式(七)桥接模式详解
  • Linux之实战命令53:mtr应用实例(八十七)
  • 将获取的数据存储到Excel文件中
  • 动态规划之子数组系列(下)
  • 分行或者分列计算数组中各元素的累积numpy.cumproduct()
  • vue中标签的ref和id的用法和区别优缺点
  • UE5蓝图中忽略触发区域进行碰撞
  • 【Java】输入十个整数,从小到大输出
  • ATom:2016-2018 年来自 CAPS 仪器的云和粗气溶胶测量数据
  • 【C++篇】栈的层叠与队列的流动:在 STL 的韵律中探寻数据结构的优雅之舞
  • 深度学习技术演进:从 CNN、RNN 到 Transformer 的发展与原理解析
  • input标签v-model属性失效
  • softmax回归从零实现
  • 怎么压缩ppt大小?压缩PPT文件非常简单的几种方法
  • Python 语法与数据类型详解
  • 易泊车牌识别相机在智慧工地的应用
  • 中间件之Seata
  • 中小企业设备管理效率提升:Spring Boot系统设计
  • 铜业机器人剥片 - SNK施努卡
  • git 修改当前分支的上游分支