Redis核心技术与实战1-从构建一个简单的键值数据库SimpleKV开始

数据模型与操作接口

开始构造 SimpleKV 时,首先就要考虑里面可以存什么样的数据,对数据可以做什么样的操作,也就是数据模型和操作接口。
数据模型和操作接口能够决定什么情况下适合用我们构造的这个键值数据库,什么情况下不适合用,而是需要采用其他类型的数据库。

数据模型

键值数据库的基本数据模型是: key-value 模型。
通常key是String类型。

有的键值数据库仅支持vlaue为String类型,例如memcached数据库。
也可以设计为value支持所有基本数据类型+String类型。
而redis则支持多种复杂数据类型:如String、哈希表、列表、集合等。

Redis能够在实际业务场景中得到广泛的应用,就得益于支持多样化类型的value。

操作接口

新增\更新:PUT(或者SET)
获取:GET
删除:DELETE
范围:SCAN
是否已经存在:EXISTS

键值对保存在内存还是外存?

保存在内存,存取速度快(ns级别),有断电丢失的危险
保存在外存,断电不会丢失,但是访问速度太慢(ms级别)。

根据应用场景来选择

例如,缓存场景下的数据要求能快速访问但允许丢失,这时就采用内存保存键值数据。
Memcached和Redis都是内存键值数据库。

采用什么访问模式?- 访问模块

一种方式是通过函数库调用的方式供外部应用使用,比如,以动态链接库的形式链接到我们自己的程序中。
还可以通过网络框架以Socket通信的形式对外提供键值对操作。

网络框架访问模式

通过网络框架提供访问服务的模式,扩大了键值数据库的应用场景,但是也给键值数据库的性能、运行模型的设计带来了一些潜在问题:如何设计合适的网络I\O模型?

所谓网络I\O,就是在网络框架访问模式下,如何处理用户的访问:如何处理网络连接、采用何种协议解析网络请求、如何处理数据存取?是采用单线程还是多线程或者多进程的方式?不同的网络I\O模型对于键值数据库的性能和扩展性有不同的影响。

如果采用一个线程既要处理网络连接、请求解析,又要完成数据存取,那么一旦某一步操作发生阻塞、整个用户访问就会被阻塞住,这就降低了系统响应速度。
如果我们采用不同线程处理不同操作,那么当某个线程被阻塞时,其它线程仍能正常运行。但是多个线程访问同一资源时,又会发生竞争,也会影响效率。

Redis采用的是单线程的网络I\O模型,且做到了“单线程、高性能”。

如何定位键值对的位置-索引模块

当解析了用户请求后,键值数据库需要查找用户请求操作的键值对是否存在,这依赖于数据库的索引模块。
索引的作用是,让键值数据库根据key找到value的存储位置,进而执行操作。

索引的类型有很多,常见的有哈希表、B+树、字典树等。
不同的索引类型在空间消耗、性能、并发控制等方面有不同的特征。
有些键值数据库采用跳表来存储key-value对,而redis和memcached则都是采用的哈希表。

将用户请求的的key-value对写入或删除-存储模块

当用户调用PUT命令操作数据时,需要为key-value数据分配内存空间
当用户调用DELETE命令操作数据时,需要将key-value对所占用的内存空间释放掉

内存分配器

SimpleKV采用简单的glibc来作为内存分配器。
但是对于Redis来说,由于其value支持各种复杂数据类型,因此键值对的大小不一,glibc的分配器在处理随机大小的内存块分配时,表现并不好。一旦保存的键值对数据规模过大,就会出现严重的内存碎片问题。

Redis则提供了多种可选择的内存分配器,用户可以根据应用场景来选择。

如何实现重启后快速提供服务-持久化

持久化的两种方案:
每次PUT或者DELETE时,写内存的同时落盘(调用文件接口写文件)。将导致效率非常低
按照一定频率周期性地将数据落盘,每隔一段时间将这段时间内的所有PUT或者DELETE的数据写入到文件,这种情况下有可能丢失

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值