QFS文件系统-学习记录

#总览
Quantcast File System (QFS) 是高性能,且具有故障容错能力的分布式文件系统。它可以支持MapReduce处理,以及其他应用程序的大文件的I/O操作。本文将会介绍QFS,它的相关配置等等。更详细的介绍,请参见QFS官方wiki

如果你有什么未解决的问题,可发送邮件到
[email protected] 或者搜索论坛
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文件系统-学习记录_第1张图片
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 
#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请求数据块。

QFS文件系统-学习记录_第2张图片

###MetaServer
部署metaserver的机器需要支持故障容错的磁盘阵列以支持它的transaction logs和checkpoints。
QFS文件系统-学习记录_第3张图片
###Chunk server
存储具体数据,I/O密集型,网络密集型。
QFS文件系统-学习记录_第4张图片

##简单cluster
###使用块副本
下面的例子演示了使用3个数据节点配置副本数为3的cluster.
注意: 这个配置不妨碍使用RS编码,因为客户可以针对每一个文件设置不同的容错能力
QFS文件系统-学习记录_第5张图片

####配置
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

描述
k 副本因子, 通常其为 1 且 n=3, 当大于 1 时 n == 0
m 条纹内数据块数目, 数据范围 1 到 64 且 n == 3, 当其为 255 时 n == 0
n 条纹内校验块数目, 当前只有 0 和 3 是合法的, 且 n == 0 时只有数据块

当前只有和3副本经过严格的测试。 QFS支持增加条纹内数据块的数目以降低额外的存储开销。可是,不管数据条纹的数目是多少,其只支持校验0或者3的校验条纹数目。

Replication vs Reed-Solomon
只使用额外的50%的存储开销就可达到3故障容错能力;对比来说,副本配置()需要200%的冗余存储开销才能容忍2个chunks的丢失。

编码 文件大小 空间使用 容错能力
replication 3 6 MB 18 MB up to 2 chunks
replication 4 6 MB 24 MB up to 3 chunks
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放置。 这是因为有9个块(6个数据块,3个校验块)。 如副本中配置的那样,将条纹内的数据块放入不同的节点组中,可达到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编码,即使一个机器故障也可能导致数据丢失。

QFS文件系统-学习记录_第6张图片

#####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节点。

QFS文件系统-学习记录_第7张图片

还有一个head node来放置metaserver

QFS文件系统-学习记录_第8张图片

###布局
机架是常见的故障域,任何时刻都可能发生网络或者电源故障。因此,机架成为最理想的chunk放置域。如前面讨论的, 需要9个机架: 一个机架存储条纹内的一个块.

QFS文件系统-学习记录_第9张图片

考虑采用RS编码的话,此集群有大约4324.32 TB 或者 4.22 PB的存储空间。

QFS文件系统-学习记录_第10张图片

不像前面的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 :20000 /mnt/qfs -o allow_other,ro
    • Unmount:使用$ sudo umount /mnt/qfs
  2. 编辑/etc/fstab,系统启动自动mount
    • 创建到qfs_fuse的符号链接: $ ln -s /sbin/mount.qfs
    • 添加以下行到/etc/fstab:
      :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 
 -p 
 [-f ]
 [-a -- show response headers]
 [-v -- verbose]
 [-F =]
 --    ...
......

根据命令的输出结果,得出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

你可能感兴趣的:(分布式系统)