HDFS集中式高速緩存管理及短路讀取案例
node
做者:尹正傑算法
版權聲明:原創做品,謝絕轉載!不然將追究法律責任。vim
一.HDFS中集中式緩存概述緩存
1>.Hadoop緩存概述安全
一般datanode從磁盤中讀取數據塊,但對於訪問頻繁的文件(例如小型Hive事實表),其對應的塊可能被顯式地緩存在datanode的內存中,以堆外緩存的形式存在。可使用Hadoop的集中式緩存管理來顯示緩存指定路徑。能夠在文件或目錄級別緩存數據。當緩存路徑時,NameNode會指定擁有該文件塊的DataNode將這些塊從磁盤緩存起來,實質上時將這些快緩存至內存中。 默認狀況下,一個數據塊僅緩存在一個datanode的內存中,固然能夠針對每一個文件配置datanode的數量。用戶或應用經過在緩存池(cache pool,是一個用於管理緩存權限和資源使用的管理性分組)中增長一個cache directive來告訴namenode須要緩存哪些文件及緩存多久。 當工做集的總量大於RAM時,服務器會從內存中置換出數據,爲新數據騰出空間。緩存大數據集用於查詢效率不高的狀況,由於極可能不會重複讀取這些相同的數據集。能夠考慮使用嚴格的SLA(服務級別協議)緩存關鍵工做負載的數據,以防止這些數據競爭磁盤I/O。緩存在磁盤爭用的集羣中特別有用。 舒適提示: Cloudera工程師進行的測試代表,與從磁盤讀取數據相比,Impala等應用程序從緩存讀取的速度提升了59倍。
2>.Hadoop和OS的頁面緩存服務器
Hadoop和DataNode使用操做系統的頁面緩存,該緩存策略會緩存最近訪問的全部數據到本地文件系統。可是,在像Hadoop這樣的分佈式系統中,僅使用操做系統頁面緩存時不夠的。因爲沒有每一個DataNode的內存狀態的全局信息,所以當提供多個HDFS副本時,客戶端沒法根據局部緩存性進行任務調度。因此性能有所損失,由於客戶端在不知道局部緩存的狀況下進行任務調度。
當客戶端運行查詢時,應用調度程序選擇一個數據塊副本位置,並在該DataNode上運行任務,且將副本拉入操做系統頁面緩存。可是,調度程序不知道存儲在頁面緩存中的副本,於是不能利用局部緩存來分配任務。
另外一個問題是,因爲大多數操做系統的頁面緩存使用LRU(最近最少使用)算法的修改版原本肯定他們應該保存在內存中的數據,所以他們可能會從緩存中置換出用戶的工做數據集。
操做系統頁面緩存很差的另外一個緣由是,它比直接從內存讀取效率低,由於直接從內存讀取提供了"零讀取複製(俗稱零拷貝)"性能。
3>.集中式緩存的關鍵原則及原理概述app
NameNode的集中式緩存管理遵循如下關鍵原則: (1)掌握集中式緩存的狀態,這有助於局部緩存調度做業; (2)可預測的混合負載性能,經過集羣高速緩存狀態感知; (3)經過將當前數據集固定在本地緩存中而不是將其刷新到磁盤,能夠實現零讀取複製。 緩存池對可使用的內存量設置限制,用戶經過緩存指令管理緩存。緩存指令能夠指定如下內容: (1)要緩存的HDFS文件或目錄,由路徑指示; (2)緩存複製因子(從1到文件的複製因子); (3)指令的緩存池。 HDFS集中式緩存管理的工做原理以下: (1)當HDFS客戶端緩存文件時,它會向NameNode發送一個緩存指令,請求緩存該文件; (2)NameNode向DataNode發送緩存命令; (3)一旦緩存了數據,DataNode就會發送一個緩存報告; (4)應用調度程序能夠從NameNode找到緩存信息,並依據局部緩存進行任務的調度。 DataNode在堆外內存緩存數據,這意味着緩存大量數據不會對垃圾回收產生不利影響。HDFS將緩存塊從頁面緩存直接映射到客戶端的地址空間,這避免了重複讀取的系統調用中涉及的上下文切換開銷。零讀取複製時結果,顧名思義,它花費了不多的時間複製數據,大部分CPU週期可用於"實際工做"。集中式高速緩存管理的另外一個好處是,因爲DataNode在緩存數據時會對數據進行校驗,所以客戶端在讀取數據時能夠跳過校驗和驗證。 能夠經過將任務與高速緩存塊副本進行協同定位來提升應用程序的讀取性能。而後,應用程序在肯定防止任務的位置時查詢緩存塊位置集。集羣內存應用程序也更高效,由於只能固定一個塊的三個副本中的一個,因此不須要再重複讀取塊以後將塊的全部副本若如緩衝區高速緩存。
4>.配置緩存注意事項框架
可使用hdfs cacheadmin命令行接口配置緩存。cacheadmin命令用於配置緩存指令和緩存池,這兩個組件是緩存HDFS數據時所必須配置的關鍵組件。 在實現HDFS緩存時,必須增長鎖定內存的操做系統限制。將"hdfs-site.xml"中的"dfs.datanode.max.locked.memory"參數設置爲DataNode節點最大鎖定內存軟ulimit可用於緩存的最大內存量,不然在DataNode在啓動時會停止。 儘管使用"ulimit -l"命令顯示內存鎖定限制以千字節(KB)爲單位,但必須以字節(Bytes)爲單位指定此屬性。默認狀況下,此參數設置爲0,這將禁用內存中的緩存。若是本機庫對DataNode不可用,則配置不起做用。
在Linux系統中,當設置"dfs.datanode.max.locked.memory"參數時,可能還須要調高"/etc/security/limits.conf"文件中"memlock"屬性的值。生產環境我推薦緩存中內存設置閾值能夠考慮在節點內存的5%~10%左右便可。
5>. 緩存指令dom
[root@hadoop101.yinzhengjie.com ~]# hdfs cacheadmin Usage: bin/hdfs cacheadmin [COMMAND] [-addDirective -path <path> -pool <pool-name> [-force] [-replication <replication>] [-ttl <time-to-live>]] [-modifyDirective -id <id> [-path <path>] [-force] [-replication <replication>] [-pool <pool-name>] [-ttl <time-to-live>]] [-listDirectives [-stats] [-path <path>] [-pool <pool>] [-id <id>]] [-removeDirective <id>] [-removeDirectives -path <path>] [-addPool <name> [-owner <owner>] [-group <group>] [-mode <mode>] [-limit <limit>] [-defaultReplication <defaultReplication>] [-maxTtl <maxTtl>]] [-modifyPool <name> [-owner <owner>] [-group <group>] [-mode <mode>] [-limit <limit>] [-defaultReplication <defaultReplication>] [-maxTtl <maxTtl>]] [-removePool <name>] [-listPools [-stats] [<name>]] [-help <command-name>] Generic options supported are: -conf <configuration file> specify an application configuration file -D <property=value> define a value for a given property -fs <file:///|hdfs://namenode:port> specify default filesystem URL to use, overrides 'fs.defaultFS' property from configurations. -jt <local|resourcemanager:port> specify a ResourceManager -files <file1,...> specify a comma-separated list of files to be copied to the map reduce cluster -libjars <jar1,...> specify a comma-separated list of jar files to be included in the classpath -archives <archive1,...> specify a comma-separated list of archives to be unarchived on the compute machines The general command line syntax is: command [genericOptions] [commandOptions] [root@hadoop101.yinzhengjie.com ~]#
如上所述,可使用addDirective屬性添加緩存指令。可使用"-removeDirective"或"-removeDirectives"屬性刪除一個或多個緩存指令。可使用"-listDirectives"選線列出全部緩存指令。也能夠選擇指定如下內容: (1)使用stats標誌查看指令統計信息; (2)使用path屬性只能查看特定路徑下的指令; (3)使用pool屬性只列出特定緩存池中的指令; 爲了緩存文件或目錄,必須使用緩存指令文件或目錄的絕對路徑。請注意,若是緩存絕對路徑,則只會緩存該界別的文件,而不會緩存該目錄下的文件。還能夠指定在緩存文件或目錄時的複製因子和到期時間。 在默認狀況下,緩存文件或目錄的複製因子爲1,但能夠指定更高的複製因子。能夠指定集羣中特定節點上覆制數據塊的數量。另外,在默認狀況下,指令永不會過時,但能夠經過ttl(time-to-live)屬性來指定保持有效的時間。
6>.緩存池socket
能夠配置只管理實體的緩存池,其用於管理裏一組緩存指令。經過設置適當的權限,能夠限定對特定用戶和組的緩存池訪問或容許用戶添加或刪除配置的緩存指令。集羣中全部的緩存池總量等於HDFS緩存保留的聚合內存量。
配置了HDFS塊緩存後,MapReduce和其它做業框架能夠經過緩存塊的節點上調度做業來利用緩存,從而減小經過I/O讀取數據的機會。
二.緩存配置實戰案例
1>.修改Linux的內存限制
[root@hadoop101.yinzhengjie.com ~]# free -h total used free shared buff/cache available Mem: 3.8G 456M 2.7G 11M 715M 3.1G Swap: 0B 0B 0B [root@hadoop101.yinzhengjie.com ~]# [root@hadoop101.yinzhengjie.com ~]# cat /etc/security/limits.conf #Add by yinzhengjie * soft core unlimited * hard core unlimited * soft nproc 1000000 * hard nproc 1000000 * soft nofile 1000000 * hard nofile 1000000 * soft memlock 32000 * hard memlock 32000 * soft msgqueue 8192000 * hard msgqueue 8192000 [root@hadoop101.yinzhengjie.com ~]# [root@hadoop101.yinzhengjie.com ~]# ulimit -l #很顯然,我這裏設置的是32MB 32000 [root@hadoop101.yinzhengjie.com ~]#
2>.修改Linux的HDFS配置文件(重啓集羣方能生效)
[root@hadoop101.yinzhengjie.com ~]# cat ${HADOOP_HOME}/etc/hadoop/hdfs-site.xml #修改該配置後必須重啓集羣,不然以下圖所示並不會生效喲~ ...... <property> <name>dfs.datanode.max.locked.memory</name> <value>32000000</value> <description>用於在數據節點上的內存中緩存塊副本的內存量(以字節爲單位)。數據節點的最大鎖定內存軟限制(RLIMIT_MEMLOCK)必須至少設置爲該值,不然數據節點將在啓動時停止。默認狀況下,此參數設置爲0,這將禁用內存中緩存。若是本機庫不可用於DataNode,則此配置無效。</description>
</property> ...... [root@hadoop101.yinzhengjie.com ~]#
[root@hadoop101.yinzhengjie.com ~]# hdfs dfsadmin -report Configured Capacity: 24740939366400 (22.50 TB) Present Capacity: 24740939366400 (22.50 TB) DFS Remaining: 24739753041920 (22.50 TB) DFS Used: 1186324480 (1.10 GB) DFS Used%: 0.00% Under replicated blocks: 0 Blocks with corrupt replicas: 0 Missing blocks: 0 Missing blocks (with replication factor 1): 0 Pending deletion blocks: 0 ------------------------------------------------- Live datanodes (3): Name: 172.200.6.102:50010 (hadoop102.yinzhengjie.com) Hostname: hadoop102.yinzhengjie.com Rack: /rack001 Decommission Status : Normal Configured Capacity: 8246979788800 (7.50 TB) DFS Used: 395472896 (377.15 MB) Non DFS Used: 0 (0 B) DFS Remaining: 8246584315904 (7.50 TB) DFS Used%: 0.00% DFS Remaining%: 100.00% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Sun Aug 16 11:00:02 CST 2020 Last Block Report: Sun Aug 16 07:44:09 CST 2020 Name: 172.200.6.103:50010 (hadoop103.yinzhengjie.com) Hostname: hadoop103.yinzhengjie.com Rack: /rack002 Decommission Status : Normal Configured Capacity: 8246979788800 (7.50 TB) DFS Used: 395423744 (377.11 MB) Non DFS Used: 0 (0 B) DFS Remaining: 8246584365056 (7.50 TB) DFS Used%: 0.00% DFS Remaining%: 100.00% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Sun Aug 16 11:00:02 CST 2020 Last Block Report: Sun Aug 16 07:04:02 CST 2020 Name: 172.200.6.104:50010 (hadoop104.yinzhengjie.com) Hostname: hadoop104.yinzhengjie.com Rack: /rack002 Decommission Status : Normal Configured Capacity: 8246979788800 (7.50 TB) DFS Used: 395427840 (377.11 MB) Non DFS Used: 0 (0 B) DFS Remaining: 8246584360960 (7.50 TB) DFS Used%: 0.00% DFS Remaining%: 100.00% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Sun Aug 16 11:00:00 CST 2020 Last Block Report: Sun Aug 16 10:23:18 CST 2020 [root@hadoop101.yinzhengjie.com ~]#
3>.添加名爲"yinzhengjiePool" 的緩存池
[root@hadoop101.yinzhengjie.com ~]# hdfs cacheadmin -listPools #默認狀況下是沒有緩存池的。 Found 0 results. [root@hadoop101.yinzhengjie.com ~]# [root@hadoop101.yinzhengjie.com ~]# hdfs cacheadmin -addPool yinzhengjiePool #此處咱們添加一個名爲"yinzhengjiePool"的緩存池 Successfully added cache pool yinzhengjiePool. [root@hadoop101.yinzhengjie.com ~]# [root@hadoop101.yinzhengjie.com ~]# hdfs cacheadmin -listPools #再次查看緩存池會發現咱們剛剛建立出來的緩存池。 Found 1 result. NAME OWNER GROUP MODE LIMIT MAXTTL DEFAULT_REPLICATION yinzhengjiePool root root rwxr-xr-x unlimited never 1 [root@hadoop101.yinzhengjie.com ~]#
4>.添加緩存指令
[root@hadoop101.yinzhengjie.com ~]# hdfs dfs -ls -h / Found 3 items --w------- 2 jason yinzhengjie 309.5 K 2020-08-16 11:37 /hosts drwx------ - root admingroup 0 2020-08-14 19:19 /user drwxr-xr-x - root admingroup 0 2020-08-14 23:22 /yinzhengjie [root@hadoop101.yinzhengjie.com ~]# [root@hadoop101.yinzhengjie.com ~]# hdfs cacheadmin -addDirective -path /hosts -pool yinzhengjiePool #將HDFS指定路徑緩存到咱們剛剛建立的緩存池內。 Added cache directive 1 [root@hadoop101.yinzhengjie.com ~]# [root@hadoop101.yinzhengjie.com ~]# hdfs cacheadmin -listPools Found 1 result. NAME OWNER GROUP MODE LIMIT MAXTTL DEFAULT_REPLICATION yinzhengjiePool root root rwxr-xr-x unlimited never 1 [root@hadoop101.yinzhengjie.com ~]# [root@hadoop101.yinzhengjie.com ~]# hdfs cacheadmin -listPools -stats yinzhengjiePool #查看"yinzhengjiePool"該緩存池的狀態。 Found 1 result. NAME OWNER GROUP MODE LIMIT MAXTTL DEFAULT_REPLICATION BYTES_NEEDED BYTES_CACHED BYTES_OVERLIMIT FILES_NEEDED FILES_CACHED yinzhengjiePool root root rwxr-xr-x unlimited never 1 505 0 0 1 0 [root@hadoop101.yinzhengjie.com ~]#
5>.經過"dfsadmin -report"命令以檢查報告是否顯示高速緩存
[root@hadoop101.yinzhengjie.com ~]# hdfs dfsadmin -report Configured Capacity: 24740939366400 (22.50 TB) Present Capacity: 24740939366400 (22.50 TB) DFS Remaining: 24739612456817 (22.50 TB) DFS Used: 1326909583 (1.24 GB) DFS Used%: 0.01% Under replicated blocks: 0 Blocks with corrupt replicas: 0 Missing blocks: 0 Missing blocks (with replication factor 1): 0 Pending deletion blocks: 0 ------------------------------------------------- Live datanodes (3): Name: 172.200.6.102:50010 (hadoop102.yinzhengjie.com) Hostname: hadoop102.yinzhengjie.com Rack: /rack001 Decommission Status : Normal Configured Capacity: 8246979788800 (7.50 TB) DFS Used: 485080556 (462.61 MB) Non DFS Used: 0 (0 B) DFS Remaining: 8246494708244 (7.50 TB) DFS Used%: 0.01% DFS Remaining%: 99.99% Configured Cache Capacity: 32000000 (30.52 MB) Cache Used: 0 (0 B) Cache Remaining: 32000000 (30.52 MB) Cache Used%: 0.00% Cache Remaining%: 100.00% Xceivers: 1 Last contact: Sun Aug 16 11:48:15 CST 2020 Last Block Report: Sun Aug 16 11:44:39 CST 2020 Name: 172.200.6.103:50010 (hadoop103.yinzhengjie.com) Hostname: hadoop103.yinzhengjie.com Rack: /rack002 Decommission Status : Normal Configured Capacity: 8246979788800 (7.50 TB) DFS Used: 395423744 (377.11 MB) Non DFS Used: 0 (0 B) DFS Remaining: 8246584365056 (7.50 TB) DFS Used%: 0.00% DFS Remaining%: 100.00% Configured Cache Capacity: 32000000 (30.52 MB) Cache Used: 0 (0 B) Cache Remaining: 32000000 (30.52 MB) Cache Used%: 0.00% Cache Remaining%: 100.00% Xceivers: 1 Last contact: Sun Aug 16 11:48:15 CST 2020 Last Block Report: Sun Aug 16 11:44:39 CST 2020 Name: 172.200.6.104:50010 (hadoop104.yinzhengjie.com) Hostname: hadoop104.yinzhengjie.com Rack: /rack002 Decommission Status : Normal Configured Capacity: 8246979788800 (7.50 TB) DFS Used: 446405283 (425.73 MB) Non DFS Used: 0 (0 B) DFS Remaining: 8246533383517 (7.50 TB) DFS Used%: 0.01% DFS Remaining%: 99.99% Configured Cache Capacity: 32000000 (30.52 MB) Cache Used: 319488 (312 KB) #不難發現,僅有一個Datanode節點緩存數據啦~ Cache Remaining: 31680512 (30.21 MB) Cache Used%: 1.00% Cache Remaining%: 99.00% Xceivers: 1 Last contact: Sun Aug 16 11:48:15 CST 2020 Last Block Report: Sun Aug 16 11:44:39 CST 2020 [root@hadoop101.yinzhengjie.com ~]#
三.Short-circuit本地讀(短路讀取)
若是讀取HDFS數據的客戶端與DataNode位於同一臺服務器上,則客戶端能夠直接拉取該文件,這比將數據傳輸到客戶端的DataNode再讀取要快。短路讀取指的是由客戶端直接從本地文件系統讀取數據,同時使用UNIX域套接字繞過DataNode,這爲客戶端和DataNode之間的通訊提供了通道。 短路讀取(Short-circuit)本地讀取不只可提高性能,並且也會增長安全性。Hadoop的一個關鍵原則就是數據侷限性。HDFS嘗試從客戶端(client)所在的同一節點讀取數據,從而將大部分讀取視爲本地讀取。 在默認狀況下不啓用短路讀取。要使用短路讀取,須要在客戶端及DataNode上配置如下內容。
[root@hadoop101.yinzhengjie.com ~]# vim ${HADOOP_HOME}/etc/hadoop/hdfs-site.xml ...... <property> <name>dfs.client.read.shortcircuit</name> <value>true</value> <description>此配置參數打開短路本地讀取。默認值爲"false"</description> </property> <property> <name>dfs.domain.socket.path</name> <value>/yinzhengjie/data/hadoop/fully-mode/hdfs/dn_socket</value> <description>這是UNIX域套接字的路徑,該套接字將用於DataNode和本地HDFS客戶端之間的通訊。若是此路徑中存在字符串「 _PORT」,它將被DataNode的TCP端口替換。</description> </property> ...... [root@hadoop101.yinzhengjie.com ~]# [root@hadoop101.yinzhengjie.com ~]# manage-hdfs.sh restart #修改上述配置後,須要重啓集羣 hadoop101.yinzhengjie.com | CHANGED | rc=0 >> stopping namenode hadoop105.yinzhengjie.com | CHANGED | rc=0 >> stopping secondarynamenode hadoop104.yinzhengjie.com | CHANGED | rc=0 >> stopping datanode hadoop102.yinzhengjie.com | CHANGED | rc=0 >> stopping datanode hadoop103.yinzhengjie.com | CHANGED | rc=0 >> stopping datanode Stoping HDFS: [ OK ] hadoop101.yinzhengjie.com | CHANGED | rc=0 >> starting namenode, logging to /yinzhengjie/softwares/hadoop-2.10.0-fully-mode/logs/hadoop-root-namenode-hadoop101.yinzhengjie.com.out hadoop105.yinzhengjie.com | CHANGED | rc=0 >> starting secondarynamenode, logging to /yinzhengjie/softwares/hadoop/logs/hadoop-root-secondarynamenode-hadoop105.yinzhengjie.com.out hadoop103.yinzhengjie.com | CHANGED | rc=0 >> starting datanode, logging to /yinzhengjie/softwares/hadoop/logs/hadoop-root-datanode-hadoop103.yinzhengjie.com.out hadoop102.yinzhengjie.com | CHANGED | rc=0 >> starting datanode, logging to /yinzhengjie/softwares/hadoop/logs/hadoop-root-datanode-hadoop102.yinzhengjie.com.out hadoop104.yinzhengjie.com | CHANGED | rc=0 >> starting datanode, logging to /yinzhengjie/softwares/hadoop/logs/hadoop-root-datanode-hadoop104.yinzhengjie.com.out Starting HDFS: [ OK ] [root@hadoop101.yinzhengjie.com ~]#