[譯]HDFS的中心化緩存 (Centralized Cache Management in HDFS)

原文

概覽

HDFS上的中心化緩存是一個(gè)顯式的緩存機(jī)制, 使得用戶可以指定哪個(gè)路徑被緩存. Namenode和擁有指定文件塊的DataNode們通訊, 并命令他們將文件塊緩存到堆外緩存中.

HDFS的中心化緩存管理有如下的明顯優(yōu)勢:

  1. 明確的固定(pinning)可以防止被頻繁使用的數(shù)據(jù)被從內(nèi)存中移除. 這對那些數(shù)據(jù)尺寸超過主存的情況很重要, 而這類情況在HDFS上是非常常見.

  2. 因?yàn)镈ataNode的緩存是由NameNode管理的, 應(yīng)用方可以查詢被緩存的文件塊的位置, 并決定任務(wù)的位置. 將任務(wù)和緩存的文件塊副本放在一起改善了讀的性能.

  3. 當(dāng)文件塊被DataNode緩存后, 客戶端可以使用更新, 更高效, 和零拷貝的讀API. 因?yàn)榫彺嫖募K的校驗(yàn)和驗(yàn)證由DataNode執(zhí)行了一次, 客戶端就能以0開銷地使用新API(問: 什么新API?).

  4. 中心化緩存可以改善整個(gè)集群的內(nèi)存使用情況. 當(dāng)只能依靠各個(gè)DataNode的操作系統(tǒng)高速緩存時(shí), 重復(fù)地讀取一塊文件塊會導(dǎo)致該塊的n個(gè)拷貝被讀入高速緩存. 使用中心化緩存管理后, 一個(gè)用戶可以顯示指定只有n個(gè)副本中的m個(gè)可以被固定在緩存中, 并節(jié)省n-m的內(nèi)存.

使用場景

中心化緩存對于被常重復(fù)訪問的文件非常有用. 例如, Hive里一個(gè)較小的事實(shí)表, 經(jīng)常要和其他表在查詢中連接, 這就是需要被緩存的一個(gè)好候選.
反之, 緩存一個(gè)某年的查詢報(bào)告就沒那么必要, 因?yàn)闅v史數(shù)據(jù)一般就被讀一次.

中心化緩存管理對那種有服務(wù)等級協(xié)議(SLA)有多樣差異化的運(yùn)行負(fù)載也非常有用. 緩存那些優(yōu)先級高的的工作集數(shù)據(jù), 可以保證它不用和低優(yōu)先級的工作集數(shù)據(jù)競爭磁盤IO. (就像機(jī)場的VIP候機(jī)廳)

架構(gòu)

hdfs-central-cache.png

在這個(gè)架構(gòu)中, NameNode負(fù)責(zé)協(xié)調(diào)集群中所有DataNode的堆外緩存. NameNode定期地接收各個(gè)DataNode發(fā)送過來的緩存報(bào)告, 報(bào)告描述了任意DataNode上被緩存的所有文件塊. NameNode通過在心跳響應(yīng)中發(fā)送的緩存和踢出緩存命令來管理DataNode上的緩存.

NameNode查詢自身的緩存指令(directives?)來決定哪些路徑應(yīng)該被緩存. 緩存指令被永久存儲在文件系統(tǒng)映像(fsimage)和操作日志(edit log)中, 并且可以把java和命令行的api進(jìn)行添加,刪除和修改. NameNode也存儲了一些緩存池, 這些管理實(shí)體被用來將緩存指令分組, 進(jìn)行資源管理和權(quán)限控制.

NameNode定期地掃描命名空間和緩存指令來決定,哪些文件塊要被緩存,哪些要踢出緩存, 并將緩存動作指派到DataNode上. 掃描亦可由用戶動作發(fā)起, 例如添加或者刪除緩存指令, 或刪除一個(gè)緩存池.

