spark load data from mysql

code first

本机通过spark-shell.cmd启动一个spark进程

	SparkSession spark = SparkSession.builder().appName("Simple Application").master("local[2]").getOrCreate();

        Map<String, String> map = new HashMap<>();
map.put("url","jdbc:mysql:xxx");
map.put("user", "user");
map.put("password", "pass");
String tableName = "table";
map.put("dbtable", tableName);
map.put("driver", "com.mysql.jdbc.Driver");
String lowerBound = 1 + ""; //低界限
String upperBound = 10000 + ""; //高界限 map.put("fetchsize", "100000"); //实例和mysql服务端单次拉取行数,拉取后才能执行rs.next()
map.put("numPartitions", "50"); //50个分区区间,将以范围[lowerBound,upperBound]划分成50个分区,每个分区执行一次查询
map.put("partitionColumn", "id"); //分区条件列
System.out.println("tableName:" + tableName + ", lowerBound:"+lowerBound+", upperBound:"+upperBound);
map.put("lowerBound", lowerBound);
map.put("upperBound", upperBound); Dataset dataset = spark.read().format("jdbc").options(map).load(); //transform操作
dataset.registerTempTable("tmp__");
Dataset<Row> ds = spark.sql("select * from tmp__"); //transform操作
ds.cache().show(); //action,触发sql真正执行

执行到show时,任务开始真正执行,此时,我们单机debug,来跟踪partitionColumn的最终实现方式

debug类

org.apache.spark.sql.execution.datasources.jdbc.JDBCRelation.buildScan

此时parts为size=50的分区列表

  override def buildScan(requiredColumns: Array[String], filters: Array[Filter]): RDD[Row] = {
// Rely on a type erasure hack to pass RDD[InternalRow] back as RDD[Row]
JDBCRDD.scanTable(
sparkSession.sparkContext,
schema,
requiredColumns,
filters,
parts,
jdbcOptions).asInstanceOf[RDD[Row]]
}

单个分区内的whereClause值

whereCluase="id < 21 or id is null"

继续往下断点,到单个part的执行逻辑,此时代码应该是在Executor中的某个task线程中

org.apache.spark.sql.execution.datasources.jdbc.JDBCRDD.compute

	val myWhereClause = getWhereClause(part)

	val sqlText = s"SELECT $columnList FROM ${options.table} $myWhereClause"
stmt = conn.prepareStatement(sqlText,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)
stmt.setFetchSize(options.fetchSize)
rs = stmt.executeQuery()
val rowsIterator = JdbcUtils.resultSetToSparkInternalRows(rs, schema, inputMetrics) CompletionIterator[InternalRow, Iterator[InternalRow]](
new InterruptibleIterator(context, rowsIterator), close())

此时

myWhereClause=WHERE id < 21 or id is null

最终的sql语句

sqlText=SELECT id,xx FROM tablea WHERE id < 21 or id is null

所有part都会经过compute

Executor执行完任务后,将信息发送回Driver

Executor: Finished task 7.0 in stage 2.0 (TID 12). 1836 bytes result sent to driver

总结

  • numPartitions、partitionColumn、lowerBound、upperBound结合后,spark将生成很多个parts,每个part对应一个查询whereClause,最终查询数据将分成numPartitions个任务来拉取数据,因此,partitionColumn必须是索引列,否则,效率将大大降低
  • 自动获取table schema,程序会执行类型select * from tablea where 1=0 来获取字段及类型
  • lowerBound,upperBound仅用来生成parts区间,最终生成的sql中,不会使用它们来作为数据范围的最小或最大值

