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:命令处理流程的更多相关文章

  1. REdis命令处理流程处理分析

    分析版本:REdis-5.0.4. REdis命令处理流程可分解成三个独立的流程(不包括复制和持久化): 1) 接受连接请求流程: 2) 接收请求数据和处理请求流程,在这个过程并不会发送处理结果给Cl ...

  2. redis 命令的调用过程

    参考文献: Redis 是如何处理命令的(客户端) 我是如何通过添加一条命令学习redis源码的 从零开始写redis客户端(deerlet-redis-client)之路--第一个纠结很久的问题,r ...

  3. 深入理解Redis:底层数据结构

    简介 redis[1]是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...

  4. Netty开发redis客户端,Netty发送redis命令,netty解析redis消息

    关键字:Netty开发redis客户端,Netty发送redis命令,netty解析redis消息, netty redis ,redis RESP协议.redis客户端,netty redis协议 ...

  5. 深入理解redis复制原理

    原文:深入理解redis复制原理 1.复制过程 2.数据间的同步 3.全量复制 4.部分复制 5.心跳 6.异步复制 1.复制过程 从节点执行 slaveof 命令. 从节点只是保存了 slaveof ...

  6. Redis(二):redis命令构建及关键属性解析

    上一篇文章,我们从框架层面,主要介绍了redis的启动过程,以及主要的命令处理流程逻辑.这些更多的都是些差不多的道理,而要细了解redis,则需要更细节的东西. 今天我们稍微内围的角度,来看看几个命令 ...

  7. Redis命令拾遗二(散列类型)

    本文版权归博客园和作者吴双共同所有,欢迎转载,转载和爬虫请注明原文地址 :博客园蜗牛NoSql系列地址  http://www.cnblogs.com/tdws/tag/NoSql/ Redis命令拾 ...

  8. Shell命令和流程控制

    Shell命令和流程控制 在shell脚本中可以使用三类命令: 1)Unix 命令: 虽然在shell脚本中可以使用任意的unix命令,但是还是由一些相对更常用的命令.这些命令通常是用来进行文件和文字 ...

  9. Redis命令

    redis的常用命令主要分为两个方面.一个是键值相关命令.一个是服务器相关命令(redis-cli进入终端) 1.键值相关命令 keys * 取出当前所有的key exists name 查看n是否有 ...

随机推荐

  1. php笔记[2]

    strlen()函数获得字符窜的长度 读取文件:fgets(),fgetss()和fgetcsv() 读取整个文件:readfile(),fpassthru()和file() 读取一个字符:fgetc ...

  2. iOS - OC NSPoint 位置

    前言 结构体,这个结构体用来表示事物的一个坐标点. typedef CGPoint NSPoint; struct CGPoint { CGFloat x; CGFloat y; }; typedef ...

  3. windos多线程编程

    随机数滚动发生器 #include <stdio.h> #include <Windows.h> #include <ctime> #include <pro ...

  4. 使用连接来代替in和not in(使用外连接技巧)

    比如:表A里面的一个字段叫做MOBILE 里面存的记录如下 : 123456781 表B里面的一个字段也叫做MOBILE里面存的记录如下 12341910   (1)我们要查询一下A和B里面都有的,以 ...

  5. JavaWeb学习总结(四)—ServletConfig和ServletContext

    一.ServletConfig 1. ServletConfig介绍: ServletConfig是Servlet中的init()方法的参数类型,服务器会在调用init()方法时传递ServletCo ...

  6. 基本分类方法——KNN(K近邻)算法

    在这篇文章 http://www.cnblogs.com/charlesblc/p/6193867.html 讲SVM的过程中,提到了KNN算法.有点熟悉,上网一查,居然就是K近邻算法,机器学习的入门 ...

  7. Android Contacts (android通讯录读取)-content provider

    Content Provider 在数据处理中,Android通常使用Content Provider的方式.Content Provider使用Uri实例作为句柄的数据封装的,很方便地访问地进行数据 ...

  8. UEditor文档

    UEditor文档http://fex.baidu.com/ueditor/Ueditor 前后端数据交互 http://blog.csdn.net/bobo_93/article/details/5 ...

  9. 销售 >> 当今社会生产力最大的源泉为 >>自助服务 与推销员随之消失

    销售可能是变化最大的企业职能.比如,经济学家喜欢提出陷阱问题“什么概念或者想法成为当今社会生产力最大的源泉?” 大多数人回答计算机,  正确的回答是自助服务与推销员随之消失               ...

  10. React Native For Android 架构初探

    版权声明:本文由王少鸣原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/171 来源:腾云阁 https://www.qclo ...