Redis的数据类型内部实现

Redis的数据类型内部实现

redis执行快是因为Redis是基于内存实现的,还有他每种数据类型的数据结构的实现。

String

Stirng是我们Redis最基本的一个数据类型,最大的存储大小是512MB

在String的类型的内部实现主要是int和SDS(实现的动态字符串),SDS使用len属性的值来判断字符串是否结束,而且SDS所有的API都会以处理二进制的方式进行存储,所以String 也可以保存图片、视频、压缩文件等。

SDS获取字符串长度的时间复杂度是O(1),因为C语言的字符串长度并不记录自身长度,redis使用了len属性记录了字符串长度,所以获取字符串长度的时间复杂度是O(1)

Redis的SDS API是安全的,拼接字符串不会造成缓冲区的溢出,因为SDS在拼接字符串的时候会检查SDS空间是否满足,如果不满足就会自动扩容,所以不会造成内存溢出。

字符串的内部编码有int、raw和embstr,

如果我们的存储的内容可以用long类型表示,那么会将字符串编码转换为int,会将数字保存在redisObject.ref中

如果我们存储的对象是字符串,并且长度小于等于32字节(不同版本大小不一样),那么字符串对象将使用一个SDS来保存,该SDS会和redisObject一起找一块连续内存的空间进行分配,对象编码为embstr。该格式可以更好的利用cpu缓存。但是在Redis内部,embstr是可读的,如果我们对他进行修改命令,其实是先字符串编码转换为raw

如果我们存储的字符串长度大于32字节(不同redis版本大小不一样),那么对象编码就为raw,他会进行2次内存分配,一次给redisObject,一次给SDS

适用的场景:对象缓存,计数、分布式系统的共享session

LIST

在Redis3.2之前包括3.2 使用的是双向链表和压缩链表实现,如果列表元素小于512个,列表每个元素的值都小于64字节,那么久使用压缩列表,如果上面条件不满足那么就使用双向链表。

在Redis3.2后使用了quicklist

quicklist将list分割为多个节点,每一个节点都是快速列表,每个节点可以包含多个元素,这样有助于减少节点的数量提高性能。

每一个节点都是快速列表,它是一个双向链表的结合体,这个结合体可以让在两端插入和删除操作。快速列表采用紧密的方式存储,有利于减少内存的占用。

该方法的优点就是在两边插入是很快的, 缺点是如果在中间插入可能会移动很多元素。

list的最大的长度是2^32-1,每个列表支持42亿个元素

使用的场景比如我们做消息队列,或者消息推送的业务。

Hash

如果我们的元素小于512个,那么就会使用压缩列表作为我们的Hash的数据结(Redis会压缩这些k-v),否则就会使用Hash表。

适用场景购物车

Set

如果我们的长度小于512会使用整数集合作为set的数据类型,否则使用Hash作为

使用场景:数学的交集,并集,差集。比如一个用户了关注了一些人,另外一个用户也关注了一些人,查看他们的共同关注。

Zset

zset比set多一个排序属性socre。zset不能有重复元素,但是分值可以。

如果有序集合的元素个数小于128个,并且每个元素的值都小于64就使用压缩列表,否则就使用跳表作为我们的底层数据结构。

使用的场景是 抽奖

BigMap

是位图,遗传连续的二进制数组,也可以通过高偏移量来定位元素,他只有最小的单位bit 0|1 设置,表示每个元素的状态值。时间复杂度是O(1).

BitMap的底层是String,因为String是会保存二进制的字节数组,所以Redis会把自己饿数组的每个bit位利用起来,来比奥什一个元素的二值状态。

使用的场景:签到功能

HyperLogLog

HyperLogLog是一个用来统计基数的,就是统计一个集合中不重复的元素个数,但是准确率不是很高,但是优点是内存占用特别小,每个key只需要12kb就可以算2^64个不同的基数,但是它的准确率很低,他的错误计算率在0.81%

非常适合百万级以上的网页 UA 的场景,同意有容错的统计。

UA是网页访问量统计

GEO

GEO使用的了Sorted Set(Zset),把经纬度保存到Zset然后通过Zset提供的按权重进行有序范围查找的特性,实现LBS(基于位置服务)服务中频繁使用所搜附近的需求。

Steam

​ Redis提供的消息队列功能,它支持消息的持久化、支持自动生成唯一id、支持ack确认消息的模式、支持消费组模式,让那个消息队列更加未定和可靠。

ack确认机制

自动

当消息交给我们的服务就被确认了。

手动

需要我们服务向消息队列发送确认机制。

使用场景业务分割等。

相关推荐
牛奔4 分钟前
如何让 GORM 打印 SQL 语句?三种方式全解析
数据库·sql
XWalnut11 分钟前
Redis从入门到精通
数据库·redis·缓存
andafaAPS30 分钟前
安达发|工艺品aps自动排产排程排单软件:告别生产“一团乱麻“
大数据·数据库·人工智能·安达发aps·计划排产软件·自动排单软件
zt1985q34 分钟前
本地部署源代码管理解决方案 Bitbucket Data Center 并实现外部访问
运维·服务器·数据库·网络协议·postgresql·源代码管理
xiaofeichaichai1 小时前
Service Worker、PWA 与 Web Worker — 离线缓存与主线程算力分离
前端·缓存
一只专注api接口开发的技术猿1 小时前
OpenClaw 对接淘宝商品 API,低成本实现全天候选品监控|附可运行 Python 实操代码
大数据·开发语言·数据库·python
爱喝水的鱼丶2 小时前
SAP-ABAP:SAP基础数据校验工具开发系列博客(共5篇)第三篇:SAP接口对接开发:实现数据的实时/批量校验交互
运维·数据库·学习·性能优化·sap·abap·经验交流
真香号2 小时前
记一次生产RocketMQ消息积压消费慢的排查与解决
数据库·rocketmq·java-rocketmq
数据库小学妹2 小时前
国产数据库技术成熟度实测:从Oracle兼容到高可用,四个维度评估能不能上生产
数据库·经验分享·oracle·性能优化·dba
JdSnE27zv3 小时前
数据库性能优化三:程序操作优化
数据库·sql·性能优化