QFS檔案系統-學習記錄

lipeng08發表於2016-05-19

#總覽
Quantcast File System (QFS) 是高效能,且具有故障容錯能力的分散式檔案系統。它可以支援MapReduce處理,以及其他應用程式的大檔案的I/O操作。本文將會介紹QFS,它的相關配置等等。更詳細的介紹,請參見QFS官方wiki

如果你有什麼未解決的問題,可傳送郵件到
qfs-devel@googlegroups.com 或者搜尋論壇
QFS Developer Mailing List. 你也可以通過JIRA issue tracker來問問題,報告bugs以及關於QFS功能更新的請求.

更進一步檢視QFS內部如何工作的,請參見論文
QFS paper presented at VLDB.

#簡介
Hadoop和其他的批處理框架在具有順序讀順序寫(例如MB或者GB級別)的訪問模式的檔案系統下具有較高的效能。 Quantcast File System (QFS)正是基於這種需求出發開發的分散式檔案系統。 它在KFS的基礎上演化而來的。 在2011年,QFS開發團隊不再使用HDFS作為後端儲存,轉向使用QFS。 同時,他們將原始碼開源在https://github.com/quantcast/qfs

QFS架構
QFS包含3個模組:

  1. Metaserver: 中心後設資料伺服器,用來管理檔案系統目錄結構以及檔案到資料塊的對映關係
  2. Chunk Server: 分散式元件。 儲存資料塊以及管理對資料塊的I/O訪問。
  3. Client Library: 此庫提供檔案系統API來允許應用程式與QFS互動。 應用程式需要連線QFS客戶端庫以訪問QFS

QFS基於C++實現,使用TCP sockets, STL以及boost庫。 它已經被部署到執行centos5或6的x86-64架構的生產環境中。 客戶端庫也已經在CentOS 5 and 6, OSX 10.X, Cygwin, and Debian/Ubuntu進行了測試。

##QFS特性

  1. 增量擴容: Chunk server能在執行時候加入到系統中。它在與metaserver建立連線後,就成為系統的一部分。
  2. 均衡: 在資料放置過程彙總,metaserver盡力使資料均衡分佈到系統的所有節點。
  3. 再均衡: metaserver在檢測到系統節點的負載不均衡後會對系統資料進行再均衡。 例如有些節點利用率過低(低於20%),有些節點利用率過高(高於80%)
  4. 故障容錯: 資料塊支援副本以及Reed-solomn 6+3編碼
  5. 細粒度的副本,條紋以及恢復模式: 檔案級別的配置模式
  6. 再副本: 當檔案的資料塊副本低於預設值後,metaserver在後臺啟動自動複製操作。
  7. 資料完整性: 為了處理磁碟故障引起的資料塊故障,對資料塊生成校驗資訊。 當客戶端讀取資料塊,會啟動資料塊校驗。如果校驗不匹配,會執行再副本操作。
  8. 客戶端側的後設資料快取: QFS客戶端庫快取相關的metadata資料來避免重複的metaserver查詢以及路徑轉換。metadata快取超時30s
  9. 檔案寫: QFS客戶端庫使用write-back的cache。 當cahce滿了後,客戶端將資料flush到chunk server。 應用程式也可以主動呼叫sync()重新整理資料。
  10. 租約: QFS客戶端庫使用cache來提高效能。 使用租約支援cache一致性
  11. 版本: 資料塊具有版本,用來檢測舊的資料塊,例如考慮如下的場景:
    1. 有3個chunk server s1 s2和s3,儲存具有版本號為v的chunk c
    2. 假設s1故障,並且在s1故障期間,客戶端寫入chunk c
    3. 寫操作會在s2和s3中成功,並生成新的版本號v’
    4. 當s1重啟,它上報自己的chunks到metaserver
    5. metaserver收到s1上報的版本號v的chunk c, 它發現最新的版本號是v’,於是metaserver通知s1,它的chunk c是舊的
    6. s1刪除chunk c
  12. 客戶端側的轉移故障: 客戶端庫在讀取資料時候,發現相應的chunk server故障,會轉向其他的chunk server讀取,這對外部應用透明
  13. 語言支援: 客戶端庫支援c++,java和實驗性的python
  14. 工具: 命令列工具位於…/bin/tools/qfs目錄, 它與hadoop fs相似,但是它需要加入JVM虛擬機器,將stat命令的執行時間從hadoop的700ms降低到10ms。 它也支援額外的上傳和下載命令。
  15. linux下的FUSE支援: 通過FUSE掛載QFS, 支援類linux命令列工具操縱QFS
  16. Unix風格的許可權支援

