HDFS集中式的缓存管理原理与代码剖析
Hadoop 2.3.0已经发布了,其中最大的亮点就是集中式的缓存管理(HDFS centralized cache management)。这个功能对于提升Hadoop系统和上层应用的执行效率与实时性有很大帮助,本文从原理、架构和代码剖析三个角度来探讨这一功能。 主要解决了哪些问题 1.用户可
Hadoop 2.3.0已经发布了,其中最大的亮点就是集中式的缓存管理(HDFS centralized cache management)。这个功能对于提升Hadoop系统和上层应用的执行效率与实时性有很大帮助,本文从原理、架构和代码剖析三个角度来探讨这一功能。
主要解决了哪些问题
1.用户可以根据自己的逻辑指定一些经常被使用的数据或者高优先级任务对应的数据常驻内存而不被淘汰到磁盘。例如在Hive或Impala构建的数据仓库应用中fact表会频繁地与其他表做JOIN,显然应该让fact常驻内存,这样DataNode在内存使用紧张的时候也不会把这些数据淘汰出去,同时也实现了对于?mixed workloads的SLA。
2.centralized cache是由NameNode统一管理的,那么HDFS client(例如MapReduce、Impala)就可以根据block被cache的分布情况去调度任务,做到memory-locality。
3.HDFS原来单纯靠DataNode的OS buffer cache,这样不但没有把block被cache的分布情况对外暴露给上层应用优化任务调度,也有可能会造成cache浪费。例如一个block的三个replica分别存储在三个DataNote 上,有可能这个block同时被这三台DataNode的OS buffer cache,那么从HDFS的全局看就有同一个block在cache中存了三份,造成了资源浪费。?
4.加快HDFS client读速度。过去NameNode处理读请求时只根据拓扑远近决定去哪个DataNode读,现在还要加入speed的因素。当HDFS client和要读取的block被cache在同一台DataNode的时候,可以通过zero-copy read直接从内存读,略过磁盘I/O、checksum校验等环节。
5.即使数据被cache的DataNode节点宕机,block移动,集群重启,cache都不会受到影响。因为cache被NameNode统一管理并被被持久化到FSImage和EditLog,如果cache的某个block的DataNode宕机,NameNode会调度其他存储了这个replica的DataNode,把它cache到内存。
基本概念
cache directive: 表示要被cache到内存的文件或者目录。
cache pool: 用于管理一系列的cache directive,类似于命名空间。同时使用UNIX风格的文件读、写、执行权限管理机制。命令例子:
hdfs cacheadmin -addDirective -path /user/hive/warehouse/fact.db/city -pool financial -replication 1?
以上代码表示把HDFS上的文件city(其实是hive上的一个fact表)放到HDFS centralized cache的financial这个cache pool下,而且这个文件只需要被缓存一份。
系统架构与原理
用户可以通过hdfs cacheadmin命令行或者HDFS API显式指定把HDFS上的某个文件或者目录放到HDFS?centralized?cache中。这个centralized?cache由分布在每个DataNode节点的off-heap内存组成,同时被NameNode统一管理。每个DataNode节点使用mmap/mlock把存储在磁盘文件中的HDFS block映射并锁定到off-heap内存中。
DFSClient读取文件时向NameNode发送getBlockLocations RPC请求。NameNode会返回一个LocatedBlock列表给DFSClient,这个LocatedBlock对象里有这个block的replica所在的DataNode和cache了这个block的DataNode。可以理解为把被cache到内存中的replica当做三副本外的一个高速的replica。
注:centralized cache和distributed cache的区别:
distributed cache将文件分发到各个DataNode结点本地磁盘保存,并且用完后并不会被立即清理的,而是由专门的一个线程根据文件大小限制和文件数目上限周期性进行清理。本质上distributed cache只做到了disk locality,而centralized cache做到了memory locality。
实现逻辑与代码剖析
HDFS centralized cache涉及到多个操作,其处理逻辑非常类似。为了简化问题,以addDirective这个操作为例说明。
1.NameNode处理逻辑
NameNode内部主要的组件如图所示。FSNamesystem里有个CacheManager是centralized cache在NameNode端的核心组件。我们都知道BlockManager负责管理分布在各个DataNode上的block replica,而CacheManager则是负责管理分布在各个DataNode上的block cache。
DFSClient给NameNode发送名为addCacheDirective的RPC, 在ClientNamenodeProtocol.proto这个文件中定义相应的接口。
NameNode接收到这个RPC之后处理,首先把这个需要被缓存的Path包装成CacheDirective加入CacheManager所管理的directivesByPath中。这时对应的File/Directory并没有被cache到内存。
一旦CacheManager那边添加了新的CacheDirective,触发CacheReplicationMonitor.rescan()来扫描并把需要通知DataNode做cache的block加入到CacheReplicationMonitor. cachedBlocks映射中。这个rescan操作在NameNode启动时也会触发,同时在NameNode运行期间以固定的时间间隔触发。
Rescan()函数主要逻辑如下:
rescanCacheDirectives()->rescanFile():依次遍历每个等待被cache的directive(存储在CacheManager. directivesByPath里),把每个等待被cache的directive包含的block都加入到CacheReplicationMonitor.cachedBlocks集合里面。
rescanCachedBlockMap():调用CacheReplicationMonitor.addNewPendingCached()为每个等待被cache的block选择一个合适的DataNode去cache(一般是选择这个block的三个replica所在的DataNode其中的剩余可用内存最多的一个),加入对应的DatanodeDescriptor的pendingCached列表。
2.NameNode与DataNode的RPC逻辑
DataNode定期向NameNode发送heartbeat RPC用于表明它还活着,同时DataNode还会向NameNode定期发送block report(默认6小时)和cache block(默认10秒)用于同步block和cache的状态。
NameNode会在每次处理某一DataNode的heartbeat RPC时顺便检查该DataNode的pendingCached列表是否为空,不为空的话发送DatanodeProtocol.DNA_CACHE命令给具体的DataNode去cache对应的block replica。
3.DataNode处理逻辑
DataNode内部主要的组件如图所示。DataNode启动的时候只是检查了一下dfs.datanode.max.locked.memory是否超过了OS的限制,并没有把留给Cache使用的内存空间锁定。
在DataNode节点上每个BlockPool对应有一个BPServiceActor线程向NameNode发送heartbeat、接收response并处理。如果接收到来自NameNode的RPC里面的命令是DatanodeProtocol.DNA_CACHE,那么调用FsDatasetImpl.cacheBlock()把对应的block cache到内存。
这个函数先是通过RPC传过来的blockId找到其对应的FsVolumeImpl (因为执行cache block操作的线程cacheExecutor是绑定在对应的FsVolumeImpl里的);然后调用FsDatasetCache.cacheBlock()把这个block封装成MappableBlock加入到mappableBlockMap里统一管理起来,然后向对应的FsVolumeImpl.cacheExecutor线程池提交一个CachingTask异步任务(cache的过程是异步执行的)。
FsDatasetCache有个成员mappableBlockMap(HashMap)管理着这台DataNode的所有的MappableBlock及其状态(caching/cached/uncaching)。目前DataNode中”哪些block被cache到内存里了”也是只保存了soft state(和NameNode的block map一样),是DataNode向NameNode 发送heartbeat之后从NameNode那问回来的,没有持久化到DataNode本地硬盘。
CachingTask的逻辑: 调用MappableBlock.load()方法把对应的block从DataNode本地磁盘通过mmap映射到内存中,然后通过mlock锁定这块内存空间,并对这个映射到内存的block做checksum检验其完整性。这样对于memory-locality的DFSClient就可以通过zero-copy直接读内存中的block而不需要校验了。
4.DFSClient读逻辑:
HDFS的读主要有三种: 网络I/O读 -> short circuit read -> zero-copy read。网络I/O读就是传统的HDFS读,通过DFSClient和Block所在的DataNode建立网络连接传输数据。?
当DFSClient和它要读取的block在同一台DataNode时,DFSClient可以跨过网络I/O直接从本地磁盘读取数据,这种读取数据的方式叫short circuit read。目前HDFS实现的short circuit read是通过共享内存获取要读的block在DataNode磁盘上文件的file descriptor(因为这样比传递文件目录更安全),然后直接用对应的file descriptor建立起本地磁盘输入流,所以目前的short circuit read也是一种zero-copy read。
增加了Centralized cache的HDFS的读接口并没有改变。DFSClient通过RPC获取LocatedBlock时里面多了个成员表示哪个DataNode把这个block cache到内存里面了。如果DFSClient和该block被cache的DataNode在一起,就可以通过zero-copy read大大提升读效率。而且即使在读取的过程中该block被uncache了,那么这个读就被退化成了本地磁盘读,一样能够获取数据。?
对上层应用的影响
对于HDFS上的某个目录已经被addDirective缓存起来之后,如果这个目录里新加入了文件,那么新加入的文件也会被自动缓存。这一点对于Hive/Impala式的应用非常有用。
HBase in-memory table:可以直接把某个HBase表的HFile放到centralized cache中,这会显著提高HBase的读性能,降低读请求延迟。
和Spark RDD的区别:多个RDD的之间的读写操作可能完全在内存中完成,出错就重算。HDFS centralized cache中被cache的block一定是先写到磁盘上的,然后才能显式被cache到内存。也就是说只能cache读,不能cache写。
目前的centralized cache不是DFSClient读了谁就会把谁cache,而是需要DFSClient显式指定要cache谁,cache多长时间,淘汰谁。目前也没有类似LRU的置换策略,如果内存不够用的时候需要client显式去淘汰对应的directive到磁盘。
现在还没有跟YARN整合,需要用户自己调整好留给DataNode用于cache的内存和NodeManager的内存使用。
参考文献
http://hadoop.apache.org/docs/r2.3.0/hadoop-project-dist/hadoop-hdfs/CentralizedCacheManagement.html
https://issues.apache.org/jira/browse/HDFS-4949
原文地址:HDFS集中式的缓存管理原理与代码剖析, 感谢原作者分享。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

