Redis服务器是典型的一对多服务器程序:一个服务器可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回复。

通过使用由I/O多路复用技术实现的文件事件处理器,Redis服务器使用单线程单进程的方式处理命令请求,并于多个客户端进行网络通信。

每个与服务器进行连接的客户端,服务端都为这些客户端建立相应的redisClient结构(客户端状态),保存客户端当前的状态信息,以及执行相关功能时需要用到的数据结构。

Redis服务器状态结构的clients属性是一个链表,这个链表保存了所有与服务器连接的客户端的状态结构,对客户端执行批量操作,或者查找某个指定的客户端,都可以通过遍历clients链完成。

struct redisServer{
//一个链表,保存了所有客户端状态
list *clients;
}

1、客户端状态的fd属性记录了客户端正在使用的套接字描述符

typedef struct redisClient{
int fd;
} redisClient;

根据客户端的类型不同fd的属性值可以是-1,或者是大于-1的整数:伪客户端fd属性为-1;普通客户端的fd属性值为大于-1的整数。

2、默认情况下一个连接到服务器的客户端是没有名称的, 可以使用Client setname 命令为客户端设置一个名称。

3、客户端的标志属性flags记录了客户端角色(role),以及客户端状态

typedef struct redisClient{
int flag;
} redisClient;

在主从服务器进行复制操作时,主服务器会成为从服务器的客户端,而从服务器也会成为主服务器的客户端。

REDIS_MASTER 客户端是一个主服务器

REDIS_BLOCKED 客户端正在被列表命令阻塞

REDIS_MULTI | REDIS_DIRTY_CAS 客户端正在执行事务,但事务的安全性已经被破坏

REDIS_SLAVE | REDOS_PRE_PSYNC 客户端是一个从服务器,并且版本低于REDIS2.8

REDIS_LUA_CLIENT | REDIS_FORCE_AOF | REDIS_FORCE_REPL 这是专门执行Lua脚本包含的redis命令的伪客户端 ,它强制服务器将当前执行的命令写入到AOF文件,并复制给从服务器。

4、客户端状态的输入缓冲区用户保存客户端发送的命令请求:

typedef struct redisClient {
sds querybuf;
} redisClient;

5、在服务器将客户端发送的命令请求保存在客户端状态的querybuf属性后,服务器将对命令请求的内容进行分析,并将得出的命令参数以及命令参数的个数分别保存到客户端状态的argv属性和argc属性

typedef struct redisClient{
robj **argv;
int argc;
} redisClient;

argv属性是一个数组,数组的每个项都是一个字符串队形,其中avgv[0]是要执行的命令,其之后的其他项都是传给命令的参数。

6、当服务器从协议内容中分析并得出argv属性和argc属性的值之后,服务器将根据项argv[0]的值,在命令表中查找命令所对应的实现函数。

命令表是一个字典表,字典的键是一个SDS结构,保存了命令的名字,字典值是命令的名字,字典值是命令所对应的redisCommand结构,这个结构保存了命令的实现函数、命令的标志、命令应该给定的参数个数、命令的总执行次数和总耗时长等统计信息。

当程序在命令表中成功找到argv[0]所对应的redisCommand结构时,它会将客户端状态的cmd指针指向这个结构:

typedef struct redisClient{
struct redisCommand *cmd;
} redisClient;

之后,服务器就可以使用cmd属性所指向的redisCommand结构,以及argv、argc属性中保存的命令参数信息,调用命令实现函数,执行客户端指定的命令。

7、执行命令所得的命令回复会被保存在客户端状态的输出缓冲区里面,每个客户端有两个输出缓冲区可以用,一个缓冲区的大小是固定的,一个大小是可变的。

固定大小的缓冲区用于保存那些长度比较小的回复,可变大小的缓冲区用于保存耐饿长度比较大的回复。

客户端的固定大小缓冲区由buf和bufpos两个属性组成

typedef struct redisClient{
char buf[REDIS_REPLY_CHUNK_BYTES];//REDIS_REPLY_CHUNK_BYTES 默认16 *1024 也就是说固定缓冲区默认 16k
int bufpos;//记录已使用的字节数量
} redisClient;

8、身份认证

客户端状态的authenticated属性用于记录客户端是否通过了身份验证:

typedef struct redisClient{
int authenticated;
} redisClient;

authenticated属性仅在服务器启用了身份验证功能的时候使用,如果服务器没有启用的话,即使为0也不会拒绝客户端的命令请求。

9、时间

typedef struct redisClient{
time_t ctime;//创建客户端的时间 连接服务器时长(秒)
time_t lastinteraction;//最后一次与服务器互动时间,计算客户端空转时间
//记录缓冲区第一次到达软性限制的时间
time_t obuf_soft_limit_reached_time;
} redisClient;

如果客户端是通过网络连接于服务器进行连接的普通客户端,那么客户端使用connect函数连接到服务器时,服务器就会调用连接事件处理器,为客户端创建相应的客户端状态,并将这个新的客户端状态添加到服务器状态结构clients链表的末尾。

普通客户端可以因为多种原因而被关闭:

客户端进程退出或者被杀死,那么客户端与服务端的网络连接被关闭。

如果客户端向服务端发送了带有不符合协议的命令请求,那么这个客户端也会被关闭。

如果客户端成为了CLIENT KILL命令的目标,那么它也会被关闭。

如果服务端设置了timeout配置项,那么客户端的空转事件超过timeout现象设置的值时,客户端被关闭。

如果客户端发送的命令请求的大小超过了输入缓冲区的限制大小(默认1G),那么客户端会被服务器关闭。

如果要发送给客户端的命令回复的大小超过了输出缓冲区的限制大小,那么这个客户端会被服务器关闭。