我們當(dāng)前不會緩存那些, 構(gòu)建中, 損壞或者不完整的文件塊. 如果一個(gè)緩存指令涉及到文件鏈接, 這個(gè)鏈接的目標(biāo)文件不會被緩存.

當(dāng)前可以緩存文件或者目錄. 文件塊或更低級別的緩存將在未來實(shí)現(xiàn).

概念

緩存指令

一個(gè)緩存指令定義了要緩存的一個(gè)路徑. 路徑可以是目錄或者文件. 目錄是不會被遞歸式緩存的, 只有當(dāng)前目錄這一級的文件會被緩存.

指令同時(shí)定義了額外參數(shù), 例如緩存復(fù)制因子和過期時(shí)間. 緩存復(fù)制因子指定緩存要復(fù)制多少次. 如果多個(gè)緩存指令要緩存某一個(gè)文件, 那么最大緩存復(fù)制因子就被應(yīng)用.

過期時(shí)間由命令行指定為存活時(shí)間(time-to-live, TTL), 一個(gè)在未來的相對時(shí)間. 當(dāng)一個(gè)緩存指令過期后, 就不會再被NameNode在做緩存決定時(shí)考慮到.

緩存池

緩存池作為一個(gè)管理實(shí)體, 管理著緩存指令的分組. 緩存池有一個(gè)UNIX那種權(quán)限, 限制哪些用戶和組可以訪問某個(gè)池. 寫權(quán)限允許用戶在某個(gè)池上添加和刪除緩存指令. 讀權(quán)限允許用戶列出一個(gè)池中的緩存指令, 讀額外的元數(shù)據(jù). 執(zhí)行權(quán)限目前沒用到.

緩存池也用以管理資源. 池可以指定當(dāng)前池中能緩存的數(shù)據(jù)尺寸的最大限制(byte). 通常, 所有池的緩存限制之和,等于HDFS集群中所有的保留內(nèi)存(哪里指定?)之和. 緩存池同時(shí)也跟蹤記錄了很多統(tǒng)計(jì)來提升用戶如何決定什么應(yīng)該被緩存.

池也可以強(qiáng)制定義一個(gè)最大存活時(shí)間TTL. 這個(gè)定義限制了緩存指令在這個(gè)池中的最大存活時(shí)間.

緩存管理 命令行接口

在命令行下, 管理員和用戶可以通過hdfs cacheadmin命令集, 來操作緩存池和緩存指令.

緩存指令通過一個(gè)唯一, 不重復(fù)的64位整數(shù)ID來識別. 即使這個(gè)緩存指令被刪掉后, ID也不會被重復(fù)使用.

緩存指令命令

addDirective

用法: hdfs cacheadmin -addDirective -path 路徑 -pool 緩存池名 [-force] [-replication 復(fù)制因子] [-ttl 存活時(shí)間]
添加一個(gè)新的緩存指令

參數(shù) 說明
路徑 要緩存的路徑, 這個(gè)路徑可以是目錄或文件(通配符可以嗎?)
緩存池名 要把這個(gè)緩存指令加到哪個(gè)緩存池中. 你必須要有這個(gè)緩存池的寫權(quán)限才能加緩存指令
-forece 不檢查這個(gè)緩存池的最大尺寸限制
緩存復(fù)制因子 緩存復(fù)制多少份,默認(rèn)是1
存活時(shí)間 這個(gè)緩存指令的有效期, 可以指定為分鐘, 小時(shí), 天. 例如 30m, 4h, 2d. 有效單位是smhd. 用"never"來指定一個(gè)緩存永遠(yuǎn)存活, 如果不指定, 這個(gè)緩存指令就永不過期

removeDirective

用法: hdfs cacheadmin -removeDirective <Id>
刪除一個(gè)緩存指令

參數(shù) 說明
id 要?jiǎng)h除的緩存指令的id, 你必須有這個(gè)緩存指令的緩存池的寫權(quán)限才能刪除它. 要列出緩存指令的id, 請用-listDirectives命令

