myloader导入更快吗?并没有......

打印 上一主题 下一主题

主题 564|帖子 564|积分 1692


  • 0.结论先行
  • 1.背景介绍
  • 2.测试过程
  • 3.结果对比


  • 附录
myloader还默认禁用binlog了
0. 结论先行

重要结论先说:导入大批量数据时,采用GreatSQL 8.0.32-24中新增并行load data特性是最快的,关于该特性的描述详见:Changes in GreatSQL 8.0.32-24
1. 背景介绍

前几天我用MySQL官网提供的airportdb库中的weatherdata表做测试,结论是相比原生快了约5倍。
群里有小伙伴反驳说用myloader更香,于是就有了本次测试。
由于weatherdata表较小,表空间只有228MB,所以我改用sysbench表做测试,该表共600万行数据,表空间约1.5GB,其他信息如下:
  1. greatsql> show create table myload\G
  2. *************************** 1. row ***************************
  3.        Table: myload
  4. Create Table:CREATE TABLE `myload` (
  5.   `id` int NOT NULL AUTO_INCREMENT,
  6.   `k` int NOT NULL DEFAULT '0',
  7.   `c` char(120) NOT NULL DEFAULT '',
  8.   `pad` char(60) NOT NULL DEFAULT '',
  9.   PRIMARY KEY (`id`),
  10.   KEY `k_2` (`k`)
  11. ) ENGINE=InnoDB AUTO_INCREMENT=6194244 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
  12. greatsql> show table status like 'myload'\G
  13. *************************** 1. row ***************************
  14.            Name: myload
  15.          Engine: InnoDB
  16.         Version: 10
  17.      Row_format: Dynamic
  18.            Rows: 5930876
  19. Avg_row_length: 233
  20.     Data_length: 1385168896
  21. Max_data_length: 0
  22.    Index_length: 153894912
  23.       Data_free: 7340032
  24. Auto_increment: 6194244
  25.     Create_time: 2023-07-08 09:25:02
  26.     Update_time: 2023-07-08 09:25:33
  27.      Check_time: NULL
  28.       Collation: utf8mb4_0900_ai_ci
  29.        Checksum: NULL
  30. Create_options:
  31.         Comment:
复制代码
2. 测试过程

本次测试基于GreatSQL 8.0.32-24版本,其他相关信息如下:
  1. # myloader版本
  2. $ myloader --version
  3. myloader0.15.0-1, built against MySQL 5.7.42-46 with SSL support with GZIP
  4. # MySQL Shell版本
  5. JS > shell.version
  6. Ver 8.0.32 for Linux on x86_64 - for MySQL 8.0.32 (MySQL Community Server (GPL))
复制代码
默认开启binlog + 双1 + redo log + doublewrite buffer:
  1. |binlog_rows_query_log_events |ON|
  2. | innodb_buffer_pool_size | 8589934592|innodb_doublewrite |ON|
  3. |innodb_flush_log_at_trx_commit |1|
  4. |innodb_redo_log_capacity |2147483648|
  5. |sync_binlog |1|
复制代码
3. 结果对比

下面是几个不同导入方式的对比测试结果,每种方式我都测试至少3次,去除噪点数据后取平均值:
工具耗时(秒)binlog大小(MB)mysqld内存增长(MB)原生load data62.80174110911536并行load data(chunk=4MB,并发16线程)11.8110911522myloader(dump时chunk=64MB,load时并发16线程)29.35822461868myloader(dump时chunk=64MB,load时并发16线程)+ 关binlog21.426无myloader(默认 + 开binlog)82.6512246myloader(默认 + 关binlog)62.830无util.importTable(默认,chunk=64MB,并发8线程)16.003410911662从这个测试结果可以看到几个对比关系:

  • 原生load data最慢,因为是单线程的,它的耗时是并行load data的5.32倍;
  • 原生load data的耗时是多线程模式下myloader的2.14倍;
  • 原生load data的耗时是多线程模式下util.importTable的3.92倍;
  • 当myloader没有开启并行(mydumper备份时要先进行分配)的话,它的耗时是最久的,是并行load data的7倍,是多线程模式下util.importTable的5.16倍;
  • 当myloader未开启binlog时(其默认行为,有"作弊"嫌疑),其耗时是并行load data的1.81倍,是多线程模式下util.importTable的1.34倍;
  • 最后,myloader导入后造成的binlog文件最大,内存开销也最大。

综上,在MySQL 8.0/GreatSQL 8.0.32中,采用myloader导入数据就不再是最优方案了,推荐采用GreatSQL的并行load data,或者MySQL Shell的util.loadDump/util.importTable导入,其本质也是采用并行的思路,导入效率更高,额外的binlog和内存开销也更小。
最后,补充说下,myloader导入时产生的binlog更多,是因为它的导入方式是反复执行INSERT SQL,在 binlog_rows_query_log_events = ON 时,相比load data方式会产生更多binlog。
附录

1. myloader多分片方式导出
设置导出时进行分片,每个分片(chunk)10MB
  1. $ mydumper -F 10 -S /data/GreatSQL/mysql.sock -T sbtest.myload -o /tmp/myload
复制代码
最后的(未压缩)文件总大小为1.2GB。
2. outfile导出
  1. greatsql> select * into outfile '/tmp/myload.csv' from myload;
复制代码
很简单,平平无奇,最后的(未压缩)文件总大小为1.1GB。
3. util.dumpTables多分片方式导出 设置导出时进行分片,每个分片(chunk)64MB(默认值)
  1. MySQL  localhost  JS > util.dumpTables("sbtest", ["myload"], "/tmp/myload", {threads:16, chunking:true, bytesPerChunk:"67108864"})
复制代码
最后的(压缩后)文件总大小为505MB。

Enjoy GreatSQL
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

去皮卡多

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表