Redis6-过期淘汰、经典数据类型的实现
一、redis的缓存过期淘汰策略
redis配置文件中有一个maxmemory,配置内存大小。默认是64位无限制,32位最大3GB。官网推荐配置是物理内存的四分之三。
查看redis内存使用情况,info memory:
1、如果超过了最大内存怎么办
当超过最大内存之后,设置的时候,会提示OOM,所以会出现内存淘汰策略(LRU)
redis的key当过期了之后,不一定会立刻删除,需要根据不同清情况分析。
redis的内存删除方式:
- 立刻删除:能够保证数据新鲜、内存空间释放,但是性能消耗很大
- 惰性删除:过期后方位第一次删除,对内存不友好,但是性能消耗低
- 定期删除:折中上面两个方式,定期清理过去数据,但是删除哪个数据、周期是多少需要确定
过期淘汰算法:
- LRU(最近最少使用):优先淘汰最近未被使用的数据
- LFU(使用频率最少):优先淘汰最近使用最少的数据
redis6的过期淘汰策略(8种):
名称 | 策略的解释 |
noeviction | 默认策略,不淘汰数据 |
allKeys-lru | 所有key中,使用LRU算法(推荐) |
allKeys-lfu | 所有key中,使用LFU算法 |
allKeys-random | 所有key中,使用随机淘汰 |
volatile-ttl | 设置过期key中,挑选出最早过期的key删除 |
volatile-lru | 设置过期key中,使用LRU算法 |
volatile-lfu | 设置过期key中,使用LFU算法 |
volatile-random | 设置过期key中,使用随机淘汰 |
二、redis经典五种属类型及底层实现
redis可以理解为都是所有的都是字典,key是String、value是redisObject。使用type命令可以看到bitmap类型是stirng、hyperloglog类型是string、GEO类型是zset。所以redis底层数据结构还是经典的五种类型。
RedisObject、五种数据类型、底层实现的关系:
在redis中,每个键值对都会对应一个dictEntry,存放了指向key、value、下一个dictEntry的指针,key是字符串但是使用redis自定义的SDS存放,而value存放在redisObject中。
redisObject的结构:
- type:当前对象的数据类型
- encoding:当前对象底层存储的编码类型
- lru:采用LRU算法,记录对象最后访问的时间
- refcount:对象引用次数
- *ptr:指向真正底层数据结构的指针
2.1、String数据结构介绍
1、3大编码格式(为了精确的利用内存)
- int:保存long型有符号整数,长度最多19位。
- embstr:redis封装的格式SDS(简单动态字符),超过long型&&长度小于44字节的字符串
- raw:redis封装的格式SDS(简单动态字符),保存长度大于44字符串
2、编码格式案例
3、SDS简单动态字符串简介
redis为什么不直接用c语言的字符串,而是自己建立了一套结构SDS,不满意效率。
- c字符串获取长度,需要遍历char[],时间复杂度是o(N),SDS是o(1)
- 内存重新分配问题,c字符串是char[]数组,扩容、缩容不方便
- c字符串遇到'\0'就是结束,容易出现读取问题,二进制安全
SDS结构如下:
- len:已用字节长度
- alloc:字符串最大字节长度
- flags:用来博鳌是SDS的类型,SDS8、SDS16、SDS32、SDS64
- buf[]:真正的字符串
4、源码分析
Redis在启动的时候,会建立1万个0~9999的redisObject变量作为共享对象,这就意味着set字符串键在0~10000的时候,不需要建立对象直接使用共享对象。
embstr和raw不同的地方在于,embstr是内存连续的,raw是重新申请了一块内存,所以embstr会减少内存碎片的产生。还有一点,对embstr进行append,则会转换成raw。
2.2、Hash数据结构介绍
- hash-max-ziplist-entries:使用压缩表保存时,hash集合中最大元素个数
hash-max-ziplist-value:使用缩缩表保存时,hash集合中单个元素最大长度
通过上图可知,hash默认数据类型是压缩表,当集合个数太大或者元素长度太大的时候,才会使用hashtable进行保存。可以升级,无法降级。
综上所述,hash数据结构存在2种:ziplist、hashtbale(几乎等价java种的hashtable)
压缩表(ziplist):双向链表,但是不存储指针
是一种紧凑的编码格式,压缩了数据,减少内存空间,但是需要压缩、解压写入、读取。也就是读写率换取空间。内存利用率极高的原因是连续的内存。所以当数据比较小的时候,使用压缩表最合适。
- header:
- zlbytes:所占内存字节数,用于重新分配和计算zlend
- zltail:尾节点到起始地址有多少字节
- zllen :节点数量
- entry:节点
- 前一个节点长度:用这个字段和总长度,就能计算出每个节点的位置
- encoding
- entry-data
- zlend:0xff,用于标记压缩表的末端
优点:
- 普通列表存在2个指针,有些数据可能还么有指针大,所以优化掉了指针内存,通过长度推算位置
- 列表内存一般不连续,遍历速度慢,ziplist把相关偏移量记录在节点中,可以跳到上一个或下一个节点
- 列表长度不在遍历,时间复杂度是O(1)
HashTbale:OBJ_ENCODING_HT是哈希表机构或者称为字典结构
2.3、List数据结构介绍
在低版本(3.2之前)的Redis中,list采用底层的数据结构是ziplist+linkedlist,而高版本的Redis中list的底层数据结构是quicklist,而quicklist也用到了ziplist。
quicklist是ziplist和linkedlist的混合体,他将linkedlist按段切分,每一段使用ziplist来紧凑存储,多个ziplist使用双向指针串起来。
- list-compress-depth:1表示quicklist两端各有一个节点不压缩,中间节点压缩
- list-max-ziplist-size:-1表示quicklist每个节点上的ziplist大小不能超过4K
2.4、Set数据结构介绍
redis中用intset和hashset存储set,如果元素都是整型,就使用intset。否则使用hashset(数组+链表),其中key是元素,value是null。
2.5、ZSet数据结构介绍
Redis中使用ziplist和skiplist(跳表)来实现ZSet,当元素不满速上面的情况,就使用ziplist否则使用skiplist。
跳跃表(skiplist):
由于普通的链表无法进行二分查找,因此借鉴数据库的索引思想,提取出链表中关键节点(索引),现在关键节点上查找,在进入下层链表查找。提取多层关键节点,就形成了skiplist。所以跳表=链表+多级索引(索引的索引),也就是给链表怎加索引,用空间换时间。
优化为,两两取首:
主要就是用多级索引能够快速查找,但是为什么是两两取首?既然决定了用空间,那么就让器粒度最低。
针对读多写少的情景,优点是查询块,缺点是浪费空间。
2.6、小结
Redis6-过期淘汰、经典数据类型的实现相关推荐
- rocksdb原理_基于RocksDB实现精准的TTL过期淘汰机制
本文来自OPPO互联网技术团队,如需要转载,请注明出处及作者. Parker 是 OPPO 互联网自研的一个基于 RocksDB 的分布式 KV 存储系统,它是一款类 Redis 的存储系统,主要解决 ...
- Redis的内存回收机制和数据过期淘汰策略
本文来说下Redis的内存回收机制和数据过期淘汰策略 文章目录 概述 为什么需要内存回收 过期删除策略 定时删除 惰性删除 定期删除 删除策略比对 过期删除策略原理 redisDb结构体定义 expi ...
- Redis系列教程(九):Redis的内存回收原理,及内存过期淘汰策略详解
Redis内存回收机制 Redis的内存回收主要围绕以下两个方面: 1.Redis过期策略:删除过期时间的key值 2.Redis淘汰策略:内存使用到达maxmemory上限时触发内存淘汰数据 Red ...
- 【Redis】过期淘汰策略以及内存淘汰机制
文章目录 过期时间的设置 Redis是如何知道一个key是否过期的? Redis的两种过期key删除策略 Redis内存淘汰机制 过期时间的设置 在我们使用Redis的时候,最常使用的就是SET命令了 ...
- win10控制面板快捷键_win10要淘汰经典的“控制面板”,如何快速找到它
尽管微软正在采取措施将大多数Windows设置从控制面板移至"设置"应用程序中,许多用户仍然觉得需要访问经典的"控制面板",因为大多数有用的设置仍位于其中.你可 ...
- Python经典数据类型:字典
选择题 以下关于Python字典的描述中,错误的是: A.在定义字典时,键和值用冒号连接 B.字典通过整数索引来查找其中的元素 C.字典的键值对之间没有顺序且不能重复 D.字典用中括号中包含键名的格式 ...
- python经典数据类型
一.列表 1.知识点 1)符号标识:[] 2)常用方法:append insert pop 3)下标截断取值 4)如何更新值 5)for循环结合使用遍历列表元素 6)有序 2.实战操作 1)#往列表当 ...
- 【2020尚硅谷Java大厂面试题第三季 04】Redis 9种数据类型使用场景,分布式锁演变步骤,lua脚本,redis事务,Redisson,Redis内存占用,删除策略,内存淘汰策略,手写LRU
1.安装redis6.0.8 2023 02 02 为:redis-7.0.8.tar.gz 2.redis传统五大数据类型的落地应用 3.知道分布式锁吗?有哪些实现方案?你谈谈对redis分布式锁的 ...
- access字段类型varchar_数据库即将被淘汰的几种数据类型,烦恼还是解脱?
朋友们,关系型数据库已经有几十年的发展历史了.我们所熟知的Oracle.SQL Server.PostgreSQL.MySQL等主流数据库,都支持非常丰富的数据类型.有些数据类型出现的比较早,后续发展 ...
最新文章
- InputStream OutputStream 傻傻分不清
- VisualVM——JDK自带的性能分析工具
- php程序yii是什么意思,Yii框架啥意思
- UVa 740 - Baudot Data Communication Code
- (转)SpringMVC学习(七)——Controller类的方法返回值
- 二进制文本编辑器_Textadept for mac(文本编辑) v10.5免费版
- 的采样方式_DR803M4水质自动采样器(岸边站自动排空型)
- ZooKeeper(3.4.5) - 原生 API 的简单示例
- Atitit 文档资料管理同步解决方案
- c++ STL之queue
- 一文速学-时间序列分析算法之一次移动平均法和二次移动平均法详解+实例代码
- 360浏览器的极速模式和兼容模式的区别
- HTML 学习总结2 框架 表单
- 第一次在Vue项目中播放m3u8格式视频遇到的问题和解决方法
- 量子力学最新发现:人不会真正死去
- 从词嵌入到文档距离论文笔记(From Word Embeddings To Document Distances)
- 真静态与伪静态的区别,伪静态的实现原理及简单使用
- “30以上不配转行”:大龄转行,还来得及吗?
- SCI写作助手网站收集
- 上海亚商投顾:科创50指数录得6连阳 芯片股掀涨停潮
热门文章
- linux怎么做raid0,Linux创建RAID0_实战
- 优思学院|工业工程的发展史----从精益生产、六西格玛、到TOC
- 2020年社工库_浸润社工2020年韩博士医院重阳节联欢会
- 147859-97-0|pGlu-HWSHDWKPG-NH2
- AndroidStudio里面导入别人的demo详细步骤
- 网络访问相关知识(入门)
- 堆排序-HeapSort
- 2013.10.5-7台风“菲特“fitow模拟实例【WRF模拟实操:WRFdomain范围设置,namelist代码,WRF模拟流程,wrfout结果查看头文件,原文对比】
- 计算机科学主攻机器人,计算机学院·软件学院新进博士教师郝宗波访谈
- php cmseasy,CMSeasy功能介绍