深入理解Redis:命令处理流程
Redis是著名的NoSQL键值数据库服务器,为了保证效率,其数据都缓存在内存中。与Memcached相比,Redis支持的数据类型更多,包括String,List,Set,Zset和Hash。下面简单介绍一下Redis内部运行流程。
Redis是单线程运行的。在这个主线程中,Redis通过循环不断接收处理外部事件,处理外部事件同时产生的网络操作,如回复客户端请求,也转化为事件进行处理。
Redis的主函数在redis.c文件中,主函数最终调用aeMain函数进入事件处理循环,aeMain即是Redis运行的核心部分。下面详细看一下aeMain函数:
void aeMain(aeEventLoop *eventLoop) {
eventLoop->stop= 0;
while(!eventLoop->stop) {
if(eventLoop->beforesleep != NULL)
eventLoop->beforesleep(eventLoop);
aeProcessEvents(eventLoop,AE_ALL_EVENTS);
}
}
可以看到,这个函数非常简单。每次循环中,Redis都依次调用beforeSleep函数和aeProcessEvents函数。
aeProcessEvents函数是具体处理外部事件的函数,它将会处理外部(也包括内部事件)事件。在调用aeProcessEvents之前,redis都会调用beforeSleep函数。
我们先看看aeProcessEvents函数,它会处理两类事件:定时器事件以及文件(包括网络)相关事件。对应的函数分别是processTimeEvents和readQueryFromClient(其对应接收客户端数据操作,而写操作对应的函数是sendReplyToClient,这两个网络事件相关的函数具体实现在networking.c中)。
具体来看readQueryFromClient,它在接收完客户端数据后,调用processInputBuffer.后续具体流程是:
processInputBuffer->processCommand->call。
其中processCommand会通过lookupCommand函数,查找Redis对应执行的命令,然后调用call函数。Redis支持的命令定义在redis.c的变量redisCommandTable中。
call函数是redid执行命令的核心函数。其中具体执行命令的语句是
c->cmd->proc();//lookupCommand函数查找到的命令处理函数
Redis在本地执行完命令后,如果需要将数据写入AOF文件,或者将数据发送给slave服务器,则调用propagate函数。propagate函数会调用feedAppendOnlyFile和replicationFeedSlaves,通过函数名即能确认两个函数具体功能。
feedAppendOnlyFile函数将命令存入缓存,在本次事件循环结束后,进入下次事件循环之前,redis调用beforeSleep函数时会将缓存写入本地磁盘,具体细节可参考Redis持久化相关介绍。replicationFeedSlaves调用addReply,最终调用aeCreateFileEvent创建一个Socket事件将命令同步到slave.这个事件将在下次事件循环时处理,具体执行的函数将是sendReplyToClient。
现在转回来看c->cmd->proc();以zadd命令为例:
zadd命令对应的函数是zaddCommand,具体实现函数是zaddGenericCommand,其在内存中修改完zset数据(请参考zset实现介绍)后,同样也调用addReply(通过addReplyLongLong)回复客户端,Redis在aeMain的下一次循环时处理对应产生的socket事件。
以上即Redis处理客户端命令的整个过程。需要说明的是,对于每个写操作命令来说,Redis回复客户端之前,将会在内存中更新命令结果,同时可以选择是否同步将命令写入磁盘(可以在beforeSleep函数中会将AOFbuffer写入磁盘,具体参考Redis持久化介绍),然后才会回复客户端,并将命令更新结果同步到slave。
深入理解Redis:命令处理流程的更多相关文章
- REdis命令处理流程处理分析
分析版本:REdis-5.0.4. REdis命令处理流程可分解成三个独立的流程(不包括复制和持久化): 1) 接受连接请求流程: 2) 接收请求数据和处理请求流程,在这个过程并不会发送处理结果给Cl ...
- redis 命令的调用过程
参考文献: Redis 是如何处理命令的(客户端) 我是如何通过添加一条命令学习redis源码的 从零开始写redis客户端(deerlet-redis-client)之路--第一个纠结很久的问题,r ...
- 深入理解Redis:底层数据结构
简介 redis[1]是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...
- Netty开发redis客户端,Netty发送redis命令,netty解析redis消息
关键字:Netty开发redis客户端,Netty发送redis命令,netty解析redis消息, netty redis ,redis RESP协议.redis客户端,netty redis协议 ...
- 深入理解redis复制原理
原文:深入理解redis复制原理 1.复制过程 2.数据间的同步 3.全量复制 4.部分复制 5.心跳 6.异步复制 1.复制过程 从节点执行 slaveof 命令. 从节点只是保存了 slaveof ...
- Redis(二):redis命令构建及关键属性解析
上一篇文章,我们从框架层面,主要介绍了redis的启动过程,以及主要的命令处理流程逻辑.这些更多的都是些差不多的道理,而要细了解redis,则需要更细节的东西. 今天我们稍微内围的角度,来看看几个命令 ...
- Redis命令拾遗二(散列类型)
本文版权归博客园和作者吴双共同所有,欢迎转载,转载和爬虫请注明原文地址 :博客园蜗牛NoSql系列地址 http://www.cnblogs.com/tdws/tag/NoSql/ Redis命令拾 ...
- Shell命令和流程控制
Shell命令和流程控制 在shell脚本中可以使用三类命令: 1)Unix 命令: 虽然在shell脚本中可以使用任意的unix命令,但是还是由一些相对更常用的命令.这些命令通常是用来进行文件和文字 ...
- Redis命令
redis的常用命令主要分为两个方面.一个是键值相关命令.一个是服务器相关命令(redis-cli进入终端) 1.键值相关命令 keys * 取出当前所有的key exists name 查看n是否有 ...
随机推荐
- openstack 排错
1.查看日志 grep ERROR /var/log/keystone/keystone.log 2. # nova list ERROR:n/a (http 404) 检查环境变量是否正确.
- iOS - UIKit
1.UIKit 框架基本结构 1)控件 屏幕上的所有 UI 元素都叫做控件(也有叫做视图.组件),比如按钮(UIButton).文本(UILabel)都是控件. 为了便于开发者打造各式各样的优秀 Ap ...
- HDU 5119
被一个学长逼着做的题...谢谢他了~ 题中dp[i][j] i即为第i个数,j为当前输入的数能xor到的数 同时一个数有两种选择,1.not xor 2.xor 最大的j不会超过11...11b( ...
- Python学习(5)条件语句
目录 Python 条件语句 Python 简单的语句组 Python 条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 可以通过下图来简单了 ...
- Python循环嵌套
可以在循环体内嵌入其他的循环体,如在while循环中可以嵌入for循环, 反之,你可以在for循环中嵌入while循环. 实例: 以下实例使用了嵌套循环输出3~13之间的素数: 以上实例输出结果: F ...
- FragmentPagerAdapter与FragmentStatePagerAdapter区别
在一个 Android 应用中,我使用 FragmentPagerAdapter 来处理多 Fragment 页面的横向滑动.不过我碰到了一个问题,即当 Fragment 对应的数据集发生改变时,我希 ...
- white-space: nowrap
CSS:需要加上宽度(width:100px).超出隐藏(overflow:hidden;).强制在同一行显示(white-space: nowrap;).省略号(text-overflow:elli ...
- OpenGL的GLUT初始化函数[转]
OpenGL的GLUT初始化函数 void glutInit(int* argc,char** argv) 初始化GLUT库.对应main函数的形式应是:int main(int argc,char* ...
- ajax请求超时时间
http://www.cnblogs.com/charling/p/3356216.html get post 请求 http://www.cnblogs.com/oneword/archive/20 ...
- CSS学习笔记(float和盒子模型)
1.当元素或者是它的包裹层设置了绝对定位或者是浮动,那么margin:0 auto;自动居中的效果就不会实现. 2.盒子模型的三位立体结构图中从第一层到第五层依次为:border.content+pa ...