###兩個問題:

  1. 租約解決cache一致性:
  2. FUSE支援:
    Linux用於支援使用者空間檔案系統的核心模組名叫FUSE,FUSE一詞有時特指Linux下的使用者空間檔案系統。
    將QFS掛載為FUSE,可以使用普通的linux命令訪問QFS檔案系統目錄。 簡單說來,就是將網路的檔案系統掛載到本地,如本地訪問一樣訪問遠端。

#編譯
1,在https://github.com/quantcast/qfs下載zip壓縮包原始碼,自動命名為qfs-master.zip
2,解壓縮原始碼,unzip qfs-master.zip
3,進入qfs-master目錄,開啟README.md
4,從連結地址https://github.com/quantcast/qfs/wiki/Developer-Documentation進行編譯
##具體編譯過程:
1,在原始碼最頂層目錄make命令
2,等待直到編譯成功
使用者應用程式與qfs client的lib連線,然後client lib連線metaserver或者chunk server進行檔案操作

編譯模式設定
1,預設debug模式編譯,可選用release模式
BUILD_TYPE=release make
生成的內容在build/release/bin目錄中
2,啟用verbose輸出
VERBOSE=true make
3,編譯test
make test
這會在本地建立metaserver和chunkserver,並進行一系列測試,這可能會耗費幾分鐘時間。
4,編寫測試程式

#include <gtest/gtest.h>
#include "tests/integtest.h"

class FooTest : public QFSTest {
public:
    virtual void SetUp() { ... }
    virtual void TearDown() { ... }
};

TEST_F(FooTest, TestBar) {
    ...
}

5,編寫c++客戶端
例子程式碼在 examples/cc/qfssample_main.cc file.
QFS客戶端介面在 src/cc/libclient/KfsClient.h.
客戶端連結的庫有 libqfs_client library 和其他的 libqfs_ dependencies
6,編寫java客戶端
java通過jni呼叫相應介面
例子程式碼在 examples/java/QfsSample.java.
java客戶端相關介面在 src/java/qfs-access/src/main/java/com/quantcast/qfs/access/KfsAccess.java.

java額外的jar包路徑: build/java/qfs-access/qfs-access-.jar in the CLASSPATH. 執行客戶端需要 build/release/lib should be in the LD_LIBRARY_PATH (or DYLD_LIBRARY_PATH, if it is Mac OS X). To build,

$ cd ~/code/qfs/examples/java
$ qfsjar=`echo ../../build/qfs-access/qfs-access*.jar`
$ javac -classpath "$qfsjar" QfsSample.java
To execute,

$ libdir="`cd ../../build/release/lib && pwd`"
$ export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${libdir}"
$ qfsjar=`echo ../../build/qfs-access/qfs-access*.jar`
$ java -Djava.library.path="$libdir" -classpath ".:$qfsjar" QfsSample 127.0.0.1 20000

編寫python(實驗階段)
使用命令 make python. 將會生成 build/build//qfs.so
python客戶端使用qfs.so, 例子程式碼 examples/python/qfssample.py

Set PYTHONPATH accordingly if you are using a qfs.so install path different from the default path, so that the python run-time can detect the qfs.so. Also, ensure that LD_LIBRARY_PATH has the path to the QFS libraries. For example,

