使用 Physical Import Mode

本文档介绍如何编写 Physical Import Mode 的配置文件,如何进行性能调优等内容。

配置及使用

可以通过以下配置文件使用 Physical Import Mode 执行数据导入:

  1. [lightning]
  2. # 日志
  3. level = "info"
  4. file = "tidb-lightning.log"
  5. max-size = 128 # MB
  6. max-days = 28
  7. max-backups = 14
  8. # 启动之前检查集群是否满足最低需求。
  9. check-requirements = true
  10. [mydumper]
  11. # 本地源数据目录或外部存储 URL
  12. data-source-dir = "/data/my_database"
  13. [tikv-importer]
  14. # 导入模式配置,设为 local 即使用 Physical Import Mode
  15. backend = "local"
  16. # 冲突数据处理方式
  17. duplicate-resolution = 'remove'
  18. # 本地进行 KV 排序的路径。
  19. sorted-kv-dir = "./some-dir"
  20. [tidb]
  21. # 目标集群的信息。tidb-server 的地址,填一个即可。
  22. host = "172.16.31.1"
  23. port = 4000
  24. user = "root"
  25. # 设置连接 TiDB 的密码,可为明文或 Base64 编码。
  26. password = ""
  27. # 必须配置。表结构信息从 TiDB 的“status-port”获取。
  28. status-port = 10080
  29. # 必须配置。pd-server 的地址,填一个即可。
  30. pd-addr = "172.16.31.4:2379"
  31. # tidb-lightning 引用了 TiDB 库,并生成产生一些日志。
  32. # 设置 TiDB 库的日志等级。
  33. log-level = "error"
  34. [post-restore]
  35. # 配置是否在导入完成后对每一个表执行 `ADMIN CHECKSUM TABLE <table>` 操作来验证数据的完整性。
  36. # 可选的配置项:
  37. # - "required"(默认)。在导入完成后执行 CHECKSUM 检查,如果 CHECKSUM 检查失败,则会报错退出。
  38. # - "optional"。在导入完成后执行 CHECKSUM 检查,如果报错,会输出一条 WARN 日志并忽略错误。
  39. # - "off"。导入结束后不执行 CHECKSUM 检查。
  40. # 默认值为 "required"。从 v4.0.8 开始,checksum 的默认值由此前的 "true" 改为 "required"。
  41. #
  42. # 注意:
  43. # 1. Checksum 对比失败通常表示导入异常(数据丢失或数据不一致),因此建议总是开启 Checksum。
  44. # 2. 考虑到与旧版本的兼容性,依然可以在本配置项设置 `true` 和 `false` 两个布尔值,其效果与 `required` 和 `off` 相同。
  45. checksum = "required"
  46. # 配置是否在 CHECKSUM 结束后对所有表逐个执行 `ANALYZE TABLE <table>` 操作。
  47. # 此配置的可选配置项与 `checksum` 相同,但默认值为 "optional"。
  48. analyze = "optional"

Lightning 的完整配置文件可参考完整配置及命令行参数

冲突数据检测

冲突数据,即两条或两条以上的记录存在 PK/UK 列数据重复的情况。当数据源中的记录存在冲突数据,将导致该表真实总行数和使用唯一索引查询的总行数不一致的情况。冲突数据检测支持三种策略:

  • record: 仅将冲突记录添加到目的 TiDB 中的 lightning_task_info.conflict_error_v1 表中。注意,该方法要求目的 TiKV 的版本为 v5.2.0 或更新版本。如果版本过低,则会启用 ‘none’ 模式。
  • remove: 推荐方式。记录所有的冲突记录,和 ‘record’ 模式相似。但是会删除所有的冲突记录,以确保目的 TiDB 中的数据状态保持一致。
  • none: 关闭冲突数据检测。该模式是三种模式中性能最佳的,但是可能会导致目的 TiDB 中出现数据不一致的情况。

在 v5.3 版本之前,Lightning 不具备冲突数据检测特性,若存在冲突数据将导致导入过程最后的 checksum 环节失败;开启冲突检测特性的情况下,无论 record 还是 remove 策略,只要检测到冲突数据,Lightning 都会跳过最后的 checksum 环节(因为必定失败)。

