帮你快速理解、总结文档立即下载

C 连接示例

最近更新时间:2026-10-20 11:39:02
本文档已由 AI 辅助审校
我的收藏
本文介绍使用 C 语言客户端通过代理模式和直连模式连接腾讯云分布式缓存数据库实例的示例。

准备工作

环境要求

GCC 4.8及以上版本。
CMake 或 Make 构建工具。

安装客户端

推荐使用 hiredis(Redis 官方 C 客户端)和 hiredis-cluster(集群支持):
安装 hiredis
git clone https://github.com/redis/hiredis.git
cd hiredis
make
sudo make install
安装 hiredis-cluster(直连模式需要)
git clone https://github.com/Nordix/hiredis-cluster.git
cd hiredis-cluster
mkdir build && cd build
cmake ..
make
sudo make install

编译链接

# 代理模式
gcc -o redis_example redis_example.c -lhiredis

# 直连模式
gcc -o redis_cluster_example redis_cluster_example.c -lhiredis_cluster -lhiredis

获取连接信息

2. 在实例列表中,单击目标实例 ID,进入实例详情页。
3. 在网络信息区域,获取实例 VIP 地址和端口(默认6379)。
4. 在配置信息区域,获取实例的连接密码。
默认账号使用 实例 ID:密码 格式,自定义账号使用 用户名@密码 格式;免密认证实例无需密码。

代理模式连接示例

代理模式下,客户端通过 Proxy 代理层提供的统一 VIP 地址连接实例,Proxy 自动处理请求路由和故障转移,客户端无需感知后端拓扑变化。

hiredis 基础连接示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hiredis/hiredis.h>

int main() {
// 连接参数
const char *host = "192.xx.xx.2"; // 实例 VIP 地址
int port = 6379; // 实例端口
const char *password = "crs-xxxx:密码"; // 默认账号密码格式:实例ID:密码

struct timeval timeout = {2, 0}; // 连接超时 2 秒

// 建立连接
redisContext *c = redisConnectWithTimeout(host, port, timeout);
if (c == NULL || c->err) {
if (c) {
printf("Connection error: %s\\n", c->errstr);
redisFree(c);
} else {
printf("Connection error: can't allocate redis context\\n");
}
return 1;
}

// 认证
redisReply *reply = redisCommand(c, "AUTH %s", password);
if (reply == NULL || reply->type == REDIS_REPLY_ERROR) {
printf("Auth failed: %s\\n", reply ? reply->str : "unknown error");
freeReplyObject(reply);
redisFree(c);
return 1;
}
freeReplyObject(reply);

// 写入数据
reply = redisCommand(c, "SET name %s", "腾讯云分布式缓存数据库");
printf("SET result: %s\\n", reply->str);
freeReplyObject(reply);

// 读取数据
reply = redisCommand(c, "GET name");
printf("GET name: %s\\n", reply->str);
freeReplyObject(reply);

// 设置带过期时间的 Key
reply = redisCommand(c, "SETEX session:user123 3600 %s", "session_data");
printf("SETEX result: %s\\n", reply->str);
freeReplyObject(reply);

// 哈希操作
reply = redisCommand(c, "HSET user:1001 name %s age %s", "张三", "28");
printf("HSET result: %lld\\n", reply->integer);
freeReplyObject(reply);

reply = redisCommand(c, "HGET user:1001 name");
printf("HGET name: %s\\n", reply->str);
freeReplyObject(reply);

// 列表操作
reply = redisCommand(c, "LPUSH queue:tasks %s %s %s", "task1", "task2", "task3");
printf("LPUSH result: %lld\\n", reply->integer);
freeReplyObject(reply);

reply = redisCommand(c, "RPOP queue:tasks");
printf("RPOP: %s\\n", reply->str);
freeReplyObject(reply);

// 关闭连接
redisFree(c);
return 0;
}

SSL 加密连接示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hiredis/hiredis.h>
#include <hiredis/hiredis_ssl.h>

