redis的数据结构
1.1 String字符串
表现形式为
数据结构:SDS(简单的动态字符串)
使用原因:redis是使用c语言开发的,但在c语言中是没有字符串类型的,只能使用指针或符数组的形式表示一个字符串,所以在redis设计了一种简单的动态字符串(可以根据不同的数据类型不同的数据结构选择不同的数据结构)
支持的数据类型:字符串,整数(原子递增,返回一个递增以后的值),浮点
SDS模型图:
优点:
1,SDS获取字符串长度复杂度O(1),而C的字符串为O(n)。
因为SDS保存了长度在len中,但是C的字符串需要从头到位遍历字符数组。
2,SDS避免了一些C的内存溢出的问题。
在C中,某些情况下会发生内存溢出的问题。假如两个字符出s1 ‘hello’,s2 ‘world’ 在内存中紧挨着保存着。如果在没有给s1申请更多内存的前提下,就为s1追加一些字符串,这时就不知情的把s2的数据修改了。而SDS字符串拼接函数,已经做好了检查长度的问题,如果空间不够,就会先扩展空间。
3,SDS通过free的内存预分配和惰性释放,降低内存分配次数
C的字符串,每当增加长度的时候,都必须申请内存,不然可能内存溢出;每当减少长度的时候,都要释放内存,不然可能内润泄漏。而SDS在len+free不够的时候才扩展内存扩展的规则是 如果len小于 1Mb,则len和free保持一致,这样buffer数组长度为2*len+1;如果len大于等于1Mb时,free总是分配1MB,这样buffer数组长度为 len+1Mb+1byte;当SDS字符串长度减少的时候,内存并不会立即回收,而是把内存放到free中。这样以后再需要增加长度的时候,不需要再申请内存。
4,判断字符串结尾的方式
C的字符串以遇到’\0’作为判断到了字符串结尾,而SDS以len来判断。这样SDS中间可以包含’\0’
使用场景:session共享,ip限制(短信验证)
注意:namespace key命名冲突(命名要规范)
1.2 List 列表
表现形式为:
数据结构:3.2版本之前采用的是:zipList 和 LinkList
3.2版本之后采用的是:quickList
quickList详解:是由zipList组成的双向链表
图解:
使用场景:消息队列(从左侧存数据,从右侧取数据)
栈:先进后出
1.3 Hash
表现形式:
数据结构:hashtable(数据量大) zipList(数据量小)
ReHash:redis插入新节点前判断是否要扩容
图解HashTable:
1.4 Set(无序集合)
数据结构:inset(存储整数类型的数据) hashTable
使用场景:标签
1.4 Zset(有序集合)
数据结构:skipList(跳表)
图解:
skipList(跳表的解释):跳表就是链表与二分法的结合。1.链表从头节点到尾节点都是有序的 2.可以进行跳跃查找(形如二分法),降低时间复杂度。3.以空间换时间
场景:主要可以使用排序