redis的5种基础数据结构(二): list(列表) 和 hash(字典)

一、list(列表)

1.核心特点

Redis的列表相当于Java语言里面的LinkedList,它是链表而不是数组。
list的插入和删除操作非常快,时间复杂度为O(1),但是索引定位慢,时间复杂度为O(n).

2.常用用途

常用来做异步队列使用。将需要延后处理的任务结构体序列化字符串,塞进redis的列表,另一个线程从列表中进行轮询处理结果。

3.内部结构

ziplist + quicklist

(1)ziplist(压缩列表)

ziplist都是紧凑存储,没有冗余空间。只能存储少量数据元素。
存储少量元素的原因:因为存储紧凑,新增元素时,需要扩展内存,并将之前的内容一次性拷贝到新的地址。如果内容过大,内存分配和元素拷贝就会消耗很大,因此不适合存储大量元素。

(2)quicklist(快速列表)

quicklist是ziplist和linkedlist的混合体。(ziplist + 链表)
多个ziplist使用双向指针串联起来,每个ziplist大小为8K.

二、hash(字典)

(redis服务器中出现最为频繁的复合型数据结构)

1.内部结构

  • 数组+链表。跟java的HashMap结构一样。
  • 字典内部存在两个hashTable.在扩容和缩容时,进行渐进式搬迁。两个hashTable分别存储旧值和新值,搬迁结束后,旧的hashtable被删除。

2.hash攻击

  • hashtabel的性能好不好完全取决于hash函数的质量。如果hash函数可以将key打散的比较均匀,那么这个hash函数就是一个好函数。
  • redis的字典默认的hash函数式siphash.
  • 如果hash函数存在偏向性,就会导致链表长度不均,甚至所有元素集中到个别链表中,导致查找效率急剧下降,有限的服务器计算能力被查找的低效率拖垮,这就是hash攻击。

3.扩容和缩容

  • hash表中元素个数等于第一维数组长度时,开始扩容,扩容为原来的2倍。(区别于hashMap,其受加载因子的影响)
  • 如果redis在做bgsave,不做扩容,若元素个数是数组长度的5倍,则进行强制扩容。
  • 缩容的条件:元素个数低于数组长度的10%
上一篇:Redis 核心篇:唯快不破的秘密


下一篇:Redis核心原理与实践--列表实现原理之quicklist结构