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

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

相关推荐
云中飞鸿8 分钟前
linux中qt安装
开发语言·qt
少控科技21 分钟前
QT第6个程序 - 网页内容摘取
开发语言·qt
清风拂山岗 明月照大江29 分钟前
Redis笔记汇总
java·redis·缓存
消失的旧时光-19432 小时前
第十四课:Redis 在后端到底扮演什么角色?——缓存模型全景图
java·redis·缓存
stevenson_aspdotnet2 小时前
QT5.15.12 编译备忘
qt
消失的旧时光-19433 小时前
第十四课 · 实战篇:Redis 缓存系统落地指南(Spring Boot 从 0 到可用)
spring boot·redis·缓存
飞升不如收破烂~4 小时前
Redis 分布式锁+接口幂等性使用+当下流行的限流方案「落地实操」+用户连续点击两下按钮的解决方案自用总结
数据库·redis·分布式
森焱森4 小时前
详解 Spring Boot、Flask、Nginx、Redis、MySQL 的关系与协作
spring boot·redis·python·nginx·flask
茶杯梦轩4 小时前
从零起步学习Redis || 第七章:Redis持久化方案的实现及底层原理解析(RDB快照与AOF日志)
redis·后端
无小道4 小时前
QT——QFIie和QFileInfo文件类
开发语言·qt·命令模式