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

【Redis】Redis的内部设计与实现

Redis的设计、实现

数据结构和内部编码

type命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)hash(哈希)、list(列表)、set(集合)、zset (有序集合),但这些只是Redis对外的数据结构。

实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis会在合适的场景选择合适的内部编码。

image.png

每种数据结构都有两种以上的内部编码实现,例如list数据结构包含了linkedlist和ziplist两种内部编码。同时有些内部编码,例如ziplist,可以作为多种外部数据结构的内部实现,可以通过object encoding命令查询内部编码。

Redis这样设计有两个好处:

        第一,可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令,例如Redis3.2提供了quicklist,结合了ziplist和linkedlist两者的优势,为列表类型提供了一种更为优秀的内部编码实现,而对外部用户来说基本感知不到。

        第二,多种内部编码实现可以在不同场景下发挥各自的优势,例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,这时候Redis会根据配置选项将列表类型的内部实现转换为linkedlist。

redisobject对象

Redis存储的所有值对象在内部定义为redisobject结构体,内部结构如图所示。

image.png

Redis存储的数据都使用redis0bject来封装,包括string、hash、list、set,zset在内的所有数据类型。理解redis0bject对内存优化非常有帮助,下面针对每个字段做详细说明:

type字段

type字段:表示当前对象使用的数据类型,Redis主要支持5种数据类型:string, hash、 list,set,zset。可以使用type { key}命令查看对象所属类型,type命令返回的是值对象类型,键都是string类型。

encoding字段

encoding 字段 :表示Redis内部编码类型,encoding在 Redis内部使用,代表当前对象内部采用哪种数据结构实现。理解Redis内部编码方式对于优化内存非常重要,同一个对象采用不同的编码实现内存占用存在明显差异。

lru字段

lru字段:记录对象最后次被访问的时间,当配置了maxmemory和maxmemory-policy=volatile-lru或者allkeys-lru时,用于辅助LRU算法删除键数据。可以使用object idletime {key}命令在不更新lru字段情况下查看当前键的空闲时间。

image.png

可以使用scan +object idletime 命令批量查询哪些键长时间未被访问,找出长时间不访问的键进行清理, 可降低内存占用。

refcount字段

refcount字段:记录当前对象被引用的次数,用于通过引用次数回收内存,当refcount=0时,可以安全回收当前对象空间。使用object refcount(key}获取当前对象引用。当对象为整数且范围在[0-9999]时,Redis可以使用共享对象的方式来节省内存。

PS面试题,Redis的对象垃圾回收算法-----引用计数法。

*ptr字段

*ptr字段:与对象的数据内容相关,如果是整数,直接存储数据;否则表示指向数据的指针。

Redis新版本字符串且长度<=44字节的数据,字符串sds和redisobject一起分配,从而只要一次内存操作即可。

PS :高并发写入场景中,在条件允许的情况下,建议字符串长度控制在44字节以内,减少创建redisobject内存分配次数,从而提高性能。

image.png

Redis中的线程和IO模型


http://www.kler.cn/a/154556.html

相关文章:

  • GEE下载ERA5-Land气象数据(1950-至今,降水、温度)
  • SpringBoot 2.2.10 无法执行Test单元测试
  • hrnet人体关键点检测模型适配atlas笔记
  • Python学习------第八天
  • 自由学习记录(22)
  • Spring Boot框架:构建可扩展的网上商城
  • vue中中的动画组件使用及如何在vue中使用animate.css
  • go学习之goroutine和channel
  • 微信小程序获取定位显示在百度地图上位置出现偏差
  • vcomp140.dll是什么意思?vcomp140.dll缺失怎么修复的五个方法
  • WT2003H MP3语音芯片方案:强大、灵活且易于集成的音频解决方案
  • 给定一组经纬度如何判断某点是否在这组经纬度的范围之内(电子围栏实现代码)
  • 关于Maxscript你了解多少?
  • ChatGpt回答人工智能发展利大于弊的辩证论述
  • 同步加载、异步加载、延迟加载、预加载的区别
  • Java数据结构之《希尔排序》题目
  • 代码随想录算法训练营第39天| 62.不同路径 63. 不同路径 II
  • 吉他初学者学习网站搭建系列(4)——如何查询和弦图
  • NacosSync 用户手册
  • 苍穹外卖——删除购物车信息
  • Java流Stream使用详解(下)
  • 【JavaSE】API(学习笔记)
  • 【Unity】Blender场景导入
  • Azure Machine Learning - 在 Azure AI 搜索中创建全文查询
  • mac修改默认shell为bash
  • 转载:利用Flask实现深度学习模型部署