整体看

https://mp.weixin.qq.com/s/7ct-mvSIaT3o4-tsMaKRWA
不同数据结构在源码中的名称
1.简单动态字符串sds.c
2.整数集合intset.c
3.压缩列表ziplist.c
4.快速链表quicklist.c
5.字典dict.c
6.Streams的底层实现结构listpack.c和rax.c

不同数据类型在源码中的名称
Redis对象object.c
字符串t_string.c
列表t_list.c
字典t_hash.c
集合及有序集合t_set.c和t_zset.c
数据流t_stream.c

Redis数据库的实现:
1.数据库的底层实现db.c
2.持久化rdb.c和aof.c

Redis服务端和客户端实现:
事件驱动ae.c和ae_epoll.c
网络连接anet.c和networking.c
服务端程序server.c
客户端程序redis-cli.c

主从复制replication.c
哨兵sentinel.c
集群cluster.c
其他数据结构,如hyperloglog.c、geo.c等
其他功能,如pub/sub、Lua脚本

redis 是 key-value 存储系统

其中key类型一般为字符串,value 类型则为redis对象(redisObject)

bitmap--------------------------实质String
hyperLogLog-----------------实质String
GEO----------------------------实质Zset


Redis 中每个对象都是一个 redisObject 结构


/** Redis 对象*/
typedef struct redisObject {// 类型 4bitsunsigned type:4;// 编码方式 4bitsunsigned encoding:4;// LRU 时间(相对于 server.lruclock) 24bitsunsigned lru:22;// 引用计数 Redis里面的数据可以通过引用计数进行共享 32bitsint refcount;// 指向对象的值 64-bitvoid *ptr;
} robj;

set hello word

key 是字符串,但是 Redis 没有直接使用 C 的字符数组,而是存储在redis自定义的 SDS中。
value 既不是直接作为字符串存储,也不是直接存储在 SDS 中,而是存储在redisObject 中。
实际上五种常用的数据类型的任何一种,都是通过 redisObject 来存储的。


看看类型:----------------type 键
看看编码:----------------object encoding hello
debug结构:--------------debug object person

encoding:编码方式

String

  1. int
    保存long 型(长整型)的64位(8个字节)有符号整数
    9223372036854775807

    如果是浮点数, Redis 内部其实先将浮点数转化为字符串值,然后再保存

  2. embstr:
    代表 embstr 格式的 SDS(Simple Dynamic String 简单动态字符串),保存长度小于等于44字节的字符串
    EMBSTR 顾名思义即:embedded string,表示嵌入式的String

  3. raw
    保存长度大于44字节的字符串

SDS

Redis没有直接复用C语言的字符串,而是新建了属于自己的结构-----SDS
在Redis数据库里,包含字符串值的键值对都是由SDS实现的(Redis中所有的键都是由字符串对象实现的即底层是由SDS实现,Redis中所有的值对象中包含的字符串对象底层也是由SDS实现)。

sdshdr5、(2^5=32byte)
sdshdr8、(2 ^ 8=256byte)
sdshdr16、(2 ^ 16=65536byte=64KB)
sdshdr32、 (2 ^ 32byte=4GB)
sdshdr64,2的64次方byte=17179869184G用于存储不同的长度的字符串。
len 表示 SDS 的长度,使我们在获取字符串长度的时候可以在 O(1)情况下拿到,而不是像 C 那样需要遍历一遍字符串。
alloc 可以用来计算 free 就是字符串已经分配的未使用的空间,有了这个值就可以引入预分配空间的算法了,而不用去考虑内存分配的问题。
buf 表示字符串数组,真存数据的。

Redis为什么重新设计一个 SDS 数据结构?


空间预分配:

1)如果sds修改后,sds长度(len的值)小于1mb,那么会分配与len相同大小的未使用空间,此时len与free值相同。例如,修改之后字符串长度为100字节,那么会给分配100字节的未使用空间。最终sds空间实际为 100 + 100 + 1(保存空字符’\0’);

2)如果大于等于1mb,每次给分配1mb未使用空间
惰性空间释放:对字符串进行缩短操作时,程序不立即使用内存重新分配来回收缩短后多余的字节,而是使用 free 属性将这些字节的数量记录下来,等待后续使用(sds也提供api,我们可以手动触发字符串缩短);

set k1 123


Redis 启动时会预先建立 10000 个分别存储 0~ 9999 的 redisObject 变量作为共享对象,这就意味着如果 set字符串的键值在 0~10000 之间的话,则可以 直接指向共享对象 而不需要再建立新对象,此时键值不占空间!

  • set k1 123
  • set k2 123

  • Object.c

set k1 abc




set k1 大于44长度的一个字符串


OBJ_ENCODING_RAW格式,这与OBJ_ENCODING_EMBSTR编码方式的不同之处在于,
此时动态字符串sds的内存与其依赖的redisObject的内存不再连续了


只有整数才会使用int,浮点数先转为字符串。
embstr和raw底层都是SDS

int : Long类型的整数时,RedisObject的ptr指针直接赋值为整数数据,不在额外的指针再指向整数了,节省了指针的空间开销。
embstr : 当保存的是字符串数据且字符串小于等于44字节时,embstr类型将会调用内存分配函数,只分配一块连续的内存空间,空间中依次包含的redisObject与sdshdr两个数据结构,
让元数据、指针和SDS是一块连续的内存区域,这样就可以避免内存碎片

