你知道快速的Redis有哪些慢操作吗?( 四 )


第四,例外情况,是指某些数据结构的特殊记录,例如压缩列表和双向链表都会记录表头和表尾的偏移量 。这样一来,对于 List 类型的 LPOP、RPOP、LPUSH、RPUSH 这四个操作来说 , 它们是在列表的头尾增删元素,这就可以通过偏移量直接定位,所以它们的复杂度也只有 O(1) , 可以实现快速操作 。
小结我们学习了 Redis 的底层数据结构,这既包括了 Redis 中用来保存每个键和值的全局哈希表结构,也包括了支持集合类型实现的双向链表、压缩列表、整数数组、哈希表和跳表这五大底层结构 。
Redis 之所以能快速操作键值对,一方面是因为 O(1) 复杂度的哈希表被广泛使用,包括 String、Hash 和 Set , 它们的操作复杂度基本由哈希表决定,另一方面,Sorted Set 也采用了 O(logN) 复杂度的跳表 。不过 , 集合类型的范围操作,因为要遍历底层数据结构,复杂度通常是 O(N) 。这里 , 我的建议是:用其他命令来替代,例如可以用 SCAN 来代替,避免在 Redis 内部产生费时的全集合遍历操作 。
当然 , 我们不能忘了复杂度较高的 List 类型,它的两种底层实现结构:双向链表和压缩列表的操作复杂度都是 O(N) 。因此,我的建议是:因地制宜地使用 List 类型 。例如 , 既然它的 POP/PUSH 效率很高,那么就将它主要用于 FIFO 队列场景,而不是作为一个可以随机读写的集合 。
Redis 数据类型丰富,每个类型的操作繁多 , 我们通常无法一下子记住所有操作的复杂度 。所以,最好的办法就是掌握原理,以不变应万变 。这里 , 你可以看到 , 一旦掌握了数据结构基本原理,你可以从原理上推断不同操作的复杂度,即使这个操作你不一定熟悉 。这样一来 , 你不用死记硬背,也能快速合理地做出选择了 。




推荐阅读