zoukankan      html  css  js  c++  java
  • Redis12:客户端

    客户端

    对于每个与服务器进行连接的客户端,服务器都为这些客户端建立了相应的redisClient结构,这个结构代表客户端状态,redis服务器状态结构的clients属性记录了所有与服务器连接的客户端的状态结构,它是一个链表,如一个服务器与三个客户端连接:

    客户端状态包含的属性可以分为两类:一类是比较通用的属性,和特定功能基本不相关,一类是和特定功能相关的属性。这里主要介绍第一类属性。

    客户端属性

    套接字描述符

    在redisClient中,int类型的fd代表对应客户端的套接字描述符。

    如果fd是-1,代表该客户端为伪客户端,伪客户端处理的命令请求来源于AOF文件或Lua脚本,而不是网络。

    如果fd是大于-1的整数,就代表该客户端为普通客户端。

    执行下列命令可以列出所有连接到服务器的普通客户端:

    client list
    

    命令执行后会显示很多结果,包括每个服务器的fd(套接字描述符)、name(客户端名)、age(已经连接的秒数)、idle(空转秒数:距离客户端与服务器最后一次进行互动以来过去的秒数)

    客户端名字

    默认一个连接到服务器的客户端是没有名字的,需要执行下列命令来为客户端设置一个名字:

    client setname 名
    

    名字可以根据客户端的作用来自定义。

    标志

    标志属性是int类型的,名字为flags,它的值通常都是一个常量,标志属性记录了客户端的角色和客户端所处的状态,以下是一些flags属性的例子:

    REDIS_MASTER代表客户端是一个主服务器。

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

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

    (这个值有时会用或来代表同时处于多个状态)

    输入缓冲区

    客户端的输入缓冲区是用来保存客户端发送的命令的,它的类型是sds,名字为querybuf。当客户端向服务器发送命令请求时,服务器的客户端状态的querybuf就会记录该命令的协议值,它最大不能超过1G,否则服务器就会关闭这个客户端。

    命令和命令参数

    服务器将命令请求保存在客户端状态的querybuf属性后,就会对命令内容进行分析,将分析得出的命令参数及命令参数个数保存在客户端的argv属性和argc属性,argv是一个数组类型,它的每一项都是一个字符串对象,其中第一项是要执行的命令,后面是命令的参数,而argc负责记录argv数组的长度。

    如客户端发送的命令是set key value,那么argv和argc属性就分别是:

    命令的实现函数

    在得到上述属性后,服务器会根据argv[0]的值,在命令表中查找命令所对应的命令实现函数。

    命令表是一个字典,输入一个SDS命令名称,就能找到一个redisCommand结构,客户端的cmd指针就会指向这个结构。至此,服务器的客户端状态已经拥有了命令参数信息、命令参数、执行命令对应的实现函数。

    输出缓冲区

    输出缓冲区用来装入服务器发回来的命令执行结果的。每个客户端都有两个输出缓冲区可用,一个是固定大小的缓冲区,一个是可变大小的缓冲区。

    固定大小的缓冲区由一个名为REDIS_REPLY_CHUNK_BYTES的char数组和一个名为bufpos的int数组成,前者是一个大小为16KB的缓冲区,后者记录了该缓冲区中目前使用的字节数量。

    当数组空间已经用完或者结果太大无法放入其中时,服务器就会开始使用可变大小缓冲区,可变大小缓冲区由一个reply链表组成,这个链表连接了多个字符串对象,可以保存非常长的结果。

    身份验证

    客户端状态有一个名为authenticated的int数,它用于记录客户端是否通过了验证。

    如果该值是0,代表未通过验证,是1代表通过验证。如果未通过验证的客户端向服务器发送命令,那么除了auth外的所有命令服务器都会拒绝执行,只有客户端向服务器发送auth命令成功进行身份验证后,该值从0变成1,才能恢复正常。

    默认只有在服务器启用了身份验证功能时才能使用,如果未启用该功能那么该值默认是0.

    时间

    客户端状态有几个和时间相关的属性:

    ctime记录了创建客户端的时间、lastinteraction记录了客户端与服务器最后一次互动的时间、obuf_soft_limit_reached_time记录了输出缓冲区第一次达到软性限制soft limit的时间。

    通过这三个时间,可以计算出客户端的存活时间age和空转时间idle。

    客户端的创建和关闭

    普通客户端的创建和关闭

    客户端使用connect函数连接到服务器时,服务器就会调用连接事件处理器,为客户端建立相应的客户端状态,并将这个新的客户端状态添加到服务器状态结构clients链表的末尾。

    普通客户端关闭的原因有多种:

    1、客户端进程退出或被杀死

    2、客户端向服务器发送了不符合协议格式的命令请求

    3、对某个客户端执行client kill

    4、如果用户为服务器设置了timeout配置选项,当客户端的空转时间超过timeout选项设置的值时,客户端将被关闭

    5、客户端发送的命令请求超过了输入缓冲区的限制大小(默认为1GB),或命令回复超出了输出缓冲区的限制大小,客户端将被关闭

    客户端的可变大小输出缓冲区理论上可以保存任意长的命令回复,为了避免回复过大,占用太多的服务器资源,服务器会时刻检查输出缓冲区的大小,相关的模式有两种:

    1、硬性模式hard limit:如果输出缓冲区的大小超过了硬性模式规定的大小,那么服务器立即关闭客户端

    2、软性模式soft limit:如果输出缓冲区的大小超过了软性模式规定的大小,但还没超过硬性模式限制,那么服务器将记录下obuf_soft_limit_reached_time,也就是达到软性限制的起始时间,然后继续监视客户端,如果在规定时间内不再超出软性限制那么客户端就不会被关闭,如果一直超出软性限制那么客户端就会被关闭。

    在配置文件中可以设置硬性模式和软性模式的参数,以及针对的客户端类型:

    不限制普通客户端的输出缓冲区:
    client-output-buffer-limit normal 0 0 0
    限制从服务器客户端:
    client-output-buffer-limit slave 256mb 64mb 60
    限制执行发布与订阅功能的客户端:
    client-output-buffer-limit pubsub 32mb 8mb 60
    

    其他客户端的创建和关闭

    对于Lua脚本的伪客户端,服务器会在初始化时创建负责执行Lua脚本中包含的redis命令的伪客户端,关联在redisServer中的名为lua_client的redisClient类型中。它在服务器运行的整个生命周期都存在,直到服务器被关闭它才会被关闭。

    服务器在载入AOF文件时,会创建对应的伪客户端,载入完成后关闭这个客户端。

  • 相关阅读:
    【C++11】准备:gcc 4.9.0编译安装
    【转】C++ 虚函数表解析
    【工作总结】内存泄漏总结
    【工作总结】C++ string工具类
    工作总结
    【工作笔记】CxImage简介
    【工作笔记】没有界面程序调用ActiveX控件
    【工作笔记】npapi插件编写
    【工作笔记】VLC播放器在chrome中的调用
    Linux多任务编程之三:exec函数族及其基础实验(转)
  • 原文地址:https://www.cnblogs.com/yinyunmoyi/p/11523758.html
Copyright © 2011-2022 走看看