我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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/class="lazy" data-src/server.h#L903。

图片图片

并且从源码中可以看到当把一个对象设置为共享时候就会把 refcount 设置为 INT_MAX。

源码位置在:https://github.com/redis/redis/blob/unstable/class="lazy" data-src/object.c#L56。

图片图片

从这里就能看出,如果某个对象的引用次数是 2^31-1,那么就说明这个对象是一个引用对象。

Redis 实战

Redis 博大精深,然而很多时候我们说到 Redis,却只知道缓存或者分布式锁,面试的时候也只能从这两个角度去准备。

但是在实际面试中,Redis 这块能够发挥的地方可太多了:

  • Redis 中 String 类型使用了什么样的数据结构?
  • 为什么每种数据类型几乎都设计了两种以上的数据结构?
  • 为什么要延迟双删?原因是什么
  • RedLock 解决了什么问题,为什么现在又被废弃了?现在用什么?
  • watchdog 什么情况下会失效?
  • Redis 挂了怎么办?
  • 如何实现百万级排行榜?
  • 。。。

还有很多,我就不一一列举了。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

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

经验共享:回流和重绘对于网页性能优化有何不同?

回流与重绘:哪个更适合优化网页性能?在进行网页设计与开发时,优化网页性能是一个至关重要的问题。网页性能指的是网页的加载速度和响应速度,这直接影响用户体验和网站的可用性。而回流(reflow)和重绘(repaint)是两个常见的操作,对网页
经验共享:回流和重绘对于网页性能优化有何不同?
2024-01-26

Java享元设计模式优化对象创建提高性能和效率

Java享元设计模式通过共享可重用的对象,减少了系统中对象的数量,优化了对象的创建和管理,提高了性能和效率。它是一种经典的设计模式,适用于需要处理大量相似对象的应用程序
2023-05-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录