淘宝TFS分布式文件系统

简介

TFS(Taobao File System)是淘宝开发的一个分布式文件系统,适用于海量小文件存储。

参考:http://code.taobao.org/p/tfs/wiki/intro/

系统环境

Red Hat 4.1.2-50 x64

gcc version 4.1.2 20080704

ip:192.168.1.2

PS:测试环境单台及其跑nameserver+dataserver。多台分布可以参考一下配置:

http://gdcsy.blog.163.com/blog/static/12734360920125624859906/

http://elf8848.iteye.com/blog/1724423

安装过程(!)

一、 配置基本环境

[root@locatfs local]#yum update

需要确保安装了automake autoconfig 和 libtool,使用auotmake –version查看,一般情况下已安装。 1.4以上版本需要安装libuuid-devel,zlib-devel,mysql-devel三个开发包 [root@locatfs local]# yum install readline-devel readline

[root@locatfs local]# yum install ncurses-devel.x86_64  ncurses.x86_64

[root@locatfs local]# yum install -y automake libtool  libxslt groff pcre-devel  gcc* zlib-devel

[root@locatfs local]# yum install  e4fsprogs e4fsprogs-devel

#ext4

#加载ext4模块,让系统支持ext4文件系统

[root@locatfs local]#  modprobe ext4

 

二、 升级安装高版本mysql

  1. 安装配置yum源

[root@locatfs local]#

wget http://centos.ustc.edu.cn/epel/5/x86_64/epel-release-5-4.noarch.rpm

[root@locatfs local]#

wget ftp://ftp.pbone.net/mirror/rpms.famillecollet.com/enterprise/5/remi/i386/remi-release-5-8.el5.remi.noarch.rpm

[root@locatfs local]#rpm -ivh epel-release-5-4.noarch.rpm

[root@locatfs local]#rpm -ivh remi-release-5-8.el5.remi.noarch.rpm

  1. 向以下3个文件尾部追加一个文本(可以不做)

[root@locatfs local]#echo ‘priority=1′ >> /etc/yum.repos.d/remi.repo

[root@locatfs local]#echo ‘priority=1′ >> /etc/yum.repos.d/epel-testing.repo

[root@locatfs local]#echo ‘priority=1′ >> /etc/yum.repos.d/epel.repo

  1. 检查是否有可升级版本并升级。发现有版本可以升级到mysql5.5.11。

[root@locatfs local]#yum –enablerepo=remi list mysql

[root@locatfs local]#yum –enablerepo=remi update mysql

PS:这里可能需要升级一些rpm,根据系统不同确定。如果yum没有那就下载rpm(http://rpm.pbone.net/),然后用rpm -Uvh升级

三、 下载安装TFS

  1. 安装svn(如果没有安装)

[root@locatfs local]# yum install subversion

  1. 获取源代码

[root@locatfs local]# cd /opt

[root@locatfs local]# svn co -r 18 http://code.taobao.org/svn/tb-common-utils/trunk tb-common-util

[root@locatfs local]# svn checkout http://code.taobao.org/svn/tfs/tags/release-2.2.16/ tfs-2.2.16

[root@locatfs local]# wget http://googletest.googlecode.com/files/gtest-1.6.0.zip

PS:注意版本,tb-common-util用18、tfs用2.2.16(比较稳定)、gtest用1.6.0

  1. 安装gtest

[root@locatfs local]# unzip gtest-1.6.0.zip

[root@locatfs local]# cd gtest-1.6.0

[root@locatfs local]# ./configure

[root@locatfs local]# make

[root@locatfs local]# cd make/

[root@locatfs local]# make

[root@locatfs local]# ./sample1_unittest

  1. 编译和安装tbnet, tbsys库

[root@locatfs local]# vi /etc/profile

添加tblib根目录

export TBLIB_ROOT=/usr/local/tb/lib

[root@locatfs local]# source /etc/profile

进入tb-common-utils文件夹, 执行build.sh进行安装.

[root@locatfs local]# cd tb-common-utils/

[root@locatfs local]# chmod +x *.sh

[root@locatfs local]# ./build.sh

  1. 编译安装tfs

[root@locatfs local]# cd /opt/tfs-2.2.16/

[root@locatfs local]# ./build.sh  init

[root@locatfs local]# ./configure –prefix=/usr/local/tfs –without-tcmalloc

[root@locatfs local]# make

[root@locatfs local]# make install

PS:

1) 如果提示找不到/usr/local/tfs/scripts/cs_sync:

