Redis协议与客户端

Redis协议与客户端

通信协议

  1. TCP洗衣
  2. RESP(redis serialization protocol)redis序列化协议,每行\r\n分隔

发送格式

<参数数量>\r\n
<参数1字节数>\r\n
<参数1>\r\n
...
<参数N字节数>\r\n
<参数N>\r\n

例如发送: set hello world

3
3
set
5
hello
5
world
# 实际发送为 3\r\n3\r\nset\r\n5\r\nhello\r\n5\r\nworld\r\n

返回格式

  1. 状态回复:第一个字节为+,例如 set
  2. 错误回复:第一个字节为-
  3. 整数回复:第一个字节为: 例如 incr
  4. 字符串回复:第一个字节为$ 例如 get
  5. 多条字符串回复:第一个字节为* 例如 mget

redis源码中的解析如下:

static sds cliFormatReplyTTY(redisReply *r, char *prefix) {
    sds out = sdsempty();
    switch (r->type) {
    case REDIS_REPLY_ERROR:
        // 处理错误回复
    case REDIS_REPLY_STATUS:
        // 处理状态回复
    case REDIS_REPLY_INTEGER:
        // 处理整数回复
    case REDIS_REPLY_STRING:
        // 处理字符串回复
    case REDIS_REPLY_NIL:
        // 处理空
    case REDIS_REPLY_ARRAY:
        // 处理多条字符串回复
    return out;
}

无论是字符串回复还是多字符串回复,如果有nil值都返回$-1

Python客户端redis-py

Github:https://github.com/andymccurdy/redis-py

redis-py的API保留了Redis API的原始风格

安装

pip install redis

基本使用

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

操作5种数据结构

使用Pipeline

使用Lua脚本

Go客户端

Github: https://github.com/go-redis/redis

API文档:https://godoc.org/github.com/go-redis/redis

go get -u github.com/go-redis/redis

基本操作

 client := redis.NewClient(&redis.Options{
        Addr:     "127.0.0.1:6379",
        Password: "", // no password set
        DB:       0,  // use default DB
    })

pong, err := client.Ping().Result()
fmt.Println(pong, err)

err = client.Set("key", "value", 0).Err()
if err != nil {
    panic(err)
}

val, err := client.Get("key").Result()
if err != nil {
    panic(err)
}
fmt.Println("key", val)

val2, err := client.Get("key2").Result()
if err == redis.Nil {
    fmt.Println("key2 does not exists")
} else if err != nil {
    panic(err)
} else {
    fmt.Println("key2", val2)
}

客户端管理

客户端API

  1. client list

    • 客户端标识:

      • id:客户端连接唯一标识,随Redis连接自增,重启Redis重置0
      • addr:客户端ip和端口
      • fd:socket文件描述符,fd=-1表示为redis内部的伪装客户端
      • name:客户端名字(client setName, client getName)
    • 输入缓冲区:动态调整,不超过1G,超过则断开,不受maxmemory限制

      • qbuf:缓冲区总容量

      • qbuf-free:缓冲区剩余容量

      • /* Protocol and I/O related defines */
        
        #define REDIS_MAX_QUERYBUF_LEN (1024*1024*1024) /* 1GB max query buffer. */
        

        出问题概率较低,可以监控输入缓冲区:

        • 通过定期指定client list手机qbuf信息找到问题
        • 通过info clients找到最大缓冲区
    • 输出缓冲区:用于保存结果返回给客户端,client-output-buffer-limit设置

      • 客户端类型:

        • normal:普通客户端
        • slave:slave客户端
        • pubsub:发布订阅客户端
      • 配置:

        client-output-buffer-limit

        class:客户端类型

        hard limit:客户端输出缓冲区大于hard limit则关闭

        客户端输出缓冲区超过了soft limit并且持续了soft limit秒,则关闭

        默认配置如下:

        client-output-buffer-limit normal 0 0 0
        client-output-buffer-limit slave 256mb 64mb 60
        client-output-buffer-limit pubsub 32mb 8mb 60

      • 组成:

        • 固定缓冲区:16KB,返回较小的执行结果

        • 动态缓冲区:返回较大的结果

          typedef struct redisClient {
          // 动态缓冲区列表
          list *reply;
          // 动态缓冲区列表的长度(对象个数)
          unsigned long reply_bytes;
          // 固定缓冲区已经使用的字节数
          int bufpos;
          // 字节数组作为固定缓冲区
          char buf[REDIS_REPLY_CHUNK_BYTES];
          } redisClient;
      • 命令字段:

        • obl:固定缓冲区长度
        • oll:动态缓冲区列表长度
        • omem:使用的字节数
      • 预防:

        • client list,info clients监控
        • 限制普通客户端输出缓冲区, normal 20mb 10mb 120
        • 适当增大slave输出缓冲区
        • 限制此类命令,如高并发下的monitor命令
        • 及时监控内存,内存抖动频繁可能是输出缓冲区过大
    • 客户端存活状态

      • age:客户端已经连接时间

      • idle:最近一次的空闲时间

        age==idle说明连接一直空闲

    • 客户端的限制

      • maxclients:最大客户端连接数,默认10000
      • timeout:限制连接的最大空闲时间,单位秒,超时被关闭,默认0
      • 可通过config set xx动态设置
    • 客户端类型

    • 其他

  2. client setNameclient getName

    client setName xx

    client getName

  3. client kill

    client kill ip:port

    可以用来手动kill客户端连接

  4. client pause

    client pause timeout(毫秒)

    阻塞客户端指定的毫秒数

    只对normal和pubsub客户端有效,slave客户端无效

    可讲redis客户端连接从一个redis节点切换到另一个节点

    生成环境慎用

  5. monitor

    监控redis正在执行的命令

    redis并发量过大,monitor客户端输出缓冲区暴涨,可能瞬间占用大量内存

其他客户端配置

配置项说明
timeout检测客户端空闲连接超时,0不检测
maxclients客户端最大连接数
tcp-keepalive检测TCP连接活性的周期,默认0不检测,建议60,防止大量死连接
tcp-backlogTCP三次握手后,会将接受的连接放入队列,此为队列大小,默认511,一般不调整

客户端统计片段

常见异常

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值