数据库 
首页 > 数据库 > 浏览文章

从云数据迁移服务看MySQL大表抽取模式的原理解析

(编辑:jimmy 日期: 2024/11/25 浏览:3 次 )

摘要:MySQL JDBC抽取到底应该采用什么样的方式,且听小编给你娓娓道来。

小编最近在云上的一个迁移项目中被MySQL抽取模式折磨的很惨。一开始爆内存被客户怼,再后来迁移效率低下再被怼。MySQL JDBC抽取到底应该采用什么样的方式,且听小编给你娓娓道来。

1.1 Java-JDBC通信原理

JDBC与数据库之间的通信是通过socket完,大致流程如下图所示。Mysql Server ->内核Socket Buffer -> 客户端Socket Buffer ->JDBC所在的JVM

从云数据迁移服务看MySQL大表抽取模式的原理解析

1.2 JDBC读取数据的三种模式

1.2.1 方式1:使用JDBC默认参数读取数据

主要分为以下几步:

1)Mysql Server通过OuputStream 向 Socket Server 本地Kennel Buffer 写入数据,这里是一次内存拷贝。

2)当Socket Server 本地Kennel Buffer 有数据,就会通过TCP链路把数据传输到Socket Client 所在机器的Kennel Buffer。

3)JDBC 所在JVM利用InputSream读取本地Kennel Buffer 数据到JVM内存,没有数据时,则读取被阻塞。

接下来就是不断重复1,2,3的过程。 问题 是,Socket Client 端的JVM在默认模式下读取Kennel Buffer是没有考虑本机内存大小的,有多少读多少。如果数据太大,就会造成FULL GC,紧接着内存溢出。

参考 JDBC API docs,默认模式 Java demo 代码如下

从云数据迁移服务看MySQL大表抽取模式的原理解析

1.2.2 方式2:游标查询

为了解决方式1爆内存的问题,JDBC提供了一个游标参数,在建立jdbc连接时加上useCursorFetch=true。设置游标后,JDBC 每次会告诉Server端每次抽取的数据量,避免爆内存。通信过程如下图所示。

从云数据迁移服务看MySQL大表抽取模式的原理解析

"text-align: center">从云数据迁移服务看MySQL大表抽取模式的原理解析

1.2.3 方式3: Stream读取数据

方式1会导致JVM内存溢出,方式2虽然不会FULL GC但是通信效率较低,而且也会导致Mysql服务端IOPS飙升,消耗磁盘空间等问题。因此,我们介绍Stream读取数据 ,流式需要在读取Result前设置

从云数据迁移服务看MySQL大表抽取模式的原理解析

方式3在通信前不会做任何Server-Cient的交互操作,避免通信效率低下。服务端准备好数据写入Server的Kennel Buffer中,这些数据通过TCP链路传输到Client的Kennel Buffer中,紧接着client端inputStream.read()方法被唤醒去读取数据,与方式1不同,client每次只会读取一个package大小的数据,如果一个package不满一行则会再读取一个package。当client消费数据的速度不及数据传输速率时,client端kennel区的数据就会被堆满,紧接着Server端的kennel数据也会堆满进而阻塞了OuputStream。这样,JDBC在Stream模式下就像一个水管连接两个蓄水池,Client和Server达到一个平衡。

"text-align: center">从云数据迁移服务看MySQL大表抽取模式的原理解析

1.3 云数据迁移服务在三种模式下的调优

云数据迁移服务(Cloud Data Migration, CDM)是华为云上一个迁移工具,详见 CDM官网 ,小编则通过CDM介绍如何切换三种模式抽取数据。CDM默认使用的是方式3,流式抽取数据,如果需要切换方式1,方式2需额外配置。

1.3.1 配置方式1:默认读取

新建Mysql连接器,建立方法详见官网,在高级属性中增加useCursorFetch=false和adopt.stream=false

从云数据迁移服务看MySQL大表抽取模式的原理解析

1.3.2 配置方式2:游标查询

编辑Mysql连接器,在高级属性中增加useCursorFetch=true和adopt.stream=false。游标查询的大小可通过界面上的Fetch Size调整,默认1000。

从云数据迁移服务看MySQL大表抽取模式的原理解析

1.3.3 配置方式3:流式

CDM默认走的流式,无需额外配置。注意Stream模式下,界面上的 Fetch Size 是不起作用的,原因参考上一节。

1.3.4 性能对比

新建Mysql2Hive的CDM迁移作业,源表101个字段,100万行数据,配置如下

从云数据迁移服务看MySQL大表抽取模式的原理解析

从云数据迁移服务看MySQL大表抽取模式的原理解析

方式1:写入100万行数据耗时1m22s

从云数据迁移服务看MySQL大表抽取模式的原理解析

方式2:同样写入100万行,调整fetchSzie分别为1,10,100,100,最低耗时2m1s

从云数据迁移服务看MySQL大表抽取模式的原理解析

方式3:同样写入100万行,耗时1m5s

从云数据迁移服务看MySQL大表抽取模式的原理解析

小编还测试了100万的小表,明显方式1和方式3的速率要远远高于方式2,另外小编还测试了1000万的大表,方式1爆内存,方式2正常迁移但耗时20分钟以上,而方式3仍然可以在15分钟内跑完。

上一篇:MySQL数据类型DECIMAL用法详解
下一篇:mysql中decimal数据类型小数位填充问题详解
友情链接:杰晶网络 DDR爱好者之家 南强小屋 黑松山资源网 白云城资源网 网站地图 SiteMap