Redis学习手册(实例代码)

news2024/11/27 0:15:35

在下面的代码示例中,将给出两种最为常用的Redis命令操作方式,既普通调用方式和基于管线的调用方式。
    注:在阅读代码时请留意注释。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <stddef.h>
  4 #include <stdarg.h>
  5 #include <string.h>
  6 #include <assert.h>
  7 #include <hiredis.h>
  8 
  9 void doTest()
 10 {
 11     int timeout = 10000;
 12     struct timeval tv;
 13     tv.tv_sec = timeout / 1000;
 14     tv.tv_usec = timeout * 1000;
 15     //以带有超时的方式链接Redis服务器,同时获取与Redis连接的上下文对象。
 16     //该对象将用于其后所有与Redis操作的函数。
 17     redisContext* c = redisConnectWithTimeout("192.168.149.137",6379,tv);
 18     if (c->err) {
 19         redisFree(c);
 20         return;
 21     }
 22     const char* command1 = "set stest1 value1";
 23     redisReply* r = (redisReply*)redisCommand(c,command1);
 24     //需要注意的是,如果返回的对象是NULL,则表示客户端和服务器之间出现严重错误,必须重新链接。
 25     //这里只是举例说明,简便起见,后面的命令就不再做这样的判断了。
 26     if (NULL == r) {
 27         redisFree(c);
 28         return;
 29     }
 30     //不同的Redis命令返回的数据类型不同,在获取之前需要先判断它的实际类型。
 31     //至于各种命令的返回值信息,可以参考Redis的官方文档,或者查看该系列博客的前几篇
 32     //有关Redis各种数据类型的博客。:)
 33     //字符串类型的set命令的返回值的类型是REDIS_REPLY_STATUS,然后只有当返回信息是"OK"
 34     //时,才表示该命令执行成功。后面的例子以此类推,就不再过多赘述了。
 35     if (!(r->type == REDIS_REPLY_STATUS && strcasecmp(r->str,"OK") == 0)) {
 36         printf("Failed to execute command[%s].\n",command1);
 37         freeReplyObject(r);
 38         redisFree(c);
 39         return;
 40     }
 41     //由于后面重复使用该变量,所以需要提前释放,否则内存泄漏。
 42     freeReplyObject(r);
 43     printf("Succeed to execute command[%s].\n",command1);
 44 
 45     const char* command2 = "strlen stest1";
 46     r = (redisReply*)redisCommand(c,command2);
 47     if (r->type != REDIS_REPLY_INTEGER) {
 48         printf("Failed to execute command[%s].\n",command2);
 49         freeReplyObject(r);
 50         redisFree(c);
 51         return;
 52     }
 53     int length = r->integer;
 54     freeReplyObject(r);
 55     printf("The length of 'stest1' is %d.\n",length);
 56     printf("Succeed to execute command[%s].\n",command2);
 57 
 58     const char* command3 = "get stest1";
 59     r = (redisReply*)redisCommand(c,command3);
 60     if (r->type != REDIS_REPLY_STRING) {
 61         printf("Failed to execute command[%s].\n",command3);
 62         freeReplyObject(r);
 63         redisFree(c);
 64         return;
 65     }
 66     printf("The value of 'stest1' is %s.\n",r->str);
 67     freeReplyObject(r);
 68     printf("Succeed to execute command[%s].\n",command3);
 69 
 70     const char* command4 = "get stest2";
 71     r = (redisReply*)redisCommand(c,command4);
 72     //这里需要先说明一下,由于stest2键并不存在,因此Redis会返回空结果,这里只是为了演示。
 73     if (r->type != REDIS_REPLY_NIL) {
 74         printf("Failed to execute command[%s].\n",command4);
 75         freeReplyObject(r);
 76         redisFree(c);
 77         return;
 78     }
 79     freeReplyObject(r);
 80     printf("Succeed to execute command[%s].\n",command4);
 81 
 82     const char* command5 = "mget stest1 stest2";
 83     r = (redisReply*)redisCommand(c,command5);
 84     //不论stest2存在与否,Redis都会给出结果,只是第二个值为nil。
 85     //由于有多个值返回,因为返回应答的类型是数组类型。
 86     if (r->type != REDIS_REPLY_ARRAY) {
 87         printf("Failed to execute command[%s].\n",command5);
 88         freeReplyObject(r);
 89         redisFree(c);
 90         //r->elements表示子元素的数量,不管请求的key是否存在,该值都等于请求是键的数量。
 91         assert(2 == r->elements);
 92         return;
 93     }
 94     for (int i = 0; i < r->elements; ++i) {
 95         redisReply* childReply = r->element[i];
 96         //之前已经介绍过,get命令返回的数据类型是string。
 97         //对于不存在key的返回值,其类型为REDIS_REPLY_NIL。
 98         if (childReply->type == REDIS_REPLY_STRING)
 99             printf("The value is %s.\n",childReply->str);
100     }
101     //对于每一个子应答,无需使用者单独释放,只需释放最外部的redisReply即可。
102     freeReplyObject(r);
103     printf("Succeed to execute command[%s].\n",command5);
104 
105     printf("Begin to test pipeline.\n");
106     //该命令只是将待发送的命令写入到上下文对象的输出缓冲区中,直到调用后面的
107     //redisGetReply命令才会批量将缓冲区中的命令写出到Redis服务器。这样可以
108     //有效的减少客户端与服务器之间的同步等候时间,以及网络IO引起的延迟。
109     //至于管线的具体性能优势,可以考虑该系列博客中的管线主题。
110     if (REDIS_OK != redisAppendCommand(c,command1)
111         || REDIS_OK != redisAppendCommand(c,command2)
112         || REDIS_OK != redisAppendCommand(c,command3)
113         || REDIS_OK != redisAppendCommand(c,command4)
114         || REDIS_OK != redisAppendCommand(c,command5)) {
115         redisFree(c);
116         return;
117     }
118 
119     redisReply* reply = NULL;
120     //对pipeline返回结果的处理方式,和前面代码的处理方式完全一直,这里就不再重复给出了。
121     if (REDIS_OK != redisGetReply(c,(void**)&reply)) {
122         printf("Failed to execute command[%s] with Pipeline.\n",command1);
123         freeReplyObject(reply);
124         redisFree(c);
125     }
126     freeReplyObject(reply);
127     printf("Succeed to execute command[%s] with Pipeline.\n",command1);
128 
129     if (REDIS_OK != redisGetReply(c,(void**)&reply)) {
130         printf("Failed to execute command[%s] with Pipeline.\n",command2);
131         freeReplyObject(reply);
132         redisFree(c);
133     }
134     freeReplyObject(reply);
135     printf("Succeed to execute command[%s] with Pipeline.\n",command2);
136 
137     if (REDIS_OK != redisGetReply(c,(void**)&reply)) {
138         printf("Failed to execute command[%s] with Pipeline.\n",command3);
139         freeReplyObject(reply);
140         redisFree(c);
141     }
142     freeReplyObject(reply);
143     printf("Succeed to execute command[%s] with Pipeline.\n",command3);
144 
145     if (REDIS_OK != redisGetReply(c,(void**)&reply)) {
146         printf("Failed to execute command[%s] with Pipeline.\n",command4);
147         freeReplyObject(reply);
148         redisFree(c);
149     }
150     freeReplyObject(reply);
151     printf("Succeed to execute command[%s] with Pipeline.\n",command4);
152 
153     if (REDIS_OK != redisGetReply(c,(void**)&reply)) {
154         printf("Failed to execute command[%s] with Pipeline.\n",command5);
155         freeReplyObject(reply);
156         redisFree(c);
157     }
158     freeReplyObject(reply);
159     printf("Succeed to execute command[%s] with Pipeline.\n",command5);
160     //由于所有通过pipeline提交的命令结果均已为返回,如果此时继续调用redisGetReply,
161     //将会导致该函数阻塞并挂起当前线程,直到有新的通过管线提交的命令结果返回。
162     //最后不要忘记在退出前释放当前连接的上下文对象。
163     redisFree(c);
164     return;
165 }
166 
167 int main() 
168 {
169     doTest();
170     return 0;
171 }
172 
173 //输出结果如下:
174 //Succeed to execute command[set stest1 value1].
175 //The length of 'stest1' is 6.
176 //Succeed to execute command[strlen stest1].
177 //The value of 'stest1' is value1.
178 //Succeed to execute command[get stest1].
179 //Succeed to execute command[get stest2].
180 //The value is value1.
181 //Succeed to execute command[mget stest1 stest2].
182 //Begin to test pipeline.
183 //Succeed to execute command[set stest1 value1] with Pipeline.
184 //Succeed to execute command[strlen stest1] with Pipeline.
185 //Succeed to execute command[get stest1] with Pipeline.
186 //Succeed to execute command[get stest2] with Pipeline.
187 //Succeed to execute command[mget stest1 stest2] with Pipeline.

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/598439.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

