redis使用笔记

redis使用笔记

  • 1、Redis简介
    • [1.1 含义](#1.1 含义)
    • [1.2 功能](#1.2 功能)
    • [1.3 特点](#1.3 特点)
  • [2. 常用的数据结构](#2. 常用的数据结构)
    • [2.1 HASH](#2.1 HASH)
  • [3 redis接口定义](#3 redis接口定义)
    • [3.1 redisReply](#3.1 redisReply)
    • [3.2 redisContext](#3.2 redisContext)
    • [3.3 redisCommand](#3.3 redisCommand)
  • [4 实践操作](#4 实践操作)
    • [4.1 遇到问题](#4.1 遇到问题)
      • [4.1.1 Get哈希的时候返回error](#4.1.1 Get哈希的时候返回error)
      • [4.1.2 长度一直为0,str没法打印(未解决)](#4.1.2 长度一直为0,str没法打印(未解决))

1、Redis简介

最近项目需要使用redis,第一次操作做下工作笔记,以方便后续遇到问题时回头整理复盘,本篇我会持续补充持续更新~

1.1 含义

Redis(Remote Dictionary Server),是一种基于内存的数据结构存储服务。

1.2 功能

可以用作于数据库,缓存和消息队列,而且是开源的。

1.3 特点

  • 基于内存的存储,操作速度非常快;
  • 丰富的数据结构,包括字符串、列表、集合、有序集合等;
  • 支持持久化存储;
  • 集群支持;
  • 灵活性;
  • 易于使用;

2. 常用的数据结构

2.1 HASH

cpp 复制代码
HMSET key field value [field value ...]

如果key存在,则更新value的值,如果key不存在,则更新key-value的键值对

cpp 复制代码
HMSET usertable name "Alice" age 30 gender "female"

解释:将name Alice、age 30、gender female设置到usertable里面。同理,有set就必然会有get,含义就不再赘述,直接看代码:

cpp 复制代码
HMGET key field [field ...]
HMGET usertable name age gender // 举例

即从usertable里面获取name age gender这三个哈希字段,这只是命令的源码,实际开发过程中还要配合hiredis的接口进行操作访问:

3 redis接口定义

3.1 redisReply

cpp 复制代码
typedef struct redisReply {
    int type;
    long long integer;
    double dval;
    size_t len;
    char *str;
    char vtype[4];
    size_t elements;
    struct redisReply **element;
} redisReply;

type的枚举类型如下:

cpp 复制代码
#define REDIS_REPLY_STRING 1 // 字符串
#define REDIS_REPLY_ARRAY 2 // 数组
#define REDIS_REPLY_INTEGER 3 // 整形
#define REDIS_REPLY_NIL 4 // 不存在的类型
#define REDIS_REPLY_STATUS 5 // 状态回复类型
#define REDIS_REPLY_ERROR 6 // 错误恢复类型
#define REDIS_REPLY_DOUBLE 7
#define REDIS_REPLY_BOOL 8
#define REDIS_REPLY_MAP 9
#define REDIS_REPLY_SET 10
#define REDIS_REPLY_ATTR 11
#define REDIS_REPLY_PUSH 12
#define REDIS_REPLY_BIGNUM 13
#define REDIS_REPLY_VERB 14

3.2 redisContext

一般是用来与redis服务器建连,常见用法如下:

cpp 复制代码
redisContext *context = redisConnect("127.0.0.1", 6379);
if ((context == nullptr) || (context->err)) {
      if (context) {
          qDebug() << "Error: " << context->errstr;
          redisFree(context);
      } else {
          qDebug() << "Error: Failed to allocate redis context";
      }
      return;
}

注意它是非线程安全的。

3.3 redisCommand

主要有两个入参,第一个是redisContext,另一个就是需要执行的命令,比如set、get这些。举个例子:

cpp 复制代码
reply = redisCommand(context, "SET name xiaoyi"); // set
reply = redisCommand(context, "GET name"); // get

不仅如此,还可以通过插入变量来控制命令,如下:

cpp 复制代码
reply = redisCommand(context, "SET name %s", value);

4 实践操作

cpp 复制代码
void main()
{
	const char* hostIP = "xxx.xxx.xxx.xxx";
    qDebug() << "hostIP is: " << hostIP;
    redisContext *context = redisConnect(hostIP, 6379);
    qDebug() << "connect begin!";
    if ((context == nullptr) || (context->err)) {
        if (context) {
            qDebug() << "Error: " << context->errstr;
            redisFree(context);
        } else {
            qDebug() << "Error: Failed to allocate redis context";
        }
        return;
    }
    qDebug() << "connect success!";
    redisReply *reply = (redisReply *)redisCommand(context, "HMGET xxxx k v ");
    if (reply == nullptr) {
        qDebug() << "reply is nullptr";
        return;
    }
    qDebug() << "Get reply type" << reply->type;
    qDebug() << "Get reply len" << reply->len;
    qDebug() << "Get reply elements" << reply->elements;
    qDebug() << "Get reply element 0 type:" << reply->element[0]->type;
    qDebug() << "GET reply Error: " << reply->str;
    freeReplyObject(reply);
    // free redis connect
    redisFree(context);
}

而实际情况未必就能如愿以偿,要明白编译、调试失败是常态,成功只是无数次实验中的少数。

4.1 遇到问题

4.1.1 Get哈希的时候返回error

源代码:

cpp 复制代码
redisReply *reply = (redisReply *)redisCommand(context, "GET Bams_AC_alarm11");

打印窗口如下:

原因:通过上面错误的定义,得知6表示的是查询失败,查询相关资料得知redisCommand中的命令应该采用HMGET类型,修改如下:

cpp 复制代码
redisReply *reply = (redisReply *)redisCommand(context, "HMGET Bams_AC_alarm11 v t ");

验证结果:

4.1.2 长度一直为0,str没法打印(未解决)

修改代码如下:

cpp 复制代码
const char* command1 = "GET nameKey";
    redisReply *reply = (redisReply *)redisCommand(context, command1);
    if (reply == nullptr) {
        qDebug() << "reply is nullptr";
        return;
    }
    qDebug() << "Command:" << command1;
    if (reply->type == REDIS_REPLY_STRING) {
        printf("rely str is %s\n", reply->str);
        printf("rely len is %s\n", reply->len);
    }

无意中将len打印成string类型,但发现居然能把正确的值给打印出来:

偶然无意间用字符类型打印了len,结果就出现了自己预期中的值:

没想通这是为什么,然后通过redis desktop manager本地进行查询,确认确实也是设置进去且查询的数值一致:

迷,先记着吧,后面解决后再更新。

相关推荐
飞飞-躺着更舒服16 分钟前
【QT】实现电子飞行显示器(改进版)
开发语言·qt
CYBEREXP20081 小时前
MacOS M3源代码编译Qt6.8.1
c++·qt·macos
DT辰白4 小时前
基于Redis的网关鉴权方案与性能优化
数据库·redis·缓存
木子七4 小时前
Redis-十大数据类型
redis
千册6 小时前
QT:QLabel的LED透明跑马灯
开发语言·qt
追烽少年x6 小时前
Qt中的异步相关类
qt
Fan_5586 小时前
007 Qt_按钮类控件
开发语言·qt
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭7 小时前
聊聊volatile的实现原理?
java·jvm·redis
喵呜角角7 小时前
Qt Quick:ComboBox 组合框
开发语言·qt
灯火不休➴7 小时前
[Redis] 在Linux中安装Redis并连接图形化工具详细过程(附下载链接)
linux·数据库·redis