$ export PYTHONPATH=/usr/lib/python2.7/dist-packages:$PYTHONPATH
$ export LD_LIBRARY_PATH=/usr/lib/python2.7/dist-packages/qfs:$LD_LIBRARY_PATH
$ python examples/python/qfssample.py

##測試編譯qfs
1,啟動簡單的server
./examples/sampleservers/sample_setup.py -a install
提示在build目錄找不到MetaServer,檢視python程式碼,發現其搜尋目錄為build/release/bin
2,進行release編譯
BUILD_TYPE=release make
3,再次啟動server

Meta server started, listening on localhost:20000
netstat -tlnp  |grep 20000 
tcp        0      0 0.0.0.0:20000               0.0.0.0:*                   LISTEN      2587/metaserver  

#部署說明
QFS著眼於在廉價裝置上部署,其支援兩種型別的容錯:塊副本和RS編碼。 本文件說明了簡單部署以及大規模部署。
注意:在檔案建立的時候,必須給定副本或者編碼型別,QFS不支援預設型別。

##元件
QFS支援三種元件

  • metaserver: 中樞控制系統,將檔案系統映象儲存在記憶體中。
  • chunk server: 負責chunk的儲存和存取操作。
  • clients: 獲取待讀資料後設資料資訊,並向chunk server請求資料塊。

這裡寫圖片描述

###MetaServer
部署metaserver的機器需要支援故障容錯的磁碟陣列以支援它的transaction logs和checkpoints。
這裡寫圖片描述
###Chunk server
儲存具體資料,I/O密集型,網路密集型。
這裡寫圖片描述

##簡單cluster
###使用塊副本
下面的例子演示了使用3個資料節點配置副本數為3的cluster.
注意: 這個配置不妨礙使用RS編碼,因為客戶可以針對每一個檔案設定不同的容錯能力
這裡寫圖片描述

####配置
MetaServer.prp

# port used by clients to connect to the metaserver
metaServer.clientPort = 20000

# port used by chunk servers to connect to the metaserver
metaServer.chunkServerPort = 30000

# chunk placement groups by IP address or first three octets
metaServer.rackPrefixes = 192.168.1.1 1   192.168.1.2 2 192.168.1.3 3

# create new file system if no transaction logs or checkpoints are found
metaServer.createEmptyFs = 1

# location to write transaction logs
metaServer.logDir = /home/qfsm/transaction_logs

# location to write checkpoints, this needs be pruned periodically
metaServer.cpDir = /home/qfsm/checkpoint

# unique cluster id
metaServer.clusterKey = my-fs-unique-identifier

ChunkServer.prp

# address of the metaserver, host names should not be used
chunkServer.metaServer.hostname 192.168.0.1

# metaserver port for chunk server to use
chunkServer.metaServer.port = 30000

# chunk server client listener port
chunkServer.clientPort = 22000

# locations to store chunk data, independent spindles should be
used
chunkServer.chunkDir = /mnt/data0 /mnt/data1

# unique cluster id
chunkServer.clusterKey = my-fs-unique-identifier

注意

  • 不支援基於DNS查詢的host names,請使用IPv4地址或者本機配置的hostname
  • metaserver checkpoint目錄需要定時清理,checkpoint檔案大概是檔案系統在記憶體中的大小
  • clusterKey引數在所有的chunk servers以及metaserver中保持一致。 這使得一個節點可以同時存在多個chunk servers,只要他們具有不同的clusterKye

###使用Reed-Solomon編碼
RS編碼比副本要求更少的空間來容忍故障。客戶端庫產生相應的校驗資訊以用來重構chunk,並將校驗資訊散步到多個server中,而不是像副本方式那樣寫入一個chunk的多個副本。這種空間的高效是以增加的恢復頻寬或者更長的chunk重構時間為代價的: 因為丟失chunk並沒有額外的副本使用,它必須利用編碼條紋下其他的資料塊來重構,帶來較大的時間和頻寬代銷。

注意: 糾刪碼的配置並不阻止chunk副本的使用,因為客戶端可以在檔案建立時候針對單個檔案設定不同的容錯能力。

