【Hadoop學習】HDFS中的集中化緩存管理


Hadoop版本:2.6.0

本文系從官方文檔翻譯而來,轉載請尊重譯者的工作,注明以下鏈接:

http://www.cnblogs.com/zhangningbo/p/4146398.html

 

概述


 

HDFS中的集中化緩存管理是一個明確的緩存機制,它允許用戶指定要緩存的HDFS路徑。NameNode會和保存着所需快數據的所有DataNode通信,並指導他們把塊數據緩存在off-heap緩存中。

HDFS集中化緩存管理具有許多重大優勢:

1.明確的鎖定可以阻止頻繁使用的數據被從內存中清除。當工作集的大小超過了主內存大小(這種情況對於許多HDFS負載都是司空見慣的)時,這一點尤為重要。

2.由於DataNode緩存是由NameNode管理的,所以,在確定任務放置位置時,應用程序可以查詢一組緩存塊位置。把任務和緩存塊副本放在一個位置上可以提高讀操作的性能。

3.當塊已經被DataNode緩存時,客戶端就可以使用一個新的更高效的零拷貝讀操作API。因為緩存數據的checksum校驗只需由DataNode執行一次,所以,使用這種新API時,客戶端基本上不會有開銷。

4.集中緩存可以提高整個集群的內存使用率。當依賴於每個DataNode上操作系統的buffer緩存時,重復讀取一個塊數據會導致該塊的N個副本全部被送入buffer緩存。使用集中化緩存管理,用戶就能明確地只鎖定這N個副本中的M個了,從而節省了N-M的內存量。

 

使用場景


 

集中化緩存管理對於重復訪問的文件很有用。例如,Hive中的一個較小的fact表(常常用於joins操作)就是一個很好的緩存對象。另一方面,對於一個全年報表查詢的輸入數據做緩存很可能就沒有多大作用了,因為,歷史數據只會讀取一次。

集中化緩存管理對於帶有性能SLA的混合負載也很有用。緩存正在使用的高優先級負載可以保證它不會和低優先級負載競爭磁盤I/O。

 

架構


 

Caching Architecture

 

在這個架構中,NameNode負責協調集群中所有DataNode的off-heap緩存。NameNode周期性地接收來自每個DataNode的緩存報告(其中描述緩存在給定DN中的所有塊)。NameNode通過借助DataNode心跳上的緩存和非緩存命令來管理DataNode緩存。

NameNode查詢自身的緩存指令集來確定應該緩存那個路徑。緩存指令永遠存儲在fsimage和edit日志中,而且可以通過Java和命令行API被添加、移除或修改。NameNode還存儲了一組緩存池,它們是用於把資源管理類和強制權限類的緩存指令進行分組的管理實體。

NameNode周期性地重復掃描命名空間和活躍的緩存指定以確定需要緩存或不緩存哪個塊,並向DataNode分配緩存任務。重復掃描也可以又用戶動作來觸發,比如,添加或刪除一條緩存指令,或者刪除一個緩存池。

當前,我們不緩存construction、corrupt下的塊數據,或者別的不完整的塊。如果一條緩存指令包含一個符號鏈接,那么該符號鏈接目標不會被緩存。

當前,我們只實現了文件或目錄級的緩存。塊和子塊緩存是未來的目標。

 

概念


 

緩存指令

一條緩存指令定義了一個要被緩存的路徑(path)。這些路徑(path)可以是文件夾或文件。文件夾是以非迭代方式緩存的,只有在文件夾頂層列出的文件才有意義。

文件夾也可以指定額外的參數,比如緩存副本因子,有效期等。副本因子指定了要緩存的塊副本數。如果多個緩存指令指向同一個文件,那么就用最大緩存副本因子。

有效期是在命令行指定的,就像TTL一樣,相對有效期會在未來版本引入。緩存指令過期之后,在決定緩存時,它就不再被NameNode考慮了。

 

緩存池

緩存池是一個管理實體,用於管理緩存指令組。緩存池擁有類UNIX的權限,可以限制哪個用戶和組可以訪問該緩存池。寫權限允許用戶向緩存池添加或從中刪除緩存指令 。讀權限允許用戶列出緩存池內的緩存指令,還有其他元數據。執行權限不能使用。

緩存池也可以用於資源管理。它可以強加一個最大限制值,可以限制通過緩存池中的指令緩存入的字節數。通常,緩存池限制值之和約等於為HDFS在集群中做緩存而保留的總內存量。緩存池也可以追蹤許多統計信息以便於集群用戶決定應該緩存什么。

緩存池也可以強加一個TTL最大值。該值限制了被添加到緩存池的指令的最大有效期。

 

