14 KiB
tags, create time
| tags | create time | ||||
|---|---|---|---|---|---|
|
2026-07-04 12:00 |
CacheCloud Redis 管理台
概述
CacheCloud(搜狐开源)是一个 Redis 私有云平台,支持 Standalone、Sentinel、Cluster 三种架构的一站式高效管理。xinfra 中所有需要 Redis 服务的场景都通过 CacheCloud 进行统一的实例申请和管理——开发同学不再需要手动安装部署 Redis,只需在平台上提交工单即可获取可用实例。
核心目标:降低大规模 Redis 运维成本,提升资源管控能力和利用率。平台提供快速搭建/迁移、运维管理、弹性伸缩、统计监控、客户端整合接入等功能。
系统架构
整体拓扑
graph TB
subgraph "用户层"
Dev[开发同学 / 运维人员]
end
subgraph "接入层 (Nginx 双机房)"
NG1[Nginx 机房 A]
NG2[Nginx 机房 B]
VIP[Virtual IP → 双向漂移]
VIP --> NG1
VIP --> NG2
end
subgraph "应用层 (Spring Boot)"
CC[CacheCloud Web Server]
DB[(MySQL 元数据)]
AGT_Mgr[Agent 管理器]
ALERT[报警组件<br/>邮件 / 微信 / HTTP]
CUSTOM[自定义扩展模块]
end
subgraph "执行层 (Agent 代理)"
AGT1[Agent 宿主机 A<br/>Redis Standalone / Sentinel]
AGT2[Agent 宿主机 B<br/>Redis Cluster Shard 1]
AGT3[Agent 宿主机 C<br/>Redis Cluster Shard 2]
end
Dev -->|cc.company.com| VIP
VIP --> NG1 & NG2
NG1 & NG2 --> CC
CC <--> DB
CC --> AGT_Mgr
CC --> ALERT
CC --> CUSTOM
AGT_Mgr -->|SSH + 心跳| AGT1 & AGT2 & AGT3
关键设计决策:CacheCloud 采用 Agent 模式而非直接 SSH 连接 Redis 实例。每个宿主机部署一个 Agent 进程,负责该机器上所有 Redis 实例的生命周期管理(启停、升级、备份恢复)。这样做的好处是 Agent 可复用 SSH 连接、缓存本地状态,大幅减少管理平台到 Redis 主机的网络开销。
核心组件
| 组件 | 职责 |
|---|---|
| Web UI / REST API | 自助申请实例、配置修改、工单审批、监控大屏 |
| Agent 代理 | 部署在每个宿主机上,负责 Redis 进程生命周期管理、状态上报、远程命令执行 |
| 元数据库 (MySQL) | 存储实例拓扑、配置模板、账号权限、工单流转记录 |
| 报警模块 | 内置邮件和微信报警,同时暴露 HTTP 接口供任意语言集成 |
| 扩展模块 | 登录组件 (LoginComponent)、报警组件 (EmailComponent/WeChatComponent) 均可自行实现 |
实例类型与选型指南
三种架构对比
| 维度 | Standalone | Sentinel (Master-Slave) | Cluster |
|---|---|---|---|
| 高可用 | ❌ 单机,无 Failover | ✅ 主从 + Sentinel 自动故障转移 | ✅ 多分片,自动槽迁移 |
| 横向扩展 | ❌ 受单机容量限制 | ❌ 受单机容量限制 | ✅ 新增节点即扩容 |
| 复杂度 | 简单 | 中等 | 较高 |
| 推荐场景 | 测试环境、低频读写缓存 | 生产环境常规业务、内存需求 ≤ 6GB | 大数据量、高并发、内存需求 > 6GB |
建议:并不是 Cluster 越好。如果当前或未来所需内存不超过 6GB 且要求高可用,选择 Sentinel 就足够了。
选型决策树
flowchart TD
Start{是否需要高可用?}
Start -->|否: 测试/灰度| Standalone[Standalone]
Start -->|是| NeedScale{是否需要横向扩展?}
NeedScale -->|否≤6GB| Sentinel[Sentinel 主从]
NeedScale -->|是>6GB| Cluster[Redis Cluster]
客户端接入方式
CacheCloud 提供了多种客户端 SDK 及 REST API,覆盖 Java、Python 等主流语言。
REST API(最通用)
通过简单 HTTP 请求即可获取实例连接信息,适用于任何语言:
GET http://{domain}/cache/client/redis/{appType}/{appId}.json?clientVersion={version}
参数说明:
| 参数 | 含义 | 枚举值 |
|---|---|---|
appType |
实例类型 | cluster / sentinel / standalone |
appId |
应用 ID | 平台分配的数字 ID |
响应示例:
{
"message": "client is up to date, Cheers!",
"shardNum": 10,
"appId": 10192,
"status": 1,
"shardInfo": "10.10.xx.xx:6390,10.10.xx.xx:6382 10.10.xx.xx:6387,10.10.xx.xx:6379 ..."
}
shardInfo字段以空格分隔每个分片,逗号分隔同一个分片的主从地址。解析后即可直连。
Java — cachecloud-client-redis(Jedis 封装)
@Configuration
public class RedisConfiguration {
@Bean(destroyMethod = "close")
public PipelineCluster pipelineCluster(@Value("${cachecloud.demo.appId}") long appId) {
return ClientBuilder.redisCluster(appId).build();
}
@Bean(destroyMethod = "destroy")
public JedisSentinelPool jedisSentinelPool(@Value("${cachecloud.demo.appId}") long appId) {
return ClientBuilder.redisSentinel(appId).build();
}
@Bean(destroyMethod = "destroy")
public JedisPool jedisPool(@Value("${cachecloud.demo.appId}") long appId) {
return ClientBuilder.redisStandalone(appId).build();
}
}
使用方式:
@Autowired private PipelineCluster pipelineCluster;
public String get(String key) {
return pipelineCluster.get(key);
}
所有
...Pool.getResource()使用后必须调用jedis.close()—— 它并非真正关闭连接,而是将连接归还给连接池(内部判断连接是否损坏后决定returnResource还是returnBrokenResource)。
Java — cachecloud-client-lettuce(Lettuce 封装)
适合需要异步/响应式场景的应用:
@Bean(destroyMethod = "shutdown")
public RedisClusterClient redisClusterClient(long appId, String password) {
return LettuceClientBuilder.redisCluster(appId, password).build();
}
@Bean(destroyMethod = "close")
public StatefulRedisClusterConnection<String, String> clusterConnection(RedisClusterClient client) {
StatefulRedisClusterConnection<String, String> conn = client.connect();
conn.setReadFrom(ReadFrom.REPLICA_PREFERRED); // 读操作优先走从节点
return conn;
}
Python 接入(REST API 动态拉取连接信息)
import requests
from rediscluster import RedisCluster
app_id = 10192
url = f'http://cc.company.com/cache/client/redis/cluster/{app_id}.json'
resp = requests.get(url).json()
startup_nodes = [
dict(zip(['host', 'port'], addr.split(':')))
for shard in resp['shardInfo'].split(' ')
for addr in shard.split(',')
]
rc = RedisCluster(startup_nodes=startup_nodes, password='your-pass')
跨机房部署(Cross-Room)
对于容灾要求高的业务,CacheCloud 支持跨机房双活:同一业务在两个机房分别部署应用实例,客户端 SDK 自动做双写双读和机房切换。原理是两个 PipelineCluster 实例被包装进一个 RedisCrossRoomClient。
系统功能全景
用户端功能
| 功能 | 说明 |
|---|---|
| 应用管理 | 查看统计信息、实例列表、应用拓扑、连接信息 |
| 监控面板 | 命令曲线、延迟监控、日报统计 |
| 命令执行 | 在线执行 Redis 命令用于排查 |
| 键值分析 | 分析 bigkey、hotkey 分布 |
运维端功能
| 功能分类 | 具体能力 |
|---|---|
| 数据统计 | 全局统计、client 统计、server 统计 |
| 工单审批 | 实例申请、配置修改、数据清理等操作需管理员审批 |
| 应用运维 | 应用维度的启停、配置下发、日志查看 |
| 实例运维 | 实例维度的启停、配置查询、数据清理 |
| 数据迁移 | 跨实例数据迁移工具 |
| 诊断工具 | 慢查询分析、连接数诊断等 |
| 模板管理 | 按规格预设 Redis 配置模板(maxmemory、持久化策略等) |
| 任务流 | 编排运维操作流程(如批量升级) |
报警配置
CacheCloud 内置的报警覆盖了 Redis 机器级别和实例级别的重要指标,支持的报警渠道:
- 邮件报警 — 默认实现,也可替换为 HTTP 回调
- 微信报警 — 企业微信/钉钉 webhook 风格
报警可通过 HTTP 接口自定义,格式如下:
POST www.xxx.com/emailAlert?title=xx&content=xx&receiver=x&cc=x
POST www.xxx.com/weChatAlert?title=xx&message=xx&weChatList=xx
基础运维实践
maxmemory-policy 策略选择
| 策略 | 行为 | 适用场景 |
|---|---|---|
volatile-lru |
删除有过期时间的 key,LRU 淘汰 | 默认策略,有 TTL 的缓存 |
allkeys-lru |
对所有 key 做 LRU 淘汰 | 纯缓存场景,不设 TTL |
volatile-ttl |
删除即将过期的 key | 希望按过期时间优先淘汰 |
noeviction |
不淘汰,写操作返回错误 | 需要绝对保证数据完整性 |
注意:修改的配置会对应用的所有节点生效,因为所有节点的配置是统一的。
Jedis 连接池调优参考
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(DEFAULT_MAX_TOTAL * 5); // 根据实际 QPS 调整
poolConfig.setMaxIdle(DEFAULT_MAX_IDLE * 3);
poolConfig.setMinIdle(DEFAULT_MIN_IDLE * 2);
poolConfig.setMaxWaitMillis(3000); // 连接耗尽时最多等待 3s
poolConfig.setJmxEnabled(true); // 开启 JMX 便于观察
poolConfig.setTestWhileIdle(true); // 空闲时定期检查连接有效性
poolConfig.setTimeBetweenEvictionRunsMillis(60000); // 每分钟检查一次
关键字段解读:
| 配置项 | 默认值 | 调优建议 |
|---|---|---|
maxTotal |
8 | 根据峰值连接数估算,通常 × 3~5 |
testOnBorrow |
false | 不建议设为 true,会显著增加延迟 |
testOnReturn |
false | 一般保持 false,由 testWhileIdle 兜底 |
whenExhaustedAction |
1 (阻塞) | 配合 maxWaitMillis 使用,避免无限等待 |
常见陷阱与最佳实践
1. Bigkey 的寻找与优化
什么是 bigkey:value 所占内存空间较大的 key。字符串类型超过 100KB 即视为 bigkey;非字符串类型(Hash/List/Set/ZSet)则以元素数量过多为准。
危害:
- 内存不均匀:Cluster 中造成部分节点内存暴增
- 超时阻塞:Redis 单线程特性下,大 key 操作耗时 > 客户端超时
- 网络拥塞:单次大流量冲击网卡,影响同机其他实例
- 过期删除阻塞:未启用 lazyfree 时阻塞主线程
- 碎片整理冲突:Redis 4.0+ activeDefrag 对超大 key 可能导致周期性延迟
发现手段:
| 方法 | 命令 | 特点 |
|---|---|---|
| redis-cli | redis-cli --bigkeys |
全量扫描,建议在从节点执行 |
| DEBUG OBJECT | DEBUG OBJECT key |
获知序列化长度 serializedlength |
| MEMORY USAGE | MEMORY USAGE key |
仅 Redis 4.0+,返回精确内存占用 |
| 监控输出缓冲区 | info clients 关注 client_biggest_input_buf / client_recent_max_output_buffer |
间接判断是否存在大 key 读取 |
优雅删除方案:
- String:直接使用
DEL,通常不会阻塞 - Hash/List/Set/ZSet:使用
HSCAN/SSCAN/ZSCAN分批获取元素 +HDEL/SREM/ZREM逐个删除,或使用 Redis 4.0+ 的UNLINK(异步删除)
def del_big_hash(r, key):
cursor = 0
while True:
cursor, members = r.hscan(key, cursor, count=100)
if not members:
break
r.hdel(key, *members) # pipeline 批量更高效
if cursor == 0:
break
2. Hotkey 的处理方向
当某个 key 的访问量远超平均水平时:
- 本地缓存:在应用侧加一层 Guava/Caffeine 缓存
- key 拆分:将一个大 key 拆成多个子 key(如
user:1001:friends→user:1001:friends:1,user:1001:friends:2) - 读写分离:读操作通过 Sentinel 路由到从节点
3. 实例规格匹配
不要盲目选大规格。建议先通过 Prometheus/Grafana 观察历史 QPS、内存使用和连接数,再确定实例规格。过度配置会在资源看板上体现为浪费。
4. 临时 vs 长期实例
- 临时实例(测试/灰度用)应设置自动回收策略——超出保留期后系统自动销毁
- 长期实例则需要完善监控、定期巡检配置变更
5. 机房就近原则
Redis 对网络延迟非常敏感。跨机房访问比同机房慢数倍,因此应用申请时应填写服务所在机房,确保实例分配到最近的机器。
Redis 版本演进速览
CacheCloud 管理的 Redis 实例可能运行在不同版本,了解各版本的关键特性有助于理解平台行为差异:
| 版本 | 核心新特性 | CacheCloud 相关 |
|---|---|---|
| 3.x | 原生 Cluster | 最早支持的 Cluster 形态 |
| 4.0 | Lazyfree 异步删除、AOF/RDB 混合持久化、内存碎片整理 | 支持 UNLINK 删除 bigkey |
| 5.0 | Stream 数据类型、RESP3 协议、Dynamic HZ | 客户端兼容性更好 |
| 6.0 | 多线程 IO、ACL、SSL 加密、协助客户端缓存 | 多线程 IO 提升非 Pipeline 场景 2 倍性能 |
启发问题:为什么 Redis 6.0 的多线程只处理网络 IO 而不涉及命令执行?这背后有什么权衡?
与 xinfra 的对接方向
进阶目标中提到要「基于 CacheCloud API 实现页面直接创建 Redis Cluster」,这意味着:
- 阅读 Open API 文档:梳理可用的创建/配置/查询接口
- 封装创建流程:选择规格 → 调用 API → 等待就绪 → 返回连接信息
- 集成到 xinfra 统一服务管理页面:让开发者在 xinfra 内即可完成 Redis 实例的全生命周期操作
- 可选增强:对接 xinfra 的审批流、用量统计、成本分摊等模块
关联笔记
- technical/xinfra-preview/cloud-dm-overview — SQL 审核与 Redis 访问同属数据层基础设施
- technical/xinfra-preview/k8s-rke2-fundamentals — CacheCloud 的宿主机未来可能迁移至 K8s 部署
- https://github.com/sohutv/cachecloud — CacheCloud GitHub 仓库(含完整 Wiki 和代码)
- https://github.com/antirez/redis — Redis 官方仓库