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本地进行查询,确认确实也是设置进去且查询的数值一致:

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

相关推荐
海绵波波10740 分钟前
Qt操作主/从视图及XML——实例:汽车管理系统
xml·qt·汽车
Jay_fearless43 分钟前
Redis SpringBoot项目学习
spring boot·redis
Wang's Blog1 小时前
Redis: 集群环境搭建,集群状态检查,分析主从日志,查看集群信息
数据库·redis
Fairy_sevenseven1 小时前
【二十八】【QT开发应用】模拟WPS Tab
开发语言·qt·wps
Death2002 小时前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
niu_sama2 小时前
基于muduo库函数实现protobuf协议的通信
开发语言·qt
不写八个2 小时前
Qt教程(001):Qt概述与安装
开发语言·qt
Death2002 小时前
Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系
c语言·c++·qt·3d·c#
wclass-zhengge7 小时前
Redis篇(最佳实践)(持续更新迭代)
redis·缓存·bootstrap
Dylanioucn7 小时前
【分布式微服务云原生】探索Redis:数据结构的艺术与科学
数据结构·redis·分布式·缓存·中间件