假设一张表 order_line 的表结构如下:

  1. CREATE TABLE IF NOT EXISTS `order_line` (
  2. `ol_o_id` int(11) NOT NULL,
  3. `ol_d_id` int(11) NOT NULL,
  4. `ol_w_id` int(11) NOT NULL,
  5. `ol_number` int(11) NOT NULL,
  6. `ol_i_id` int(11) NOT NULL,
  7. `ol_supply_w_id` int(11) DEFAULT NULL,
  8. `ol_delivery_d` datetime DEFAULT NULL,
  9. `ol_quantity` int(11) DEFAULT NULL,
  10. `ol_amount` decimal(6,2) DEFAULT NULL,
  11. `ol_dist_info` char(24) DEFAULT NULL,
  12. PRIMARY KEY (`ol_w_id`,`ol_d_id`,`ol_o_id`,`ol_number`)
  13. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

若在导入过程中检测到冲突数据,则可以查询 lightning_task_info.conflict_error_v1 表得到以下内容:

  1. mysql> select table_name,index_name,key_data,row_data from conflict_error_v1 limit 10;
  2. +---------------------+------------+----------+-----------------------------------------------------------------------------+
  3. | table_name | index_name | key_data | row_data |
  4. +---------------------+------------+----------+-----------------------------------------------------------------------------+
  5. | `tpcc`.`order_line` | PRIMARY | 21829216 | (2677, 10, 10, 11, 75656, 10, NULL, 5, 5831.97, "HT5DN3EVb6kWTd4L37bsbogj") |
  6. | `tpcc`.`order_line` | PRIMARY | 49931672 | (2677, 10, 10, 11, 75656, 10, NULL, 5, 5831.97, "HT5DN3EVb6kWTd4L37bsbogj") |
  7. | `tpcc`.`order_line` | PRIMARY | 21829217 | (2677, 10, 10, 12, 76007, 10, NULL, 5, 9644.36, "bHuVoRfidQ0q2rJ6ZC9Hd12E") |
  8. | `tpcc`.`order_line` | PRIMARY | 49931673 | (2677, 10, 10, 12, 76007, 10, NULL, 5, 9644.36, "bHuVoRfidQ0q2rJ6ZC9Hd12E") |
  9. | `tpcc`.`order_line` | PRIMARY | 21829218 | (2677, 10, 10, 13, 85618, 10, NULL, 5, 7427.98, "t3rsesgi9rVAKi9tf6an5Rpv") |
  10. | `tpcc`.`order_line` | PRIMARY | 49931674 | (2677, 10, 10, 13, 85618, 10, NULL, 5, 7427.98, "t3rsesgi9rVAKi9tf6an5Rpv") |
  11. | `tpcc`.`order_line` | PRIMARY | 21829219 | (2677, 10, 10, 14, 15873, 10, NULL, 5, 133.21, "z1vH0e31tQydJGhfNYNa4ScD") |
  12. | `tpcc`.`order_line` | PRIMARY | 49931675 | (2677, 10, 10, 14, 15873, 10, NULL, 5, 133.21, "z1vH0e31tQydJGhfNYNa4ScD") |
  13. | `tpcc`.`order_line` | PRIMARY | 21829220 | (2678, 10, 10, 1, 44644, 10, NULL, 5, 8463.76, "TWKJBt5iJA4eF7FIVxnugNmz") |
  14. | `tpcc`.`order_line` | PRIMARY | 49931676 | (2678, 10, 10, 1, 44644, 10, NULL, 5, 8463.76, "TWKJBt5iJA4eF7FIVxnugNmz") |
  15. +---------------------+------------+----------------------------------------------------------------------------------------+
  16. 10 rows in set (0.14 sec)

根据上述信息人工甄别需要保留的重复数据,手动插回原表即可。

性能调优

提高 Lightning Physical Import Mode 导入性能最直接有效的方法:

  • 升级 Lightning 所在节点的硬件,尤其重要的是 CPU 和 sorted-key-dir 所在存储设备的性能。
  • 使用并行导入特性实现水平扩展。

当然,Lightning 也提供了部分并发相关配置以影响 Physical Import Mode 的导入性能。但是从长期实践的经验总结来看,以下四个配置项一般保持默认值即可,调整其数值并不会带来显著的性能提升,可作为了解内容阅读。

  1. [lightning]
  2. # 引擎文件的最大并行数。
  3. # 每张表被切分成一个用于存储索引的“索引引擎”和若干存储行数据的“数据引擎”。
  4. # 这两项设置控制两种引擎文件的最大并发数。
  5. index-concurrency = 2
  6. table-concurrency = 6
  7. # 数据的并发数。默认与逻辑 CPU 的数量相同。
  8. # region-concurrency =
  9. # I/O 最大并发数。I/O 并发量太高时,会因硬盘内部缓存频繁被刷新
  10. # 而增加 I/O 等待时间,导致缓存未命中和读取速度降低。
  11. # 对于不同的存储介质,此参数可能需要调整以达到最佳效率。
  12. io-concurrency = 5

导入时,每张表被切分成一个用于存储索引的“索引引擎”和若干存储行数据的“数据引擎”,index-concurrency用于调整”索引引擎”的并发度。

在调整 index-concurrency 时,需要注意 index-concurrency * 每个表对应的源文件数量 > region-concurrency 以确保 cpu 被充分利用,一般比例大概在 1.5 ~ 2 左右为优。index-concurrency 不应该设置的过大,但不低于 2 (默认),过大会导致太多导入的 pipeline 变差,大量 index-engine 的 import 阶段堆积。

table-concurrency 同理,需要确保table-concurrency * 每个表对应的源文件数量 > region-concurrency 以确保 cpu 被充分利用。 推荐值为region-concurrency * 4 / 每个表对应的源文件数量 左右,最少设置为 4.

如果表非常大,Lightning 会按照 100 GiB 的大小将表分割成多个批次处理,并发度由 table-concurrency 控制。

上述两个参数对导入速度影响不大,使用默认值即可。

io-concurrency 用于控制文件读取并发度,默认值为 5。可以认为在某个时刻只有 5 个句柄在执行读操作。由于文件读取速度一般不会是瓶颈,所以使用默认值即可。

读取文件数据后,lightning 还需要做后续处理,例如将数据在本地进行编码和排序。此类操作的并发度由 region-concurrency 配置控制。region-concurrency 的默认值为 CPU 核数,通常无需调整,建议不要将 Lightning 与其它组件部署在同一主机,如果客观条件限制必须混合部署,则需要根据实际负载调低 region-concurrency

此外,TiKV 的 num-threads 配置也可能影响性能,新集群建议设置为 CPU 核数。