巨杉Tech | SparkSQL+SequoiaDB 性能調優策略

當今時代,企業數據越發膨脹。數據是企業的價值,但數據處理也是一種技術挑戰。在海量數據處理的場景,即使單機計算能力再強,也無法滿足日益增長的數據處理需求。所以,分佈式纔是解決該類問題的根本解決方案。而在分佈式領域,有兩類典型產品,分別是分佈式存儲和分佈式計算。用戶只有將兩者的特性充分利用,纔可以真正發揮分佈式架構的存儲和計算能力。

本文介紹 SequoiaDB(分佈式存儲)和 Spark(分佈式計算)兩款產品的對接使用,以及在海量數據場景下如何提高統計分析性能。

01 SequoiaDB 與 SparkSQL 介紹

SequoiaDB 是一款開源的金融級分佈式關係型數據庫,支持標準 SQL 和事務功能,支持複雜索引查詢、與 Hadoop、Hive、Spark 都有較深度的集成。SequoiaDB 在分佈式存儲功能上,較一般的大數據產品能提供更多的數據切分規則,包括:水平切分、範圍切分、主子表切分(類似 partition 分區)和多維切分方式,用戶可以根據不用的場景選擇相應的切分方式,以提高系統的存儲能力和操作性能。

Spark 近年來發展特別迅猛,使用 SparkSQL 做大數據處理和分析的開發者越來越多。SparkSQL 是 Spark 產品中一個組成部分,SQL 的執行引擎使用 Spark 的 RDD 和 Dataframe 實現。

SparkSQL 和另外一款流行的大數據 SQL 產品— Hive 有相似之處,但是兩款產品還是有本質上的區別,最大的不同點在於執行引擎,Hive 默認支持 Hadoop 和 Tez 計算框架,而 SparkSQL 只支持 Spark RDD 計算框架,但是 SparkSQL 的擁有更加深度的執行計劃優化和處理引擎優化。

02 SequoiaDB 與 SparkSQL 如何整合?

Spark 本身是一款分佈式計算框架。它不像 Hadoop 一樣,同時爲開發者提供分佈式計算和分佈式存儲,而是開放了存儲層的開發接口,只要開發者按照 Spark 的接口規範實現了接口方法,任何存儲產品都可以成爲 Spark 數據計算的來源,同時也包括 SparkSQL 的數據來源。

SequoiaDB 是一款分佈式數據庫,能夠爲用戶存儲海量的數據,但是如果要對海量數據做統計、分析,還是需要藉助分佈式計算框架的併發計算性能,提高計算效率。所以 SequoiaDB 爲 Spark開發了 SequoiaDB for Spark 的連接器,讓 Spark 支持從SequoiaDB 中併發獲取數據,再完成相應的數據計算。

Spark 和 SequoiaDB 對接方式比較簡單,用戶只要將 SequoiaDB for Spark 連接器 spark-sequoiadb.jar 和 SequoiaDB 的 java 驅動 sequoiadb.jar 加入到每個 Spark Worker 的 CLASSPATH 中即可。

例如,用戶希望 SparkSQL 對接到 SequoiaDB,可以爲 spark-env.sh 配置文件中增加 SPARK_CLASSPATH 參數,如果該參數已經存在,則將新 jar 包添加到 SPARK_CLASSPATH 參數上,如:

SPARK_CLASSPATH="/media/psf/mnt/sequoiadb-driver-2.9.0-SNAPSHOT.jar:/media/psf/mnt/spark-sequoiadb_2.11-2.9.0-SNAPSHOT.jar"

用戶修改完 spark-env.sh 配置後,重啓 spark-sql 或者 thriftserver 就完成了 Spark 和 SequoiaDB 的對接。

03 SequoiaDB 與 SparkSQL 性能優化

Spark SQL+SequoiaDB 的性能優化將會從 connector 計算技術原理、SparkSQL 優化、SequoiaDB 優化和 connector 參數優化4個方面進行介紹。

3.1 SequoiaDB for SparkSQL

A) connector 工作原理

Spark 產品雖然爲用戶提供了多種功能模塊,但是都只是數據計算的功能模塊。Spark 產品本身沒有任何的存儲功能,在默認情況下,Spark 是從本地文件服務器或者 HDFS 上讀取數據。而 Spark 也將它與存儲層的接口開放給廣大開發者,開發者只要按照 Spark 接口規範實現其存儲層連接器,任何數據源均可稱爲 Spark 計算的數據來源。