把tfs下的cs_sync.sh复制成cs_sync 执行:cp -a ./scripts/cs_sync.sh /root/tfs_bin/scripts/cs_sync

2) 如果出错:checking for tc_cfree in -ltcmalloc… no:

这是因为后面的tfs版本使用tcmalloc库了,可以在config时加–without-tcmalloc参数,重新编译,或者装tcmalloc库。我试过前者,是可以编译的。

TCMalloc(Thread-Caching Malloc)是google开发的开源工具,与标准的glibc库的malloc相比,TCMalloc在内存的分配上效率和速度要高,可以在很大程度上提高服务器在高并发情况下的性能,降低系统负载。这个模块可以用来让MySQL在高并发下内存占用更加稳定。

参考 :http://blog.chinaunix.net/space.php?uid=10449864&do=blog&id=2956849

3)如果-ljemalloc报错:

yum install jemalloc jemalloc-devel

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

如果没有其它报错,那恭喜安装完成。

目前情况:

tfs安装在 /usr/local/tfs/

tbsys、tbnet 安装在  /usr/local/tb/

/usr/local/tfs/conf/共有三个文件需要配置:ns.conf、ads.conf和ds.conf;没有的话从源码conf中复制

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

四、 配置启动

说明:

ns.conf                                用于启动nameserver         //只运行dataserver的服务器不用配置。

ads.conf和ds.conf   用于启动dataserver     //只运行nameserver的服务器不用配置。

nameserver和dataserver的启动顺序不限

[nameserver]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  1. 配置nameserver(除了红字,其它可以保持默认)

[root@locatfs local]# vi ns.conf

[public]

#日志文件的size,默认 1GB

log_size=1073741824

 

#保留日志文件的个数,默认 64

log_num = 4

 

#日志文件的级别, 默认 debug

log_level = error       //不然日志会很大

 

#工作队列size,  默认  10240

task_max_queue_size = 10240

 

#nameserver监听端口,自行修改,这里我们用8108

port =8108

 

#工作目录,也就是tfs的安装目录

work_dir=/usr/local/tfs

 

#网络设备,即通信网卡,一般用内网,ifconfig查看

dev_name= eth0

 

#工作线程池 default  4

thread_count = 4

 

#本机IP地址(vip),配置ha时为vip,没配置可以为主ns的ip

ip_addr = 192.168.1.2

 

[nameserver]

 

#系统保护时间,单位(秒), default: 300

#保护时间内不进行任何操作,包括添加block等

safe_mode_time = 300

 

#nameserver IP地址列表(master, salve的ip地址,只能以’|’分隔)

#单台nameserver时,另一个ip配置为无效ip即可

ip_addr_list = 192.168.1.2|192.168.0.2

 

#Ip地址 mask

#用于区分dataserver所在的子网,选择不同子网的dataserver备份数据

group_mask = 255.255.255.255

 

#Block size的最大值, 单位(字节)

block_max_size = 83886080   //这个值到底怎么配置好,有待实验。 必须 >= dataserver的mainblock_size,推荐设置一致。

 

#Block 最大备份数, default: 2

#单台dataserver时,需要配置为1

max_replication = 1

 

#Block 最小备份数, default: 2

#单台dataserver时,需要配置为1

min_replication = 1

 

#DataServer 容量使用的百分比, default: 98

use_capacity_ratio = 98

 

#Block使用的百分比, default: 95

block_max_use_ratio = 98

 

#Dataserver 与 nameserver 的心跳时间, 单位(秒), default: 2

heart_interval = 2

 

# object 死亡的最大时间, 单位(秒), default: 86400

object_dead_max_time = 3600

 

# 集群号

cluster_id = 1

 

# Block当前备份数与最大备份数百分比,如果大于这个百分比,就开始复制

replicate_ratio_ = 50

 

#每个DataServer 主可写块的大小, default: 3