nohup的作用及原理解析在Unix和類Unix作業系統中,nohup是一個常用的命令,用於在後台運行命令,即便用戶退出當前會話或關閉終端窗口,命令仍然能夠繼續執行。在本文中,我們將詳細解析nohup指令的作用和原理。一、nohup的作用後台運行命令:透過nohup命令,我們可以讓需要長時間運行的命令在後台持續執行,而不受用戶退出終端會話的影響。這在需要運行

DNS(DomainNameSystem)是網際網路中用來將網域名稱轉換為對應IP位址的系統。在Linux系統中,DNS快取是一種將網域名稱和IP位址的映射關係儲存在本地的機制,可提高網域解析速度,減輕DNS伺服器的負擔。 DNS快取允許系統在之後存取相同網域名稱時快速檢索IP位址,而不必每次都向DNS伺服器發出查詢請求,從而提高網路效能和效率。本文不念將和大家一起探討如何在Linux上查看和刷新DNS緩存,以及相關的詳細內容和範例程式碼。 DNS快取的重要性在Linux系統中,DNS快取扮演關鍵的角色。它的存在

身為一名程式設計師,對於能夠簡化程式設計體驗的工具,我感到非常興奮。借助人工智慧工具的幫助,我們可以產生演示程式碼,並根據需求進行必要的修改。在VisualStudioCode中新引入的Copilot工具讓我們能夠創建具有自然語言聊天互動的AI生成程式碼。透過解釋功能,我們可以更好地理解現有程式碼的含義。如何使用Copilot產生程式碼?要開始,我們首先需要取得最新的PowerPlatformTools擴充。要實現這一點,你需要進入擴充頁面,搜尋“PowerPlatformTool”,然後點擊Install按鈕