緩存管理命令接口


 

在命令行上,管理員和用戶可以使用過hdfs cacheadmin子命令借助緩存池來交互。

緩存指令由一個唯一的無重復的64位整數ID來標識。即使緩存指令后來被刪除了,ID也不會重復使用。

緩存池由一個唯一的字符串名稱來標識。

 

緩存管理命令

addDirective

用法: hdfs cacheadmin -addDirective -path <path> -pool <pool-name> [-force] [-replication <replication>] [-ttl <time-to-live>]

<path> 要緩存的路徑。該路徑可以是文件夾或文件。
<pool-name> 要加入緩存指令的緩存池。你必須對改緩存池有寫權限以便添加新的緩存指令。
-force 不檢查緩存池的資源限制
<replication> 要使用的緩存副本因子,默認為1
<time-to-live>  緩存指令可以保持有效多長時間。可以按照分鍾,小時,天來指定,如30m,4h,2d。有效單位為[smhd]。“never”表示永不過期的指令。如果未指定該值,那么,緩存指令就不會過期。

 

removeDirective

用法: hdfs cacheadmin -removeDirective <id>

<id>  要刪除的緩存指令的ID。你必須對該指令的緩存池擁有寫權限,以便刪除它。要查看詳細的緩存指令列表,可以使用-listDirectives命令。

 

removeDirectives

用法: hdfs cacheadmin -removeDirectives <path>

<path>  要刪除的緩存指令路徑。你必須對該指令的緩存池擁有寫權限,以便刪除它。要查看詳細的緩存指令列表,可以使用-listDirectives命令。

 

listDirectives

用法:hdfs cacheadmin -listDirectives [-stats] [-path <path>] [-pool <pool>]

<path>  只列出帶有該路徑的緩存指令。注意,如果路徑path在緩存池中有一條我們沒有讀權限的緩存指令,那么它就不會被列出來。
<pool>  只列出該緩存池內的緩存指令。
-stats  列出基於path的緩存指令統計信息。

 

 

緩存池命令

 

addPool