max_write_filecount = 16

 

#dataserver 与 nameserver 的心跳线程池的大小, default: 2

heart_thread_count = 2

 

#dataserver 与 nameserver 的心跳工作队列的大小, default: 10

heart_max_queue_size = 10

 

#block 缺失备份时, 需要等待多长时间才进行复制, 单位(秒), default: 240

repl_max_time = 60

 

#block进行压缩的比例, block 删除的文件的比例达到这个值时进行压缩

compact_delete_ratio =  15

 

#block进行压缩时, dataserver的最大负载,超出这个值dataserver,不进行压缩

compact_max_load = 200

 

# object 清理的时间, 单位(秒), default: 300

object_clear_max_time = 300

 

#nameserver上出现租约等待时, 阻塞线程最大个数, 这个值最好是工作线程的一半

max_wait_write_lease = 15

 

#租约删除的最长时间, 单位(小时), default: 1

lease_expired_time = 3

 

#最大租约超时时间

max_lease_timeout = 3000

 

#清理租约的阀值, default: 102400

cleanup_lease_threshold = 102400

 

#创建计划的间隔时间, 单位(秒), default: 30

build_plan_interval = 10

 

#计划超时时间, 单位(秒), default: 120

run_plan_expire_interval = 120

 

#创建计划的百分比, 计划数量 = dataserver 数量 * build_plan_ratio

build_plan_ratio = 25

 

#定时dump统计信息的间隔时间, 单位(微秒), default: 60000000

dump_stat_info_interval = 60000000

 

#创建计划等待时间, 主要用有很多紧急复制时,单位(秒), default: 2

build_plan_default_wait_time = 2

 

#负载均衡时block相关的个数(这个参数有点问题, 以后会改成百分比), default: 5

balance_max_diff_block_num = 5

 

#每次新增Block的个数, default: 3

add_primary_block_count = 3

 

#存储block桶的个数, default: 32

block_chunk_num = 32

 

#每个任务处理的预期时间, 单位(微秒), default: 200

task_percent_sec_size = 200

 

#每个任务队列的最大size

task_max_queue_size = 10000

 

#同步日志缓冲区slot的大小, 超出这个值会写入磁盘, default: 1

oplog_sync_max_slots_num = 1024

 

#同步日志线程池的大小, default: 1

oplog_sync_thread_num = 1

  1. 启动nameserver

执行scripts目录下的tfs

[root@locatfs local]# cd /usr/local/tfs/scripts

[root@locatfs local]#./tfs start_ns

执行正常返回:

 

查看监听端口:

 

说明nameserver启动成功。

[dataserver]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  1. 配置dataserver(除了红字,其它可以保持默认)

[root@locatfs local]# vi ds.conf

[public]

 

#日志文件的size,default 1GB

log_size=1073741824

 

#保留日志文件的个数,default 64

log_num = 64

 

#日志文件的级别, default debug

log_level=debug

 

#工作队列size, default 10240

task_max_queue_size = 10240

 

#监听端口, 1024 ~ 65535

port = 9998

 

#工作目录

work_dir=/usr/local/tfs/

 

#网络设备

dev_name= eth0

 

#工作线程池 default 4

thread_count = 4

 

#本机IP地址(vip)

ip_addr = 192.168.1.2

 

[dataserver]

 

#!NameServer vip地址

ip_addr = 192.168.1.2

 

#!nameserver IP地址列表(master, salve的ip地址,只能以’|’分隔) (ns.conf中配 置的一致)

ip_addr_list = 192.168.1.2|192.168.0.2

 

#!NameServer 监听的端口, 1024 ~ 55535(ns.conf中配置的一致)

port = 8108

 

#备集群NameServer的vip地址, 可以不用配置

#slave_nsip = 192.168.0.2

 

#备集群NameServer监听端口, 可以不用配置

#slave_nsport = 9999

 

#dataserver 与 nameserver心跳间隔时间, 单位(秒), default: 2

heart_interval = 2

 

check_interval = 2

 

#datafile失效时间, 单位(秒), default: 90

#expire_datafile_time = 90

 

#拷贝一个Block超时时间, 单位(秒), default: 180

#expire_clonedblock_time = 180

 

