数据类型
- string,list,set,hast,sortset
数据结构
- string,list,set,hast,sortset都只是数据的保存形式,底层的数据结构是:简单动态字符串,双向链表,压缩列表,哈希表,跳表,整数数组,Redis使用了一个哈希表保存所有的键值对
- 五种数据形式的底层实现
a,string:简单动态字符串 b,list:双向链表,压缩列表 c,hash:压缩列表,哈希表 d,Sorted Set:压缩列表,跳表 e,set:哈希表,整数数组
- List ,hash,set ,sorted set被统称为集合类型,一个键对应了一个集合的数据
- 集合类型的键和值之间的结构组织:
- Redis使用一个哈希表保存所有键值对,一个哈希表实则是一个数组,数组的每个元素称为哈希桶。
- 哈希桶中的元素保存的不是值的本身,而是指向具体值的指针
- 哈希冲突解决
- Redis的hash表是全局的,所以当写入大量的key时,将会带来哈希冲突,可以使用渐进式地扩容来减低哈希冲突(不用一次性扩容的原因是单次请求操作可能会触发扩容,这时会导致长时间的阻塞)
- Redis解决hash冲突的方式,是链式哈希:同一个哈希桶中的多个元素用一个链表来保存
- 一次性扩容
- 为了使rehash操作更高效,Redis默认使用了两个全局哈希表:哈希表1和哈希表2,起始时hash2没有分配空间
- 随着数据增多,Redis执行分三步执行rehash;
- 给hash2分配更大的内存空间,如是hash1的两倍
- 把hash1中的数据重新映射并拷贝到哈希表2中
- 释放hash1的空间
- 渐进式扩容
- 由于步骤2重新映射非常耗时,会阻塞redis
- 讲集中迁移数据,改成每处理一个请求时,就从hash1中的第一个索引位置,顺带将这个索引位置上的所有entries拷贝到hash2中。
- 压缩列表,跳表的特点
- 压缩列表类似于一个数组,不同的是:压缩列表在表头有三个字段zlbytes,zltail和zllen分别表示长度,列表尾的偏移量和列表中的entry的个数,压缩列表尾部还有一个zlend,表示列表结束,所以压缩列表定位第一个和最后一个是O(1),但其他就是O(n)
- 跳表:是在链表的基础上增加了多级索引,通过索引的几次跳转,实现数据快速定位,时间复杂度是O(logn),适合用来进行区域查询