第4章 客户端

作者: leon4ever | 来源:发表于2018-05-24 14:27 被阅读16次

    本章了解Redis服务端和客户端的通信协议,以及主流编程语言的Redis客户端使用方法。

    1. 客户端通信协议

    • 基于TCP协议
    • 制定了RESP(Redis序列化协议)实现交互

    发送命令格式

    CRLF 代表"\r\n"

    *<参数数量> CRLF 
    $<参数1的字节数量>CRLF
    <参数1>CRLF
    ...
    $<参数N的字节速率>CRLF
    <参数N>CRLF
    

    比如set hello world命令,传输格式为:

    *3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n
    

    返回结果格式

    • 状态回复:在RESP中第一个字节为 "+"
    • 错误回复:"-"
    • 整数回复:":"
    • 字符串回复:"$"
    • 多条字符串回复:"*"
    Redis在RESP下的编码.jpg

    2. Java客户端Jedis

    3. Python客户端redis-py

    3.1 获取redis-py

    pip install redis
    

    3.2 redis-py的基本使用方法

    import redis
    client = redis.StrictRedis(host='127.0.0.1', port = 3679)
    key = "hello"
    setResult = client.set(key, "python-redis")
    value = client.get(key)
    

    3.3 redis-py中的Pipeline的使用方法

    pipeline = clinet.pipeline(transcation=Flase)  //不使用事务
    //生成pipeline
    pipeline.set("hello", "world")
    pipeline.incr("counter")
    //执行pipeline
    result = pipeline.execute()
    

    3.4 redis-py中的Lua脚本使用方法

    eval(String script, int KeyCount, String ... params)
    //script:Lua脚本内容,keyCount:键的个数,params:相关参数
    script_load(String script)
    evalsha(String sha1, int keyCount, String ... params)
    

    以简单的Lua脚本为例

    script = "return redis.call('get',KEYS[1])"
    client.eval(script, 1, "hello")
    
    scriptSha = client.script_load(script)
    client.evalsha(scriptSha, 1, "hello")
    

    4. 客户端管理

    在服务端可以查看客户端状态

    4.1 客户端API

    1. client list

      • 标识: id、addr、fd、name

      • 输入缓冲区:qbuf、qbuf-free,将客户端发送的命令临时保存,注意容量(动态分配)不能超过1G,也要注意有可能超过maxmemory

      • 输出缓冲区:obl(固定缓冲区长度),oll(动态缓冲区长度),omem(使用的字节数)


        客户端输出缓冲模型.jpg
        固定缓冲区和动态缓冲区.jpg
      • 客户端的存活状态:age和idle分别代表客户端已连接的时间和最近一次空闲时间

      • 客户端的限制最大连接数maxclients和超时时间timeout

      • 客户端类型:flag标识类型


        客户端类型.jpg
      • 其他


        client list命令结果全部属性.jpg
    2. client setName 和 client getName 设置名字

    3. client kill ip:port 杀掉指定IP地址和端口的客户端

    4. client pause timeout(毫秒):用于阻塞客户端,让主从保持一致,将客户端切换到另一个节点

    5. monitor:监控Redis正在执行的命令,能监听其他客户端执行的命令,但是会占用大量内存

    4.2 客户端相关配置

    • timeout
    • maxclients
    • tcp-keepalive:检测TCP连接活性的周期
    • tcp-backlog:TCP三次握手后,将接受的连接放入队列,tcp-backlog就是队列的大小

    4.3 客户端统计片段

    127.0.0.1:6379> info clients
    #Clients
    connected_clients:1414      //当前客户端数量,超过maxclients会被拒绝
    client_longest_output_list:0    //当前所有输出缓冲区中队列对象个数的最大值
    client_biggest_input_bur:2097152  //当前所有输入缓冲区中占用的最大容量
    blocked_client:0    //正在执行阻塞命令的客户端个数
    

    5. 客户端常见异常

    1. 无法从连接池获取到连接:连接池小,没有释放归还?存在慢查询操作?或者阻塞了
    2. 客户端读写超时:读写超时阈值短,命令本身慢,网络问题,Redis自身阻塞
    3. 客户端连接超时:timeout设置短了,Redis自设脑阻塞,网络问题
    4. 客户端缓冲区异常:输出缓冲区满了,不正常并发读写
    5. Lua脚本正在执行,超过time-limit
    6. Redis正在加载持久化文件
    7. Redis使用内存超过maxmemory
    8. 客户端连接数过大

    6. 客户端案例分析

    6.1 Redis内存陡增

    Redis主从节点内存不一致.jpg
    1. 查看主从数据是否一致
    2. 是否由于客户端缓冲区造成主节点内存陡增,info clients

    发现有客户端执行monitor命令

    处理方法:

    1. 运维层面禁止monitor
    2. 限制输出缓冲区大小
    3. 使用专业Redis运维工具,快速发现定位问题

    6.2 客户端周期性超时

    客户端耗时统计.jpg

    慢查询导致超时。
    要避免不正确的使用方式。

    相关文章

      网友评论

        本文标题:第4章 客户端

        本文链接:https://www.haomeiwen.com/subject/wlqsjftx.html