一. 概述

  Redis服务器是可以与多个客户端建立网络连接,每个客户端可以向服务器发送命令请求,而服务器则接收并处理客户端发送的命令请求,并向客户端返回命令回复。通过使用I/O多路复用技术实现的文件事件处理器,Redis服务器使用单进程单线程的方式来处理命令请求,并与多个客户端进行网络通信。

  1.1 伪客户端和普通客户端

    对于每个与服务器进行连接的客户端,服务器都为这些客户端建立了相应的redis.h/redisClient结构(客户端状态),这个结构保存了客户端当前的状态信息。根据客户端类型的不同,分为伪客户端和普通客户端。伪客户端处理的命令请求来源于AOF文件或者Lua脚本,而不是网络,这种客户端不需要套接字连接。普通客户端使用套接字与服务器进行通信,下面脚本显示了全部的普通客户端:

    127.0.0.1:> client list
id= addr=127.0.0.1: fd= name= age= idle= flags=N db= sub= psub= multi=- qbuf= qbuf-free= obl= oll= omem= events=r cmd=client
id= addr=127.0.0.1: fd= name= age= idle= flags=N db= sub= psub= multi=- qbuf= qbuf-free= obl= oll= omem= events=r cmd=command

  上面脚本,当fd为-1时,就是一个伪客户端。普通客户端的fd都大于0。name代表客户端名称,默认为空,可以用client setname命令来设置一个客户端的名字,例如给当前客户端设置名称,以下脚本:

    127.0.0.1:> client setname client1
OK
127.0.0.1:> client list
id= addr=127.0.0.1: fd= name=client1 age= idle= flags=N db= sub= psub= multi=- qbuf= qbuf-free= obl= oll= omem=
   events=r cmd=client
id= addr=127.0.0.1: fd= name= age= idle= flags=N db= sub= psub= multi=- qbuf= qbuf-free= obl= oll= omem=
  events=r cmd=command

  

  1.2  flags标志

    flags记录了客户端的角色(role),以及客户端目前所处的状态,flags属性的值可以是单个标志,也可以是多个标志的二进制。客户端 flag 可以由以下部分组成:

属性值

描述

O

客户端是 MONITOR 模式下的附属节点(slave)

S

客户端是一般模式下(normal)的附属节点

M

客户端是主节点(master)

x

客户端正在执行事务

b

客户端正在等待阻塞事件

i

