1. 程式人生 > >Drill 記憶體設定

Drill 記憶體設定

你可以在任何Drill叢集上,為查詢處理的Drillbit程序,配置直接記憶體的大小。Drillbit程序預設的記憶體大小是8G,但是Drill推薦根據負載大小,設定16G及以上的記憶體。Drillbit程序分配給查詢操作的直接記憶體大小不能超過這個引數值。

這裡插入一下“直接記憶體”的釋義:

直接記憶體不是jvm執行時資料區的一部分,也不是java虛擬機器規範中定義的記憶體區域,但是這部分記憶體也被頻繁的使用,而且也可能導致OutOfMemoryError的異常出現。

在jdk1.4中新加入了NIO類,引入了一直基於通道和快取區的I/O方式,它可以使用Native函式庫直接分配堆外記憶體,然後通過一個儲存在Java堆裡的DirectByteButter物件作為這塊記憶體的引用進行操作。這樣在一些場景中可以顯著提高效能,因為避免了在java堆裡和Native堆裡來回複製資料。

顯然,本機直接記憶體的分配不會受java堆記憶體大小的限制,但是,既然也是記憶體,則肯定還是會受到本機總實體記憶體大小及處理器定址空間的限制。所以在配置jvm虛擬機器引數時,一般會根據實際實體記憶體來設定-Xmx,-Xms等引數資訊,但經常會忽略掉直接記憶體,使得jvm各個記憶體區域的和大於實體記憶體限制,從而導致動態擴充套件時出現OutOfMemeryError異常。

Drill使用java直接記憶體,通常在記憶體中執行操作,相比於在磁碟上操作,效果要好。不像MapReduce在一個工作的每個階段都會寫磁碟,除非絕對需要,Drill通常不寫資料到磁碟上。

Jvm的堆記憶體不限制Drillbit程序的直接記憶體大小,Drill的非堆記憶體一般設定為4-8G(預設是4G),通常這已經足夠,因為Drill避免資料存放在堆中。

Drill 1.5後,使用了一個新的收集器,可以提高操作使用直接記憶體的效率,並可以更準確的追蹤記憶體的變化。基於這種變化,排序操作(早期版本查詢可以執行成功)可能會因為記憶體不足,導致查詢失敗和記憶體溢位錯誤,而非溢寫到磁碟上。

planner.memory.max_query_memory_per_node這個系統選型,可以設定在每個節點上的一次查詢中,可以分配給排序操作的最大直接記憶體。

如果一個查詢計劃包含多個排序操作,它們共享這部分記憶體。如果你運行了包含排序操作的查詢,出現了記憶體錯誤,可以試試增加這個引數的值。如果增加此值,你扔碰到記憶體錯誤,你可以減少planner.width.max_per_node

所設定的值,從而減少每個節點的系統併發度。但是,這通常會增加查詢完成的時間。

修改 Drillbit 的記憶體值

你可以在叢集中修改每一個Drillbit節點的記憶體值,為了達到這個目的,可以在Drillbit的啟動指令碼drill-env.sh中(位於/conf下),設定DRILL_MAX_DIRECT_MEMORY變數,如下:

export DRILL_MAX_DIRECT_MEMORY=${DRILL_MAX_DIRECT_MEMORY:-“”}
注意:如果這個引數未設定,大小限制取決於實際可用的系統記憶體。
修改完 drill-env.sh後,記得重啟每臺節點上的Drillbit程序以使其生效。

關於Drillbit啟動指令碼

在drill-env.sh檔案中包含以下的選項:

export DRILL_HEAP=${DRILL_HEAP:-"4G"}

export DRILL_MAX_DIRECT_MEMORY=${DRILL_MAX_DIRECT_MEMORY:-"8G"}

DRILL_MAX_HEAP 是每個節點上JVM理論上的堆最大值。
DRILL_MAX_DIRECT_MEMORY是每個節點java直接記憶體的最大值。

如果效能是一個問題,可以新增-Dbounds=false, 如下所示:
export DRILL_JAVA_OPTS=”$DRILL_JAVA_OPTS -Dbounds=false”

引用列表:
1. https://drill.apache.org/docs/configuring-drill-memory/
2. http://2387209.blog.51cto.com/2377209/1508621