1 简介
TiDB支持水平弹性扩展、ACID 事务、标准 SQL、MySQL 语法和 MySQL 协议,具有数据强一致的高可用特性,是一个不仅适合 OLTP 场景还适OLAP 场景的混合数据库。
开发语言 SQL层:GO TiKV分布式存储引擎: Rust
文档:
https://docs.pingcap.com/zh/tidb/stable/overview
https://zhuanlan.zhihu.com/p/71073707
应用场景:
- 海量数据、高并发 OLTP 系统(高并发写入、水平扩展、分布式事务、强一致性、在线DDL、高可用)。
- 海量数据、高性能实时分析 HTAP(实时风控/数仓/报表)。
TiDB 实践
今日头条:http://t.cn/RnLfEMf
游族平台:https://mp.weixin.qq.com/s/_VAWuTO2KUlGB8B0ouLRTw
马蜂窝:https://www.slidestalk.com/TUG/MongoDBTiDB65928
同程旅游:https://segmentfault.com/a/1190000014361145
易果集团(实时数仓):http://t.cn/RTYVhzH
二维火餐饮(实时报表):https://mp.weixin.qq.com/s/Ui3i2xhvPB_gig3WU_2Jaw
对比MySQL
不支持的特性
- 存储过程
- 视图
- 触发器
- 自定义函数
- 外键约束
- 全文索引
- 空间索引
- 非 UTF8 字符集
有差异的特性
2 架构
TiDB Server
至少2台, 集群万兆网卡。
接收并处理SQL请求,通过PD找到数据的 TiKV 地址并返回结果。
其本身并不存储数据,只负责计算,可以无限水平扩展,可以通过负载均衡组件(如LVS、HAProxy 或 F5)对外提供统一的接入地址。
TiKV Server
至少3台,与 TiDB 分开部署,以免竞争 CPU, 使用 本地SSD 磁盘。
- 负责存储数据。是一个分布式的提供事务的 Key-Value 存储引擎。
- 其存储数据的基本单位是 Region,每个 Region 负责存储一个 Key Range (从 StartKey 到 EndKey 的左闭右开区间)的数据,每个 TiKV 节点会负责多个 Region 。
- 使用 Raft 协议做复制,保持数据的一致性和容灾。副本以 Region 为单位进行管理,不同节点上的多个 Region 构成一个 Raft Group,互为副本。
- TiKV 之间的负载均衡以 Region 为单位 由 PD 调度。
PD Server
必须3台。
Placement Driver,整个集群的管理模块,其主要工作有三个:
- 一是存储集群的元信息(某个 Key 存储在哪个 TiKV 节点);
- 二是对 TiKV 集群进行调度和负载均衡(如数据的迁移、Raft group leader 的迁移等);
- 三是分配全局唯一且递增的事务 ID。
- PD 是一个集群,需要部署奇数个节点,一般线上推荐至少部署 3 个节点。


3 负载均衡
- 存储的负载均衡
- 计算的负载均衡
- 下线节点
- 上线节点
PD 会根据整个 TiKV 集群的状态, 对集群的负载进行调度。 以 Region 为单位,以 PD 配置的策略为调度逻辑,自动完成。
4 SQL 在 KV 原理
- Database/Table 的元信息(定义、属性、Schema信息等)会分配一个唯一的 ID 标识,存储在 TiKV 中,编码成 KV 对,key: ID+m_前缀,value: 序列化后的元数据
- 表:TiDB 对每个表分配一个 TableID (整个集群内唯一);
- 行:每一行分配一个 RowID(表内唯一, 如果表有整形的 Primary Key,那么会用 Primary Key 的值当做 RowID);
这些ID都是int64类型。每行数据按照如下规则进行编码成Key-Value pair:
Key: tablePrefix_rowPrefix_tableID_rowIDValue: [col1, col2, col3, col4]
索引:每一个索引都会分配一个 IndexID (表内唯一),映射为KV,key 以 TableID+indexID 构造前缀,以索引值构造后缀;
-- 唯一索引Key: tablePrefix_idxPrefix_tableID_indexID_indexColumnsValueValue: rowID-- 非唯一Key: tablePrefix_idxPrefix_tableID_indexID_ColumnsValue_rowIDValue:null
注
xxPrefix都是字符串常量。 定义如下: var( tablePrefix = []byte{‘t’} recordPrefixSep = []byte(“_r”) indexPrefixSep = []byte(“_i”) )
5 TiDB 表设计
表特性:
- 行存储格式,全局排序。
- 主键:业务列,自增主键,隐式主键。
- 超级超宽表:经验值单行大小 < 64K。
- 顺序扫描,尽量减少逆序 scan。
- 主键、索引连续还是离散?
- N + 1 KV Pairs 的写入,事务模型保证一致性。
- 一行的数据都是存在一个 KV Pair 中,不会被切分。
- 一次体检的全部数据 小于 100 MB.
考虑 TiDB 做编码以及事务额外 key 的开销,建议每个事务的行数不多于一万。
建议 Insert、Update、Delete 语句,都通过分 Batch 提交或增加 Limit 限制。
6 数据导入与写入
7 查询及优化
查看执行计划
EXPLAIN select * from A
查询并终止连接
SHOW PROCESSLIST;KILL TIDB id;
8 注意事项
- 删除大数据量的时候,用小数据量多批量方式操作,如每次 1000 条。
- 大批量数据导入后,建议操作: analyze table table_name