removeDirectives

用法: hdfs cacheadmin -removeDirectives 路徑
刪除指定路徑相關(guān)所有的緩存指令

參數(shù) 說明
路徑 要?jiǎng)h除的緩存指令的路徑, 你必須有這個(gè)緩存指令的緩存池的寫權(quán)限才能刪除它. 要列出緩存指令的id, 請用-listDirectives命令

listDirectives

用法: hdfs cacheadmin -listDirectives [-stats] [ -path 路徑 ] [ -pool 池]
列出緩存指令

參數(shù) 說明
路徑 只列出這個(gè)路徑相關(guān)的緩存指令. 注意, 如果對應(yīng)這個(gè)路徑的某個(gè)緩存指令所在的緩存池你沒有讀權(quán)限, 那這個(gè)緩存指令就不會列出.
緩存池 只列出這個(gè)緩存池中的緩存指令
-stats 列出基于路徑的緩存指令統(tǒng)計(jì)匯總

緩存池命令

addPool

用法: hdfs cacheadmin -addPool 緩存池名 [-owner 所有者用戶名] [-group 用戶組] [-mode 模式] [-limit 尺寸限制] [-maxTtl 最大存活時(shí)間]

參數(shù) 說明
緩存池名 緩存池的名字(最大長度?特殊字符?)
所有者 這個(gè)緩存池所有者的用戶名, 默認(rèn)是當(dāng)前用戶名
用戶組 這個(gè)池的用戶組. 默認(rèn)值是當(dāng)前用戶的主組的名字
模式 這個(gè)池的UNIX風(fēng)格的權(quán)限模式. 權(quán)限模式用8進(jìn)制表示. 例如. 0755. 默認(rèn)值是0755
尺寸限制 結(jié)合這個(gè)池上所有緩存指令, 這個(gè)池能緩存的最大字節(jié)數(shù). 默認(rèn)值是沒有限制
最大存活時(shí)間 對這個(gè)池,緩存指令能指定的最大存活時(shí)間. 可以指定為 秒, 分, 時(shí), 天. 例如 120s, 30m, 4h, 2d. 有效單位是[smhd]. 默認(rèn)是沒有最大值限制. 也可以用"never"來表示沒有限制

modifyPool

用法: hdfs cacheadmin -modifyPool 緩存池名 [-owner 所有者用戶名] [-group 用戶組] [-mode 模式] [-limit 尺寸限制] [-maxTtl 最大存活時(shí)間]
修改一個(gè)已經(jīng)存在的緩存池的元數(shù)據(jù)

參數(shù) 說明
緩存池名 緩存池的名字
所有者 這個(gè)緩存池所有者的用戶名
用戶組 這個(gè)池的用戶組
模式 這個(gè)池的Unix風(fēng)格的8進(jìn)制權(quán)限
尺寸限制 這個(gè)池能緩存的最大byte數(shù)
最大存活時(shí)間 這個(gè)池里緩存指令的最大存活時(shí)間

listPools

用法: hdfs cacheadmin -listPools [-stats] [名字]
列出一個(gè)或者多個(gè)緩存池的信息, 例如: 名字, 所有者, 權(quán)限, 等等

參數(shù) 說明
-stats 顯示為額外緩存池的統(tǒng)計(jì)信息
名字 如果指定, 只列出命名為此的緩存池

help

用法: hdfs cacheadmin -help 命令名
顯示某個(gè)命令的詳細(xì)幫助信息

參數(shù) 說明
命令名 要查看幫助的命令. 如果沒有指定,顯示所有命令的詳細(xì)幫助

配置

Native Libraries (原生庫)

為了將文件塊鎖定在內(nèi)存中, DataNode依賴于libhadoop.so或者h(yuǎn)adoop.dll(windows)中的JNI代碼. 要用HDFS中心緩存管理, 請確保啟動JNI.

