当前位置: 首页 > news >正文

redis使用笔记

redis使用笔记

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

1、Redis简介

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

1.1 含义

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

1.2 功能

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

1.3 特点

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

2. 常用的数据结构

2.1 HASH

HMSET key field value [field value ...]

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

HMSET usertable name "Alice" age 30 gender "female"

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

HMGET key field [field ...]
HMGET usertable name age gender // 举例

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

3 redis接口定义

3.1 redisReply

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的枚举类型如下:

#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服务器建连,常见用法如下:

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这些。举个例子:

reply = redisCommand(context, "SET name xiaoyi"); // set
reply = redisCommand(context, "GET name"); // get

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

reply = redisCommand(context, "SET name %s", value);

4 实践操作

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 connectredisFree(context);
}

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

4.1 遇到问题

4.1.1 Get哈希的时候返回error

源代码:

redisReply *reply = (redisReply *)redisCommand(context, "GET Bams_AC_alarm11");

打印窗口如下:
在这里插入图片描述
原因:通过上面错误的定义,得知6表示的是查询失败,查询相关资料得知redisCommand中的命令应该采用HMGET类型,修改如下:

redisReply *reply = (redisReply *)redisCommand(context, "HMGET Bams_AC_alarm11 v t ");

验证结果:
在这里插入图片描述

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

修改代码如下:

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本地进行查询,确认确实也是设置进去且查询的数值一致:
在这里插入图片描述
迷,先记着吧,后面解决后再更新。

相关文章:

  • 【Linux】线程封装_互斥
  • 怎么看待Groq
  • Redis缓存三大问题-穿透、击穿、雪崩
  • html地铁跑酷
  • map和set(二)——AVL树的简单实现
  • SQL之常用字符串函数
  • php开发100问?
  • Rust 语言中的 dyn 关键字
  • 通过Step Back提示增强LLM的推理能力
  • 华容道问题求解_详细设计(五)之hash值和回放功能
  • qt使用QAxObject操作excel程序关闭之后excel进程未被关闭的解决方案
  • 【C++】三大特性之继承
  • Kafka|处理 Kafka 消息重复的有效措施
  • 线性代数 --- 特征值与特征向量(下)
  • CTP-API开发系列之五:SimNow环境介绍
  • 10个确保微服务与容器安全的最佳实践
  • flutter的key在widget list的作用以及必要性
  • GitUp, 你不可错过的秀外慧中的git工具
  • HTML5新特性总结
  • Spring Boot快速入门(一):Hello Spring Boot
  • 初识MongoDB分片
  • 服务器从安装到部署全过程(二)
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 力扣(LeetCode)56
  • 使用 Docker 部署 Spring Boot项目
  • 使用Gradle第一次构建Java程序
  • 树莓派 - 使用须知
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 用jquery写贪吃蛇
  • 1.Ext JS 建立web开发工程
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • 浅谈sql中的in与not in,exists与not exists的区别
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • #1014 : Trie树
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • #pragma once与条件编译
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练
  • (一)Linux+Windows下安装ffmpeg
  • (转)使用VMware vSphere标准交换机设置网络连接
  • (轉)JSON.stringify 语法实例讲解
  • .aanva
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET4.0并行计算技术基础(1)
  • .NET6 命令行启动及发布单个Exe文件
  • .Net中ListT 泛型转成DataTable、DataSet
  • @基于大模型的旅游路线推荐方案
  • [C#][opencvsharp]opencvsharp sift和surf特征点匹配
  • [C]编译和预处理详解
  • [C++] new和delete