下圖爲 Spark worker 與存儲層中 datanode 的關係。
巨杉Tech | SparkSQL+SequoiaDB 性能調優策略

圖1

Spark 計算框架與存儲層的關係,可以從下圖中瞭解其原理。Spark master 在接收到一個計算任務後,首先會與存儲層做一次通訊,從存儲層的訪問快照或者是存儲規劃中,得到本次計算任務所設計的所有數據的存儲情況。存儲層返回給 Spark master 的結果爲數據存儲的 partition 隊列。

然後 Spark master 會將數據存儲的 partition 隊列中的 partition 逐個分配給給 Spark worker。Spark work 在接收到數據的 partition 信息後,就能夠了解如何獲取計算數據。然後 Spark work 會主動與存儲層的 node 節點進行連接,獲取數據,再結合 Spark master 下發給 Spark worker 的計算任務,開始數據計算工作。
巨杉Tech | SparkSQL+SequoiaDB 性能調優策略
圖2

SequoiaDB for Spark 的連接器的實現原理和上述描述基本一致,只是在生成數據計算的 partition 任務時,連接器會根據 Spark 下壓的查詢條件到 SequoiaDB 中生成查詢計劃。

如果 SequoiaDB 能夠根據查詢條件做索引掃描,連接器生成的 partition 任務將是讓Spark work 直接連接 SequoiaDB 的數據節點。

如果 SequoiaDB 無法根據查詢條件做索引掃描,連接器將獲取相關數據表的所有數據塊信息,然後根據 partitionblocknum 和 partitionmaxnum 參數生成包含若干個數據塊連接信息的 partititon 計算任務。

B) Connector 參數

SequoiaDB for Spark 連接器在 SequoiaDB 2.10之後進行了重構,提高 Spark 併發從SequoiaDB 獲取數據的性能,參數也有相應的調整。

用戶在 SparkSQL 上創建數據源爲 SequoiaDB 的 table,建表模版如下:

create [temporary] <table|view> <name>[(schema)] using com.sequoiadb.spark options (<options>);

SparkSQL 創表命令的關鍵字介紹:

  1. temporary 關鍵字,代表該表或者視圖是否爲鄰時創建的,如果用戶標記了temporary 關鍵字,則該表或者視圖在客戶端重啓後將自動被刪除;

  2. 建表時用戶可以選擇不指定表結構,因爲如果用戶不顯式指定表結構,SparkSQL 將在建表時自動檢測已經存在數據的表結構;

  3. com.sequoiadb.spark 關鍵字爲 SequoiaDB for Spark connector 的入口類;

  4. options 爲 SequoiaDB for Spark connector 的配置參數;

SparkSQL 建表例子如下:

create table tableName (name string, id int) using com.sequoiadb.spark options (host 'sdb1:11810,sdb2:11810,sdb3:11810', collectionspace 'foo', collection 'bar', username 'sdbadmin', password 'sdbadmin');

SparkSQL for SequoiaDB 的建表 options 參數列表如下:
巨杉Tech | SparkSQL+SequoiaDB 性能調優策略
表1

3.2 SparkSQL 優化

用戶如果要使用 SparkSQL 對海量數據做統計分析操作,那麼應該從3個方面進行性能調優:

  1. 調大 Spark Worker 最大可用內存大小,防止在計算過程中數據超出內存範圍,需要將部分數據寫入到臨時文件上;

  2. 增加 Spark Worker 數目,並且設置每個 Worker 均可以使用當前服務器左右 CPU 資源,以提高併發能力;

  3. 調整 Spark 的運行參數;

用戶可以對 spark-env.sh 配置文件進行設置,SPARK_WORKER_MEMORY 爲控制 Worker 可用內存的參數,SPARK_WORKER_INSTANCES 爲每臺服務器啓動多少個 Worker 的參數。

如果用戶需要調整 Spark 的運行參數,則應該修改 spark-defaults.conf 配置文件,對優化海量數據統計計算有較明顯提升的參數有:

  1. spark.storage.memoryFraction, 該參數控制 Worker 多少內存比例用戶存儲臨時計算數據,默認爲0.6,代表60%的含義;

  2. spark.shuffle.memoryFraction, 該參數控制計算過程中 shuffle 時能夠佔用每個 Worker 的內存比例,默認爲0.2,代表20%的含義,如果臨時存儲的計算數據較少,而計算中有較多的 group by, sort, join 等操作,應該考慮將spark.shuffle.memoryFraction 調大,spark.storage.memoryFraction 調小,避免超出內存部分需要寫入臨時文件中;

  3. spark.serializer, 該參數設置 Spark 在運行時使用哪種序列化方法,默認爲 org.apache.spark.serializer.JavaSerializer, 但是爲了提升性能,應該選擇 org.apache.spark.serializer.KryoSerializer 序列化。

