#总览
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包含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  = 542metaServer.rootDirGroup = 543metaServer.rootDirMode  = 0755# Defaults for checkpoint and transaction log without permissions conversion on# startup.metaServer.defaultLoadUser     = 542metaServer.defaultLoadGroup    = 543metaServer.defaultLoadFileMode = 0644metaServer.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 boolLayoutManager::InRecoveryPeriod() const{return (TimeNow() < mRecoveryStartTime + mRecoveryIntervalSec);}inline boolLayoutManager::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

QFS文件系统-学习记录相关推荐

  1. 野火STM32F103——Fat文件系统及Flash芯片W25Q64学习记录

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 目录 文章目录 前言 一.Fatfs是什么? 二.W25Q64是什么 三.使用步骤 1.引入库 2.移植文件系统 文件简单读 ...

  2. Redis的学习记录

    Redis的学习记录 1.先导了解 1.1 NOSQL概述 1.1.1 为什么要用NoSql? 1.1.2 NoSql了解 1.1.3 NoSql特点 1.1.4 NoSQL的四大分类 2. Redi ...

  3. 架构与设计 之一 C 嵌入式设计模式(Design Patterns for Embedded Systems in C)的学习记录

    唉   时至今日,已经不知道在嵌入式的道路上到底挣扎了多少个岁月,总感觉要"病入膏肓"了.此间总是不时出现一些疑惑:人家搞 Java.搞 C# 的动不动就是什么架构 / 框架的,搞 ...

  4. 【学习记录】macOS的Redis安装及基本使用

    [学习记录]macOS的Redis安装及基本使用 一. Redis的安装与启动 二. 简单使用 ① 尝试插入第一个key-value ② Redis的数据类型与基本使用 字符串 列表 字典(哈希表) ...

  5. django实现证件照换底色后端和小程序(第三周学习记录)

    第三周学习记录 继续上周的django后台搭建,经过讨论选择不使用mysql数据库存储用户上传证件照信息,直接通过base64转码的形式在后台处理并返回前端直接通过数据流预览并实现图片下载 一.后端获 ...

  6. 磁盘配额(Quota)磁盘阵列(RAID)逻辑卷轴管理器(LVM)学习记录

    磁盘配额(Quota)磁盘阵列(RAID)逻辑卷轴管理器(LVM)学习记录 磁盘配额(quota) 启用Quota Quota指令 Quota实例 软件磁盘阵列 建立方法 观察已建立装置 出错救援方法 ...

  7. Zookeeper 3.5.7学习记录(一)——集群的坑

    Zookeeper 3.5.7学习记录(一)--集群的坑 目录 Zookeeper 3.5.7学习记录(一)--集群的坑 对应课程 概述 基础 安装Zookeeper 3.5.7 基本操作 配置文件z ...

  8. 【目录】全志V3S学习记录

    全志V3s从一次接触到现在已经有两年了!现在复盘一下! 使用的硬件开发板有: Lichee zero Lichee zero dock CherryPi PC V3s Mangopi v3s SINV ...

  9. linux个人学习记录

    linux学习记录 资料: Linux 黑马程序员_bilibili AcWing Linux基础课 可能是东半球最全面易懂的 Tmux 使用教程! Shell 教程 | 菜鸟教程 (runoob.c ...

最新文章

  1. php自己写配置项,创建配置文件 用PHP写出自己的BLOG系统 2
  2. 生活中的化学物质 —— 化学盐
  3. 出租(标记+格式输出)
  4. 修改 IIS 队列长度
  5. 第六章 SpringCloud之Ribbon负载均衡
  6. 如何实现listbox选项,然后双击鼠标实现选项的删除
  7. JDBC中Statement接口提供的execute、executeQuery和executeUpdate之间的区别
  8. 全球11大免费GIS数据源在此,速速来取!
  9. 戴尔 Inspiron 530s 通过 Clover_v2.5k_r5093 安装 macOS Catalina 10.15.3 教程
  10. C语言程序设计题(带答案)
  11. 主曲率、平均曲率、高斯曲率、法曲率、主方向
  12. React在ESLint下的报错收录(react-hooks/exhaustive-deps)
  13. A*算法在Unity中的实现
  14. Docker 配置国内镜像加速器,加速下载速度
  15. uniapp+nvue开发之仿微信语音+视频通话功能 :实现一对一语音视频在线通话
  16. Python第九章 文件系统
  17. pyton 爬虫-图片
  18. python 频数表_python里计算每个数字出现的频数
  19. 共识算法比较Tendermint的BFT与EOS的dPoS
  20. [go学习笔记.第二章] 2.go语言的开发工具以及安装和配置SDK

热门文章

  1. 历经四个月,谷歌联盟的PIN码问题终于解决了
  2. Windows下使用GPU加速FFmpeg处理图片合成视频
  3. 千牛工作台linux版,深度商店应用千牛工作台、Discord、QQ(Linux)、新浪微博安卓版...
  4. redis基数树rax源码分析(1)
  5. 绁炵粡缃戠粶鏁版嵁鏍煎紡,鏂囨湰绁炵粡缃戠粶
  6. 在uniapp中使用element-ui组件
  7. 浏览器的收藏夹在哪里打开
  8. LA 5713 秦始皇修路
  9. Yann Lecun 纽约大学Spring2020深度学习课程,附66页PPT下载
  10. 著名画家赵准旺的名人评语