spark load data from mysql的更多相关文章

  1. 使用MySQL的SELECT INTO OUTFILE ,Load data file,Mysql 大量数据快速导入导出

    使用MySQL的SELECT INTO OUTFILE .Load data file LOAD DATA INFILE语句从一个文本文件中以很高的速度读入一个表中.当用户一前一后地使用SELECT ...

  2. mysql导入数据load data infile用法整理

    有时候我们需要将大量数据批量写入数据库,直接使用程序语言和Sql写入往往很耗时间,其中有一种方案就是使用MySql Load data infile导入文件的形式导入数据,这样可大大缩短数据导入时间. ...

  3. MySQL 之 LOAD DATA INFILE 快速导入数据

    SELECT INTO OUTFILE > help select; Name: 'SELECT' Description: Syntax: SELECT [ALL | DISTINCT | D ...

  4. Mybatis拦截器 mysql load data local 内存流处理

    Mybatis 拦截器不做解释了,用过的基本都知道,这里用load data local主要是应对大批量数据的处理,提高性能,也支持事务回滚,且不影响其他的DML操作,当然这个操作不要涉及到当前所lo ...

  5. mysql load data 乱码的问题

    新学mysql在用load data导入txt文档时发现导入的内容,select 之后是乱码,先后把表,数据库的字符集类型修改为utf8,但还是一样,最后在 http://bbs.chinaunix. ...

  6. mysql load data infile的使用 和 SELECT into outfile备份数据库数据

    LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE] INTO TABLE t ...

  7. 快速的mysql导入导出数据(load data和outfile)

    1.load data: ***实际应用:把日志生成的xls文件load到MySQL中: mysql_cmd = "iconv -c -f utf-8 -t gbk ./data/al_ve ...

  8. [MySQL]load data local infile向MySQL数据库中导入数据时,无法导入和字段不分离问题。

    利用load data将文件中的数据导入数据库表中的时候,遇到了两个问题. 首先是load data命令无法执行的问题: 命令行下输入load data local infile "path ...

  9. mysql导入数据load data infile用法

    mysql导入数据load data infile用法 基本语法: load data [low_priority] [local] infile 'file_name txt' [replace | ...

随机推荐

  1. Springboot+Vue实现仿百度搜索自动提示框匹配查询功能

    案例功能效果图 前端初始页面 输入搜索信息页面 点击查询结果页面 环境介绍 前端:vue 后端:springboot jdk:1.8及以上 数据库:mysql 核心代码介绍 TypeCtrler .j ...

  2. 【FLASK】钩子函数的使用

    from flask import Flask from flask import abort app = Flask(__name__) # 在第一次请求之前调用,可以在此方法内部做一些初始化操作 ...

  3. Processing 网格纹理制作(棋盘格)使用pixel() set()像素点绘制方式

    接上 我们趁热打铁,紧接上一回的棋盘格绘制,来挖掘一些不同绘制思路,使用pixel()函数来绘画.这是一个以每个像素点作为对象来绘制的思路,而不是以图形的方式来填充.这就改变了绘画思路.实际上,Pro ...

  4. 消息队列MQ面试专题(rabbitmq)

    正文: 1.什么是 rabbitmq 采用 AMQP 高级消息队列协议的一种消息队列技术,最大的特点就是消费并不需要确保提供方存在,实现了服务之间的高度解耦 2.为什么要使用 rabbitmq 在分布 ...

  5. 2、JVM的内存

    1.JVM中的内存结构 从OS的角度来看,JVM运行时会把一部分内存虚拟机化,所以把内存分为直接内存(未被虚拟机化的内存)和运行时数据区(被虚拟机化的内存) JVM的运行时数据区若从线程的角度来看,可 ...

  6. 012 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 06 浮点型“字面值”

    012 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 06 浮点型"字面值" 浮点型字面值 首先要知道一点:在整型部分中,默认情况下,即整型数 ...

  7. 【随笔】Apache降权和禁用PHP危险函数

    测试环境: Windows Server 2003 + phpstudy 首先在win2003里运行phpstudy,这里注意需要选择应用系统服务模式,应用之后重启phpstudy. 打开系统服务(开 ...

  8. 【题解】CF1228D Complete Tripartite

    Link 题目大意:给定一个无向图,将它划分为三个点集,要求在一个点集中的点没有边相连,且颜色相同,不同集合中的点互相有边相连. \(\text{Solution:}\) 我们发现,与一个点之间没有边 ...

  9. webRTc实现视频直播

    <!DOCTYPE html> <html> <head> <script type='text/javascript' src='https://cdn.s ...

  10. 01 . OpenResty简介部署,优缺点,压测,适用场景及用Lua实现服务灰度发布

    简介 OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极高的动态 ...