redis的两种持久化方案:从应用到底层 36张图带你进入Redis世界
redis的两种持久化方案:从应用到底层 36张图带你进入Redis世界当你执行set name sowhat的时候,其实Redis会创建两个RedisObject对象,键的RedisObject 和 值的RedisOjbect 其中它们type = REDIS_STRING,而SDS分别存储的就是 name 跟 sowhat 字符串咯。里面有指针用来指向 SDS。底层:C语言中String用char[]数组表示,源码中用SDS(simple dynamic string)封装char[],这是是Redis存储的最小单元,一个SDS最大可以存储512M信息。structsdshdr{ unsignedintlen;//标记char[]的长度 unsignedintfree;//标记char[]中未使用的元素个数 charbuf[];//存放元素的坑 } Redis对SDS再次封装生成了RedisObject,核心有两个作用:说明是5种类型哪一种。
以下文章来源于sowhat1412 ,作者sowhat1412
总感觉哪里不对,但是又说不上来
1、基本类型及底层实现 1.1、String用途:
适用于简单key-value存储、setnx key value实现分布式锁、计数器(原子性)、分布式全局唯一ID。
底层:C语言中String用char[]数组表示,源码中用SDS(simple dynamic string)封装char[],这是是Redis存储的最小单元,一个SDS最大可以存储512M信息。
structsdshdr{
unsignedintlen;//标记char[]的长度
unsignedintfree;//标记char[]中未使用的元素个数
charbuf[];//存放元素的坑
}
Redis对SDS再次封装生成了RedisObject,核心有两个作用:
说明是5种类型哪一种。
里面有指针用来指向 SDS。
当你执行set name sowhat的时候,其实Redis会创建两个RedisObject对象,键的RedisObject 和 值的RedisOjbect 其中它们type = REDIS_STRING,而SDS分别存储的就是 name 跟 sowhat 字符串咯。
并且Redis底层对SDS有如下优化:
SDS修改后大小 > 1M时 系统会多分配空间来进行空间预分配。
SDS是惰性释放空间的,你free了空间,可是系统把数据记录下来下次想用时候可直接使用。不用新申请空间。
1.2、List查看源码底层 adlist.h 会发现底层就是个 双端链表,该链表最大长度为2^32-1。常用就这几个组合。
lpush lpop = stack 先进后出的栈
lpush rpop = queue 先进先出的队列
lpush ltrim = capped collection 有限集合
lpush brpop = message queue 消息队列
一般可以用来做简单的消息队列,并且当数据量小的时候可能用到独有的压缩列表来提升性能。当然专业点还是要 RabbitMQ、ActiveMQ等
1.3、Hash散列非常适用于将一些相关的数据存储在一起,比如用户的购物车。该类型在日常用途还是挺多的。
这里需要明确一点:Redis中只有一个K,一个V。其中 K 绝对是字符串对象,而 V 可以是String、List、Hash、Set、ZSet任意一种。
hash的底层主要是采用字典dict的结构,整体呈现层层封装。从小到大如下:
1.3.1、dictEntry真正的数据节点,包括key、value 和 next 节点。
1.3.2、dictht1、数据 dictEntry 类型的数组,每个数组的item可能都指向一个链表。
2、数组长度 size。
3、sizemask 等于 size - 1。
4、当前 dictEntry 数组中包含总共多少节点。