int main() {
const char *host = "192.xx.xx.2";
int port = 6379;
const char *password = "crs-xxxx:密码";
const char *ca_cert = "/path/to/ca.pem";

struct timeval timeout = {2, 0};

// 初始化 SSL
redisInitOpenSSL();

// 创建 SSL 上下文
redisSSLContext *ssl_context = redisCreateSSLContext(
ca_cert, // CA 证书
NULL, // 客户端证书(不需要)
NULL, // 客户端私钥(不需要)
NULL, // 证书密码
NULL, // 错误信息
NULL // 错误信息长度
);

if (ssl_context == NULL) {
printf("Failed to create SSL context\\n");
return 1;
}

// 建立 SSL 连接
redisContext *c = redisConnectWithTimeout(host, port, timeout);
if (c == NULL || c->err) {
printf("Connection error: %s\\n", c ? c->errstr : "unknown");
redisFreeSSLContext(ssl_context);
if (c) redisFree(c);
return 1;
}

// 初始化 SSL 连接
if (redisInitiateSSLWithContext(c, ssl_context) != REDIS_OK) {
printf("SSL init error: %s\\n", c->errstr);
redisFreeSSLContext(ssl_context);
redisFree(c);
return 1;
}

// 认证
redisReply *reply = redisCommand(c, "AUTH %s", password);
if (reply == NULL || reply->type == REDIS_REPLY_ERROR) {
printf("Auth failed: %s\\n", reply ? reply->str : "unknown");
if (reply) freeReplyObject(reply);
redisFreeSSLContext(ssl_context);
redisFree(c);
return 1;
}
freeReplyObject(reply);

// 操作数据
reply = redisCommand(c, "SET ssl_test %s", "encrypted_connection");
printf("SET: %s\\n", reply->str);
freeReplyObject(reply);

reply = redisCommand(c, "GET ssl_test");
printf("GET: %s\\n", reply->str);
freeReplyObject(reply);

// 清理资源
redisFree(c);
redisFreeSSLContext(ssl_context);
return 0;
}

直连模式连接示例

直连模式下,客户端使用 Redis Cluster 协议直接连接各分片节点,本地处理 MOVED/ASK 重定向,可直接使用社区标准的 Redis Cluster 客户端接入。
说明:
直连模式仅适用于集群架构实例。
需使用 hiredis-cluster 库(基于 hiredis 的集群扩展)。
需在控制台开启直连模式并获取各分片节点的连接地址。
认证方式复用 Redis 原生 ACL 机制:默认账号仅传密码,自定义账号需分别设置账号名与密码,不支持 用户名@密码 拼接格式。
直连模式暂不支持 SSL 加密连接。

hiredis-cluster 基础连接示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hiredis/hiredis.h>
#include <hiredis_cluster/hircluster.h>

int main() {
// 直连模式下各分片节点地址
const char *nodes = "192.xx.xx.2:6379,192.xx.xx.3:6379,192.xx.xx.4:6379";
const char *password = "password"; // 直连模式默认账号仅传密码,不带实例 ID 前缀

struct timeval timeout = {2, 0};

// 创建集群连接上下文
redisClusterContext *cc = redisClusterContextInit();
if (cc == NULL) {
printf("Failed to init cluster context\\n");
return 1;
}

// 设置连接超时
redisClusterSetOptionTimeout(cc, timeout);

// 设置密码
redisClusterSetOptionPassword(cc, password);

// 设置最大重定向次数
redisClusterSetOptionMaxRedirect(cc, 3);

// 连接集群
if (redisClusterSetOptionAddNodes(cc, nodes) != REDIS_OK) {
printf("Failed to set nodes\\n");
redisClusterFree(cc);
return 1;
}

if (redisClusterConnect2(cc) != REDIS_OK) {
printf("Connection error: %s\\n", cc->errstr);
redisClusterFree(cc);
return 1;
}

// 写入数据(客户端自动路由到正确的分片)
redisReply *reply = redisClusterCommand(cc, "SET cluster:key1 %s", "value1");
printf("SET key1: %s\\n", reply->str);
freeReplyObject(reply);

reply = redisClusterCommand(cc, "SET cluster:key2 %s", "value2");
printf("SET key2: %s\\n", reply->str);
freeReplyObject(reply);

// 读取数据
reply = redisClusterCommand(cc, "GET cluster:key1");
printf("GET key1: %s\\n", reply->str);
freeReplyObject(reply);

reply = redisClusterCommand(cc, "GET cluster:key2");
printf("GET key2: %s\\n", reply->str);
freeReplyObject(reply);

// 哈希操作
reply = redisClusterCommand(cc, "HSET user:{1001} name %s age %s", "张三", "28");
printf("HSET: %lld\\n", reply->integer);
freeReplyObject(reply);

reply = redisClusterCommand(cc, "HGET user:{1001} name");
printf("HGET name: %s\\n", reply->str);
freeReplyObject(reply);

// 使用 Hash Tag 确保相关 Key 路由到同一分片
reply = redisClusterCommand(cc, "SET {order:1001}:status %s", "paid");
printf("SET order status: %s\\n", reply->str);
freeReplyObject(reply);

reply = redisClusterCommand(cc, "SET {order:1001}:amount %s", "99.00");
printf("SET order amount: %s\\n", reply->str);
freeReplyObject(reply);

reply = redisClusterCommand(cc, "GET {order:1001}:status");
printf("GET order status: %s\\n", reply->str);
freeReplyObject(reply);

// 关闭连接
redisClusterFree(cc);
return 0;
}