Reed-Solomon <rs k,m+n>

描述
k 副本因子, 通常其為 1 且 n=3, 當大於 1 時 n == 0
m 條紋內資料塊數目, 資料範圍 1 到 64 且 n == 3, 當其為 255 時 n == 0
n 條紋內校驗塊數目, 當前只有 0 和 3 是合法的, 且 n == 0 時只有資料塊

當前只有<rs 1, 6+3>和3副本經過嚴格的測試。 QFS支援增加條紋內資料塊的數目以降低額外的儲存開銷。可是,不管資料條紋的數目是多少,其只支援校驗0或者3的校驗條紋數目。

Replication vs Reed-Solomon
<rs 1, 6+3>只使用額外的50%的儲存開銷就可達到3故障容錯能力;對比來說,副本配置(<rs 3, 6+0>)需要200%的冗餘儲存開銷才能容忍2個chunks的丟失。

編碼 檔案大小 空間使用 容錯能力
replication 3 <rs 3,6+0> 6 MB 18 MB up to 2 chunks
replication 4 <rs 4,6+0> 6 MB 24 MB up to 3 chunks
<rs 1,6+3> 6 MB 9 MB up to 3 chunks

有用的公式:

disk usage = file size x ((data stripes + recovery stripes) / data stripes) x replication)
effective capacity = raw capacity x (data stripes / ((data stripes + recovery stripes) x replication))

####佈局
它需要最少9個chunk servers才可達到理想的chunk放置。 這是因為<rs 1, 6+3>有9個塊(6個資料塊,3個校驗塊)。 如副本中配置的那樣,將條紋內的資料塊放入不同的節點組中,可達到3個節點的故障容錯能力。

對於<rs 1, N+3>的編碼,需要至少N+3個chunk servers以處理3個同時的chunk server故障。基於上述假設(chunk server的數目至少N+3),再均衡策略並不會嘗試將每個chunk server下的chunk數目保持一致。

例如如下場景:
起始只有一個chunk server。當客戶的寫入一個具有6個資料塊的大檔案且使用RS(6+3)進行編碼,這會在這個chunk server中儲存9個塊。然後又有5個chunk servers加入到系統中,再均衡放置策略會將第一個server中的5個chunks移動到這5個servers中,而在第一個server節點中留下4個chunk。 如果第一個節點掛掉,會發生資料丟失(6+3最多支援3容錯)。

這意味著,如果你係統中只有6個chunk servers且使用6+3的RS編碼,即使一個機器故障也可能導致資料丟失。

這裡寫圖片描述

#####MetaServer.prp

# port used by clients to connect to the metaserver
metaServer.clientPort 20000

# port used by chunk servers to connect to metaserver
metaServer.chunkServerPort = 30000

# chunk placement groups by IP address or first three octets
metaServer.rackPrefixes = 192.168.1.1 1   192.168.1.2 2   192.168.1.3 3   192.168.1.4 4   192.168.1.5 5   192.168.1.6 6   192.168.1.7 7   192.168.1.8 8    192.168.1.9 9

# create new file system if no transaction logs or checkpoints are found
metaServer.createEmptyFs = 1

# location to write transaction logs
metaServer.logDir = /home/qfsm/transaction_logs

# location to write checkpoints, this needs be pruned periodically
metaServer.cpDir = /home/qfsm/checkpoint

# unique cluster id
metaServer.clusterKey = my-fs-unique-identifier

#####ChunkServer.prp

# IP address of the metaserver, host names should not be used
chunkServer.metaServer.hostname 192.168.0.1

# metaserver port for chunk server to use
chunkServer.metaServer.port = 30000

# chunk server client listener port
chunkServer.clientPort = 22000

# locations to store chunk data, independent spindles should be used
chunkServer.chunkDir = /mnt/data0 /mnt/data1

# unique cluster id
chunkServer.clusterKey = my-fs-unique-identifier

