• Redis入门完整教程:客户端通信协议


    几乎所有的主流编程语言都有Redis的客户端(http://redis.io/clients),
    不考虑Redis非常流行的原因,如果站在技术的角度看原因还有两个:第
    一,客户端与服务端之间的通信协议是在TCP协议之上构建的。第二,
    Redis制定了RESP(REdis Serialization Protocol,Redis序列化协议)实现客
    户端与服务端的正常交互,这种协议简单高效,既能够被机器解析,又容易
    被人类识别。例如客户端发送一条set hello world命令给服务端,按照RESP
    的标准,客户端需要将其封装为如下格式(每行用\r\n分隔):
    *3
    $3
    SET
    $5
    hello
    $5
    world
    这样Redis服务端能够按照RESP将其解析为set hello world命令,执行后
    回复的格式如下:
    +OK
    可以看到除了命令(set hello world)和返回结果(OK)本身还包含了
    一些特殊字符以及数字,下面将对这些格式进行说明。
    1.发送命令格式
    RESP的规定一条命令的格式如下,CRLF代表"\r\n"。
    *< 参数数量 > CRLF
    $< 参数 1 的字节数量 > CRLF
    < 参数 1> CRLF
    ...
    $< 参数 N 的字节数量 > CRLF
    < 参数 N> CRLF
    依然以set hell world这条命令进行说明。
    参数数量为3个,因此第一行为:
    *3
    参数字节数分别是355,因此后面几行为:
    $3
    SET
    $5
    hello
    $5
    world
    有一点要注意的是,上面只是格式化显示的结果,实际传输格式为如下
    代码,整个过程如图4-1所示:
    *3\r\n$3\r\nSET\r\n$5\r\nhello\r\n$5\r\nworld\r\n
    2.返回结果格式
    Redis的返回结果类型分为以下五种,如图4-2所示:
    ·状态回复:在RESP中第一个字节为"+"。
    ·错误回复:在RESP中第一个字节为"-"。
    ·整数回复:在RESP中第一个字节为":"。
    ·字符串回复:在RESP中第一个字节为"$"。
    ·多条字符串回复:在RESP中第一个字节为"*"。

     

    我们知道redis-cli只能看到最终的执行结果,那是因为redis-cli本身就是
    按照RESP进行结果解析的,所以看不到中间结果,redis-cli.c源码对命令结
    果的解析结构如下:
    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;
    }
    例如执行set hello world,返回结果是OK,并不能看到加号:
    127.0.0.1:6379> set hello world
    OK
    为了看到Redis服务端返回的“真正”结果,可以使用nc命令、telnet命
    令、甚至写一个socket程序进行模拟。下面以nc命令进行演示,首先使用
    nc127.0.0.16379连接到Redis:
    nc 127.0.0.1 6379
    状态回复:set hello world的返回结果为+OK:
    set hello world
    +OK
    错误回复:由于sethx这条命令不存在,那么返回结果就是"-"号加上错
    误消息: 

    sethx
    -ERR unknown command 'sethx'
    整数回复:当命令的执行结果是整数时,返回结果就是整数回复,例如
    incr、exists、del、dbsize返回结果都是整数,例如执行incr counter返回结果
    就是“:”加上整数:
    incr counter
    :1
    字符串回复:当命令的执行结果是字符串时,返回结果就是字符串回
    复。例如get、hget返回结果都是字符串,例如get hello的结果
    为“$5\r\nworld\r\n”:
    get hello
    $5
    world
    多条字符串回复:当命令的执行结果是多条字符串时,返回结果就是多
    条字符串回复。例如mget、hgetall、lrange等命令会返回多个结果,例如下面
    操作:
    首先使用mset设置多个键值对:
    mset java jedis python redis-py
    +OK
    然后执行mget命令返回多个结果,第一个*2代表返回结果的个数,后面
    的格式是和字符串回复一致的:
    mget java python
    *2
    $5
    jedis
    $8
    redis-py
    有一点需要注意,无论是字符串回复还是多条字符串回复,如果有nil
    值,那么会返回$-1。
    例如,对一个不存在的键执行get操作,返回结果为:
    get not_exist_key
    $-1
    如果批量操作中包含一条为nil值的结果,那么返回结果如下:
    mget hello not_exist_key java
    *3
    $5
    world
    $-1
    $5
    jedis
    有了RESP提供的发送命令和返回结果的协议格式,各种编程语言就可
    以利用其来实现相应的Redis客户端,后面两节将介绍Java和Python两个编程
    语言的Redis客户端。

  • 相关阅读:
    数独游戏底层算法
    可视化大屏自适应方案
    VS2019_静态编译MDT_问题解决:无法解析的外部符号 _imp_XXXXXXXXX
    MR756-ASEMI汽车用整流二极管MR756
    java计算机毕业设计社区老年人信息管理系统源程序+mysql+系统+lw文档+远程调试
    编写 bzt 脚本的正确姿势
    【错误记录】Uncaught TypeError: m.nodeName.toLowerCase is not a function
    把自己本地项目发布到Gitee
    AI加速(八)| 循环展开Unrooling——你肯定能学会的程序加速方法
    【Docker】ubuntu20.04 X86机器搭建NVIDIA ARM64 TX2的Docker镜像
  • 原文地址:https://blog.csdn.net/tysonchiu/article/details/125609570