用法:hdfs cacheadmin -addPool <name> [-owner <owner>] [-group <group>] [-mode <mode>] [-limit <limit>] [-maxTtl <maxTtl>

<name>  新緩存池的名稱。
<owner>  該緩存池所有者的名稱。默認為當前用戶。
<group>  緩存池所屬的組。默認為當前用戶的主要組名。
<mode>  以UNIX風格表示的該緩存池的權限。權限以八進制數表示,如0755.默認值為0755.
<limit>  在該緩存池內由指令總計緩存的最大字節數。默認不設限制。
<maxTtl>  添加到該緩存池的指令的最大生存時間。該值以秒,分,時,天的格式來表示,如120s,30m,4h,2d。有效單位為[smhd]。默認不設最大值。“never”表示沒有限制。

 

 

modifyPool

用法:hdfs cacheadmin -modifyPool <name> [-owner <owner>] [-group <group>] [-mode <mode>] [-limit <limit>] [-maxTtl <maxTtl>]

<name>  要修改的緩存池的名稱。
<owner>  該緩存池所有者的名稱。
<group>  緩存池所屬的組。
<mode>  以UNIX風格表示的該緩存池的權限。八進制數形式。
<limit>  在該緩存池內要緩存的最大字節數。
<maxTtl>  添加到該緩存池的指令的最大生存時間。

 

 

removePool

用法:hdfs cacheadmin -removePool <name>

<name> 要刪除的緩存池的名稱

 

 

listPools

用法:hdfs cacheadmin -listPools [-stats] [<name>]

-stats 顯示額外的緩存池統計信息
<name> 若指定,則僅列出該緩存池的信息

 

 

help

用法:hdfs cacheadmin -help <command-name>

<command name> 要獲得詳細幫助信息的命令。如果沒有指定命令,則打印所有命令的幫助信息。

配置


 

本地庫

為了把塊文件鎖定在內存,DataNode需要依賴本地JNI代碼(Linux系統為libhadoop.so,Windows系統為hadoop.dll)。如果你正在使用HDFS集中化緩存管理,請確保使能JNI

 

配置屬性

屬性名稱 默認值 描述
dfs.datanode.max.locked.memory 0 DataNode的內存中緩存塊副本要用的內存量(以字節表示)。DataNode的最大鎖定內存軟限制ulimit(RLIMIT_MEMLOCK)必須至少設為該值。 否則,DataNode在啟動時會終止。默認值為0,表示禁止內存緩存。如果本地庫對於該DataNode不可用,那么,該配置就無效。
dfs.namenode.list.cache.directives.num.responses 100 該參數控制NameNode在響應listDirectives RPC命令時通過wire發送的緩存指令數。
dfs.namenode.list.cache.pools.num.responses 100 該參數控制NameNode在響應listDirectives RPC命令時通過wire發送的緩存池數。
dfs.namenode.path.based.cache.refresh.interval.ms 30000 兩次子路徑緩存重復掃描的時間間隔,單位毫秒。路徑緩存重復掃描發生在計算緩存哪個塊,以及在哪個DataNode上緩存時。默認為30秒。 
dfs.namenode.path.based.cache.retry.interval.ms 30000 當NameNode不需要緩存某些數據,或者緩存那些沒有緩存的數據時,它必須通過在DataNode心跳響應中發送DNA_CACHE或者DNA_UNCACHE命令,以便指導DataNode這么去做。該參數控制NameNode重復發送這些命令的頻率。(即多長時間重發一次)
dfs.datanode.fsdatasetcache.max.threads.per.volume 4 DataNode上緩存新數據時每個卷要用的最大線程數。 這些線程要消耗I/O和CPU。該參數影響普通DataNode操作。
dfs.cachereport.intervalMsec 10000 決定兩次緩存上報動作的時間間隔,單位毫秒。超過這個時間后,DataNode會向NameNode發送其緩存狀態的完整報告。 NameNode使用緩存報告來更新緩存塊與DataNode位置之間的映射關系。如果內存緩存被禁用了(設置屬性dfs.datanode.max.locked.memory為0,這是默認值),那么該參數就無效了。如果本地庫對於該DataNode不可用,那么,該配置就無效。
dfs.datanode.cache.revocation.timeout.ms 900000 當DFSClient從DataNode正在緩存的塊文件中讀取數據時,DFSClient可以不做checksums校驗。DataNode一直將塊文件保存在緩存中直到客戶端完成。然而,如果客戶端一改往常般運行了很長時間,那么,DataNode可能需要從緩存中清除這個塊文件。該參數控制DataNode等待一個正在執行無校驗讀操作的客戶端發送一個副本要花多少時間。
dfs.datanode.cache.revocation.polling.ms 500 DataNode需要多長時間輪詢一次客戶端是否停止使用DataNode不想緩存的副本。

 

必選屬性

屬性名稱 默認值 描述
dfs.datanode.max.locked.memory   該參數用於確定DataNode給緩存使用的最大內存量。DataNode用戶的“locked-in-memory size”ulimit(ulimit -l)也需要增加以匹配該參數(詳見下文OS限制)。當設置了該值時,請記住你還需要一些內存空間用於做其他事情,比如,DataNode和應用程序JVM堆內存、以及操作系統的頁緩存。

 

可選屬性

以下屬性不是必選的,但可能用於調優:

屬性名稱 默認值 描述
dfs.namenode.path.based.cache.refresh.interval.ms 300000 NameNode使用該參數作為兩次子路徑緩存重復掃描的動作之間的時間間隔,單位為毫秒。該參數計算要緩存的塊和每個DataNode包含一個該塊應當緩存的副本
dfs.datanode.fsdatasetcache.max.threads.per.volume 4 DataNode使用該參數作為緩存新數據時每個卷要用的最大線程數。
dfs.cachereport.intervalMsec 10000 DataNode使用該參數作為兩次發送緩存狀態報告給NameNode的動作之間的時間間隔。單位為毫秒。
dfs.namenode.path.based.cache.block.map.allocation.percent 0.25 分配給已緩存塊映射的Java堆內存的百分比。它是hash map,使用鏈式hash。如果緩存塊的數目很大,那么map越小,訪問速度越慢;map越大,消耗的內存越多。

 

 

OS限制

如果你遇到錯誤“Cannot start datanode because the configured max locked memory size... is more than the datanode's available RLIMIT_MEMLOCK ulimit,”,就意味着操作系統對用戶可以鎖定的內存使用量強加了一個限制,該限制值比用戶設置的值更低一些。要修復這個問題,必須使用“ulimit -l”命令來調整DataNode運行需要鎖定的內存值。通常,該值是在/etc/security/limits.conf文件中配置的。然而,它也會因用戶所用的操心系統和分發版的不同而變化。

當你從shell中運行“ulimit -l”並得到一個比你用屬性dfs.datanode.max.locked.memory設置的值更高的值,或者字符串“ulimited”(表示沒有限制)時,你就會明白你已經正確配置了該值。值得注意的是,ulimit -l命令通常以KB為單位輸出內存鎖定限制值,但是dfs.datanode.max.locked.memory的值必須以字節為單位。

這些信息不適用於Windows環境部署。Windows沒有和“ulimit -l”相對應的命令。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM