首页
|
新闻
|
新品
|
文库
|
方案
|
视频
|
下载
|
商城
|
开发板
|
数据中心
|
座谈新版
|
培训
|
工具
|
博客
|
论坛
|
百科
|
GEC
|
活动
|
主题月
|
电子展
注册
登录
论坛
博客
搜索
帮助
导航
默认风格
uchome
discuz6
GreenM
»
MCU 单片机技术
»
PowerPC
» 深入浅出 Redis client/server交互流程(1)
返回列表
回复
发帖
发新话题
发布投票
发布悬赏
发布辩论
发布活动
发布视频
发布商品
深入浅出 Redis client/server交互流程(1)
发短消息
加为好友
look_w
当前离线
UID
1066743
帖子
8283
精华
0
积分
4142
阅读权限
90
在线时间
233 小时
注册时间
2017-6-23
最后登录
2019-5-18
论坛元老
UID
1066743
1
#
打印
字体大小:
t
T
look_w
发表于 2018-12-24 16:45
|
只看该作者
深入浅出 Redis client/server交互流程(1)
综述最近笔者阅读并研究redis源码,在redis客户端与服务器端交互这个内容点上,需要参考网上一些文章,但是遗憾的是发现大部分文章都断断续续的非系统性的,不能给读者此交互流程的整体把握。所以这里我尝试,站在源码的角度,将redis client/server 交互流程尽可能简单地展现给大家,同时也站在DBA的角度给出一些日常工作中注意事项。
Redis client/server 交互步骤分为以下6个步骤:
一、Client 发起socket 连接
二、Server 接受socket连接
三、客户端 开始写入
四、server 端接收写入
五、server 返回写入结果
六、Client收到返回结果
注:为使文章尽可能简洁,这里只讨论客户端命令写入的过程,不讨论客户端命令读取的流程。
在进一步阅读和了解互动流程之前,请大家确保已经熟练掌握了
Linux Socket 建立流程和epoll I/O 多路复用技术
两个技术点,这对文章内容的理解至关重要。
交互的整体流程在介绍6个步骤之前,首先看一下redis client/server 交互流程整体的程序执行流程图:
(点击放大图像)
上图中6个步骤分别用不同的颜色箭头表示,并且最终结果也用相对应的颜色标识。
首先看看绿色框里面的循环执行的方法,最末是epoll_wait方法,即等待事件产生的方法。然后再看第2、4、5步骤的末尾都有epoll_ctl方法,即epoll事件注册函数。关于epoll的相关技术解析请参看文末一段。
在这里的循环还有个beforeSleep方法,其实它跟我们这次讨论的话题没有太大的关系。但是还是想给大家介绍一下。
beforeSleep方法主要做以下几件事:
执行一次快速的主动过期检查,检查是否有过期的key
当有客户端阻塞时,向所有从库发送ACK请求
unblock 在同步复制时候被阻塞的客户端
尝试执行之前被阻塞客户端的命令
将AOF缓冲区的内容写入到AOF文件中
如果是集群,将会根据需要执行故障迁移、更新节点状态、保存node.conf 配置文件。
如此,redis整个事件管理器机制就比较清楚了。接下来进一步探讨并理解事件是如何触发并创建。
交互的六大步骤下面正式开始介绍redis client/server 交互的6大步骤
一、Client 发起socket 连接(点击放大图像)
这里以redis-cli 客户端为例,当执行以下语句时:
[root@zbdba redis-3.0]
#
./src/redis-cli -p 6379 -h 127.0.0.1
127.0.0.1:6379>
客户端会做如下操作:
1、获取客户端参数,如端口、ip地址、dbnum、socket等
也就是我们执行./src/redis-cli --help 中列出的参数
2、根据用户指定参数确定客户端处于哪种模式
目前共有:
Latency mode/Slave mode/Get RDB mode/Pipe mode/
Find big keys
/Stat mode/Scan mode/Intrinsic latency mode
以上8种模式例如:stat 模式
[url=]
[/url]
[root@zbdba redis-3.0]
#
./src/redis-cli -p 6379 -h 127.0.0.1 --stat
------- data ------ --------------------- load -------------------- - child -
keys mem clients blocked requests connections
1 817.18K 2 0 1 (+0) 2 1 817.18K 2 0 2 (+1) 2 1 817.18K 2 0 3 (+1) 2 1 817.18K 2 0 4 (+1) 2 1 817.18K 2 0 5 (+1) 2 1 817.18K 2 0 6 (+1) 2[url=]
[/url]
我们这里没有指定,就是默认的模式。
3、进入上图中step1的cliConnect 方法,cliConnect主要包含redisConnect、redisConnectUnix方法。这两个方法分别用于TCP Socket连接以及Unix Socket连接,Unix Socket用于同一主机进程间的通信。我们上面是采用的TCP Socket连接方式也就是我们平常生产环境常用的方式,这里不讨论Unix Socket连接方式,如果要使用Unix Socket连接方式,需要配置unixsocket 参数,并且按照下面方式进行连接:
[root@zbdba redis-3.0]
#
./src/redis-cli -s /tmp/redis.sock
redis /tmp/redis.sock>
4、进入redisContextInit方法,redisContextInit方法用于创建一个Context结构体保存在内存中,如下:
[url=]
[/url]
/* Context
for
a connection to Redis */
typedef struct redisContext { int err;
/* Error flags, 0 when there
is
no error */
char errstr[
128]; /* String representation of error when applicable */
int fd; int flags; char
*obuf; /* Write buffer */
redisReader
*reader; /* Protocol reader */
} redisContext;
[url=]
[/url]
主要用于保存客户端的一些东西,最重要的就是 write buffer和redisReader,write buffer 用于保存客户端的写入,redisReader用于保存协议解析器的一些状态。
5、进入redisContextConnectTcp 方法,开始获取IP地址和端口用于建立连接,主要方法如下:
s = socket(p->ai_family,p->ai_socktype,p->
ai_protocolconnect(s,p
->ai_addr,p->ai_addrlen)
到此客户端向服务端发起建立socket连接,并且等待服务器端响应。
当然cliConnect方法中还会调用cliAuth方法用于权限验证、cliSelect用于db选择,这里不着重讨论。
收藏
分享
评分
回复
引用
订阅
TOP
返回列表
电商论坛
Pine A64
资料下载
方案分享
FAQ
行业应用
消费电子
便携式设备
医疗电子
汽车电子
工业控制
热门技术
智能可穿戴
3D打印
智能家居
综合设计
示波器技术
存储器
电子制造
计算机和外设
软件开发
分立器件
传感器技术
无源元件
资料共享
PCB综合技术
综合技术交流
EDA
MCU 单片机技术
ST MCU
Freescale MCU
NXP MCU
新唐 MCU
MIPS
X86
ARM
PowerPC
DSP技术
嵌入式技术
FPGA/CPLD可编程逻辑
模拟电路
数字电路
富士通半导体FRAM 铁电存储器“免费样片”使用心得
电源与功率管理
LED技术
测试测量
通信技术
3G
无线技术
微波在线
综合交流区
职场驿站
活动专区
在线座谈交流区
紧缺人才培训课程交流区
意见和建议