type
status
date
slug
summary
tags
category
icon
password
Redis 是一个典型的 键值数据库,它本身比较复杂,因此我们构建一个比较简单的键值数据库,我们给它起名为 SimpleKV。为了对深入理解和优化 Redis ,我们需要对它的总体架构和关键模块有一个全局的认识!

一、可以存哪些数据 - 数据模型
对于键值数据库而言,基本的数据模型是 key-value 模型。
- 在 SimpleKV 中,key 是 String 类型,而 value 是基本数据类型,例如 String、整型等。
- Redis 支持的 value 类型包括了 String、哈希表、列表、集合等。
不同键值数据库支持的 key 类型一般差异不大,而 value 类型则有较大差别。我们在对键值数据库进行选型时,一个重要的考虑因素是它支持的 value 类型。
Redis 能够在实际业务场景中得到广泛的应用,就是得益于支持多样化类型的 value。
不同 value 类型的实现,不仅可以支撑不同业务的数据需求,而且也隐含着不同数据结构在性能、空间效率等方面的差异。
二、可以对数据做什么操作 - 操作模块
自然是增删改查!
- PUT:新写入或更新一个 key-value 对;
- GET:根据一个 key 读取相应的 value 值;
- SCAN:根据一段 key 的范围返回相应的 value 值;
- DELETE:根据一个 key 删除整个 key-value 对。
实际业务场景通常还有更加丰富的需求,例如可以增加 EXISTS 操作接口,用于判断某个 key 是否存在等!
三、键值对保存在内存还是外存 - 数据存储
- 保存在内存的好处是读写很快,毕竟内存的访问速度一般都在百 ns 级别。但是,潜在的风险是一旦掉电,所有的数据都会丢失。
- 保存在外存,虽然可以避免数据丢失,但是受限于磁盘的慢速读写(通常在几 ms 级别),键值数据库的整体性能会被拉低
如何进行设计选择,我们通常需要考虑键值数据库的主要应用场景,如果作为缓存使用,则可以保存到内存,因为数据不怕丢失!
我们的 SimpleKV 就采用内存保存键值数据。
四、采用什么访问模式 - 访问框架

- 通过函数库调用的方式供外部应用使用,即以动态链接库的形式链接到我们的程序中(RocksDB 采用)
- 通过网络框架以 Socket 通信的形式对外提供键值对操作,包括 Socket Server 和协议解析(Memcached、Redis 采用)
使用第二种网络框架提供服务,又会遇到问题:
网络连接的处理、网络请求的解析,以及数据存取的处理,是用一个线程、多个线程,还是多个进程来交互处理呢?即 I/O 模型设计。
Redis 又是如何做到 “单线程,高性能” 的呢?
五、如何定位键值对的位置 - 索引模块
当 SimpleKV 解析了客户端发来的请求,此时,SimpleKV 需要查找所要操作的键值对是否存在,这依赖于键值数据库的索引模块。索引的作用是让键值数据库根据 key 找到相应 value 的存储位置,进而执行操作。
索引的类型有很多,常见的有哈希表、B+ 树、字典树等。
不同的索引结构在性能、空间消耗、并发控制等方面具有不同的特征。
Memcached 和 Redis 采用哈希表作为索引,而 RocksDB 采用跳表作为索引。
内存键值数据库(例如 Redis)采用哈希表作为索引,很大一部分原因在于,其键值数据基本都是保存在内存中的,而内存的高性能随机访问特性可以很好地与哈希表 O(1) 的操作复杂度相匹配。
Redis 采用一些常见的高效索引结构作为某些 value 类型的底层数据结构,为 Redis 实现高性能访问提供了良好的支撑。
六、如何实现重启后快速提供服务 - 存储模块
内存分配器
内存分配器是键值数据库中的一个关键因素。对于以内存存储为主的 Redis 而言,这点尤为重要。Redis 的内存分配器提供了多种选择,分配效率也不一样。
持久化功能
鉴于磁盘管理要比内存管理复杂,SimpleKV 就直接采用了文件形式,将键值数据通过调用本地文件系统的操作接口保存在磁盘上。此时,SimpleKV 只需要考虑何时将内存中的键值数据保存到文件中,就可以了:
- 对于每一个键值对,都进行一次落盘保存,数据可靠但性能受限!
- 周期性存储,性能较好但数据有丢失风险!
七、小结
我们构造了一个简单的键值数据库 SimpleKV,可谓是麻雀虽小,五脏俱全。SimpleKV 包含了一个键值数据库的最基本组件
为了支持更加丰富的业务场景,Redis 对这些组件或者功能进行了扩展,或者说是进行了精细优化,从而满足了功能和性能等方面的要求。

从 SimpleKV 演进到 Redis,有以下几个重要变化:
- Redis 主要通过网络框架进行访问,而不再是动态库了,这也使得 Redis 可以作为一个基础性的网络服务进行访问,扩大了 Redis 的应用范围。
- Redis 数据模型中的 value 类型很丰富,因此也带来了更多的操作接口
- Redis 的持久化模块能支持两种方式:日志(AOF)和快照(RDB),不同持久化方 式具有不同的优劣势,影响到 Redis 的访问性能和可靠性。
- SimpleKV 是个简单的单机键值数据库,Redis 支持高可靠集群和高可扩展集群
- 作者:ITNXD
- 链接:https://blog.itnxd.eu.org/article/what-does-a-key-value-database-contain
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。


