首先要說的是機器配置
namenode/datanode:
cpu : 8core memory: 56G
我現在是基於yarn+spark的架構來說。
現在設置
yarn.nodemanager.resource.memory-mb =51200 (50GB) --每個node可以最多使用50GB作爲 container 的分配
yarn.scheduler.minimum-allocation-mb =512 (0.5GB) --分配的遞增單位是 0.5GB
yarn.scheduler.maximum-allocation-mb =51200 ( 50GB) --最大的container是50GB, 也就是說,可以從 0.5G 1G 1.5G 2G 一直到 50G 一個container
--===================================================
數據輸入爲 10個文件,大小總共10G txt非壓縮
使用spark-sql,默認的numPartitions 是1 ,所以 desired partition size = 10GB / 1 = 10GB
spark 的 block size = 512MB (實踐中觀察到,但實際的dfs.blocksize = 128MB, 有待進一步查明真相)
計算輸入分區size公式= max(split size, min (desired partition size, block size))
默認的 mapreduce.input.fileinputformat.split.minsize=1 ( 1 byte)
所以 輸入分區size= 512MB (如果需要解壓的話,那麼會變得更大)
現在需要計算 executor和container的大小.
executor大小 >= 輸入分區的大小, 所以設置 512MB, 但需要考慮:
1)如果core資源較多,executor內設置多個線程(多個core分配給一個executor)的情況,那麼GC的壓力會比較大,如果GC time較長,那麼需要考慮增加executor的內存;最好就是有多少個core就增加多少倍的輸入分區大小。
2)如果需要cache數據的話,那麼需要設置spark.storage.memoryFraction,默認值是0.6, 那麼cache內存大小計算=executor*0.868*0.6
所以除去cache的內存,executor剩下0.4左右的大小。
所以 executor size * 0.868 * 0.4 = 512 MB * cores/executor (最小值 1 core,即單線程)
container size = executor size + max(executor size * 0.1, 384) = N * 512MB (因爲遞增單位爲512MB)
executor num = nodes * 50G / container size
這個executor num可以根據整個cluster可以允許該用戶使用多少資源而定,還有core的分配。這樣可以支持多用戶共享整個cluster的資源。
接下來我還會給大家講講如何處理OOM的問題,還有如何處理我們的輸入跟輸出的調優。