Redis底层实现

一、redis的类型和数据结构到底是怎么回事?

我们常说的redis中有5种数据类型,其实是说的redisObject中的type有5中类型:string,list,hash,set,zset,虽然后面还新增了stream,module这两种类型,但是常用的还是那5种。

然后redisObject还有个encoding字段,定义了它的底层实现。encoding的类型就特别多了如,string会用有的有long,embstr,raw。 然后ziplist,inset,skipList这些数据结构都是在encoding的定义范围之内。

然后,对于redis的key,它一定是用的SDS这个结构的,就是是数值,底层也是用的SDS。

对于value来说,比如set key1 11, 因为值是11,可以转成long,所以会用int编码(编码是int,但是实际是用long存的,只有整数才能用,有小数还是使用SDS)。

一、redis中String结构的底层实现

1. redis是如何实现字符串存储的呢?是用C语言中的char数组实现的吗?

redis中使用的SDS这样个类型来存储字符串的,它的本质还是字符数组,只是在字符数组基础上增加了额外的元数据。在 Redis 中需要用到字符数组时,就直接使用 sds 这个别名。

这里有个小问题?为什么不用char数组,直接保存,而要创建SDS这样一个结构?

原因主要有两个一个是效率问题,比如获取字符串的长度,如果是char数组,你需要通过遍历字符串数组的方式去获取(字符串追加的方法也是一样,需要遍历到字符串尾部,才能追加),SDS直接读取len字段就行。再一个是redis如果想要保存任意的二进制的字符串,使用char数组做不到。因为char数组是通过使用"\0"来标记字符串结束的,所以它没办法保存"\0"这段字符。

二、SDS结构是如何节约内存开销的

SDS 结构中有一个元数据 flags,表示的是 SDS 类型。事实上,SDS 一共设计了 5 种类型,分别是 sdshdr5、sdshdr8、sdshdr16、sdshdr32 和 sdshdr64。这 5 种类型的主要区别就在于,它们数据结构中的字符数组现有长度 len 和分配空间长度 alloc,这两个元数据的数据类型不同。

因为 sdshdr5 这一类型 Redis 已经不再使用了,而sdshdr8、sdshdr16、sdshdr32 和 sdshdr64它们的现有长度 len 和分配空间长度 alloc分别是uint8_t,uint16_t,uint32_t,uint64_t,他们所占的空间大小分别是1个字节,2个字节,4个字节,8个字节。SDS 之所以设计不同的结构头(即不同类型),是为了能灵活保存不同大小的字符串,从而有效节省内存空间。当然这些还需要配合编译优化,不能按默认的8个字节对齐的方式,而是采用紧凑的方式分配内存

相关推荐
钱栈up7 分钟前
前端改了三页、后端也动了,用户说「完全没变化」——我在 116 库上找到的三个真凶
css·数据库
这个DBA有点耶20 分钟前
索引建了查询却更慢——优化器选错索引与Index Merge的隐藏代价
数据库·架构·代码规范
云贝贝贝25 分钟前
删了却没变小:PostgreSQL 死元组与表膨胀排查
数据库·postgresql
依晨照旧28 分钟前
Langfuse 打爆两台机器:一条分位数 SQL,在 400G 表上扫了 8 分钟
数据库
2601_9689007739 分钟前
推理部署配置实践:缓存窗口、硬件配比与协议统一的核查清单
缓存
笃行3502 小时前
列存储这条线,我顺着 KingbaseES 的文档摸了一遍
数据库
Navicat中国2 小时前
Navicat 18 支持 Azure OpenAI 接入,合规 AI 赋能 SQL 开发
数据库·人工智能·microsoft·ai·azure·navicat·数据
1024奇点2 小时前
【仓颉语言入门 · 第二篇 第 10 课】
开发语言·数据库·ide·mysql·开源
数据狐(Datafox)2 小时前
一文读懂京东商品详情API:返回字段解读与 JSON 样例
java·开发语言·数据库·windows·json
SelectDB2 小时前
从实时入库到实时可用:Apache Doris 5.0 增量计算场景与实践
大数据·数据库·开源