对于一个业务系统,每天处理的事务量多达数十亿。
事务明细表设计如下:
-
按月分表,按日分区,同时按客户 ID 哈希分片 (
user_id % 1000
),表名格式:orders_<yyyymm>_<slot>
例如:orders_202505_000 ~ orders_202505_999
分片不只是可以将数据量拆分,也可以缩小数据库 DDL 操作锁表的影响范围。 -
同时,如果单个客户数据量过大,超过设置的阈值(比如平均每天事务量超过 100 万),就单独拿出来建立一张表。
格式和上面相同,只是分片编号改成客户 ID(大于 10000000)。
例如:orders_202505_10000001- 系统自行判断是否需要单独分表,无需人工介入
- 搜索的时候先判断客户表是否存在,如果存在就在客户表查询,如果不存在就在公共表查询。
为了提高效率,程序启动的时候检索所有明细表,记录单独存储的客户和月份信息(每天定时更新)。
-
区分冷热数据:每月月初归档 2 个月前的明细表(数据备份到归档库),比如 5/1 归档 2 月份的表 (数据库只保留 2 ~ 3 个月的明细数据)。
- 程序限制只能查询最近一个月的数据,更多数据查询需要单独开放权限,控制使用范围
- 数据迁移期间,对正在迁移的数据进行搜索的请求返回:数据维护,稍后再试。
- 通过异步工具分批迁移数据(pt-archiver)
- 归档数据又分成温数据和冷数据:分别存入 ClickHouse、ES、S3 等,提供不同类型的数据搜索接口
-
数据库代理服务:
- 统一读入口,所有查询传入的表名都是 orders,中间层根据客户 ID 和日期范围将表名映射到真实表上。
相关表的所有查询必须包含 user_id 和 send_date 两个条件。 - 统一写入口,所有数据先写入缓冲区(必须可靠,确保数据不丢失),然后批量提交到对应的表中。
- 统一读入口,所有查询传入的表名都是 orders,中间层根据客户 ID 和日期范围将表名映射到真实表上。