场景为Spark读取一张MySQL表(innodb引擎), 数据量8000万,无自增ID,业务中一个字段为(订单ID)主键。要将该表数据读取后写入到HDFS。下面将详细介绍Spark读取MySQL大表超时问题。
# 直接使用Spark提供的JDBC分区数据选项 partitionColumn,lowerBound,upperBound
* 不可行,partitionColumn要求是数值类型,这个表中并没有虽有一些数值类型字段,但是并不合适,因为字段值非递增,不容易设定分区的上下界限,这就很容易造成数据倾斜。
# 采用 predicates 方式,定义一个划分数据的数组规则
* 使用limit 做分页将数据划分为60个分区,同时优化limit查询,用主键做子查询的方式优化。虽然经过了查询优化,但是运行时,依然遇到读取超时错误。问题原因是JDBC socketTimeout 设置了3分钟,但是某些task读取mysql时,并没有在3分钟内返回数据,是一个慢查询。 在这个场景下解决方式就是调大socketTimeout值就可以了,调成了10分钟。
* 这里要注意的是一定要对limit做优化,使用子查询或者join方式,根据主键查询做分页。 例如下
`select * from table_name where id >= (select id from table_name order by id limit 100000, 1) limit 20000`.
* 如果你直接使用 `select * from table_name limit 100000,20000 `的方式。mysql会查询出来 120000条数据,然后再扔掉100000条数据,这是完全没有意义的,会有大量无意义IO操作,影响性能。
更多关于大数据培训的问题,欢迎咨询千锋教育在线名师,如果想要了解我们的师资、课程、项目实操的话可以点击咨询课程顾问,获取试听资格来试听我们的课程,在线零距离接触千锋教育大咖名师,让你轻松从入门到精通。