天天看點

改良的SCR讓hadoop擁有更好的性能及安全性

Apache Hadoop的核心原則就是轉移計算比轉移資料代價更低。這就是我們盡可能地将計算轉移到存儲資料之處的原因。是以,HDFS通常使用大量的本地讀取,也就是說,讀取資料的用戶端和要讀取的資料在同一節點。

改良的SCR讓hadoop擁有更好的性能及安全性
起初,HDFS本地讀取和遠端讀取使用同一種方式:用戶端端通過TCP套接字連接配接

DataNode

,并通過

DataTransferProtocol

傳輸資料。這種方式很簡單,但是有一些不好的地方。例如,

DataNode

需要為每個讀取資料塊的用戶端維持一個線程和TCP套接字。核心中TCP協定是有開銷的,

DataTransferProtocol

本身也有開銷。是以這裡有值得優化的地方。

本文将介紹HDFS的一項新優化:安全短路本地讀取(secure short-circuit local reads),該實作的好處,以及它是如何為你的應用提速的。

HDFS-2246 和 Short-Circuit LocalReads

HDFS-2246

中,Andrew Purtell、Suresh Srinivas、Jitendra Nath Pandey和Benoy Antony等人添加了一項“短路本地讀取”優化。

其核心思想如下:因為用戶端和資料在同一個節點,是以沒必要再牽涉

DataNode

,用戶端自身直接從本地磁盤讀取 資料。這個性能優化被加入了CDH。CHD是Cloudera的Hadoop及相關項目的分發。這個優化是在CDH3u3中被加入的。

改良的SCR讓hadoop擁有更好的性能及安全性

HDFS-2246實作的短路本地讀取是一個很好的開始,但也帶來了許多配置上的煩惱。系統管理者必須改變DataNode資料目錄權限,以便允許用戶端打開相關檔案。還需要定義一個白名單,列出允許的使用者。通常,這些使用者被放在一個特殊的UNIX使用者組裡。

不幸的是,這類權限改變帶來了安全漏洞。有權限的使用者就可以直接浏覽所有資料了,不僅是他們需要的資料。這有點像把使用者提升成超級使用者!對包括HBase使用者在内的一些使用者而言,這是可以接受的。然而,一般而言,這會帶來很多問題。是以,盡管有些專注的管理者啟用了短路本地讀取,然而這并不是一個常見的選擇。

HDFS-347:讓短路本地讀取安全

HDFS-2246的主要問題就是它将DataNode的所有資料路徑直接開放給了用戶端。其實,隻需要開放用戶端關心的幾個資料檔案。

好在UNIX提供了這樣的機制,檔案描述符。

HDFS-347

使用該機制實作了安全的本地短路讀取。用戶端向DataNode請求資料時,DataNode打開塊檔案和中繼資料檔案,将它們直接傳給用戶端,而不是将路徑傳給用戶端。因為檔案描述符是隻讀的,用戶端不能修改接收到的檔案。同時由于用戶端自身無法通路塊所在的目錄,它也就不能通路其他不該通路的資料。

Windows 有類似的在程序間傳遞檔案描述符的機制。雖然Cloudera目前還沒有在Hadoop内添加該特性的支援,indows使用者可以将

dfs.cient.use.legacy.blockreader.local

設定為true,以便使用legacy block reader。

改良的SCR讓hadoop擁有更好的性能及安全性

緩存檔案描述符

HDFS用戶端經常多次讀取相同的塊檔案(尤其是HBase)。為了加快這種場景下的本地讀取,HDFS-2246實作的短路本地讀取中包含了一個塊路徑的緩存。該緩存允許用戶端重新打開最近讀取的塊檔案,而不需要再去詢問DataNode該塊檔案的路徑資訊。

新的短路實作包含了一個

FileInputStreamCache

,用于取代路徑緩存。緩存檔案描述符。這比緩存路徑要好,因為用戶端不用重新打開檔案才能重新讀取塊。我們發現這一實作提高了性能。

緩存的大小可以通過

dfs.client.read.shortcircuit.stream.cache.size

調整,緩存逾時時間通過

dfs.client.read.shortcircuit.streams.cache.expiry.ms

設定。設定緩存大小為0即可關閉緩存。大多數情況下,預設配置就可以了。如果你所處的情景是特殊的大規模工作集,檔案描述符限制也很高,那麼你可以試着提高參數值。

HDFS-347配置

HDFS-347引入的短路本地讀取,使任何HDFS使用者都可以使用短路本地讀取,而不是局限于配置過的少量使用者。也不需要修改Unix使用者組來設定誰可以通路DataNodeN路徑。然而,由于Java标準庫并不包含支援檔案描述符傳遞的庫,是以該特性需要使用JNI組建。你需要安裝

libhadoop.so

庫才能使用。

HDFS-347也要求設定一NUX域套接字路徑,可通過

dfs.domain.socket.path

設定。該路徑必須是安全的,以便阻止無特權的程序進行中間人攻擊。套接字路徑的每個組成目錄的都必須是root或啟動DataNode的使用者所有,人人可寫或者組成員可寫的路徑無法使用。

如果你安裝cloudera包,rpm或者deb,它會為你建立一個安全的UNIX域套接字路徑。同時會将

libhadoop.so

安裝到正确路徑下。

可以參考

上遊的文檔

擷取配置短路本地讀取的資訊。

性能

那麼,新的實作有多快?我使用了一個名為

hio_bench

的程式擷取到一些性能統計資料。

hio_bench

的代碼可由此取得:

https://github.com/cmccabe/hiotest

測試運作在8核 intelXeon 2.13 CPU 、12塊磁盤的伺服器上。我使用CDH4.3.1,底層使用ext4檔案系統。 下圖每個值是運作三次的平均值。有誤差線。

改良的SCR讓hadoop擁有更好的性能及安全性
改良的SCR讓hadoop擁有更好的性能及安全性

在所有測試中,HDFS-347實作是最快的,這大概要歸功于

FileInputStreamCache

.相反HDFS-2246實作會重複打開ext4 塊檔案多次,打開檔案可是一個代價很高的操作。

在随機讀取的場景下,相對順序讀取,短路實作有更明顯的優勢。部分原因是短路讀取還沒有實作預讀。可以參考

HDFS-4697的讨論

結論

短路本地讀取是一個很好的例子,展示了Hadoop将計算帶向資料的模型如何使優化成為可能。這個例子同時也展示了,在處理了規模不斷增長的挑戰之後,Cloudera正挑戰提高叢集中的每個節點的性能。

如果你正使用CDH4.2 或以上版本,試下這個新實作吧!