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个字节对齐的方式,而是采用紧凑的方式分配内存

相关推荐
ATA88885 分钟前
数据库管理工具的数据安全机制对比:权限管控与审计
数据库·人工智能·数据分析·数据库管理
麦聪聊数据26 分钟前
业务自助取数(下):安全可控前提下,实现取数效率百倍提升
数据库·sql
2501_9157167236 分钟前
Repository-学习指南_小白版
数据库·人工智能
snpgroupcn39 分钟前
SAP实施风险管控注意事项:四大风险域与防范策略
前端·数据库·人工智能
cyforkk1 小时前
MySQL锁机制详解:从乐观锁到悲观锁
数据库·mysql
ShiXZ2131 小时前
指令集-SQL 常用指令速查手册
数据库·sql·mysql·oracle
耀耀_很无聊2 小时前
12_Redis Lua 脚本踩坑:为什么 tonumber(ARGV[x]) 会得到 nil?
java·redis·lua
阿昭L2 小时前
数据库期末复习(三)
数据库
Dlrb12112 小时前
信息查询Web服务器-->电子商城信息查询项目
linux·服务器·数据库·html·嵌入式·epoll·数据查询
不会写DN2 小时前
MySQL 并发插入竞态问题:原子写入实践指南
数据库·mysql