配置屬性

必須項(xiàng)

確保以下配置:

  • dfs.datanode.max.locked.memory
    這個(gè)屬性決定一個(gè)DataNode可以用以緩存的最大內(nèi)存數(shù)量. 在Unix類系統(tǒng), "locked-in-memorysize" 在ulimit(ulimit -l)中, DataNode的用戶必須將其增加到和這個(gè)屬性配置對應(yīng)的值. (請參考OS限制). 配置這個(gè)值時(shí), 請留意其他需要內(nèi)存的程序, 例如DataNode和Jvm應(yīng)用堆內(nèi)存和操作系統(tǒng)緩存.

這個(gè)配置和延遲序列化寫特性共享. 數(shù)據(jù)節(jié)點(diǎn)會確保中心化緩存管理和延遲序列化寫特性所使用的內(nèi)存的總額不會超過dfs.datanode.max.locked.memory配置的值.

可選項(xiàng)

以下配置屬性不是必須的, 但可能用于調(diào)優(yōu):

  • dfs.namenode.path.based.cache.refresh.interval.ms
    NameNode用這個(gè)配置的毫秒數(shù)為周期進(jìn)行路徑緩存掃描. 這個(gè)掃描計(jì)算要緩存的文件塊和要緩存文件塊副本的各個(gè)DataNode
    默認(rèn)下, 這個(gè)參數(shù)的值是300000毫秒, 5分鐘.

  • dfs.datanode.fsdatasetcache.max.threads.per.volume
    DataNode用這個(gè)配置作為每個(gè)卷的最大線程數(shù), 來緩存新數(shù)據(jù).
    默認(rèn)下, 這個(gè)參數(shù)是4

  • dfs.cachereport.intervalMsec
    DataNode以這個(gè)毫秒數(shù)為周期來向NameNode發(fā)送其緩存狀態(tài)的報(bào)告
    默認(rèn)下, 這個(gè)參數(shù)是10000毫秒, 10秒鐘.

  • dfs.namenode.path.based.cache.block.map.allocation.percent
    這個(gè)參數(shù)決定我們要分配多少Java堆內(nèi)存給緩存文件塊map. 緩存文件塊map是一個(gè)用鏈?zhǔn)焦5囊粋€(gè)哈希map. 如果map比較小,而緩存的文件塊數(shù)量大, 那訪問map速度就慢. 比較大的map會消耗更多內(nèi)存. 默認(rèn)值是0.25%.

OS Limits 操作系統(tǒng)限制

如果你看到這個(gè)錯(cuò)誤:"Cannot start datanode because the configured max locked memory size… is more than the datanode’s available RLIMIT_MEMLOCK ulimit" (無法啟動DataNode, 因?yàn)榕渲玫膍ax locked memory大于DataNode可用的RLIMIT_MEMLOCK ulimit). 這個(gè)表示操作系統(tǒng)配置的內(nèi)存限制比你配置在HDFS里的要小. 要修復(fù), 你要調(diào)整DataNode運(yùn)行的ulimit -l值. 通常, 這個(gè)值是配置在 /etc/security/limits.conf 文件. 不過, 也取決于你使用的操作系統(tǒng)的版本.

當(dāng)你可以從shell里執(zhí)行"ulimit -l"并得到一個(gè)值大于你配置到dfs.datanode.max.locked.memory的值,或者"unlimited",意味著沒有限制,就說明你已經(jīng)正確地配置了系統(tǒng)的限制. 請注意, "ulimit -l"命令輸出的memory lock limit的單位是KB,但dfs.datanode.max.locked.memory的單位必須指定為byte.

這個(gè)提示并不能應(yīng)用到windows上的部署. 因?yàn)閣indows上沒有"ulimit -l"對應(yīng)的命令

引用:
https://blog.csdn.net/chenKFKevin/article/details/61196409

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容