客户端正在等待 VM I/O 操作(已废弃

c

在将回复完整地写出之后,关闭链接

u

客户端未被阻塞(unblocked)

N

未设置任何 flag

r

客户端套接字(在事件 loop 中)是可读的(readable)

w

客户端套接字(在事件 loop 中)是可写的(writeable)

  

  1.3 输入缓冲区qbuf 与输出缓冲区 obl  

    (1)客户端状态的输入缓冲区用于保存客户端发送的命令请求,如set key value, 输入缓冲区的大小会根据输入内容动态地缩小或扩大,但它的最大空间不超过1GB,否则服务器将关闭这个客户端。

    (2)当服务端执行命令回复,会被保存在客户端状态的输出缓冲区中,每个客户端都有两个输出缓冲区可用,一个缓冲区大小是固定的,另一个缓冲区的大小是可变的。固定大小的缓冲区用于保存回复信息长度比较小的,比如OK,简短的字符串值,整数值,错误回复等。可变大小的缓冲区用于保存长度比较大的,比如一个非常长的字符串值,或一个由很多项组成的列表,或一个包含了很多元素的集合等。 固定大小的缓冲区默认为16kb。可变大小缓冲区不能超过服务器设置的硬性限制值,本篇最后client-output-buffer-limit时有讲。 omem表示输出缓存的内存占用量。

  

  1.4 身份验证

    客户端状态的authenticated属性用于记录客户端是否通过了身份验证,当redisClinet结构下的authenticated属性为值0时,代表客户端未通过身份验证,安装redis服务后,默认是没有密码,也就是不需要身份验证,通过设置config set requirepass  xxx 来设置密码。通过auth  xx来验证密码是否正确。下面脚本是设置密码和验证密码是否正确:

    127.0.0.1:> config set requirepass
OK
127.0.0.1:> auth
OK

    当没有通过验证时,使用ping命令显示信息如下, 退出客户端,重启登录使用-a 参数输入密码,再次使用ping命令,验证成功,如下脚本:

    127.0.0.1:> ping
(error) NOAUTH Authentication required.
[root@xuegod64 ~]# redis-cli -a
127.0.0.1:> ping
PONG

  1.5 时间

    客户端还有几个和时间有关的属性,一是age属性,它记录了创建客户端的时间,这个时间可以用来计算客户端与服务器已经连接了多少秒。二是idle空转时间,即客户端与服务器最后一次进行互动以来,已经过去了多少秒。

  1.6 客户端的创建与关闭

    如果客户端是通过网络连接与服务器进行连接的普通客户端,那么在客户端使用connect函数连接到服务器时,服务器就会调用连接事件处理器(上篇简单讲到的文件事件处理器),为客户端创建相应的客户端状态,并将这个新状态添加到服务器状态结构reddisServer结构的clients数组链表的末尾。对于关闭普通客户端,人为可以使用clinet kill命令,来关闭,如下脚本所示:

    127.0.0.1:> client list
id= addr=127.0.0.1: fd= name= age= idle= flags=N db= sub= psub= multi=- qbuf= qbuf-free= obl= oll= omem= events=r cmd=client
id= addr=127.0.0.1: fd= name= age= idle= flags=N db= sub= psub= multi=- qbuf= qbuf-free= obl= oll= omem= events=r cmd=client
127.0.0.1:> client kill id
(integer)
127.0.0.1:> client list
id= addr=127.0.0.1: fd= name= age= idle= flags=N db= sub= psub= multi=- qbuf= qbuf-free= obl= oll= omem= events=r cmd=client

    如果用户为服务器设置了timeout选项,那么当客户端的空转时间(idle)超过timeout选项设置的值时,客户端将关闭。如果输入缓冲区占用空间超过1GB时,客户端将关闭。

    对于输出缓冲区的大小,达到限制时,客户端也将关闭。为了避免客户端的回复过大,占用过多的服务器资源,服务器会时刻检查客户端的输出缓冲区的大小,并在缓冲区的大小超出范围时,执行相应的限制操作。服务器使用两种模式来限制客户端输出缓冲区的大小:

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

    (2) 软性限制(soft limit): 如果输出缓冲区的大小超出了软性限制所设置的大小,并且占用的时长大于> 设置的总时长,那么服务器将关闭客户端。

    使用client-output-buffer-limit选项可以为普通客户端,从服务器客户端,执行发布订阅功能的客户端分别设置不同的软性限制和硬性限制,默认设置如下:

) "client-output-buffer-limit"
) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"

    normal是普通客户端:软性限制和硬性限制都没有限制。

    slave是从服务器客户端:硬性限制是268435456, 软性限制是67108864 并且时长为60秒。

    pubsub是发布订阅功能的客户端: 硬性限制是33554432, 软性限制是8388608并且时长为60秒。

  1.7  伪客户端的创建与关闭

    对于Lua脚本的伪客户端,在服务器初始化时创建,这个伪客户端在服务器运行的整个生命期中会一直存在,只有服务器关闭时,这个客户端才会被关闭。

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

