想从C语言动手玩转redis,边学边实践那些c语言操作细节
- 问答
- 2026-01-02 16:22:44
- 4
引用自《Redis设计与实现》以及Redis官方文档中关于C语言接口的部分,结合常见C语言编程实践进行说明)
想用C语言玩转Redis,第一步不是直接写代码,而是先把环境搭好,你得让C编译器能找到Redis的头文件和链接库,你需要先安装Redis开发包,在Ubuntu上,可以运行 sudo apt-get install libhiredis-dev,这个hiredis是Redis官方推荐的C语言客户端库,它帮你封装了和Redis服务器通信的底层细节。(来源:Redis官方GitHub仓库的hiredis部分)
安装好后,写一个最简单的程序来测试连接,创建一个test.c文件,开头先引入必要的头文件:
#include <stdio.h> #include <stdlib.h> #include <hiredis/hiredis.h>
这里stdio.h和stdlib.h是C标准库,用于输入输出和内存管理。hiredis/hiredis.h则是核心,它提供了所有操作Redis的函数和数据结构。(来源:hiredis头文件注释及API文档)
连接Redis服务器的代码很简单,但细节很重要:
int main() {
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) {
if (c) {
printf("连接错误: %s\n", c->errstr);
redisFree(c);
} else {
printf("无法分配redisContext\n");
}
exit(1);
}
printf("Redis连接成功!\n");
redisConnect函数尝试建立一个到指定地址和端口的连接,它返回一个redisContext指针,这个结构体代表了这次连接的所有状态,这里有个关键点:你必须检查连接是否真的成功了,不能只判断c是否为NULL,还要看c->err有没有被设置错误标志,如果出错,c->errstr会告诉你具体原因,比如网络不通或认证失败,这是新手常忽略的检查,直接导致程序不稳定。(来源:hiredis源码中的示例代码及错误处理注释)

连接成功后,就可以发送命令了,比如设置一个键值对:
redisReply *reply = redisCommand(c, "SET mykey \"Hello from C!\"");
if (reply == NULL) {
printf("命令执行失败(可能由于网络或内存不足)\n");
redisFree(c);
exit(1);
}
redisCommand函数是工作的主力,它把命令字符串发给Redis服务器,并等待回复,回复被包装在一个redisReply结构体里,这里又有一个细节:即使网络命令发送成功,reply也可能为NULL,这通常意味着严重的系统级错误(比如内存分配失败),而不仅仅是Redis命令本身的错误,所以要先做这个检查。
接下来要处理回复的类型,Redis的回复有多种类型,比如状态回复、错误回复、整数回复、批量回复等。redisReply结构体的type字段指明了类型:
if (reply->type == REDIS_REPLY_STATUS) {
printf("SET成功: %s\n", reply->str);
} else if (reply->type == REDIS_REPLY_ERROR) {
printf("SET错误: %s\n", reply->str);
}
对于SET命令,成功时通常返回一个状态回复(OK"),其字符串内容在reply->str里,如果命令语法错误或出问题,会返回错误回复,检查回复类型是确保程序逻辑正确的关键一步,不能想当然认为命令一定会成功。(来源:《Redis设计与实现》中关于通信协议章节的说明)

每当你使用完redisReply对象,必须释放它,否则会内存泄漏:
freeReplyObject(reply);
这是C语言编程的核心纪律之一:谁分配,谁释放。redisCommand为你分配了内存,你就得负责回收。
我们再试试获取刚才设置的值:
reply = redisCommand(c, "GET mykey");
if (reply == NULL) { ... } // 同上,省略错误处理
if (reply->type == REDIS_REPLY_STRING) {
printf("GET到的值: %s\n", reply->str);
} else if (reply->type == REDIS_REPLY_NIL) {
printf("键mykey不存在\n");
}
freeReplyObject(reply);
对于GET命令,成功获取到字符串值时,类型是REDIS_REPLY_STRING,如果键不存在,类型则是REDIS_REPLY_NIL,这里展示了如何根据不同类型进行不同处理。

除了简单的字符串,还可以处理整数,比如执行INCR命令:
reply = redisCommand(c, "INCR mycounter");
if (reply->type == REDIS_REPLY_INTEGER) {
printf("计数器增加后的值: %lld\n", reply->integer);
}
freeReplyObject(reply);
整数回复的值存储在reply->integer字段中,格式是long long类型,这提醒我们,操作Redis时要注意C语言的数据类型和Redis数据类型的映射关系。
使用参数化命令能避免手动拼接字符串的麻烦和潜在的安全风险(如注入攻击),hiredis提供了%s和%b等格式化占位符:
const char *key = "user:1001";
const char *value = "Alice";
reply = redisCommand(c, "SET %s %s", key, value);
// ... 处理回复和释放
%s用于以空字符结尾的字符串,而%b用于二进制安全的数据,需要同时指定长度,比如redisCommand(c, "SET %b %b", binary_data, data_len, value, value_len),这在处理可能包含空字符(\0)的数据时至关重要,因为C字符串遇到\0就结束了,但Redis的字符串是二进制的,可以包含\0。(来源:hiredis API文档中关于%b格式说明器的部分)
程序结束时,一定要关闭连接,释放所有资源:
redisFree(c);
return 0;
}
redisFree会清理redisContext占用的所有资源。
通过这样一步步的实践,你不仅能学会如何用C语言操作Redis的基本命令,更能体会到C编程中内存管理、错误处理和类型检查这些细节的重要性,这些都是写出健壮、可靠C程序的基础,你可以尝试更复杂的操作,比如使用管道(pipeline)提升批量操作的性能,或者订阅/发布(pub/sub)模式,原理类似,但需要处理连续到来的异步消息。
本文由召安青于2026-01-02发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/73180.html
