
Redis核心概念与基础操作
Redis本质上是一个开源的键值存储系统,但它的价值远不止简单的缓存。支持字符串、哈希、列表、集合、有序集合五种数据结构,这让它能够处理复杂场景。比如用有序集合实现实时排行榜,或者用哈希存储用户会话信息。
安装Redis最简单的方式是通过包管理器:
# Ubuntu
sudo apt-get install redis-server
CentOS
sudo yum install redis
启动服务后,用redis-cli
就能直接操作:
127.0.0.1:6379> SET user:1001 "张三"
OK
127.0.0.1:6379> GET user:1001
"张三"
Hiredis客户端深度解析
作为Redis官方推荐的C客户端,Hiredis的优势在于轻量级和高性能。编译安装只需要三步:
git clone https://github.com/redis/hiredis.git
cd hiredis
make && sudo make install
连接Redis的典型代码结构:
redisContext c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) {
if (c) printf("Error: %sn", c->errstr);
else printf("Can't allocate redis contextn");
exit(1);
}
redisReply
reply = redisCommand(c, "SET foo bar");
freeReplyObject(reply);
redisFree(c);
高效开发实践技巧
管道技术能显著提升批量操作性能。对比测试显示,执行10000次SET操作时:
方式 | 耗时(ms) | 网络IO次数 |
---|---|---|
单条命令 | 1250 | 10000 |
管道批处理 | 82 | 1 |
实现管道的代码示例:
redisReply reply;
redisAppendCommand(c, "SET key1 value1");
redisAppendCommand(c, "GET key1");
redisGetReply(c, (void)&reply); // SET返回
freeReplyObject(reply);
redisGetReply(c, (void)&reply); // GET返回
printf("GET结果: %sn", reply->str);
freeReplyObject(reply);
高级特性应用场景
发布订阅模式适合实时消息系统,比如订单状态变更通知。服务端发布消息:
PUBLISH orders "订单1234已发货"
客户端订阅代码:
void subscriber = redisConnect("127.0.0.1", 6379);
redisReply reply = redisCommand(subscriber, "SUBSCRIBE orders");
while(redisGetReply(subscriber, (void)&reply) == REDIS_OK) {
if(reply->type == REDIS_REPLY_ARRAY && reply->elements == 3) {
printf("收到消息: %sn", reply->element[2]->str);
}
freeReplyObject(reply);
}
事务处理通过MULTI/EXEC实现原子操作:
redisCommand(c, "MULTI");
redisCommand(c, "INCR counter");
redisCommand(c, "EXPIRE counter 60");
redisReply txReply = redisCommand(c, "EXEC");
if(txReply->type == REDIS_REPLY_ARRAY) {
for(int i=0; ielements; i++) {
printf("结果%d: %sn", i, txReply->element[i]->str);
}
}
Redis的数据结构选择其实是个很有意思的实践问题。字符串类型看似简单,但配合INCR/DECR命令就能轻松实现计数器,加上EXPIRE还能做限流控制;哈希结构特别适合存储用户资料这种多字段对象,一个HSET命令就能搞定整个用户档案的更新,比拆分成多个字符串键高效多了。列表结构不只是简单的队列实现,LPUSH+RPOP组合可以做生产者消费者模型,而RPUSH+LPOP又能变成栈结构,灵活得很。
实际选型时要考虑的因素其实更细致。比如集合和有序集合都能去重,但有序集合多出的ZRANGEBYSCORE命令特别适合处理时间窗口内的数据,比如统计最近5-10分钟的热搜词。再比如商品库存这种需要原子操作的场景,字符串的INCR比哈希的HINCRBY更直接;但如果是用户购物车这种需要频繁修改多个字段的,哈希的HMSET明显更合适。有时候数据结构还能组合使用,比如用集合存储用户标签,同时用有序集合维护标签热度排行,这种组合拳在社交类应用中特别常见。
Hiredis连接失败如何处理?
首先检查Redis服务是否正常运行,使用redis-cli ping确认服务可用性。如果返回PONG说明服务正常,接着检查Hiredis连接代码中的IP和端口是否正确。常见错误包括防火墙拦截、bind配置限制(检查redis.conf的bind参数)或密码认证问题(需要调用AUTH命令)。网络问题可以使用telnet测试端口连通性。
Redis和Hiredis的性能优化有哪些关键点?
关键优化手段包括:1) 使用管道技术减少网络往返,适合批量操作场景;2) 合理设置连接池大小, 5-20个连接;3) 避免大键值操作,单个value 不超过1MB;4) 对于读多写少场景启用客户端缓存;5) 使用异步API处理高并发请求。注意监控redis-benchmark测试结果,根据实际负载调整参数。
如何选择Redis的数据结构?
字符串适合简单键值缓存;哈希适合存储对象属性;列表可实现队列/栈;集合用于去重和关系运算;有序集合适合排行榜等需要排序的场景。选择依据主要看:1) 数据关系复杂度;2) 是否需要原子操作;3) 查询模式(是否需要范围查询、去重等)。例如用户会话适合用哈希,而消息队列适合列表。
Redis持久化方案如何选择?
RDB适合定期备份,恢复速度快但可能丢失几分钟数据;AOF记录所有写操作,数据更安全但文件较大。生产环境 同时开启RDB和AOF:配置save 900 1表示900秒内至少1次修改触发RDB,设置appendfsync everysec平衡性能和数据安全。注意监控磁盘IO,当数据量超过10GB时需要特别考虑持久化对性能的影响。
Hiredis如何处理订阅/发布模式?
需要创建独立连接专门处理订阅,因为订阅状态会阻塞常规命令。典型模式是:主线程用普通连接发布消息,单独开线程使用订阅连接接收消息。收到消息后通过条件变量或队列通知主线程。注意订阅连接需要保持活跃, 设置TCP_KEEPALIVE,并实现自动重连机制。当频道数量超过100时 改用Redis Streams。