Redis内部编码
我们常说的String,List,Hash,Set,Sorted Set只是对外的编码,实际上每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis可以在合适的场景选择更合适的内部编码。
如下图所示(图片纠正:intset编码,而不是inset编码),可以看到每种数据结构都有2种以上的内部编码实现,例如String数据结构就包含了raw、int和embstr三种内部编码。同时,有些内部编码可以作为多种外部数据结构的内部实现,例如ziplist就是hash、list和zset共有的内部编码,而set的内部编码可能是hashtable或者intset:
图片里面的KEY应该是VALUE。。。。。
Redis这样设计有两个好处:
- 可以偷偷的改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动对外数据结构和命令。
- 多种内部编码实现可以在不同场景下发挥各自的优势。例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降。这时候Redis会根据配置选项将列表类型的内部实现转换为linkedlist。
redis的key都是string类型,redis的value值对外提供的常用的几种数据类型有:string 、hash 、list、 set 、zset
redis里面封装的dictEntry的结构体,key都是string类型,value都是一个指向redisObject对象的地址
1.String的底层实现:string原理
底层字符串特性?
1).二进制安全(体现在len这个字段上)
2).避免频繁的内存分配,进行内存得预分配(体现在上面扩容过程)
3).兼容c语言函数库(其实底层都会加\0占一个字节作为字符串结尾)
2.哈希底层的实现:数组 + 链表(采用头插法解决冲突,不会像java语言的map一样转化为红黑树),redis会把kay、value封装成一个dictEntry的结构体(dictEntry的key为string类型,value是一个指针,指向一个redisObject对象(不像java语言一样把hashmap的key、value的具体值封装在一起))
redis为什么要把value封装成一个redisObject对象?
因为redis支持value的值有多种不同的数据类型
3.list底层实现:底层是链表,有两个list,一个是ziplist,字面意是压缩列表,另一个是quicklist,字面意是快速列表,在redis中直接使用的是quicklist
4.set底层实现: Set是一个特殊的value为空的Hash。
5.zset底层实现:Zset底层是一种跳表SkipList数据结构(跳表在原有的有序链表上面增加了多级索引,通过索引来实现快速查找,实质就是一种可以进行二分查找的
有序链表)
应用场景