黄东旭解析 TiDB 的核心优势
393
2024-04-08
我在项目上经常会遇到数据导入的需求,客户会要求我们把 txt 或者 csv 文件中的数据导入到 TiDB 集群当中。这本来是一件简单的事,直到某个银行项目中,客户给导入数据的时间,限制了一个非常短的期限,无形中让我增加了一些压力。我这才考虑到,在某些业务中,这类以文件的方式下发的数据,是要在极短的时间内,完成数据库导入工作的。所以我才着手研究该如何更快、更加安全的把数据导入到 TiDB 中。
在导入数据之前,TiDB 当然是需要准备一下啦,万一出现写热点,或者事务过大导致导入过慢、甚至失败,进而导致规定时间内,数据没有导入完成,那岂不是要被客户吊打。
在大量数据插入场景中,大概率会出现写热点的情况,针对这种情况,我们必须提前做好对应。
1.针对新表的数据插入,我们可以在创建表结构的时候,增加两个参数:SHARD_ROW_ID_BITS
pre_split_regions
示例:
CREATE TABLE `t1` ( `id` int(11) NOT NULL, ) shard_row_id_bits = 4 pre_split_regions = 4;2.对于导入追加数据的场景,已有表结构并有历史数据时,需要手动切分region我们可以使用 split-table-region 的方法来处理写热点的问题。
需要注意的是,建表语句增加了 shard_row_id_bits 和 pre_split_regions 参数后,需要尽快开始向目标表导入数据,不然分割的空 region 可能会被 merge,导致出现写热点的问题。
解决好写热点问题之后,还需要考虑大量数据的插入,可能导致 TiDB 出现 OOM 的情况。
在 TiDB 集群中,插入数据时,每条数据都会占用 tidb-server 节点的内存,当一个事务中插入的数据量过大,就会导致 tidb-server 节点使用过大的内存,出现 OOM 的情况。要解决大事务的问题,需要开启一下几个参数:
在拓扑文件中加入:enable-batch-dml: true
SET @@GLOBAL.tidb_dml_batch_size = 20000;
SET @@SESSION.tidb_batch_insert = 1;
这三个参数需要配合使用,表示在一个 insert 的事务中,TiDB 会在内部把一个 insert 的大事务,按 20000 条数据拆分成一个个小事务分批提交,这样就很好的避免了 tidb-server 节点 OOM 的情况,但是这样做会有一定的问题:无法保证 TiDB 的原子性和隔离性要求,所以不推荐。这个需要大家根据自己的实际情况进行选择。
有非常好的交互界面,用户学习成本几乎是0,直接可以上手导入数据,Navicat 内部会对文件中的数据分批执行,速度也不慢,但是只能在windows系统中操作。
2、load dataMysql 中的常规批量导入方式,可以指定十六进制分隔符,TiDB 中除 LOAD DATA...REPLACE INTO 语法之外,LOAD DATA 语句应该完全兼容 MySQL。
3、Lightning非常推荐的一款逻辑批量导入数据的工具,直接把数据转换成键值对,并插入到 TiKV 中,所以这样导入数据理论上是最快的,但是使用 lightning 也有一些不方便的地方,比如多次导入需要频繁修改配置文件,文件名称必须是“库名.表名”的形式,不能导入 txt 文件数据,如果导入失败需要手动修改 TiKV 集群为普通模式等等。
这次测试我准备了四个不同数据量的 csv 文件,文件大小在 100MB 到 11GB :
表结构为:
CREATE TABLE `sbtest` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT 0, `c` char(120) NOT NULL DEFAULT , `pad` char(60) NOT NULL DEFAULT , PRIMARY KEY (`id`) /*T![clustered_index] NONCLUSTERED */, KEY `k_1` (`k`) ) shard_row_id_bits = 4 pre_split_regions = 4 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin每台机器配置都是 8 vCore,32G内存,千兆带宽。配置有限,所有测试都在这个集群环境中进行测试。
1、除了用 Lightning 的 local 模式导入数据,其他导入方式或多或少都会有写热点出现。
2、使用 Navicat 导入数据,对磁盘资源消耗要远远高于其他方式,且速度是最慢的。
3、load data 的导入方式,对现有资源消耗并不高,想提高导入效率,只能手动并行导入数据。
4、Lightning 的 local 模式导入数据速度最快,对集群的资源消耗最小。
5、Lightning 的 tidb 模式对资源的消耗与 load data 的导入方式相似,但是效率低于 load data 的导入方式。
6、导入过程中,TiDB 集群使用内存无异常,均未出现 OOM 的情况。
7、单个文件太大,会影响 Lightning 的 local 模式对文件的处理效率。
8、Lightning 的 local 模式对 Lightning 所在机器的 CPU、硬盘和集群网络要求较高。
9、Lightning 读取文件名时,文件名的大小写要与目标表的表名完全一致,否则 Lightning 会报错。
Lightning 限制较多,但是功能也是最全的,local 模式的导入速度吊打其他导入工具。
load data 支持 txt 文件数据的导入,而且也能自定义一些常规参数,比如字段分隔符等,导入速度仅次于 Lightning 的 local 模式。基于 load data 开发一个符合业务需求的脚本,要比直接用 Lightning 开发简单的多。
针对需要用到 Lightning 的功能,而且是增量数据导入的话,建议使用 Lightning 的 tidb 模式。
Navicat 只推荐给初学者导入少量数据使用。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。