服务器使用两种模式来限制客户端输出缓冲区的大小:

1、硬性限制,如果输出缓冲区的大小超过了硬性限制所设置的大小,那么服务器立即关闭客户端。

2、软性限制,如果输出缓冲区的大小超过了软性限制设置的大小,但没有超过硬性设置的大小,obuf_soft_limit_reached_time属性记录下客户端达到软性限制的起始事件,之后服务器会继续监视客户端,如果输出缓冲区的大小一直超出软性限制,并且持续时间超过服务器设置的时长,那么服务器将关闭客户端。

服务端会在初始化时创建负责执行Lua脚本中包含redis命令的伪客户端,并将这个伪客户端关联在服务器状态结构的lua_client属性中:

struct redisServer{
redisClient *lua_client;
}

lua_client 伪客户端在服务器运行的整个声明周期中会一直存在,只有服务器关闭时,这个客户端才会关闭。

服务器在载入AOF文件时,会创建用于执行AOF文件的Redis命令的伪客户端,并在载入完成之后,关闭伪客户端。


每天学一点,总会有收获。

说明:尊重作者知识产权,文中内容参考《Redis设计与实现》,仅在此做学习与大家分享。


Redis学习笔记(十) 客户端的更多相关文章

  1. Redis学习笔记十:独立功能之监视器

    通过执行 monitor 命令可以让客户端自己变成一个监视器,实时接收并打印当前处理的命令请求的相关信息. 127.0.0.1:6379> monitor OK 1451752646.83727 ...

  2. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  3. redis 学习笔记-cluster集群搭建

    一.下载最新版redis 编译 目前最新版是3.0.7,下载地址:http://www.redis.io/download 编译很简单,一个make命令即可,不清楚的同学,可参考我之前的笔记: red ...

  4. Redis学习笔记~目录

    回到占占推荐博客索引 百度百科 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...

  5. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

  6. Redis学习笔记7--Redis管道(pipeline)

    redis是一个cs模式的tcp server,使用和http类似的请求响应协议.一个client可以通过一个socket连接发起多个请求命令.每个请求命令发出后client通常会阻塞并等待redis ...

  7. (转)redis 学习笔记(1)-编译、启动、停止

    redis 学习笔记(1)-编译.启动.停止   一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...

  8. Redis 学习笔记4: Redis 3.2.1 集群搭建

    在CenOS 6.7 linux环境下搭建Redis 集群环境 1.下载最新的Redis版本 本人下载的Redis版本是3.2.1版本,下载之后,解压,编译(make): 具体操作可以参考我的博文:R ...

  9. Redis学习笔记(2)——Redis的下载安装部署

    一.下载Redis Redis的官网下载页上有各种各样的版本,如图 但是官网下载的Redis项目不正式支持Windows.如果需要再windows系统上部署,要去GitHub上下载.我下载的是Redi ...

  10. Redis学习笔记(1)- CentOS 6.4 安装Redis

    Redis学习笔记(1)- CentOS 6.4 安装Redis 2013.10.13     学习环境 vm 10.1 + 默认.新装的干净 CentOS 6.4  64BIT系统     准备 1 ...

随机推荐

  1. Java去除ArrayList集合中重复字符串的案例

    ArrayList去除集合中的字符串重复值 分析: A:创建集合对象 B:添加多个字符串元素 C:创建新集合 D:遍历旧集合,获取得到每一个元素 E:拿着个元素到新集合去找,看有没有 有:不进去 没有 ...

  2. System类的两个静态方法currentTimeMillis 和 arraycopy

    package com.yhqtv.demo02.ThreadPool; import java.util.Arrays; public class Test { public static void ...

  3. HTTPS之密钥知识与密钥工具Keytool和Keystore-Explorer

    1 简介 之前文章<Springboot整合https原来这么简单>讲解过一些基础的密码学知识和Springboot整合HTTPS.本文将更深入讲解密钥知识和密钥工具. 2 密钥知识-非对 ...

  4. 带你玩linux集成环境

    据我现在知道的,在linux一键部署集成环境的应用有: “宝塔面板” “LNMP" "XRDP" 参考:http://www.ampnmp.com/ 具体什么安装就直接百 ...

  5. thinkphp5.0 url跳转

    <a href="{:url('member/index/index',['id'=>5])}">跳转</a> define()自定义常量在thiin ...

  6. 《Metasploit魔鬼训练营》第一章实践作业

    <Metasploit魔鬼训练营>第一章实践作业 1.搜集Samba服务usermap_script安全漏洞的相关信息,画出该安全漏洞的生命周期图,标注各个重要事件点的日期,并提供详细描述 ...

  7. 2019-2020-1 20199328《Linux内核原理与分析》第九周作业

    笔记部分 2019/11/12 14:45:44 从CPU和内存的角度看linux系统的运行 CPU角度:首先我们进行了系统调度,然后系统进入内核态,把信息压栈,然后我们进行进程管理,由于进入系统调用 ...

  8. Apple Watch Series 6或将增加焦虑监测和睡眠追踪功能

    一条新的泄露消息称,Apple Watch Series 6 将增加心理健康功能,延长电池续航时间,并对现有传感器进行扩展,这样设备可以测量血液含氧量.苹果即将更新的 Apple Watch 新款推测 ...

  9. Linux系统目录结构:目录层次标准、常用目录和文件

    1. 目录层次标准FHS FHS(Filesystem Hierarchy Standard)目录层次标准,是Linux的目录规范标准.   FHS定义了两层规范: 第一层:是"/" ...

  10. Ubuntu搭建NTP服务器

    NTP简介 NTP是Network Time Protocol的缩写,又称为网络时间协议.是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提 ...