注意

  • 不支援基於DNS型別的主機名字,需要使用IPV4地址
  • MetaServer的checkpoint目錄需要定期清理。每一個checkpoint檔案大約等於記憶體中的檔案系統映象。
  • clusterKey引數必須在整個系統的metaserver和所有的chunk server中保持一致。這允許一個機器節點有多個QFS檔案系統下的chunk servers,只要每個系統具有自己的metaserver和clusterKey.

##RS編碼高階配置
這裡我們討論一個大規模QFS的機架部署,每一個機架有22個chunk server節點。

這裡寫圖片描述

還有一個head node來放置metaserver

這裡是圖片

###佈局
機架是常見的故障域,任何時刻都可能發生網路或者電源故障。因此,機架成為最理想的chunk放置域。如前面討論的,<rs 1, 6+3> 需要9個機架: 一個機架儲存條紋內的一個塊.

這裡寫圖片描述

考慮採用RS編碼的話,此叢集有大約4324.32 TB 或者 4.22 PB的儲存空間。

這裡寫圖片描述

不像前面的RS編碼塊放置的例子,此叢集以機架而不是節點為域放置塊。這種配置可以容忍至多同時3個機架故障。然後,我們需要注意,磁碟經常會發生故障,因此總體來看,此係統可容忍1到2個機架的故障。

###配置
####MetaServer.prp

# port used by clients to connect to the metaserver
metaServer.clientPort 20000

# port used by chunk servers to connect to the metaserver
metaServer.chunkServerPort = 30000

# chunk placement groups by IP address or first three octets
metaServer.rackPrefixes = 192.168.1 1   192.168.2 2   192.168.3 3   192.168.4 4   192.168.5 5   192.168.6 6   192.168.7 7   192.168.8 8    192.168.9 9

# create new file system if no transaction logs or checkpoints are found
metaServer.createEmptyFs = 1

# location to write transaction logs
metaServer.logDir = /home/qfsm/transaction_logs

# location to write checkpoints, this needs be pruned periodically
metaServer.cpDir = /home/qfsm/checkpoint

# unique cluster id
metaServer.clusterKey = my-fs-unique-identifier

注意:上面的metaServer.rackPrefixes放置域是基於機架的,而不是基於節點的。192.168.1 1是第一個放置域,此域管理192.168.1.*的節點。

####ChunkServer.prp

# address of the metaserver, host names should not be used
chunkServer.metaServer.hostname 192.168.0.1

# metaserver port for chunk server to use
chunkServer.metaServer.port = 30000

# chunk server client listener port
chunkServer.clientPort = 22000

# locations to store chunk data, independent spindles should be used
chunkServer.chunkDir = /mnt/data0 /mnt/data1

# unique cluster id
chunkServer.clusterKey = my-fs-unique-identifier

##FUSE
你可直接使用qfs_fuse命令或者/etc/fstab來使用fuse。類似於將網路檔案系統即QFS掛載到本地。

  1. 直接使用
    • Mount:使用$ sudo ./qfs_fuse <metaserver>:20000 /mnt/qfs -o allow_other,ro
    • Unmount:使用$ sudo umount /mnt/qfs
  2. 編輯/etc/fstab,系統啟動自動mount
    • 建立到qfs_fuse的符號連結: $ ln -s <path-to-qfs_fuse> /sbin/mount.qfs
    • 新增以下行到/etc/fstab:
      <metaserver>:20000 /mnt/qfs qfs ro,allow_other 0 0

FUSE是開源的,需要遵循開源協議。

##優秀實踐

  • 使用一個可靠的服務管理工具來管理meta和chunk server,例如 daemontools. daemontools 還支援log服務管理.
  • 為你的檔案系統建立獨立的系統使用者名稱。這方便進行程式管理,以及防止多個檔案系統相互衝突.
  • 確保將chunk資料儲存在合理大小的磁碟捲上,越多的磁碟,越好.
  • 定期備份metaserver產生的checkpoint檔案系統映象。如果發生metaserver故障,它們可用來恢復檔案系統.
  • 確保定期清理metaserver產生的checkpoint映象。它位於目錄metaServer.cpDir.
  • 為你的metaserver構建雙路電源以及硬體RAID以支援故障容錯.
  • 不要將metaserver和chunk servers部署到同一個機器節點上.


