读分流说明
1. 什么是读分流
读分流是指把业务的读请求从 tcapsvr_master 转发到 tcapsvr_slave,由 slave 处理,从而减轻 master 压力、防止过载。
满足以下条件的表可以开启读分流:
- tcapsvr_master 处理能力已接近上限,需要快速缓解其压力;
- 业务读请求在总访问量中占比较大;
- 业务能接受这张表由强一致性降级为最终一致性(主从同步时延通常在 10ms 级别)。
⚠️ 读分流的核心代价是一致性降级:slave 数据相对 master 有同步时延,刚写入的数据可能在 slave 上短暂读不到 / 读到旧值。对一致性敏感的读(如写后立即读、计数校验)不要开启读分流。
2. 两种开启方式
读分流有两种开启入口,二者可叠加,但任意一个开了读分流都会生效:
| 开启方式 | 入口 | 控制粒度 | 谁来操作 |
|---|---|---|---|
| OMS 页面开启 | TcaplusDB OMS 控制台 | 可按 App / Zone / Table,并设置时段、命令、比例、是否回 master 重试 | 联系 DBA 开启,见 设置读分流 |
| SDK 侧开启 | 在请求上设置读分流标记 | 按单次请求,由业务代码控制 | 业务自己在代码里设置 |
3. 支持读分流的命令字
只有读类命令支持分流到 slave;写类命令会被忽略读分流标记。当前支持的命令字:
| 类别 | 命令字 |
|---|---|
| 单条 / 部分 Key 读 | GET_REQ、GET_BY_PARTKEY_REQ、BATCH_GET_BY_PARTKEY_REQ |
| 批量读 | BATCH_GET_REQ |
| List 读 | LIST_GET_REQ、LIST_GETALL_REQ |
| 遍历 | TABLE_TRAVERSE_REQ、LIST_TABLE_TRAVERSE_REQ |
| 索引查询 | QUERY_REQ、LIST_QUERY_REQ |
| 字段读 | PB_FIELD_GET_REQ、PB_BATCH_FIELD_GET_REQ |
| 元数据 / 统计 | METADATA_GET_REQ、GET_TABLE_RECORD_COUNT_REQ |
4. OMS 页面开启(联系 DBA)
OMS 页面可对指定 App / Zone / Table 配置读分流,并支持配置生效时段、命令、分流比例、是否回 master 重试等策略,适合不改代码、按表整体开启的场景。
具体操作步骤见 TcaplusDB OMS 控制台 - 设置读分流。
5. SDK 侧开启
5.1 两种读分流标记
SDK 通过请求标记位(flag)开启读分流,proxy 据此选路:
| 标记 | 值 | 语义 | 支持的 SDK |
|---|---|---|---|
ONLY_READ_FROM_SLAVE |
0x00000004 |
只读 slave,不回退 master(slave 不可用则请求失败) | C++ TDR / C++ PB / Go |
PRIORITY_READ_FROM_SLAVE |
0x00000100 |
优先读 slave,slave 故障 / dump / 超时时自动回退 master | C++ TDR (SP05版本支持)/ C++ PB (SP05版本支持)/ Go (20260529以后的版本) |
说明(基于 proxy 选路源码):
- 两个标记同时置位时以
PRIORITY_READ_FROM_SLAVE为准(允许回退 master)。 - 当 slave 正在 dump binlog 等场景时,proxy 会临时暂停该节点的读分流;在暂停窗口内,即使设置了
ONLY_READ_FROM_SLAVE/PRIORITY_READ_FROM_SLAVE也会回退到 master。 ONLY_READ_FROM_SLAVE模式不回退 master,slave 不可用时请求直接失败,请谨慎使用;需要可用性兜底时,C++ TDR 推荐用PRIORITY,或改用 OMS 配置(OMS 可配置回 master 重试)。
5.2 C++ TDR SDK
在请求上调用 SetFlags():
TcaplusServiceRequest* request = tcaplus_server.GetRequest(TableName);
request->Init(TCAPLUS_API_GET_REQ, ...);
// ... 设置 key ...
// 方式一:只读 slave,不回退 master
request->SetFlags(TCAPLUS_FLAG_ONLY_READ_FROM_SLAVE);
// 方式二:优先读 slave,slave 异常时自动回退 master(推荐)
// request->SetFlags(TCAPLUS_FLAG_PRIORITY_READ_FROM_SLAVE);
tcaplus_server.SendRequest(request);
SetFlags会校验命令字:对不支持读分流的命令字(如写请求)会返回-1,业务应检查返回值。
5.3 C++ PB SDK
PB SDK 在请求结构体上设置 m_nFlag(仅支持 ONLY 模式,无 PRIORITY):
// 以 ListGetAll 为例,其它读请求结构体(IndexGetRequest / GlobalIndexGetRequest /
// ListGetRequest / ListBatchGetRequest 等)同样通过 m_nFlag 设置
NS_TCAPLUS_PROTOBUF_API::ListGetAllRequest req;
req.m_pMsg = msg; // 填好主 key
req.m_nFlag = TCAPLUS_PB_API_FLAG_ONLY_READ_FROM_SLAVE; // 只读 slave
// req.m_nFlag = TCAPLUS_PB_API_FLAG_PRIORITY_READ_FROM_SLAVE; // 优先读 slave
g_stAsyncApi.ListGetAll(req, &cb);
5.4 Go SDK
高级用法(Do* 接口 + option):
opt := &option.TDROpt{
Flags: option.TcaplusFlagOnlyReadFromSlave, // 只读 slave(值为 4)
// option.TcaplusFlagPriorityReadFromSlave 优先读 slave
}
err := client.DoGet(TableName, data, opt)
底层用法(NewRequest + Do / DoMore):
req, err := client.NewRequest(ZoneId, TableName, cmd.TcaplusApiGetReq)
if err != nil {
return err
}
req.SetFlags(int32(tcaplus_protocol_cs.TCAPLUS_FLAG_ONLY_READ_FROM_SLAVE))
// TCAPLUS_FLAG_PRIORITY_READ_FROM_SLAVE 优先读 slave
// ... 设置 key 后发送 ...
5.5 遍历的读分流(C++ TDR / C++ PB / Go)
遍历(Traverse / ListTraverse)只提供 ONLY 模式开关,没有 PRIORITY, 但遍历机制SDK自动保证了丢包重试,强制slave遍历,减小对Master压力:
| SDK | 开启方式 | 内部使用标记 |
|---|---|---|
| C++ TDR | TcaplusServiceTraverser::SetOnlyReadFromSlave(true) |
ONLY |
| C++ PB | TraverseRequest::m_readFromSlave = true / ListTraverseRequest::m_readFromSlave = true |
ONLY(内部转调 SetOnlyReadFromSlave) |
| Go | traverser.SetOnlyReadFromSlave(true) |
ONLY |
// C++ TDR
TcaplusServiceTraverser* traverser = tcaplus_server.GetTraverser(TableName);
traverser->SetOnlyReadFromSlave(true);
// C++ PB
NS_TCAPLUS_PROTOBUF_API::TraverseRequest req;
req.m_pMsg = msg;
req.m_readFromSlave = true; // 遍历走 slave
g_stAsyncApi.Traverse(req, &cb);
// Go
traverser := client.GetTraverser(ZoneId, TableName)
if err := traverser.SetOnlyReadFromSlave(true); err != nil {
return err
}
6. 注意事项
- 一致性降级:读分流会读到 slave 的数据,存在主从同步时延,写后立即读等强一致场景不要开启。
ONLY模式无兜底:slave 不可用时请求直接失败;需要高可用,非遍历读请用 C++ TDR 的PRIORITY模式(带回 master 重试,见 §5.5)。- slave dump binlog 期间自动暂停:proxy 会在该窗口内把读请求回退到 master,业务无需感知(
ONLY语义在 dump 暂停期同样会被回退)。
7. 与其它文档的关系
- OMS 页面操作步骤详见 TcaplusDB OMS 控制台 - 设置读分流。