Redis 底层是用C语言进行编写的,常用的数据结构为

动态字符串(SDS),InSet,Dict,ZipList QuikList SkipList

动态字符串优点:

1.动态字符串避开了传统字符串的缺点,不可进行改变,它是可以改变的;

2.时间复杂度为O(1),时间复杂度小,性能好;

3.支持动态扩容;

4.减少内存分配次数;

5.二进制安全;

inset优点

1.有序唯一的元素存储;

2.类型升级机制,节省内存空间;

3.底层采用二分法查找法来查询;

Dict 组成:hash表(Dic)hash节点(DictHashTable)字典(dict )

dict的结构:类似于hashtable,用数组和链表来解决hash冲突

dict的扩容和收缩:扩容:如果LoadFactor>5或者LoadFactor >1 而且没有子进程就进行扩容,扩容大小为大于等于第一个used + 1的2^n;

收缩:如果LoadFactor < 0.1,就进行收缩,收缩大小为第一个大于等于used的2^n次方;

dict的rehash,rehash是渐进式的rehash,意味着每次访问dict只进行一次rehash;

rehash过程: ht0只减不增,新增操作只发生在ht1,其他操作发生在在两个hash表

ZipList : 是一种双端链表,前后都可以进行压入或弹出操作,时间复杂度为O(1)

结构为用一段记录上一节点的长度来寻址,相比于指针占用内存更小,缺点是如果数据较多,那么查询时间过长,增加或删除较大数据可能会发生连续更新问题

QuikList: QuikList 是对ZipList的一个升级,每一个节点是一个ZipList,解决了内存申请问题,并且解决了内存占用问题,中间节点可以压缩,节省了内存;

SkipList : 是一个双向链表,每个节点有score和ele值;按照score值进行排序,score按照ele进行排序,每个节点包含多层指针,层数为1到32的随机数,不同层指针到下一个节点的跨度不同,查询效率和红黑树差不多,实现更加简单;

所有的数据编码在RedisObject中,可以编码五种数据类型如下

String,List,Set,ZSet,Hash

List 在3.2版本之前底层使用ZipList 或LinkedList来实现,3.2版本之后采用QuikedList来实现

Set:因为要实现元素的唯一并且效率高,内存小,采用dict来实现,Dict是key -value形式的,所以只用key来而value设置为null,当存储元素都为整数时并且数量不超过set-max-inset-entries时,会使用inset来存储;

Zset底层为了实现有序且元素唯一,节省内存,采用dict和SkipList来实现,而数据量较少时,采用ZipList来实现

Hash: hash底层为了节省内存,采用ZipList进行编,当数据量较大时转换为Dict进行编码,ZipList中相邻的两个entry分别保存field和value