#簡單cluster的配置實現
##前提條件
單機器,centos6.5系統,64位。
程式碼已經全部編譯OK,當前使用build/debug/bin目錄下的相關命令
##目標
在此單機器下配置1個metaserver,3個chunkserver,基於副本方式,能進行上傳,下載檔案等操作。
##MetaServer配置
MetaServer配置檔名叫MetaServer.prp,可對conf/MetaServer.prp檔案進行相應修改即可。

MetaServer配置檔案如下:

metaServer.clientPort = 20000
metaServer.chunkServerPort = 30000
metaServer.logDir = meta/transaction_logs
metaServer.cpDir = meta/checkpoint
metaServer.createEmptyFs = 1
metaServer.rootDirUser  = 542
metaServer.rootDirGroup = 543
metaServer.rootDirMode  = 0755
metaServer.defaultLoadUser     = 542
metaServer.defaultLoadGroup    = 543
metaServer.defaultLoadFileMode = 0644
metaServer.defaultLoadDirMode  = 0755
metaServer.recoveryInterval = 30
metaServer.clusterKey = my-fs-unique-identifier
metaServer.msgLogWriter.logLevel = DEBUG
chunkServer.msgLogWriter.logLevel = DEBUG

注意:需要首先建立meta/transaction_logs和meta/checkpoint目錄

  • 修改日誌級別為DEBUG
  • 注意rootDirUser,rootDirGroup的配置專案,具體可參見問題1. 542和543來源於當前user的userid和groupid,可從/etc/passwd得到。

##ChunkServer配置
ChunkServer配置檔名叫ChunkServer.prp,可對conf/ChunkServer.prp檔案進行相應修改即可。

ChunkServer配置檔案如下:

chunkServer.metaServer.hostname = localhost
chunkServer.metaServer.port     = 30000
chunkServer.clientPort = 22000
chunkServer.chunkDir = meta/chunks
chunkServer.clusterKey = my-fs-unique-identifier
chunkServer.stdout = /dev/null
chunkServer.stderr = /dev/null
chunkServer.ioBufferPool.partitionBufferCount = 131072
chunkServer.msgLogWriter.logLevel = INFO

注意:需要首先建立meta/chunks目錄

  • metaServer.port為metaServer埠
  • chunkServer.clientPort為供給客戶端使用的埠,如果在同一臺機器上配置需不一樣
  • chunkServer.chunkDir為資料塊的儲存目錄,如果在同一臺機器配置,需不一樣

###另外兩個ChunkServer的配置
複製ChunkServer.prp到ChunkServer1.prp, ChunkServer2.prp,修改chunkServer.clientPort和chunkServer.chunkDir

ChunkServer1.prp配置檔案如下:

chunkServer.metaServer.hostname = localhost
chunkServer.metaServer.port     = 30000
chunkServer.clientPort = 22001
chunkServer.chunkDir = meta/chunks1
chunkServer.clusterKey = my-fs-unique-identifier
chunkServer.stdout = /dev/null
chunkServer.stderr = /dev/null
chunkServer.ioBufferPool.partitionBufferCount = 131072
chunkServer.msgLogWriter.logLevel = INFO

注意: 埠號與目錄與ChunkServer.prp不一致

##執行
###啟動metaserver
啟動命令
首先cd到qfs的根目錄

build/debug/bin/metaserver conf/MetaServer.prp

執行成功後,此命令不會自動退出,會不斷列印如下資訊:

......
05-20-2016 20:26:33.989 INFO - (metaserver_main.cc:548) start servicing
05-20-2016 20:26:34.991 INFO - (NetDispatch.cc:667) ===request=counters: 1463747194991100 5999 
......
05-20-2016 20:26:34.991 INFO - (LayoutManager.cc:9391) Initiating a replication check of all chunks

