首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Redis(三):set/get 命令源码解析

经过前两篇的介绍,我们对整个redis的动作流程已经有比较清晰的认识。

接下来就是到具体的命令处理方式的理解了,想来我们用这些工具的意义也是在此。虽然没有人觉得,一个set/get方法会有难度,但是我们毕竟不是很清楚,否则也不至于在谈到深处就懵逼了。

我觉得本文的一个重要意义就是: 让set/get还原成它本来样子,和写"hello world"一样简单。

框架性质的东西,我们前面已经讲解,就直接进入主题:set/get 的操作。

set/get 对应的两个处理函数 (redisCommand) 定义是这样的:

所以,我们只要理解了, setCommand,getCommand 之后,就可以完全自信的说,set/get 就是和 "hello world" 一样简单了。

零、hash 算法

很显然,kv型的存储一定是hash相关算法的实现。那么redis中如何使用这个hash算法的呢?

redis 中许多不同场景的hash算法,其原型是在 dictType 中定义的。

针对大部分场景,我们的key一般都是 string 类型的,但是还是会稍微有不一样的。这里我们就两个场景来说明下:

1. 命令集构建的hash算法

即是 server.commands 中的key的hash算法,这里元素是有限的。其定义如下:

2. 针对普通kv查询的hash算法

整个nosql就是kv的增删改查,所以这是个重要的算法。

可以看到,针对普通的字符串的hash可是要复杂许多呢,因为这里数据远比 command 的数据多,情况更复杂,这样的算法唯一的目标就是尽量避免hash冲突。(虽然不知道为啥这么干,但它就是牛逼)

redis中还有其他的hash算法,比如dictObjHash,dictEncObjHash, 后续有接触我们再聊。

接下来,我们正式来看看 set/get 到底如何?

一、getCommand 解析

很显然,get 会是个最简单的命令,自然要检软柿子捏了。

整个处理流程果然是异常简单,感觉人生已经达到了巅峰!但是,我们还没有看到关键,那就是查找 key 的过程。我们通过之前的介绍,知道有个叫做 redisDb 的东西,看起来它是负责所有的数据管理。它应该不会因为简单而不存储某些数据吧。

怎么样?是不是有一首歌叫凉凉~

可以说,get操作本身是相当简单的,在无hash冲突前提下,O(1)的复杂度搞定。然而它还要处理过期的数据问题,就不那么简单了。

我们用一个时序图整体体会下get的流程:

二、setCommand 解析

setCommand 是个写操作,就不是 get 那么简单了。

看完了超时及各标识位的解析,及set框架流程,我们来看下具体核心的kv存储: setKey(), setExpire();

总体来说,set操作会分为几步:

1. 判断出多重参数,如是否是NX/EX/PX/XX, 是否超时设置;

2. 编码转换数据, 如将字符串转换为long型;

3. 解析超时字段;

4. set kv, 添加或者覆盖数据库值, 同时清理过期队列;

5. 设置超时时间;

6. 触发事件监听;

7. 响应客户端;

最后,我们以set的整个时序图作为结尾,也让我们明白一点,不是每个hello world 都很简单:

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210228A01HBT00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券