前言

上一节我们学习了系统学习法的原理和作用,后续 Redis 的学习我们将按照系统学习法的方式学习,提升学习效率。 我们还学习了键值数据库关键功能数据模型和操作接口,了解不同键值数据库的数据模型的作用和意义,本节我们继续学习键值数据库

操作接口

键值数据库的基本操作就是增删改查,分别是 PUT、GET、DELETE、SCAN

  • PUT:新写入或更新一个 key-value 对
  • GET:根据一个 key 读取相应的 value 值
  • DELETE:根据一个 key 删除整个 key-value 对
  • SCAN:查询一段时间内所有 key-value 对

Redis 的新建和更新操作都是同一个操作接口 Set,实际执行时会根据 key 是否存在执行相应的新建或更新操作流程

实际业务场景中我们会遇到这样一些需求,查询用户一段时间内的访问记录,要用到 SCAN 操作,在判断用户是否处于白名单或黑名单的业务中,我们还会用到 EXIST 操作接口,判断某个 key 是否存在,对于不同键值数据库操作接口,我们可以查阅相关的文档学习。

综上所述,PUT/GET/DELETE/SCAN 是一个键值数据库的基本操作集合。

数据存储

键值数据库的数据应该存储在内存还是外存?这要根据键值数据库的主要应用场景。

比如缓存场景下数据能快速访问且允许丢失,用于这个场景的键值数据库 Memcached/Redis 都是内存键值数据库,它们的数据存储在内存中,优势是读写速度非常快,内存的访问速度在百 ns 级别,劣势是一旦断电所有数据都会丢失。保存在外存磁盘中,虽然避免数据丢失,但是由于磁盘读写速度很慢,通常在 ms 级别,键值数据库整体性能会下降。

SimpleKV 和 Redis 一样适用缓存业务场景,用内存保存键值数据,我们来了解下它的基本组件。

一个键值数据库包括访问模式,索引模块,操作模块和存储模块,如图

访问模式

键值数据库访问模式分两种

  • 通过函数库调用的方式供外部调用,上图中的 libsimplekv.so,就是以动态链接库的形式链接到我们自己的程序中,提供键值存储功能,比如 RocksDB
  • 通过网络框架以 Socket 通信的形式对外提供键值对操作,这种形式可以提供广泛的键值存储服务。网络框架中包括 Socket Server 和协议解析,比如 Memcached 和 Redis

不同的键值数据库服务器和客户端交互的协议并不相同,我们在二次开发键值数据库时,必须了解和掌握键值数据库的通信协议。

通过网络框架提供键值存储服务,一方面扩大键值数据库应用场景,适配多种不同编程语言调用,另一方面在设计选择运行模型和性能方面会产生一定的影响。

举个例子:

  1. 当客户端发送一个命令PUT hello world后,命令会被封装在网络包中发送给键值数据库
  2. 键值数据库接收网络包,按照协议解析后,客户端要写入一个 key=hello,value=world 的键值对,开始执行数据写入流程

网络 I/O 模型

在处理网络连接,解析网络请求,存取数据的时候,我们需要对不同的解决方案做选择。用一个线程 / 多个线程 / 多个进程处理?这个问题就是 I/O 模型设计,不同 I/O 模型影响键值数据库性能和拓展性。

  1. 假设我们只用一个线程处理网络连接,解析请求,存取数据,只要其中一个步骤因为某个问题阻塞,整个线程就被阻塞,降低系统响应速度,无法处理更多请求。
  2. 假设我们用多线程处理,某个线程被阻塞其他线程正常运行,但是在访问共享资源时,不同线程要保证串行操作,加锁处理,也会影响系统性能。

总结

本节我们讲解了键值数据库的基本操作接口、数据存储、访问模式、网络 I/O 模型,我们已经对 Redis 的整体架构设计有了大概印象。