###啟動chunkserver
啟動命令
首先cd到qfs的根目錄,然後分別啟動3個控制終端,啟動3個ChunkServer

build/debug/bin/chunkserver conf/ChunkServer.prp
build/debug/bin/chunkserver conf/ChunkServer1.prp
build/debug/bin/chunkserver conf/ChunkServer2.prp

##相關命令測試
###qfsfsck測試
qfsfsck命令位於build/debug/bin/qfsfsck
使用命令: qfsfsck -m localhost -p 20000
注意:20000埠在MetaServer.prp中metaServer.clientPort配置

輸出如下:

Lost files total: 0
Directories: 2
Directories reachable: 2 100%
Directory reachable max depth: 1
Files: 0
......

###qfsshell測試
在qfs主目錄下建立bin目錄,將位於build/debug/bin/tools目錄下的命令全都copy到此bin目錄,便於測試執行。

[xxx@air qfs-master]$ bin/qfsshell -s localhost -p 20000
QfsShell> 
QfsShell> help
append
cd
......
rm
rmdir
stat
QfsShell> ls
dumpster

另外一種方式,不使用互動模式執行命令
[xxx@air qfs-master]$ bin/qfsshell -s localhost -p 20000 -q ls
dumpster

###上傳檔案
上傳檔案命令如下:

build/debug/bin/tools/cptoqfs -s localhost -p 20000 -d CMakeLists.txt -k f1

此命令將當前目錄下的CMakeLists.txt上傳到伺服器並儲存為名字f1.

使用qfsshell的ls命令檢視是否上傳成功:

[lipeng@air qfs-master]$ bin/qfsshell -s localhost -p 20000 -q ls
dumpster
f1

可以看到f1檔案已經上傳成功。

使用qfscat命令檢視檔案內容:

build/debug/bin/tools/qfscat  -s localhost -p 20000 f1    

###下載檔案
下載檔案命令如下:

build/debug/bin/tools/cpfromqfs -s localhost -p 20000 -k f1 -d tmp.txt

此命令將伺服器上的存在的檔名為f1的檔案下載到本地目錄,並命名為tmp.txt

確定是否和上傳的檔案CMakeLists.txt內容一致,使用文字比較命令:

[xxx@air qfs-master]$ diff -s tmp.txt CMakeLists.txt 
Files tmp.txt and CMakeLists.txt are identical(這說明兩個檔案完全相同)

###檢視f1檔案詳情

[lipeng@air qfs-master]$ bin/qfsshell -s localhost -p 20000 -q stat f1
File:             f1
......
Replication:      3
Chunks:           1
......

檔案f1的副本因子為3,資料塊數目為1

###命令列表

[xxx@air qfs-master]$ ls build/debug/bin
chunkscrubber  chunkserver  devtools  emulator  examples  filelister  logcompactor  metaserver  qfsfsck  qfs_fuse  tests  tools

[xxx@air qfs-master]$ ls build/debug/bin/tools
cpfromqfs  cptoqfs  qfs  qfsadmin  qfscat  qfsdataverify  qfsfileenum  qfshibernate  qfsping  qfsput  qfsshell  qfsstats  qfstoggleworm

上面是常用的命令所在的目錄以及命令名字。我採用的方式是猜測根據命令名字猜測命令的行為,然後使用命令自帶的幫助,檢視如何使用此命令。

####如何使用命令
根據命令的名字猜測命令的功能,例如qfsadmin命令。
根據qfsadmin猜測命令是用來進行qfs管理的。

[xxx@air qfs-master]$ build/debug/bin/tools/qfsadmin -s localhost -p 20000
Usage: build/debug/bin/tools/qfsadmin
 -m|-s <meta server host name>
 -p <port>
 [-f <config file name>]
 [-a -- show response headers]
 [-v -- verbose]
 [-F <request field name>=<request field value>]
 --  <cmd> <cmd> ...
......

根據命令的輸出結果,得出qfsadmin支援的命令引數,例如需要檢視chunkserver的狀態,可使用如下命令:

