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

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

相关推荐
用户805533698032 小时前
现代Qt开发教程(新手篇)1.14——日志
c++·qt
庞轩px2 小时前
第四篇:RDB与AOF持久化——宕机后数据怎么恢复?
redis·缓存·持久化·aof·rdb·宕机·恢复数据
江公望2 小时前
Qt QSharedPointer用法,10分钟讲清楚
开发语言·qt
PeterLi3 小时前
Redis 分布式锁架构全解析:从基础实现到生产级选型指南
redis·分布式
下次再写4 小时前
【Redis实战】深入理解Redis缓存策略:从原理到Spring Boot实践
java·spring boot·redis·缓存穿透·缓存击穿·分布式缓存·缓存策略
小白君6534 小时前
互联网大厂Java面试:从Spring Boot到微服务的技术场景深度解析
spring boot·redis·微服务·消息队列·java面试·数据库优化
庞轩px4 小时前
第七篇:Redis分布式锁——从setnx到RedLock的演进之路
数据库·redis·分布式锁·redission·setnx·redlock·可重入锁
Shadow(⊙o⊙)4 小时前
初识Qt+经典方式实现hello world!的交互
开发语言·c++·后端·qt·学习
橙子圆1235 小时前
Redis知识2
java·数据库·redis
道剑剑非道5 小时前
FFmpeg + Qt 实现摄像头采集与 MP3 背景音乐 RTSP 推流
开发语言·qt·ffmpeg