redis 系列19 客户端的更多相关文章

  1. 【目录】redis 系列篇

    随笔分类 - redis 系列篇 redis 系列27 Cluster高可用 (2) 摘要: 一. ASK错误 集群上篇最后讲到,对于重新分片由redis-trib负责执行,关于该工具以后再介绍.在进 ...

  2. Redis系列(1)之安装

    Redis系列(1)之安装 由于项目的需要,最近需要研究下Redis.Redis是个很轻量级的NoSql内存数据库,它有多轻量级的呢,用C写的,源码只有3万行,空的数据库只占1M内存.它的功能很丰富, ...

  3. redis 系列25 哨兵Sentinel (高可用演示 下)

    一. Sentinel 高可用环境准备 1.1 Sentinel 集群环境 环境 说明 操作系统版本 CentOS  7.4.1708  IP地址 172.168.18.200 网关Gateway 1 ...

  4. Redis系列(二):Redis的数据类型及命令操作

    原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...

  5. Redis系列(一):Redis的简介与安装

    原文链接(转载请注明出处):Redis系列(一):Redis的简介与安装 什么是 Redis Redis 是一个使用ANSI C 编写的开源.支持网络协议.基于内存.可选持久性的键值对数据库,它是一个 ...

  6. 分布式缓存技术redis系列(四)——redis高级应用(集群搭建、集群分区原理、集群操作)

    本文是redis学习系列的第四篇,前面我们学习了redis的数据结构和一些高级特性,点击下面链接可回看 <详细讲解redis数据结构(内存模型)以及常用命令> <redis高级应用( ...

  7. Redis系列--内存淘汰机制(含单机版内存优化建议)

    https://blog.csdn.net/Jack__Frost/article/details/72478400?locationNum=13&fps=1 每台redis的服务器的内存都是 ...

  8. redis系列--深入哨兵集群

    一.前言 在之前的系列文章中介绍了redis的入门.持久化以及复制功能,如果不了解请移步至redis系列进行阅读,当然我也是抱着学习的知识分享,如果有什么问题欢迎指正,也欢迎大家转载.而本次将介绍哨兵 ...

  9. Redis实现之客户端

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

随机推荐

  1. 《团队作业》五小福团队作业--UNO-- LandingDay--降落

    <团队作业>五小福团队作业--UNO-- LandingDay--降落 写在前面 几周的飞行之后,降落之日也如期而至了.在2018年12月19日我们顺利地完成了项目的总结汇报.但是,短暂的 ...

  2. windows下cmd命令行上传代码到github的指定库

    https://blog.csdn.net/a419419/article/details/80063010 git错误:unable to auto-detect email address 解决办 ...

  3. <玩转Django2.0>读书笔记:模板和模型

    1. 模板内置标签 Django常用内置标签 标签 描述 {% for %} 遍历输出变量的内容 {% if %} 对变量进行条件判断 {% csrf_token %} 生成csrf_token标签, ...

  4. python:os.path模块常用方法

    os.path模块主要用于文件的属性获取,在编程中经常用到,以下是该模块的几种常用方法.更多的方法可以去查看官方文档:http://docs.python.org/library/os.path.ht ...

  5. kvm+libvirt虚拟机快照浅析[转]

    浅析snapshots, blockcommit,blockpull 作者:Kashyap Chamarthy <kchamart#redhat.com> Date: Tue, 23 Oc ...

  6. Web版需求征集系统所得2,servlet中request.getParameter获值乱码问题解决

    servlet获值乱码问题解决 解决办法一(最简单有效) request.setCharacterEncoding("utf-8"); 解决办法二 因为乱码问题的产生是因为默认格式 ...

  7. 02 . 处理axios的三个问题 :设置基路径/axios挂载到vue原型/请求时自动携带token

    //使用API时必须在请求头中使用 Authorization 字段提供 token 令牌 import axios from 'axios' // 处理axios的三个问题 // 处理一:基路径 a ...

  8. 十五、过滤器(Filter)

    过滤器(Filter) 过滤器概述 1 什么是过滤器 过滤器JavaWeb三大组件之一,它与Servlet很相似!不它过滤器是用来拦截请求的,而不是处理请求的. 当用户请求某个Servlet时,会先执 ...

  9. 麒麟子Cocos Creator实用技巧

    大家好,我是麒麟子, 开源棋牌<幼麟棋牌-四川麻将>(泄漏版叫 <达达麻将>)作者,成都幼麟科技创始人. 自09年进入游戏行业以来,不知不觉已经度过了十个春秋. 曾经我也血气方 ...

  10. 深入理解Spring Redis的使用 (五)、常见问题汇总

    目前我所知道的Redistemplate里面,我没有使用到的就是管道.这个可以进行批量的读写.类似于jdbc的batch.还有就是Redis的集群部署.但是由于我业务里没有这种需求,所以没有使用无法给 ...