[xxx@air qfs-master]$ build/debug/bin/tools/qfsadmin -s localhost -p 20000 upservers
127.0.0.1 22000
127.0.0.1 22001
127.0.0.1 22002


##閱讀程式碼

  1. 將前面的下載的程式碼解壓縮到一個目錄中
  2. 開啟eclipse(我安裝了CDT外掛,用於原始碼編譯)
  3. eclipse中建立新工程,選擇
    New->project->Makefile project with Existing code -> 輸入你的原始碼的位置以及工程名字
  4. 選擇完成按鈕,即可建立qfs工程
  5. 左邊Package Explorer選擇qfs工程,使用快捷鍵Ctrl+Shift+R命令即可快速定位檔案
  6. 使用快捷的Ctrl+H即可進行全域性搜尋關鍵字
  7. 選中函式後,使用選單右鍵->Open Call Hierachy即可檢視所有呼叫者堆疊


##問題

  1. 建立目錄失敗,許可權不夠

    [xxx@air qfs-master]$ bin/qfsshell -s localhost -p 20000 -q mkdir d1
    d1: mkdirs failure: Permission denied 13

    解答:經過一天的跟蹤程式碼,知曉了確切的執行流程,修改MetaServer.prp配置檔案,配置相應的使用者即可,我的配置如下:

     # Root directory permissions -- used only when the new file system created.
     metaServer.rootDirUser  = 542
     metaServer.rootDirGroup = 543
     metaServer.rootDirMode  = 0755
     
     # Defaults for checkpoint and transaction log without permissions conversion on
     # startup.
     metaServer.defaultLoadUser     = 542
     metaServer.defaultLoadGroup    = 543
     metaServer.defaultLoadFileMode = 0644
     metaServer.defaultLoadDirMode  = 0755
     
     #542和543是當前使用qfsshell命令的賬戶名的id,可在/etc/passwd檔案中使用使用者名稱找到。
    
  2. 建立檔案命令執行失敗,伺服器顯示meta server in recovery mode

     build/debug/bin/tools/cptoqfs -s localhost -p 20000 -d README.md -k d1  
    

    伺服器日誌提示meta server in recovery mode同時使用qfsshell也沒有發現檔案的建立

    解答:全域性搜尋recovery mode關鍵字(檢視閱讀程式碼),最終在LayoutManager::IsAllocationAllowed(MetaAllocate* req)找到了recovery mode。

     inline bool
     LayoutManager::InRecoveryPeriod() const
     {
         return (TimeNow() < mRecoveryStartTime + mRecoveryIntervalSec);
     }
     
     inline bool
     LayoutManager::InRecovery() const
     {
         return (
             mChunkServers.size() < mMinChunkserversToExitRecovery ||
             InRecoveryPeriod()
         );
     }
    

    猜測應該是機器數目不足,當前我只在一臺centos機器上部署了qfs,列印日誌檢視mChunkServers.size() == 0。

    再次檢視配置檔案conf/MetaServer.prp關於chunkserver的配置,裡面具有配置專案chunkServer.clientPort = 22000,然而通過netstat -tlnp檢視卻沒有發現此埠,這表明chunkserver根本就沒有啟動。通過手動啟動ChunkServer,命令chunkserver conf/ChunkServer.prp即可。具體配置過程請參見簡單cluster的配置實現

  3. 如何一次將所有的Server全部啟動?

    過去我一直在HDFS上修改原始碼,HDFS有start-all.sh可以一次啟動所有NameNode,DataNode節點,而不需要一個個的啟動。故而我猜測QFS應該也支援這樣的命令,暫時還沒有找到。

  4. 如何設定機器以server啟動,不需要進行互動式shell

    先搞定問題3,再考慮這個。只需要檢視日誌即可,不需要互動。

##Checkpoint and Transaction Log Pruning
#未完待續

##宣告
本人lpstudy,轉載請註明出處:http://blog.csdn.net/lpstudy/article/details/51457250

相關文章