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架构
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

布局

它需要最少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

猜你喜欢

转载自blog.csdn.net/lipeng08/article/details/51457250