Spark讀取MySQL資料

糰子粑粑發表於2020-12-31

1、什麼是ELT

資料工程師,多數情況下接觸過ETL,即提取(Extract)、轉換(Transform)、載入(Load),隨著越來越多的計算平臺能力的崛起,很多時候,資料工程師按照ELT進行資料操作,即按照提取(Extract)、載入(Load)、轉換(Transform),此好處就是,資料的轉換可以藉助於強大的計算平臺,而資料同步工具只需要更多的關注資料的提取和加更加簡單快捷的為開發者提高效率。

2、為什麼選擇Spark

a)在日益增長的業務資料同步過程中,很多傳統ETL工具都是單機執行,搭建一套具備大規模資料處理能力的資料同步系統成為大資料分析系統中不可或缺的環節。由於Spark可執行於分散式平臺並且對各種資料庫的訪問都實現了良好的支援,使用Spark來開發資料同步工具成為一個不錯的選擇;

b)Spark DataFrame提供了豐富的操作API且可以直接基於DataFrame進行SQL操作,在EL過程中且可以進行一些簡單的資料轉換;

c)Spark程式部署簡單,只需要使用spark-submit命令提交程式碼即可。

2.1、Spark ETL不帶T

本次實踐不進行轉換(Transform)實戰,只進行簡單的EL操作實戰,旨在為了能夠熟練使用Spark進行多種異構數源之間資料同步。

 

2.3、Java Spark Read on MySQL

 


public class MysqlReader {

    public Dataset<Row> reader(SparkSession sparkSession){

        Dataset<Row> rowDataset = sparkSession.read()

                                  .format("jdbc")

                                  .option("url", url)

                                  .option("dbtable", tableName)

                                  .option("user", userName)

                                  .option("password", passwd)

                                  .option("driver", "com.mysql.cj.jdbc.Driver").load();

        return rowDataset;

    }

}

如上程式碼會有一個弊端,當表資料量大的時候,因其是一個session一次性全量讀取mysql資料,存在讀取資料oom的風險。故而可以有如下第二種讀法:

Dataset<Row> rowDataset = sparkSession.read()
                .format("jdbc")
                .option("url", url)
                .option("dbtable", tableName)
                .option("user", userName)
                .option("password", passwd)
                .option("driver", "com.mysql.cj.jdbc.Driver")
                .option("partitionColumn", columnName)
                .option("lowerBound", 1)
                .option("upperBound", 1000)
                .option("fetchsize", 1000)
                .option("numPartitions", 3)
                .load();

檢視官方文件可以發現,partitionColumn 配置項和numPartitions、lowerBound、upperBound這三個必須要同時出現。其中

partitionColumn :表示讀取資料的時候按條件過濾的欄位,一般情況下選擇格式為int、datatime、timestamp型別的主鍵或索引欄位;

numPartitions :表示讀取的時候會分成幾個分割槽來讀,最終會把想要讀取的資料讀到Spark的幾個分割槽中;

lowerBound :表示讀取的時候,小於1的都一定在第一個分割槽中;

upperBound :表示讀的時候,超過1000的都一定在最後一個分割槽中;

fetchsize :表示讀取的時候,每次讀取返回的最大條數,能夠有效的控制讀取mysql資料的速率,不能過快,過快會把mysql讀崩掉;

如下圖就是實際讀取的時候,上面程式碼中的1、1000、3這幾個數字的含義體現,1000/3=333,所以日誌中,採用了334和667做為三個資料分割槽的存放規則

 

相關文章