Redis 命令执行过程(下)

  • 时间:
  • 浏览:3
  • 来源:uu快3漏洞_uu快3链接_公式

sendReplyToClient 法律方法真是 也会调用 writeToClient 法律方法,该法律方法本来 将输出缓冲区中的 buf 和 reply 列表中的数据都尽或者多的写入到对应的 socket中。

handleClientsWithPendingWrites 法律方法会遍历 clients_pending_write 列表,对于每个 client 一定会先调用 writeToClient 法律方法来尝试将返回数据从输出缓存区写入到 socekt中,或者还未写完,则非要调用 aeCreateFileEvent 法律方法来注册另六个写数据事件正确处理器 sendReplyToClient,等待 Redis 事件机制的再次调用。

顶端本来 响应内容写入输出缓冲区的过程,下面看一下将数据从输出缓冲区写入 socket 的过程。

在 《Redis 事件机制详解》

一文中我门歌词 歌词 歌词 知道,Redis 在两次事件循环之间会调用 beforeSleep 法律方法正确处理或多或少事情,而对 clients_pending_write 列表的正确处理就在其中。

在所有的 redisCommand 执行的最后,一般一定会调用 addReply 法律方法进行结果返回,我门歌词 歌词 歌词 的分析也来到了 Redis 命令执行的返回数据阶段。

具体 setKey 和 setExpire 的法律方法实现我门歌词 歌词 歌词 这里就不细讲,真是 本来 将键值加进到db的 dict 数据哈希表中,将键和过期时间加进到 expires 哈希表中,如下图所示。

prepareClientToWrite 首先判断了当前 client否有 须要返回数据:

接着或者这个 client 还未趋于稳定延迟等待写入 (CLIENT_PENDING_WRITE)的请况,则将其设置为该请况,并将其加入到 Redis 的等待写入返回值客户端队列中,也本来 clients_pending_write队列。

prepareClientToWrite 函数,将客户端加入到了Redis 的等待写入返回值客户端队列中,也本来 clients_pending_write 队列。请求正确处理的事件正确处理逻辑就刚现在开始了,等待 Redis 下一次事件循环正确处理时,将响应从输出缓冲区写入到 socket 中。

lookupKey 法律方法则是通过 dictFind 法律方法从 redisDb 的 dict 哈希表中查找键值,或者能找到,则根据 redis 的 maxmemory_policy 策略来判断是更新 lru 的最近访问时间,还是调用 updateFU 法律方法更新或多或少指标,什么指标还不要 在后续内存缺陷时对键值进行回收。

接下来看 getCommand 的具体实现,同样的,它底层会调用 getGenericCommand 法律方法。

前文讲到 processCommand 法律方法会从输入缓冲区中解融化对应的 redisCommand,或者调用 call 法律方法执行解融化来的 redisCommand的 proc 法律方法。不同命令的的 proc 法律方法是不同的,比如说名为 set 的 redisCommand 的 proc 是 setCommand 法律方法,而 get 的则是 getCommand 法律方法。通过这个 形式,实际上实现在Java 中很糙常见的多态策略。

本来 的好处是对于返回数据较少的客户端,不须要麻烦的注册写数据事件,等待事件触发再写数据到 socket,本来 在下一次事件循环周期就直接将数据写到 socket中,加快了数据返回的响应时延。

或者从这里也会发现,或者 clients_pending_write 队列过长,则正确处理时间也会已经 ,阻塞正常的事件响应正确处理,是因为 Redis 后续命令延时增加。

下面的 aeMain 法律方法本来 Redis 事件循环的主逻辑,还不要 看完每次循环时一定会调用 beforesleep 法律方法。

setCommand 会判断set命令否有 携带了nx、xx、ex或者px等可选参数,或者调用setGenericCommand命令。我门歌词 歌词 歌词 直接来看 setGenericCommand 法律方法。

getGenericCommand 法律方法会调用 lookupKeyReadOrReply 来从 dict 数据哈希表中查找对应的 key值。或者找非要,则直接返回 C_OK;或者找到了,则根据值的类型,调用 addReply 或者 addReplyBulk 法律方法将值加进到输出缓冲区中。

Redis 在调用查找键值系列法律方法前一定会先调用 expireIfNeeded 来判断键否有 过期,或者根据 Redis 否有 配置了懒删除来进行同步删除或者异步删除。关于键删除的细节还不要 查看《详解 Redis 内存管理机制和实现》一文。

Redis 将存储等待返回的响应数据的空间,也本来 输出缓冲区分成两偏离 ,另六个固定大小的 buffer 和另六个响应内容数据的链表。在链表为空或者 buffer 有足够空间时,则将响应加进到 buffer 中。或者 buffer 满了则创建另六个节点追加到链表上。_addReplyToBuffer 和 _addReplyObjectToList 本来 分别向这另六个空间写数据的法律方法。

setGenericCommand 法律方法的正确处理逻辑如下所示:

addReply 法律方法做了两件事情:

lookupKeyReadWithFlags 会从 redisDb 中查找对应的键值对,它首先会调用 expireIfNeeded判断键否有 过期或者须要删除,或者为过期,则调用 lookupKey 法律方法从 dict 哈希表中查找并返回。具体解释还不要 看代码中的详细注释

beforeSleep 函数会调用 handleClientsWithPendingWrites 函数来正确处理 clients_pending_write 列表。

在判断键释放过期的逻辑含有另六个特殊请况:

被委托人博客地址,欢迎查看

在上一篇文章中《Redis 命令执行过程(上)》中,我门歌词 歌词 歌词 首先了解 Redis 命令执行的整体流程,或者细致分析了从 Redis 启动到建立 socket 连接,再到读取 socket 数据到输入缓冲区,解析命令,执行命令等过程的原理和实现细节。接下来,我门歌词 歌词 歌词 来具体看一下 set 和 get 命令的实现细节和如保将命令结果通过输出缓冲区和 socket 发送给 Redis 客户端。

固定buffer和响应链表,整体上构成了另六个队列。这麼组织的好处是,既还不要 节省内存,不需一刚现在开始预先分配大块内存,或者还不要 正确处理频繁分配、回收内存。