一、总体图
二、为什么要区分encoding?
encoding实际上就是redis的内部实现,比如list,到底是LinkedList还是ArrayList?encoding就表示LinkedList和ArrayList。
encoding存在key中,有2个好处:
1.执行命令时,比如对一个list类型的key执行了incrby,则立刻返回错误,不需要去到value中效验value是否是int类型。
2.节省内存,理论上所有string类型都可以用raw储存,但比较小的string(小于44字节)用embstr储存会更节省内存
查看encoding命令:
object encoding {key}
三、各种类型的模型
由图中从上往下说
1.embstr
先提一下SDS,因为redis是用c语言编写的,而c语言没有string类型。所以作者定义了string类型,称它为SDS。
string类型的实际储存结构都是SDS,embstr、raw只是负责储存元数据(字符长度、SDS指针等)。
当string的长度小于等于44时(旧版本39),redis使用embstr储存。
embstr和raw的区别:
embstr的元数据和SDS是储存在同一块内存中的。因此只需要分配一次内存。
2.int
当string为整数且数值小于long时使用int储存。
c本来就有long类型,不用SDS,int跟embstr类似,只需要分配一次内存。
3.raw
字节大于44时使用raw。需要分配2次内存。
注:一旦转为raw,就算进行删减操作使字节小于44,也不会再转回embstr。
4.ziplist
中文名:压缩列表
结构是把整个list都存在一个二进制数组中,用某几位指向下一个元素的偏移量,某几位指向上一个元素的偏移量。(除了指针还有元素长度之类的)。具体百度。
好处是可以使list结构更紧凑,节省内存。坏处是长度过大时反而查找会慢。
5.hashtable
就是和普通的hash表差不多
6.linkedlist
就是和普通的双向链表差不多
7.quicklist
ziplist的好处是节省空间,但太大就解析太慢了,只能用linkedlist储存。
何不结合使用?把大长度的linkedlist拆成几个小段,每一小段就是一个ziplist。这就是quicklist的由来。
所以quicklist=ziplist+linkedlist
8.intset
当set的元素只有整数时使用,和string的int一样的道理
9.skiplist
中文名:跳表
是一种牺牲空间换时间的数据结构。
模型图:
思想就是在列表中增加高度层,查找数据时从高往下找,就能找到目标数据。是一种类似平衡树的数据结构。(与平衡树的共同点:都是牺牲增删改查速度换查找速度)
如果有写错的地方,欢迎大家指正,感谢!