redis 数据结构详解系列
如果你使用过 redis,一定对它的内部实现感到好奇。本系列文章着重讲解 redis 在内存中的数据结构的实现。redis 本质上是一个数据结构服务器(data structures server),以高效的方式实现了多种数据结构,研究它的的数据结构和算法,对于提升我们算法的编程水平有很重要的参考意义。
redis 的数据结构分2个不同的层面来讨论。
第一个层面,是从使用者的角度,redis 对外暴露的数据结构接口。比如:
- string
- list
- set
- zset /* sorted set */
- hash
第二个层面,是从内部实现的角度,分析 redis 是如何存储各种结构的数据。比如:
- sds
- ablist /* a generic doubly linked list */
- dict
- ziplist
- quicklist
- skiplist
- intset
第一个层面的”数据结构“,redis 官网 (http://redis.io/topics/data-types-intro) 有详细的介绍。本系列文章先详解第二个层面的底层数据结构内部实现,以及这两个层面的数据结构之间的关系,redis 如何通过组合第二层面的各种数据结构来实现第一个层面更高的数据结构。
在讨论一个系统的内部实现,我们都要首先明确他的设计原则,这样我们才能更深刻地理解他为什么会进行如此设计的真正意图。在本文接下来的讨论中,我们主要关注以下几点:
1、存储效率(memory efficiency)
redis 是专用于存储数据的,它对计算机的资源消耗主要在内存,因此节约内存是它很重要的一个方面。这意味着 redis 一定非常精细地考虑了压缩数据、减少内存碎片等问题。
2、快速响应(fast response time)
与快速响应相对的是高吞吐量(high throughput)。redis 是用于提供在线访问的,对于单个请求的响应时间要求很高,因此,快速响应是比高吞吐量更重要的目标。有时候这两个目标是矛盾的。
3、单线程(single-thread)
redis 的性能瓶颈不在 CPU 资源,而在于内存访问和网络IO,而采用单线程的设计带来的好处是,极大的简化了数据结构和算法的实现。相反 redis 通过异步IO和 pipelining 等机制来实现高速访问。显然,单线程的设计对单个请求的快速响应时间也提出了更高的要求。