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

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

1.1 Java-JDBC通信原理

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

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 代码如下

1.2.2 方式2:游标查询

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

​ 方式2游标查询虽然解决了内存溢出的问题,方式2极大的依赖网络质量。当网络时延增大,假设每次通信增加10ms,10万次通信就会多出1000s。这里仅仅是每次发请求的RT,TCP每次发送报文,都要求反馈ACK保证数据可靠性。client每取100行(请求行数可配置),就会有多次通信,进一步放大时延增加导致的效率问题。此外,游标查询下,Mysql无法预知查询的结束时延,为了应对自身的DML操作会在本地建立一个临时空间存放要抽取的数据。因此,游标查询时会有以下几个现象发生

a. IOPS飙升,Mysql将数据写入到临时空间,数据传输时从临时空间读取数据,这都会引发大量IO操作。

b. 磁盘空间飙升,临时空间生命周期存在于整个JDBC读取阶段,直到客户端发起Result.close()时才会被Mysql回收。

c. CPU和内存有一定比例上升。

有关游标查询的原理可参考博客MySQL JDBC StreamResult通信原理浅析以及JDBC源码,本文不在赘述。

参考 JDBC API docs,游标模式 Java demo 代码如下

1.2.3 方式3: Stream读取数据

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

方式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达到一个平衡。

​对于JDBC客户端,由于每次都是从kennel读取数据,效率会比方式2高很多,每次读取一小部分数据也不会导致JVM内存溢出。对于服务端,Mysql每次都是往kennel写数据,无需建立临时空间,不涉及IO读取,服务端压力也变小了。当然,方式3也有自己的问题,例如Stream流式时无法cancel,cancel不阻塞等等。

参考 JDBC API docs,网上很多教程需要设置useCursorFetch=trueResultSet.FETCH_REVERSE等,其实小编研究完JDBC驱动源码后发现,只需要设fetchSize=Integer. MIN_VALUE,其他配置均和默认配置保持一致即可。游标模式 Java demo 代码如下

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

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

1.3.1 配置方式1:默认读取

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

1.3.2 配置方式2:游标查询

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

1.3.3 配置方式3:流式

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

1.3.4 性能对比

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

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

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

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

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

本文分享自华为云社区《从云数据迁移服务看MySQL大表抽取模式》,原文作者:Leef724。

mysql大表数据抽取_从云数据迁移服务看MySQL大表抽取模式相关推荐

  1. 从云数据迁移服务看MySQL大表抽取模式

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

  2. 大数据workshop:《云数据·大计算:海量日志数据分析与应用》之《社交数据分析:好友推荐》篇...

    大数据workshop:<云数据·大计算:海量日志数据分析与应用>之<社交数据分析:好友推荐>篇 实验背景介绍 了解更多2017云栖大会·成都峰会 TechInsight &a ...

  3. excel导入数据校验_使用Excel数据验证限制日期范围

    excel导入数据校验 Yesterday, one of my clients emailed to let me know that she was having trouble entering ...

  4. 深度学习数据自动编码器_如何学习数据科学编码

    深度学习数据自动编码器 意见 (Opinion) When I first wanted to learn programming, I coded along to a 4 hour long Yo ...

  5. 【华为云主机迁移服务SMS,使用指南 (linux版本)】

    文章目录 华为云主机迁移服务SMS,使用指南 (linux版本) 1.迁移前准备工作 1.1 必要条件 1.2 准备 (注意切换浏览器) 2.在源端(A服务器)安装Agent (linux版), 连接 ...

  6. 为了适应云数据库mySQL产品_金山云数据库RDSMySQL的产品功能大解析

    相信大家对于云数据库RDSMySQL并不会太陌生,这是一款高性能数据库服务,对于企业来说拥有管理便捷.数据安全.稳定可靠.节约成本等优势,可以兼容MySQL协议,满足企业的不同需求. 在产品功能方面, ...

  7. 华为云服务权限在哪_华为云数据湖探索服务DLI,精细化保障企业大数据安全

    原标题:华为云数据湖探索服务DLI,精细化保障企业大数据安全 随着企业业务的不断发展,企业大数据资产在企业辅助决策.用户画像.推荐系统等诸多业务流程中扮演着越来越重要的作用,如何保证企业大数据在满足各 ...

  8. 阿里云mysql创建多个用户_阿里云MySQL创建指定用户访问指定表

    欢迎大家关注我的公众号,有问题可以及时和我交流. 1.首先进入到root用户环境 mysql -uroot -p 输入自己的root密码登录. 登录成功之后如果表之前已经存在的话就不需要创建,如果表不 ...

  9. mysql表大小限制_技术分享 | 在磁盘上查找 MySQL 表的大小

    作者:Peter Zaitsev 翻译:管长龙 我想知道 MySQL 表在磁盘上占用多少空间,但看起来很琐碎.不应该在 INFORMATION_SCHEMA.TABLES 中提供这些信息吗?没那么简单 ...

最新文章

  1. python要不要装pycharm-Python和pyCharm安装
  2. 为ListView每个Item上面的按钮添加事件
  3. Android 学习笔记 BroadcastReceiver广播...
  4. 「后端小伙伴来学前端了」Vue中全局事件总线(GlobalEventBus)原理及探究过程
  5. C++ pancake sort煎饼排序的实现算法(附完整源码)
  6. 此内容不能显示在一个框架中 ie_Chromium Edge中的IE兼容模式 与我们设想的有些不一样...
  7. Linux小实验——设备挂载、磁盘分区、格式化、RAID的配置、LVM配置、磁盘配额的配置方法和验证
  8. 为什么安装了Microsoft .NET Framework 4之后我的电脑网卡启动会变得很慢很慢。。...
  9. 控制计算机价格,本人对电脑不太懂。想十一买台笔记本电脑。价格控制在5000之内。请高手指点一下。谢谢!...
  10. C++中头文件和实现文件分离进行编译
  11. Golang笔记——结构体
  12. mysql 查看连接_怎么实时查看mysql当前连接数
  13. esayexcel导出动态表头数据
  14. HTTPSConnectionPool(host=‘api.github.com‘, port=443): Max retries exceeded with url
  15. 去掉重复值php,php多维数组去掉重复值
  16. c语言输入一个数判断是否是同构数,c语言:编写函数判断x是否同构数
  17. pdf转换成word转换器免费版哪里下载
  18. 手机软件测试wifi需要注意哪些问题,WiFi工作原理、测试及生产注意事项
  19. 使用ifconfig结合awk提取主机的IP地址方法
  20. metasploit-framework(MSF)--Github翻译

热门文章

  1. Bailian1192 最优连通子集【DFS】
  2. HDU2034 人见人爱A-B【水题】
  3. 汇编环境的搭建(windows 10 + debug)
  4. 【网络/通信】概念的理解 —— 带宽、吞吐量、净荷
  5. 【脑经急转弯】—— 灯亮还是灭?
  6. Java 字符串(一条日志信息)解析实例
  7. 不小心合并了icloud通讯录_苹果手机号码被删除如何恢复?找回通讯录的具体步骤...
  8. python入门-Python入门之类(class)
  9. python编程语言-Python简史:开发者的小小副业如何成为全球最热编程语言?
  10. micropython入门指南-【micropython入门指南 】读后感 一