git合并代码后,目录被删除了

问题&#xff1a; 同事x在a分支使用git checkout b -- test.md命令抽取b的文件&#xff0c;然后把代码合并到merge-c。 同事y在merge-c分支&#xff0c;合并了自己的分支b&#xff0c;然后拉取同事x的分支&#xff0c;发现产生了冲突&#xff0c;解决了冲突后提交。 最后发现自…

独立成分分析ICA

独立成分分析 ICA 1. 算法原理简介2.源信号与混合信号的差异2.1 独立性 Independence2.2 高斯性 Normality2.3 复杂性 Complexity 3.非高斯性的度量3.1 峭度 Kurtosis 参考文献 blind source separation (BSS) 1. 算法原理简介 mixing得到signal mixture过程&#xff1a; x 1…

如何开发背包扩容功能?

UE5 插件开发指南 前言0 数据结构1 数据读取2 事件流程3 小结前言 在背包系统中有个扩容功能,可以增加背包的负重和容量,之前没有细讲,这里针对这个问题进行补充,而快捷栏扩容和背包扩容是同样的思路,所以就不去额外解析快捷栏扩容了。如果大家可以理解背包系统,那么快捷…

【MySQL索引】提高查询速度和效率

1、认识索引 假设现在大家要去 MySQL 书中找索引的内容&#xff0c;大家应该不会拿着 MySQL 的书一张一张去找&#xff0c;而是会看MySQL 书的目录&#xff0c;然后通过目录找到索引对应的页码&#xff0c;再去对应的页码中查看索引的内容 索引的优点&#xff1a; 索引就相当于…