raw: 当字符串大于44字节时,SDS的数据量变多变大了,SDS和RedisObject布局分家各自过,会给SDS分配多个空间并用指针指向SDS结构,raw类型将会调用两次内存分配函数,
分配两块内存空间,一块用于包含redisObject结构,而另一块用于包含sdshdr结构。

redisObject占用空间

4 + 4 + 24 + 32 + 64 = 128bits = 16字节

sdshdr8占用空间

1(uint8_t) + 1(uint8_t)+ 1 (unsigned char)+ 1(buf[]中结尾的’\0’字符)= 4字节

初始最小分配为64字节,所以只分配一次空间的embstr最大为 64 - 16- 4 = 44字节

11. Redis数据类型底层实现 String 底层实现相关推荐

  1. Redis数据类型操作(一) —— String

    1. set 格式:set 'key' 'value' 添加一个String类型的键值对. 2. get 格式:get 'key' 获得key对应的String类型value值,找不到则返回nil. ...

  2. redis数据类型list总结

    前言 在上一篇,我们简单介绍了redis数据类型中的String和hash两种常用数据类型的使用,本篇继续探讨redis数据结构中的另一种,list 列表 list简介 Redis列表是简单的字符串列 ...

  3. Redis数据库(三)——Redis数据类型

    Redis数据库(三)--Redis数据类型 一.String类型 1.set / get / append / strlen 2.incr / decr / incrby / decrby 3.ge ...

  4. Redis数据类型使用场景及有序集合SortedSet底层实现详解

    Redis常用数据类型有字符串String.字典dict.列表List.集合Set.有序集合SortedSet,本文将简单介绍各数据类型及其使用场景,并重点剖析有序集合SortedSet的实现. Li ...

  5. Redis 数据类型之(底层解析)

    Redis 数据类型之(底层解析) Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redi ...

  6. redis数据类型底层实现

    Redis是基于内存幷支持持久化的NoSQL数据库,由于其高效的性能及扩展能力,可以说是目前最受欢迎的NoSQL数据库. 在我们目前广告项目中,主要用于登陆信息验证.中断状态保存.实时广告数据拉取等场 ...

  7. Redis数据类型及编码格式——介绍及String篇

    Redis核心对象 reids中定义了一个数据结构用来统一表示各种数据类型,它叫做redisObject typedef struct redisObject {unsigned type:4; // ...

  8. Redis中五大数据结构的底层实现

    来自:DBAplus社群 作者介绍 田兆壮,新炬网络开发工程师.具备扎实的Java.Scala开发经验,熟练使用Python和Shell等脚本语言:具备前后端开发能力,熟练使用关系型数据库和非关系型数 ...

  9. 面试精讲之面试考点及大厂真题 - 分布式专栏 08 Redis中有哪些数据结构及底层实现原理

    08 Redis中有哪些数据结构及底层实现原理 不经一翻彻骨寒,怎得梅花扑鼻香. --宋帆 引言 07小节面完了负载均衡,正向代理,反向代理,终于松了一口气,然后话题转向了缓存Redis,为什么是这个 ...

最新文章

  1. 2022-2028年中国完全生物降解塑料产业发展动态及投资前景预测报告
  2. python批量合并csv_Python合并多个csv文件
  3. java怎么获取文本里的值_怎么获取到text中的文本,或者title中的值
  4. 雷林鹏分享:CSS 链接
  5. linux安装mysql出错( file /usr/share/mysql/czech/errmsg.sys from install of MySQL-server-5.5.31-2.el6.i6)
  6. Sql Server中的几个系统表(二)
  7. 基于RTP协议的数据通讯程序
  8. MySQL查询数据表中数据记录(包括多表查询)
  9. JAVA 8:Lambdas表达式初体验
  10. QoS队列调度技术详解
  11. 运维专家写给运维工程师的 6 条人生忠告
  12. 【爬虫】利用Python爬虫爬取小麦苗itpub博客的所有文章的连接地址(1)
  13. 《ABAQUS 6.14超级学习手册》——1.5 ABAQUS帮助文档
  14. 自定义竖着的SeekBar
  15. HD Tune Pro硬盘检测工具官方版
  16. python numpy库下载_Numpy库的下载与安装总结
  17. 恒生电子:主推2条联盟链,但链上交易至今不到30笔 |追击上市公司
  18. 上传图片到 OSS 带压缩图片代码
  19. 三村合建水厂问题研究 (代码)
  20. Linux磁盘16进制编辑,Tweak

热门文章

  1. 山寨AppStore的暴富者
  2. 【腾讯TMQ】30分钟轻松搞定代码瘦身
  3. js条件逻辑判断-德摩根定律
  4. 自动生成硬件优化内核:陈天奇等人发布深度学习编译器TVM
  5. Windows编程的mfc编程浅述
  6. Key Dependent Message(KDM)
  7. 净水器国产一线品牌排行榜? 哪个牌子好?
  8. 《多元统计分析与R语言》大作业
  9. 基于Redux的ReactNative项目开发总结(一)
  10. c语言程序obj exe,将目标程序(.OBJ)转换成可执行文件(.EXE)的程序称为( )。A.编辑程序B.编译程序C.链接程序D.汇编_考题宝...