hiredis
什么是 Hiredis
Hiredis 是一个用于与 Redis 服务器进行通信的 C 语言库。它提供了一组 API,方便开发者在各种应用场景中实现与 Redis 服务器的数据交互操作。
在服务器端的应用中,比如构建 Web 服务或者后端处理程序时,如果需要频繁地与 Redis 进行数据存储、读取、修改等操作,使用 Hiredis 可以提高效率和性能。
使用
以下取自hiredis库官方README
开源链接
同步 API
要使用同步 API,只需要引入几个函数调用:
redisContext *redisConnect(const char *ip, int port);
void *redisCommand(redisContext *c, const char *format, ...);
void freeReplyObject(void *reply);
连接
redisConnect 函数用于创建所谓的 redisContext。上下文是 Hiredis 用来存储连接状态的地方。redisContext 结构中的整型 err 字段在连接出现错误时非零。errstr 字段会包含一个错误描述字符串。更多关于错误的信息可以在“错误”部分找到。使用 redisConnect 尝试连接 Redis 后,应检查 err 字段,以确定建立连接是否成功:
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) {
if (c) {
printf("Error: %s\n", c->errstr);
// 处理错误
} else {
printf("Can't allocate redis context\n");
}
}
也可以使用 redisConnectWithOptions,它接受一个 redisOptions 参数,可以通过这个参数配置终结点信息和许多不同的标志来改变 redisContext 的配置。
redisOptions opt = {0};
/* 可以通过我们的帮助宏之一设置终结点 */
if (tcp) {
REDIS_OPTIONS_SET_TCP(&opt, "localhost", 6379);
} else {
REDIS_OPTIONS_SET_UNIX(&opt, "/tmp/redis.sock");
}
/* 也可以通过另一个帮助宏指定 privdata */
REDIS_OPTIONS_SET_PRIVDATA(&opt, myPrivData, myPrivDataDtor);
/* 最后,可以通过 `options` 成员设置各种选项,如下所示 */
opt.options |= REDIS_OPT_PREFER_IPV4;
如果连接丢失,可以使用 int redisReconnect(redisContext *c) 恢复连接,使用与给定上下文相同的终结点和选项。
使用套接字选项的其他配置
以下套接字选项直接应用于底层套接字。 这些值不会存储在 redisContext 中,因此在使用 redisReconnect() 重新连接时不会自动应用。 这些函数成功时返回 REDIS_OK,失败时返回 REDIS_ERR 并关闭底层连接。
对于异步上下文(参见下面的“异步 API”),使用 ac->c 从 asyncRedisContext 中获取 redisContext。
int redisEnableKeepAlive(redisContext *c);
int redisEnableKeepAliveWithInterval(redisContext *c, int interval);
启用 TCP 保活,通过设置以下套接字选项(根据操作系统有所不同):
SO_KEEPALIVE;
TCP_KEEPALIVE 或 TCP_KEEPIDLE,可使用 interval 参数配置,默认为 15 秒;
TCP_KEEPINTVL 设为 interval 的三分之一;
TCP_KEEPCNT 设为 3。
int redisSetTcpUserTimeout(redisContext *c, unsigned int timeout);
设置 Linux 特有的 TCP_USER_TIMEOUT 套接字选项,如 tcp 手册页所述:
当值大于 0 时,表示传输的数据可以未确认的最大时间(以毫秒为单位),超时后 TCP 将强制关闭相应的连接并向应用程序返回
ETIMEDOUT。 如果选项值指定为 0,则 TCP 将使用系统默认值。
发送命令
向 Redis 发送命令有多种方法。首先介绍的是 redisCommand 函数,它采用类似于 printf 的格式。最简单形式如下:
reply = redisCommand(context, "SET foo bar");
%s 指定符会插入字符串,并使用 strlen 确定字符串长度:
reply = redisCommand(context, "SET foo %s", value);
当需要在命令中传递二进制安全字符串时,可以使用 %b 指定符。需要与字符串指针一起提供一个 size_t 类型的字符串长度参数:
reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen);
Hiredis 会将命令拆分为不同的参数,并将其转换为与 Redis 通信所使用的协议。 命令中的多个空格用于分隔参数,所以可以在参数中的任何位置使用指定符:
reply = redisCommand(context, "SET key:%s %s", myid, value);
使用回复
如果命令执行成功,redisCommand 的返回值会持有回复。发生错误时,返回值为 NULL,并将上下文的 err 字段设置(参见“错误”部分)。 一旦返回错误,就无法再使用该上下文,应建立新的连接。
redisCommand 返回的标准回复类型为 redisReply。使用 redisReply 的 type 字段来测试接收到了哪种类型的回复:
清理
要断开连接并释放上下文,可以使用以下函数:
void redisFree(redisContext *c);
例子
#include <stdio.h>
#include <stdlib.h>
#include <hiredis/hiredis.h>
int main() {
// 创建 Redis 上下文
redisContext *context = redisConnect("127.0.0.1", 6379);
if (context == NULL || context->err) {
if (context) {
printf("连接错误: %s\\n", context->errstr);
redisFree(context);
} else {
printf("无法分配 Redis 上下文\\n");
}
return 1;
}
// 设置键值对
/*
这条命令在 Redis 中设置了一个键值对,其中键(key)是 foo,值(value)是 bar。
因此,通过上面的代码添加的数据是键值对 foo:bar。在 Redis 中,每个键都可以关联一个
值,用于存储和检索数据。在这个例子中,我们只是简单地设置了一个键值对,但在实际应用
中,你可以根据需要设置更复杂的键值对,比如数组、哈希表、列表、集合等。
*/
redisReply *reply = redisCommand(context, "SET foo bar");
if (reply == NULL) {
printf("Redis 命令执行失败\\n");
redisFree(context);
return 1;
}
// 检查命令执行结果
if (reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "OK") == 0) {
printf("键值对设置成功\\n");
} else {
printf("键值对设置失败\\n");
}
// 释放回复对象
freeReplyObject(reply);
// 关闭 Redis 连接
redisFree(context);
return 0;
}