自定义账号(ACL)连接示例

直连模式复用 Redis 原生 ACL 认证机制,使用自定义账号时需分别设置账号名与密码,不支持 用户名@密码 拼接格式。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hiredis/hiredis.h>
#include <hiredis_cluster/hircluster.h>

int main() {
const char *nodes = "192.xx.xx.2:6379,192.xx.xx.3:6379,192.xx.xx.4:6379";
// ===== ACL 认证机制:账号名与密码是两个独立字段 =====
// 直连模式的多账号能力基于 Redis 原生 ACL:控制台创建的每个自定义账号
// 都是一个独立的 ACL user,认证时客户端向节点发送 AUTH <account> <password>。
const char *username = "myuser"; // ACL 账号名 → AUTH account
const char *password = "MyPassword"; // 账号密码 → AUTH password(纯密码,无需拼接)

struct timeval timeout = {2, 0};

redisClusterContext *cc = redisClusterContextInit();
redisClusterSetOptionTimeout(cc, timeout);

// 分别设置账号名与密码(等价于执行 AUTH account password);
// 不要写成代理模式的 "myuser@MyPassword" 拼接格式。
redisClusterSetOptionUsername(cc, username);
redisClusterSetOptionPassword(cc, password);
redisClusterSetOptionMaxRedirect(cc, 3);
redisClusterSetOptionAddNodes(cc, nodes);

if (redisClusterConnect2(cc) != REDIS_OK) {
printf("Connection error: %s\\n", cc->errstr);
redisClusterFree(cc);
return 1;
}

redisReply *reply = redisClusterCommand(cc, "SET key %s", "value");
printf("SET: %s\\n", reply->str);
freeReplyObject(reply);

reply = redisClusterCommand(cc, "GET key");
printf("GET: %s\\n", reply->str);
freeReplyObject(reply);

redisClusterFree(cc);
return 0;
}

连接参数说明

参数
说明
推荐值
host
实例连接地址。代理模式为 VIP 地址,直连模式为分片节点地址
-
port
实例端口号
6379
timeout
连接超时时间
2 秒
password
认证密码
默认账号格式:实例 ID:密码
max_redirect
最大重定向次数
3

常见问题

连接超时

确认客户端所在 CVM 与分布式缓存数据库实例在同一 VPC 内。
确认安全组规则已放通对应端口。
确认连接地址和端口正确。

认证失败

代理模式:默认账号使用 实例 ID:密码,自定义账号使用 用户名@密码。
直连模式:复用 Redis ACL 认证,默认账号仅传密码(AUTH password),自定义账号需分别设置账号名与密码(AUTH account password),不支持 用户名@密码 拼接格式。
确认密码中无特殊字符导致解析异常。

直连模式 MOVED 错误

确认使用 hiredis-cluster 的 redisClusterCommand 而非 hiredis 的 redisCommand。
确认已在控制台开启直连模式。
确认节点地址为分片节点地址而非 VIP 地址。

编译链接错误

确认 hiredis 和 hiredis-cluster 已正确安装。
确认链接时指定了 -lhiredis 和 -lhiredis_cluster。