文本三剑客

目录 文本三剑客 grep grep和egrep grep命令格式 grep命令格式 grep运用示例 正则表达式 基本正则表达式 拓展正则表达式 sed 使用sed sed用法示例 常用选项options示例 地址界定示例 编辑命令示例 sed高级编辑命令 awk awk的使用 printf命令 操作符 awk …

【嵌入式烧录/刷写文件】-2.7-将一个文本文件转换为Intel hex文件

案例背景(共5页精讲)&#xff1a; 有如下两个文本文件&#xff08;*.txt&#xff0c;*.ini&#xff0c;*.asc…&#xff09;转换为Intel hex文件。常用于Key密钥&#xff0c;signature签名…的导入&#xff0c;或对一段数据计算出hex记录的最后一个字节的校验值&#xff0c;接…

Text-to-Table: A New Way of Information Extraction

原文链接&#xff1a; https://aclanthology.org/2022.acl-long.180.pdf ACL 2022 介绍 作者受到table-to-text任务&#xff08;用于生成描述给定表格的文本语言&#xff09;的启发&#xff0c;提出了text-to-table的新任务&#xff0c;根据给定的文本&#xff0c;来生成用于文…

分布式基础概念

分布式基础概念 1. 微服务2. 集群&分布式&节点3. 远程调用4. 负载均衡5. 服务注册/发现&注册中心6. 配置中心7. 服务熔断&服务降级8. API网关 1. 微服务 微服务架构风格&#xff0c;就是把一个单体架构按照业务拆分成多个服务模块&#xff0c;每个模块之间独立…

LAMP架构搭建实操(终有弱水替沧海,再无相思寄巫山”大概意思就是,你会遇到很多人,但不会有人像我那么爱你了。)

文章目录 一、安装Nginx服务1.安装依赖包2.创建Nginx运行用户3.编译安装Nginx源码包4.优化路径便于使用5、添加 Nginx 系统服务 二、安装Mysql服务1.安装Mysql环境依赖包2.创建Mysql运行用户3.编译安装4.修改mysql配置文件5.更改mysql安装目录和配置文件的属主属组6.设置路径环…