3.3 SequoiaDB 優化

SparkSQL+SequoiaDB 這種組合,由於數據讀取是從 SequoiaDB 中進行,所以在性能優化應該考慮三點

  1. 儘可能將大表的數據分佈式存儲,所以建議符合二維切分條件的 table 應該採用主子表+ Hash 切分兩種數據均衡方式進行數據分佈式存儲;

  2. 數據導入時,應該避免同時對相同集合空間的多個集合做數據導入,因爲同一個集合空間下的多個集合是共用相同一個數據文件,如果同時向相同集合空間的多個集合做數據導入,會導致每個集合下的數據塊存儲過於離散,從而導致在 Spark SQL 從SequoiaDB 獲取海量數據時,需要讀取的數據塊過多;

  3. 如果 SparkSQL 的查詢命令中包含查詢條件,應該對應地在 SequoiaDB 中建立對應字段的索引。

3.4 connector 優化

SequoiaDB for Spark 連接器的參數優化,主要分兩個場景,一是數據讀,另外一個是數據寫入。

數據寫入的優化空間較少,只有一個參數可以調整,即bulksize參數,該參數默認值爲500,代表連接器向 SequoiaDB 寫入數據時,以500條記錄組成一個網絡包,再向 SequoiaDB 發送寫入請求,通常設置 bulksize 參數,以一個網絡包不超過2MB爲準。

數據讀取的參數優化,用戶則需要關注 partitionmode, partitionblocknum 和 partitionmaxnum 三個參數。

partitionmode,連接器的分區模式,可選值有single、sharding、datablock、auto,默認值爲auto,代表連接器智能識別。

1. single 值代表 SparkSQL 在訪問 SequoiaDB 數據時,不考慮併發性能,只用一個線程連接 SequoiaDB 的 Coord 節點,一般該參數在建表做表結構數據抽樣時採用;

2. sharding 值代表 SparkSQL 訪問 SequoiaDB 數據時,採用直接連接 SequoiaDB 各個 datanode 的方式,該參數一般採用在 SQL 命令包含查詢條件,並且該查詢可以在 SequoiaDB 中使用索引查詢的場景;

3. datablock 值代表 SparkSQL 訪問 SequoiaDB 數據時,採用併發連接 SequoiaDB 的數據塊進行數據讀取,該參數一般使用在SQL命令無法在 SequoiaDB 中使用索引查詢,並且查詢的數據量較大的場景;

4. auto 值代表 SparkSQL 在向 SequoiaDB 查詢數據時,訪問 SequoiaDB 的方式將由連接器根據不同的情況分析決定。

partitionblocknum,該參數只有在 partitionmode=datablock 時纔會生效,代表每個 Worker 在做數據計算時,一次獲取多少個 SequoiaDB 數據塊讀取任務,該參數默認值爲4。如果 SequoiaDB 中存儲的數據量較大,計算時涉及到的數據塊較多,用戶應該調大該參數,使得 SparkSQL 的計算任務保持在一個合理範圍,提高數據讀取效率。

partitionmaxnum,該參數只有在 partitionmode=datablock 時纔會生效,代表連接器最多能夠生成多少個數據塊讀取任務,該參數的默認值爲1000。該參數主要是爲了避免由於 SequoiaDB 中的數據量過大,使得總的數據塊數量太大,導致 SparkSQL 的計算任務過多,最後使得總體計算性能下降。

04 總結

文章從 Spark、SequoiaDB 以及 SequoiaDB for Spark connector 三個方面向讀者們介紹了海量數據下使用 SparkSQL+SequoiaDB 的性能調優方法。

文章中介紹的方法具有一定的參考意義,但是性能調優一直都是最考驗技術人員的工作。技術人員在對分佈式環境做性能調優時,需要綜合考慮多個方面的數據,例如:服務器的硬件資源使用情況、Spark 運行狀況、SequoiaDB 數據分佈是否合理、連機器的參數設置是否正確、SQL 命令是否有調優的空間等,要想性能提升,重點是要求技術人員找到整個系統中的性能短板,然後通過調整不同的參數或者修改存儲方案,從而讓系統運行得更加高效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章