第13章 客户端


对于每个与服务器进行连接的客户端,服务器都为这些客户端建立相应的redis.h/redisClient结构


1.客户端属性


/*
 * 客户端结构
 *
 * 为每个连接到服务器的客户端保存维持一个该结构的映射,
 * 从而实现多路复用。
 */
typedef struct redisClient {

    // socket 文件描述符
    int fd;

    // 指向当前目标数据库的指针
    redisDb *db;

    // 当前目标数据库的号码
    int dictid;

    // 查询缓存
    sds querybuf;
    size_t querybuf_peak;   /* Recent (100ms or more) peak of querybuf size */

    // 参数的个数
    int argc;

    // 字符串表示的命令,以及命令的参数
    robj **argv;

    // 命令,以及上个命令
    struct redisCommand *cmd, *lastcmd;

    // 回复类型
    int reqtype;
    int multibulklen;       /* number of multi bulk arguments left to read */
    long bulklen;           /* length of bulk argument in multi bulk request */

    // 保存回复的链表
    list *reply;
    // 链表中保存的所有回复的总字节大小
    unsigned long reply_bytes; /* Tot bytes of objects in reply list */

    // 统计数据
    int sentlen;
    time_t ctime;           /* Client creation time */
    time_t lastinteraction; /* time of the last interaction, used for timeout */
    time_t obuf_soft_limit_reached_time;
    int flags;              /* REDIS_SLAVE | REDIS_MONITOR | REDIS_MULTI ... */

    // 复制功能相关
    int slaveseldb;         /* slave selected db, if this client is a slave */
    int authenticated;      /* when requirepass is non-NULL */
    // 客户端当前的同步状态
    int replstate;          /* replication state if this is a slave */
    // 同步数据库的文件描述符
    int repldbfd;           /* replication DB file descriptor */
    // 同步数据库文件的偏移量
    long repldboff;         /* replication DB file offset */
    // 同步数据库文件的大小
    off_t repldbsize;       /* replication DB file size */
    int slave_listening_port; /* As configured with: SLAVECONF listening-port */

    // 事务实现
    multiState mstate;      /* MULTI/EXEC state */

    // 阻塞状态
    blockingState bpop;   /* blocking state */
    list *io_keys;          /* Keys this client is waiting to be loaded from the
                             * swap file in order to continue. */

    // 被监视的 KEY
    list *watched_keys;     /* Keys WATCHED for MULTI/EXEC CAS */

    // 订阅与发布
    dict *pubsub_channels;  /* channels a client is interested in (SUBSCRIBE) */
    list *pubsub_patterns;  /* patterns a client is interested in (SUBSCRIBE) */

    /* Response buffer */
    // 回复缓存的当前缓存
    int bufpos;
    // 回复缓存,可以保存多个回复
    char buf[REDIS_REPLY_CHUNK_BYTES];
} redisClient;

1.1 套接字描述符

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

根据客户端类型不同,fd属性的值可以是-1或者大于-1的整数:
  • 伪客户端为-1 AOF文件,Lua脚本
  • 普通客户端大于-1的整数:记录客户端套接字的描述符。

1.2 名字

在默认情况下,一个连接到服务器的客户端是没有名字的    CLIENT list CLIENT setname

1.3 标志

flags记录客户端的角色,以及客户端目前所处的状态


1.4 输入缓冲区

用于保存客户端发送的命令请求


1.5 命令与命令参数

argv  argv[0]命令 ,其他参数
argc 参数个数,包括argv[0]


1.6 命令的实现函数




针对命令表的查找操作不区分输入字母的大小写

1.7 输出缓冲区

执行命令所得的命令回复会被保存在客户端状态的输出缓冲区里面,每个客户端都有两个输出缓冲区可用,一个缓冲区的大小是固定的,另一个缓冲区的大小是可变的:
  • 固定大小的缓冲区用于保存那些长度比较小的回复,比如OK,简短的字符串值、整数值、错误回复等
  • 可变大小的缓冲区用于保存那些长度比较大的回复,比如一个非常长的字符串值,一个由很多项组成的列表,一个包含了很多元素的集合等等

固定缓冲区由buf和bufpos两个属性组成。
可变大小缓冲区由reply链表和一个或多个字符串对象组成


1.8 身份验证

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


仅在服务器启用了身份验证功能时使用。

1.9 时间


2.客户端的创建与关闭

2.1 创建普通客户端

2.2 关闭普通客户端

被关闭原因:
  • 客户端进程退出或者被杀死
  • 客户端向服务器发送了带有不符合协议格式的命令请求
  • 客户端成为了CLIENT KILL命令的目标
  • 服务器设置了timeout配置选项,那么当客户端的空转时间超过timeout选项设置的值时,客户端将被关闭。
  • 客户端发送的命令请求的大小超过了输入缓冲区的限制大小(默认为1GB)
  • 要发送给客户端的命令回复的大小超过了输出缓冲区的限制大小
服务器使用两种模式来限制客户端输出缓冲区的大小:
  • 硬性限制:超过硬性限制,立即关闭客户端
  • 软性限制:超过软性限制,没有超过硬性限制,obuf_soft_limit_reached_time属性记录客户端达到软性限制的起始时间;之后服务器继续监视客户端,如果输出缓冲区的大小超出软性限制,并且持续时间超过服务器设定的时长,那么服务器将关闭客户端;相反,在指定时间之内,不在超出软性限制,客户端就不会被关闭,并且obuf_soft_limit_reached_time属性的值也会被清0.

2.3 Lua脚本的伪客户端


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

2.4 AOF文件的伪客户端

在载入完成后,关闭这个伪客户端



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值