想知道如何把录音转变为文字?这三个录音转文字的方法和你分享

将录音转换为文字有许多实际应用场景&#xff0c;比如会议记录、学习和研究、采访记录、法律领域、医学领域、市场调研等等。总而言之&#xff0c;将录音转换为文字可以提供便利和效率&#xff0c;使得音频内容更易于阅读、搜索和编辑&#xff0c;并在需要时更方便地引用和分析…

Linux -- 进阶 Web服务器 搭建基于 HTTPS 协议的静态网站 (实验实操)

现在我们想架设一个 互联网网站的话&#xff0c;我们就得想法认证自己是官方的&#xff0c;得产生一个证书 这个证书呢&#xff0c;我们使用的是 X.509 格式的证书 该证书 包含三个文件 &#xff1a; key , csr , crt 。 先介绍下 &#xff1a; PKI&#xff08;Public Ke…

C++中关于引用变量初始化的一些总结

目录 1 问题2 引用初始化的说明3 示例代码 1 问题 函数的引用参数要求比较严格&#xff0c;今天就因为一个问题卡住了。我将此问题简化为下面的演示代码&#xff0c; #include <stdio.h>class CBase { public:CBase() {};virtual ~CBase() {}; };class CDerive :public …

Baumer工业相机堡盟工业相机如何使用BGAPISDK联合Halcon将图像中的六一快乐字体提取出来(C#)

Baumer工业相机堡盟工业相机如何使用BGAPISDK联合Halcon将图像中的六一快乐字体提取出来&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机使用Halcon图像算法的技术背景Baumer工业相机通过BGAPI SDK联合Halcon使用图像算法1.引用合适的类文件2.BGAPISDK在图像回调中引…

ppt怎么转pdf?经验分享

随着现代技术的不断发展&#xff0c;PPT已经成为了一种常见的演示工具。然而&#xff0c;在某些情况下&#xff0c;我们需要将PPT转换成PDF文件。PDF文件具有易读性强、占用空间小、易于传输等优点&#xff0c;因此在一些场合下&#xff0c;PDF文件更为实用。那么&#xff0c;如…

【JavaSE】Java基础语法(四十二):NIO

文章目录 1. 概述2. NIO与BIO的区别3. NIO三大模块4. NIO创建缓冲区对象【应用】5. NIO缓冲区添加数据【应用】6. NIO缓冲区获取数据【应用】7. 小结 1. 概述 BIO Blocking IO,阻塞型IONIO No Blocking IO,非阻塞型IO阻塞IO的弊端 在等待的过程中,什么事也做不了非阻塞IO的好处…

【正点原子STM32连载】 第二十三章 电容触摸按键实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第二十…

Java网络开发(Tomcat)—— 登陆 和 注册功能 的实现 和 迭代升级

目录 引出登陆功能---从html到jsp1.登陆--用post请求2.用html文件的form表单登陆&#xff08;1&#xff09;index.html页面&#xff08;2&#xff09;login.html登陆的页面&#xff08;3&#xff09;LoginServlet.java处理输入信息的代码&#xff08;4&#xff09;登陆成功&…

分布式事务一 事物以及分布式事物介绍

一 事务简介 事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中&#xff0c;一个事务由一组SQL语句组成。事务应该具有4个属性&#xff1a;原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。 原子性&#xff08;at…

MyBatis - Spring Boot 集成 MyBatis

文章目录 1.版本要求2.导入依赖3.自动配置2.可配置项 MyBatis-Spring-Boot-Starter 可以帮助你更快地在 Spring Boot 之上构建 MyBatis 应用。通过使用该模块我们能够快速实现以下目的&#xff1a; 构建单体应用程序将几乎不需要样板配置使用更少的 XML 配置 1.版本要求 MyB…

Apache Kafka - 构建数据管道 Kafka Connect

文章目录 概述主要概念ConnectorTasksWorkesConvertersTransformsDead Letter Queue 主要使用场景主要价值Kafka Connect API vs Producer 和 Consumer API构建数据管道时需要考虑的主要问题ETL VS ELT数据整合方式的不同ETL 和 ELT 各有优缺点: 概述 Kafka Connect 是一个工具…