#压缩一个Block超时时间, 单位(秒), default: 600

#expire_compactblock_time = 600

 

#复制Block线程池的大小, default: 2

replicate_threadcount = 2

 

#是否写同步日志, defalut: 1

#write_sync_flag = 1

 

#block 最大size

block_max_size = 7549747

 

#定时dump统计信息的间隔时间, 单位(秒), default: 60

dump_visit_stat_interval = 60

 

#io操作的阀值, 超过此值时, 会警告

#max_io_warning_time = 0

 

#备件类型, 1: tfs, 2: nfs

backup_type = 1

 

#备件路径,(放文件的目录,磁盘挂载区)

backup_path = /data/tfs

 

#最大datafile值, default: 50

#max_data_file_nums = 50

 

#crc error的最大个数

#max_crc_error_nums = 4

 

#eio error的最大个数

#max_eio_error_nums_ = 6

 

#超时block检测时间, 单位(秒)

#expire_checkblock_time = 86000

 

#cpu使用率

#max_cpu_usage = 60

 

#dump 统计信息的间隔时间, 单位(微秒)

#dump_stat_info_interval = 60000000

 

#mount路径

mount_name = /data/tfs

 

#mount 时磁盘的大小, 单位(KB)

mount_maxsize = 4194304

//最大的挂载空间,如果你的/data/tfs1有1T,而这里是设置了4G ,那只有4G的块可用空间,剩下的全部浪费。如果实际空间不足4G,那会报错

 

#文件系统类型: 0: no initialize, 1: ext4, 2: ext3 posix fallocate, 3: ext3 ftruncate

base_filesystem_type = 1

 

#超级块存存储的保留位置,default: 0

superblock_reserve = 0

 

#平均文件的大小, 单位(字节)

avg_file_size = 40960

 

#主块的大小, 单位(字节)

mainblock_size = 83886080    //每个数据存储块的大小

 

#扩展块的大小, 单位(字节)

extblock_size = 419430

 

#主块与扩展的比例

block_ratio = 0.5

 

#hash桶的比例

hash_slot_ratio = 0.5

 

ds_thread_count = 4

 

#访问控制ip mask, 可选

#access_control_ipmask = 192.168.0.1

 

#访问控制文件路径, 可选

#access_control_file = /home/xxxxx/xxxxxx/tfs/control.file

 

[root@locatfs local]# vi ads.conf

[public]

 

#日志文件的size,default 1GB

log_size=1073741824

 

#保留日志文件的个数,default 64

log_num = 64

 

#日志文件的级别, default debug

log_level=debug

 

#工作队列size,default 10240

task_max_queue_size = 10240

 

#监听端口, 1024 ~ 65535

port = 12000

 

#工作目录

work_dir=/usr/local/tfs/

 

#网络设备

dev_name= eth0

 

#工作线程池size, default 4

thread_count = 4

 

#本机ip地址

ip_addr = 192.168.1.2

 

[adminserver]

 

#检测的间隔时间, 单位(秒), default: 5

check_interval = 5

 

#失败的次数的阀值, default: 5

check_count = 5

 

#死亡个数的阀值

warn_dead_count = 3

 

#kill server之前等待时间

ds_fkill_waittime = 15

 

#dataserver启动命令脚本

ds_script = /usr/local/tfs/bin/dataserver -f /usr/local/tfs/conf/ds.conf -d

 

#监控的dataserver列表

ds_index_list = 1,2,3

 

[nameserver]

 

#!NameServer的vip

ip_addr = 192.168.1.2

 

#!NameServer监听的端口

port = 8108

 

[dataserver]

 

#!DataServer监听的端口

port = 9998

 

#!DataServer lock file路径

lock_file = /usr/local/tfs/logs/dataserver

 

#!DataServer 加载点路径

mount_name = /data/tfs

 

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

到这里配置文件就结束了

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  1. 启动dataserver

首先需要格式化一个分区为ext4文件系统,并挂载到/data/tfs1至/data/tfs(i),其中i为磁盘号。注意上面的 mount_name = /data/tfs  没有加(i)

1)         物理增加一个硬盘,或则已有的硬盘分区df -h或fdisk -l查看

