通過上篇文章【Spark RDD詳解】,大家應該瞭解到Spark會通過DAG將一個Spark job中用到的所有RDD劃分為不同的stage,每個stage內部都會有很多子任務處理數據,而每個stage的任務數是決定性能優劣的關鍵指標。
首先來了解一下Spark中分區的概念,其實就是將要處理的數據集根據一定的規則劃分為不同的子集,每個子集都算做一個單獨的分區,由集羣中不同的機器或者是同一台機器不同的core進行分區並行處理。
Spark對接不同的數據源,在第一次得到的分區數是不一樣的,但都有一個共性:對於map類算子或者通過map算子產生的彼此之間具有窄依賴關係的RDD的分區數,子RDD分區與父RDD分區是一致的。而對於通過shuffle差生的子RDD則由分區器決定,當然默認分區器是HashPartitioner,我們完全可以根據實際業務場景進行自定義分區器,只需繼承Parttioner組件,主要重寫幾個方法即可
以加載hdfs文件為例,Spark在讀取hdfs文件還沒有調用其他算子進行業務處理前,得到的RDD分區數由什麼決定呢?關鍵在於文件是否可切分!
對於可切分文件,如text文件,那麼通過加載文件得到的RDD的分區數默認與該文件的block數量保持一致;
對於不可切分文件,它只有一個block塊,那麼得到的RDD的分區數默認也就是1。
當然,我們可以通過調用一些算子對RDD進行重分區,如repartition。
這裏必須要強調一點,很多小夥伴不理解,RDD既然不存儲數據,那麼加載過來的文件都跑哪裏去了呢?這裏先給大家提個引子——blockmanager,Spark自己實現的存儲管理器。RDD的存儲概念其實block,至於block的大小可以根據不同的數據源進行調整,blockmanager的數據存儲、傳輸都是以block進行的。至於block內部傳輸的時候,它的大小也是可以通過參數控制的,比如廣播變量、shuffle傳輸時block的大小等