简介
根据网上一些使用案例列出目前TiDB和mysql在使用上的区别和目前的遇到的常见问题及解决方案,当然具体的使用问题还需要大量的线下测试才能确认。
问题类型 | 问题描述 | 原因及解决办法 |
---|---|---|
DDL | 在一个 DDL 里不能对多个列或者多个索引做操作。 | ADD/DROP INDEX/COLUMN 操作目前不支持同时创建或删除多个索引或列, 需要拆分单独执行,官方表示 3.0 版本有计划改进。 |
建表语句执行速度相比 MySQL 较慢 | 多台 TiDB 的时候,Owner 和接收 create table 语句的 TiDB Server 不在一台 Server 上时, 可能比 MySQL 慢一些,每次操作耗时在 0.5s 左右,官方表示会在后续的版本中不断完善。 | |
大表建索引时对业务有影响 | 官方建议在业务低峰期操作,在 2.1 版本中已经增加了操作优先级以及并发读的控制,情况有改善。 | |
TiDB 对于 MySQL 用户授权 SQL 语法的兼容支持尚不完善, 目前不支持 SHOW CREATE USER 语法, 有时候不得不读取系统表(mysql.user)来查看一个数据库账户的基本信息 | 希望后续版本优化 | |
DML | 部分操作符查询优化器支持不够好,比如 or 操作符会使用 TableScan, 改写成 union all 可避免。 | 官方表示目前使用 or 操作符确实在执行计划上有可能不准确, 已经在改进计划中,后续 3.0 版本会有优化。 |
MySQL 事务中,可以通过影响条数,作为写入(或修改)是否成功的依据; 而在 TiDB 中,这却是不可行的。 | 原因: 对于 MySQL,当更新某条记录时,会先获取该记录对应的行级锁(排他锁), 获取成功则进行后续的事务操作,获取失败则阻塞等待。 对于 TiDB,使用 Percolator 事务模型:可以理解为乐观锁实现,事务开启、 事务中都不会加锁,而是在提交时才加锁。 解决方案: 在业务层,可以借助分布式锁,实现串行化处理,但是会增加开发成本。 | |
对于热数据,数据量一般不大,但是查询频度很高,比如查询 sql 为: 这个在 MySQL 中很高效的查询,在 TiDB 中虽然也可从索引检索, 但其耗时却不尽人意(百万级数据量,耗时百毫秒级)。 | 原因:在 TiDB 中,底层索引结构为 LSM-Tree。当从内存级的 C0 层查询不到数据时, 会逐层扫描硬盘中各层;且 merge 操作为异步操作,索引数据更新会存在一定的延迟,可能存在无效索引。 由于逐层扫描和异步 merge,使得查询效率较低。 解决方案: 尽可能缩小过滤范围,比如结合异步 job 获取记录频率,在保证不遗漏数据的前提下, 合理设置 execute_time 筛选区间,例如 1 小时,sql 改写为: | |
select count(1) tidb查询慢 | 原因:和上面类似。 tidb因为存储结构和查询方式的不同,tidb其实是暴力扫表。很多使用方也都反应慢, 这个是目前的TiDB的一个常见的问题。这里给出官方的解决方案:
| |
尚不支持的sql语法: |
| |
PD | 重启一个 PD 节点的时候,业务能捕捉到 PD 不可用的异常, 会报 PD server timeout 。 | 因为重启的是 Leader 节点,所以重启之前需要手动切换 Leader,然后进行重启。 官方建议这里可以通过重启前做 Leader 迁移来减缓, 另外后续 TiDB 也会对网络通讯相关参数进行梳理和优化。 |
pd-ctl 命令行参数解析严格,多一个空格会提示语法错误。 | 官方表示低版本中可能会有这个问题,在 2.0.8 及以上版本已经改进。 | |
TiDB | 现在 TiDB 的 GC 对于每个 kv-instance 是单线程的, 当业务删除数据的量非常大时,会导致 GC 速度较慢, 很可能 GC 的速度跟不上写入。 | 目前可以通过增多 TiKV 个数来解决,长期需要靠 GC 改为多线程执行,后续版本会支持。 |
TiKV | 存储空间放大问题 | 该问题属于 RocksDB,RocksDB 的空间放大系数最理想的值为 1.111, 官方建议在某些场景下通过 TiKV 开启 RocksDB 的 dynamic-level-bytes 以减少空间放大。 |
TiKV 容易发生 Write Stall | 原因: TiKV 底层有 2 个 RocksDB 作为存储。新写的数据写入 L0 层,当 RocksDB 的 L0 层数量达到一定数量, 就会发生减速,更高则发生 Stall,用来自我保护。 生 L0 文件过多可能的原因有 2 个:
解决: TiKV调优:
| |
添加 TiKV 节点后需要较长时间才能完成数据再平衡 | 1TB 数据大约需要 24 个小时才能完成拷贝,建议在低峰期引入 |
TiDB和Mysql优缺点对比
简单总结一下TiDB的优缺点:
TiDB优点
- 高度兼容mysql协议,迁移成本低
- 高可用:相比于传统主从(M-S)复制方案,基于 Raft 的多数派选举协议可以提供金融级的 100% 数据强一致性保证,且在不丢失大多数副本的前提下,可以实现故障的自动恢复(auto-failover),无需人工介入。
- 支持海量数据,可拓展性强:分布式数据库,可通过增加TiKV节点拓展,支持分裂和自动迁移,对业务基本无感知。
- 和传统的分库分表,相比业务拓展性较强:传统的分库分表技术,开发和维护成本都较高,业务侵入性也较大,使用TiDB会明显降低 RD 和 DBA 的开发维护成本。
- 分布式事务
TiDB的不足
- 对机器配置门槛要求较高,特别是内存和CPU的要求很高,当数据量不大时会增加机器的资源使用成本。
- TiDB对sql的支持尚不完善,对一些sql的执行性能并不理想,一些复杂sql需要重新设计,还有一些mysql的功能并不支持。
- TiDB技术较新,尚在不断优化中,因此也容易踩坑。
综合
综上所述,个人认为和mysql相比,
- TiDB目前更适合TB级的海量数据处理,数据量越大,使用场景和优势越明显,
- 也比较适合对查询性能要求不高的数据分析场景或离线计算场景
- 即时场景下查询上最适合海量数据下进行多维度的精确查询
- 整体而言TiDB技术仍不能算成熟,目前还在快速的更新和迭代过程中,容易采坑,建议引入也是先从离线业务->非核心业务->核心业务的使用过程。