2)         格式化为ext4 [root@locatfs local]# mkfs.ext4 /dev/sdb

3)         挂载磁盘  [root@locatfs local]# mount /dev/sdb /data/tfs1/

4)         设置开机自动挂载[root@locatfs local]# vi /etc/fstab

加一行:

/dev/sdb                /data/tfs1              ext4    defaults        1 2

5)         存储区预分配

执行scripts下的stfs format n (n为挂载点的序号,具体用法见stfs的Usage)。例如stfs format 2,4-6 则会对/data/tfs2,
/data/tfs4,/data/tfs5,/data/tfs6,进行预分配。运行完后会在生成/data/tfs2, /data/tfs4,/data/tfs5,/data/tfs6下预先创建主块,扩展块及相应的统计信息。

[root@locatfs scripts]# stfs format 1

(1为挂载点的序号 具体可以看官网说明) //分配第一个存储区

 

6)         运行data server

有两种方法:
1)通过adminserver来启动dataserver(推荐): 执行scripts下的./tfs admin_ds
2)直接启动dataserver,执行scripts下的./tfs start_ds 2,4-6, 则会启动dataserver2,dataserver4,dataserver5,dataserver6

[root@locatfs scripts]# ./tfs admin_ds

 

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

OK,启动问问题一切安装配置过程结束

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

五、 测试

  1. 查看dataserver连接情况

[root@locatfs scripts]# cd  /usr/local/tfs/bin/

[root@locatfs scripts]# ./ssm -s 192.168.1.2:8108

server -b \\随即列出dataserver的block块

server -w \\随机列出dataserver的可写块

machine -a \\列出dataserver的使用报道。

 

 

这里需要注意如果用server -b 、-w后面的BLOCK数字,如果是0,说明没有可写块。检测ns  ads ds的配置文件,包括备份个数、主块大小知否一致.

如果看到上面的信息,那基本没问题了。

  1. 用tfstool上传一张图片

“客户端首先向nameserver发起写请求,nameserver需要根据dataserver上的可写块,容量和负载加权平均来选择一个可写的 block。并且在该block所在的多个dataserver中选择一个作为写入的master,这个选择过程也需要根据dataserver的负载以 及当前作为master的次数来计算,使得每个dataserver作为master的机会均等。master一段选定,除非master宕机,不会更 换,一旦master宕机,需要在剩余的dataserver中选择新的master。返回一个dataserver列表。

客户端向master dataserver开始数据写入操作。master server将数据传输为其他的dataserver节点,只有当所有dataserver节点写入均成功时,master server才会向nameserver和客户端返回操作成功的信息。“

也就是说客户端发起一个请求,nameserver先根据dataserver的 容量和负载 来选择一个dataserver来做为所有dataserver的master(除非master宕机,不会更换,宕机则自动重新选择)然后根据ns.conf的配置的备份数全部写入,才向nameserver和客户端返回操作成功信息。

 

[root@locatfs scripts]# cd  /usr/local/tfs/bin/

[root@locatfs bin]#./tfstool -s 192.168.1.2:8108

 

这 里我使用put上传/opt/test.jpg这张图,顺便说下,TFS目 前限制了文件大小为2M, 适合于一些小于2M数 据的存放。终端默认上传命令put ,超过2M用putl,回车后会返回一大堆字符,注意看最后一行是fail还是success,如果是fail,请检测下配置文件、端口等。如果是 success则说明已经上传上去。

 

往返回的信息上找些我们要的数据 : Block ID和block中的File ID;我们传的文件大小为1997540,下图可以看到文件被割成2个块 1048576和948964 ;储存在192.168.0.25  blockid: 889, fileid: 1

 

到这里文件写入就完成了。

  1. 读取文件

[root@locatfs scripts]# cd  /usr/local/tfs/bin/

[root@locatfs bin]#./ds_client -d 192.168.1.2:9998

list_file 889

 

上图可以看到,block 889 里面只有一个文件fileid 1   size为1997540(跟我们上传的一样大)。
取出来:

read_file_data  889 1 /tmp/test1.jpg

没有报错。我们去看看/tmp/test141.jpg,看看是不是跟我们上传的一样大