在Linux作業系統中處理檔案需要使用各種命令和技術,使開發人員能夠有效率地建立和執行檔案、程式碼、程式、腳本和其他東西。在Linux環境中,擴展名為”.a”的檔案作為靜態庫具有重要的重要性。這些程式庫在軟體開發中發揮重要作用,允許開發人員有效地管理和共享多個程式的公共功能。對於Linux環境中的有效軟體開發,了解如何建立和運行「.a」檔案至關重要。本文將介紹如何全面安裝和設定Linux「.a」文件,讓我們一起探索Linux「.a」文件的定義、用途、結構,以及建立和執行它的方法。什麼是L

在PHP開發中,快取機制透過將經常存取的資料暫時儲存在記憶體或磁碟中來提升效能,從而減少資料庫存取次數。快取類型主要包括記憶體、檔案和資料庫快取。 PHP中可以使用內建函數或第三方函式庫實作緩存,如cache_get()和Memcache。常見的實戰應用程式包括快取資料庫查詢結果以最佳化查詢效能,以及快取頁面輸出以加快渲染速度。快取機制有效改善網站回應速度,提升使用者體驗並降低伺服器負載。

自2023年3月14日開始,ChatGLM-6B以來,GLM系列模型受到了廣泛的關注與認可。特別是在ChatGLM3-6B開源之後,開發者對智譜AI推出的第四代模型充滿了期待。而這項期待,隨著GLM-4-9B的發布,終於得到了充分的滿足。 GLM-4-9B的誕生為了賦予小模型(10B及以下)更加強大的能力,GLM技術團隊經過近半年的探索,推出了這款全新的第四代GLM系列開源模型:GLM-4-9B。這一模型在確保精度的同時,大幅度壓縮了模型大小,具有更快的推理速度和更高的效率。 GLM技術團隊的探索沒

CPU(中央處理器)、記憶體(隨機存取記憶體)以及快取之間存在著緊密的相互作用,它們合力構成了電腦系統的關鍵組成部分。它們之間的協調配合,確保了電腦的正常運作和高效性能。 CPU作為電腦的大腦,負責執行各種指令和資料處理;記憶體則用於臨時儲存資料和程序,提供了快速的讀寫存取速度;而快取則起到了緩衝作用,加快了資料的存取速度,提高了電腦的CPU是電腦的核心元件,負責執行各種指令、算術運算和邏輯操作。它被稱為電腦的"大腦",承擔著處理資料和執行任務的重要角色。記憶體是電腦中重要的儲存設備,

大模型顛覆一切,終於還是顛覆了本小編頭上。還是一句話就被打造出來的Agent。像這樣,丟給Ta一篇文章,不到1秒,標題建議就新鮮出爐了。這效率,比起本人類,只能說是一個快如閃電一個慢如樹懶吧…更難頂的是,創造這個Agent,真的就是幾分鐘的事。 Prompt是醬嬸的:而且,如果你也想體驗這種顛覆一切的feel,現在,基於這個百度剛剛上新的文心智能體平台,人人都能免費打造屬於自己的智能助手。可以利用搜尋引擎、智慧硬體平台、語音辨識、地圖、汽車等百度行動生態管道,讓更多人運用上你的創意!李彥宏本人
