redis之造一个像redis的轮子

写在前面

在这里插入图片描述
学习任何技术框架,切记不要一下子就陷入到细枝末节中,而是要做到对其整体有一个全面的了解,这样当我们学习某个知识点时就能清楚的知道,该知识点是属于哪个部分的,在整体的架构中是处于哪个位置的,从而就能避免迷失在细节中,而细节往往是最复杂,也是最难的。接下来我们就通过造轮子的方式来了解下redis的整体架构。

1:给我们的轮子起一个名字

首先是因为是我们自己的,而且非常简单,其次是轮子,最后是kv数据库,所以就叫做MySimpleWheelKv

2:可以存哪些数据?

数据模型

数据库的核心是数据,MySimpleWheelKv自然也是如此,那么我们的MySimpleWheelKv都支持存放什么数据呢?因为是键值数据库,所以基本的数据模型就是key-value模型,其中key我们仅仅支持String,而Value支持String,整型。这样我们的kv数据MySimpleWheelKv可以存储的数据就确定了。

memcached和redis的key也都是仅仅支持String,但是Memcached value仅仅支持String,redis的value值则更加丰富,String,哈希,列表,集合等,也正因为redis多样化的value类型,使得其能够适应更多的应用场景,从而得到了更加广泛的应用。

3:可以对数据做什么操作?

操作接口

作为资深的CRUD boy,我们设计的kv数据库自然是要支持crud操作了,如下:

PUT:新增或者是更新一个kv
GET:获取k对应的v
DELETE:删除k对应的整个kv对

其中以上的PUT,在有些kv数据库中也叫做SET,这里我们知道即可。

4:数据存储在哪里?

数据的存储位置,我们有两个选择,一个是内存,另一个是磁盘,二者比较如下:

内存:访问速度在百万分之一秒级别,速度极快,但是掉电所有数据会丢失,即不可持久化。
磁盘:访问速度在几毫秒级别,速度慢,但是掉电数据不会丢失,即可持久化。

我们的MySimpleWheelKv追求的就是简单和速度,所以我们选择将数据存储在内存中。

5:都有哪些模块?

我们想一下,当我们使用PUT存入一对kv的时候,需要连接到服务器,服务器需要解析我们的指令,解析完我们的指令后需要将数据写到内存中,等等,各种各样的工作,试想一下,如果是将这么多的功能都写到一个地方,程序势必变得非常臃肿,后续也难以维护,难以扩展,修改A功能影响到B功能,修改B功能又影响到C功能,为了解决这些问题业界的统一方案就是:分模块,那么什么是分模块呢?就是将不同的功能独立开发,然后相互协作,完成一个整体的功能,我们根据这个思想,分为如下模块:

在这里插入图片描述

其中每个模块作用如下:

数据访问模块:负责接收客户端发送的各种指令,如PUT
操作模块:负责解析具体的指令,并执行相应的操作,如PUT key val就会将key->val写到内存中
索引模块:负责加速数据查找,如执行GET key时,快速找到对应的val
存储模块:负责存储数据

接下来我们再看下每个模块应该如何设计。

5.1:数据访问模块

业界对数据访问有一个专业的话术,叫做访问模式,一般访问模式有如下两种:

封装调用库:即客户端和服务端在同一个进程中,客户端直接使用调用库的API操作,如果是java的话可能就是,给出一个jar包,
          然后客户端执行如MySimpleWheelKvServer server = new MySimpleWheelKvServer();server.put(key, val)的操作。
socket通信:即服务端部署在独立的机器上,客户端通过网络访问,这也是我们使用的最多的一种方式。

封装调用库的方式仅支持单机模式,所有这里我们不采用,而考虑socket通信方式,但是socket通信也有其自身的一些问题,我们的数据访问模块需要处理网络连接,解析网络请求,根据不同的指令完成不同的数据存取操作,这些动作是用一个线程,还是用多个线程,这就是我们经常看到的I/O模型设计,是非常重要的一部分。单线程容易产生阻塞等待,多线程又存在资源竞争问题,确实很麻烦,需要好好的设计一番。

redis是单线程,但是又能实现高性能,可见redis的I/O模型设计还是比较NX的。

5.2:操作模块

该模块功能比较单一,即根据不同的指令调用存储模块的不同接口。

5.3:索引模块

索引,其实就是使用某些数据结构来加速查找,因为我们这里就是简单的key val,所以采用查询时间复杂度为O(1)的数据结构:哈希

5.4:存储模块

负责数据的存储,提供相应接口,供操作模块使用。

6:模块间如何协作

以PUT和GET为例。

6.1:PUT

客户端请求数据写到数据访问模块,数据访问模块解析指令,并调用操作模块执行指令,然后操作模块调用存储模块的写入数据接口,写入数据,然后存储模块内部异步的将新的数据更新到索引模块,供后续的数据查询。

6.2:GET

客户端请求数据写到数据访问模块,数据访问模块解析指令,并调用操作模块执行指令,然后调用存储模块的数据读取接口,存储模块内部调用索引模块接口获取数据位置,然后获取数据并返回。

6.3:DELETE

客户端请求数据写到数据访问模块,数据访问模块解析指令,并调用操作模块执行指令,然后调用存储模块的数据删除接口,存储模块删除数据,并调用索引模块更新索引,然后返回。

7:redis的架构图

上面简单分析了我们自己的MySimpleWheelKv的架构和设计,最后来看下Redis的架构图:

在这里插入图片描述

写在后面

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值