一,MogileFS介绍
MogileFS 是一个开源的分布式文件系统,用于组建分布式文件集群,由 LiveJournal 旗下 Danga Interactive 公司开发,其已将代码托管到github上(https://github.com/mogilefs/),目前国内许多大公司已经使用 MogileFS 了。
MogileFS 官方介绍其有以下特性:
应用层
— 不需要特殊的核心组件;
无单点故障
— MogileFS分布式文件存储系统安装的三个组件(存储节点、跟踪器、跟踪用的数据库),均可运行在多个 机器上,因此没有单点故障.(你也可以将跟踪器和存储节点运行在同一台机器上,这样你就没有必要用4台机器)推荐至少两台机器;
自动的文件复制
— 基于不同的文件“分类”,文件可以被自动的复制到多个有足够存储空间的存储节点上,这样可以满足这个“类别”的最少复制要求.比如你有一个图片网站,你可以设置原始的JPEG图片需要复制 至少三份,但实际只有1or2份拷贝,如果丢失了数据,那么MogileFS分布式文件存储系统可以重新建立遗失的拷贝数.用这种办法,MogileFS(不做RAID)可以节约磁盘,否则你将存储同样的拷贝多份,完全没有必要;
“比RAID好多了”
— 在一个非存储区域网络的RAID(non-SAN RAID)的建立中,磁盘是冗余的,但主机不是,如果你整个机器坏了,那么文件也将不能访问. MogileFS分布式文件存储系统在不同的机器之间进行文件复制,因此文件始终是可用的.
传输中立,无特殊协议
— MogileFS分布式文件存储系统客户端可以通过NFS或HTTP来和MogileFS的存储节点来通信,但首先需要告知跟踪器一下;
简单的命名空间
–文件通过一个给定的key来确定,是一个全局的命名空间.你可以自己生成多个命名空间,只要你愿意,不过这样可能在同一MogileFS中会造成key冲突;
不用共享任何东西
— MogileFS分布式文件存储系统不需要依靠昂贵的SAN来共享磁盘,每个机器只用维护好自己的磁盘;
不需要RAID
— 在MogileFS中的磁盘可以是做了RAID的也可以是没有,如果是为了安全性着想的话RAID没有必要买了,因为MogileFS分布式文件存储系统已经提供了;
与MogileFS相似的分布式文件系统还有:
Google Filesystem | GFS+MapReduce擅长处理单个大文件 |
Hadoop Distributed Filesystem | GFS的山寨版+ MapReduce ,擅长处理单个大文件 |
ClusterFS | 擅长处理单个大文件 |
Taobao Filesystem | 擅长处理海量小文件 |
MogileFS | 擅长处理海量小文件 |
Ceph | 是一个 Linux PB级别的分布式文件系统 |
MooseFS | 通用简便,适用于研发能力不强的公司 |
Lustre | 一种平行分布式文件系统 |
分布式事务的模型及规范
什么是两段式提交:
通过使用某种协议进行通信来完成分布式事务,被称为两段式提交。从名字上看,您可能已经知道有两个阶段:
第一个阶段,即预提交:
事务协调器给每个事务管理器发送准备操作的信号。
事务管理器将操作(通常是数据更新)步骤(或细节)写入事务日志。如果失败,事务管理器使用这些步骤重复操作。
事务管理器本地创建事务并通知资源管理器对资源(例如,数据库或消息服务器)执行操作。
资源管理器执行操作并向事务管理器报告成功(准备提交信号)或失败(准备回滚)。
资源管理器等待事务管理器进一步的指令。
事务管理器向事务协调器报告成功或失败。
第二阶段,即提交阶段:在第二阶段中,第一阶段的结果将传送给所有事务管理器。
如果任何事务管理器报告失败,所有的事务参与者都必须回滚。
事务协调器让所有事务管理器提交(或回滚)。
所有事务管理器将提交或回滚信息传递给其资源管理器。
资源管理器将成功或失败提示返回给事务管理器。
事务管理器向事务协调器报告成功或失败。
CAP理论:一致性,可用性,分区容错性;指一个分布式系统不可以满足一致性,可用性和分区容错性这三个需求,最多只能同时满足其中的两个;
C(Consistency):一致性,任何一个读操作总是能够读取之前完成的写操作;就是一个数据写入一立马被读到;
A(Availability):可用性,每一次操作总是能够 在确定的时间返回;无论成功或失败都能收到一个返回值的;
P(Tolerance of network Partition):分区容错性,在出现网络分区的情况下,仍然能够满足一致性和可用性;
BASE法则模型反ACID模型,完全不同ACID模型,牺牲高一致性,获得可用性或可靠性:
BA:Basically Available,基本可以用,支持分区失败(sharding碎片划分数据库);
S:Soft state,软状态,接受一段时间内的状态不同步,异步;
E:Eventually consistent:最终一致性,弱一致性的表现;
BASE思想主要强调基本的可用性,如果你需要High 可用性,也就是纯粹的高性能,那么就要以一致性或容错性为牺牲,BASE思想的方案在性能上还是有潜力可挖的。
Paxos算法:比2PC提交更轻量级的分布式事务的协调方式;大概是指不出现故拜占庭将军的前提下,要取得数据的一致性,在通信信道不安全的时候,我们数据传输可能会被人劫持,这样就不能保证数据的可信了,所以必须保证通信信道安全下Paxos算法才可行;
MogileFS 的组成部分:
tracker节点 (MogileFSd 进程-建议二个 tracker 实例)
:借助数据库保存各节点文件的元数据信息保存每个域中所有键的存储位置分布,方便检索定位数据位置的同时监控各节点,告诉客户端存储区位置并指挥storage节点复制数据副本,进程名为mogilefsd(7001)。
database节点
:用来存放 MogileFS 的元数据 (命名空间, 和文件在哪里),是 Trackers 来操作和管理它,一般使用mysql或者maraidb。
storage节点
:将指定域中的键转换为其特有的文件名存储在指定的设备文件中,转换后的文件名为值,storage节点自动维护键值的对应关系,storage节点由于使用http进行数据传输,因此依赖于perlbal,storage节点前端可以使用nginx进行反向代理,但需要安 装nginx-mogilefs-module-master模块进行名称转换,进程名 mogstored(7501), perbal(7500) 。
Domain
:一个域中的键值是惟一的,一个MogileFS可以有多个域,域可以用来存储不同应用类型的数据的容器。
Host
:每一个存储节点称为一个主机,一个主机上可以有多个存储设备(单独的硬盘),每个设备都有ID号,Domain+Fid用来定位文件。
Class
:复制最小单位,文件属性管理,定义文件存储在不同设备上份数。
模型如下所示:
二,MogileFS的安装及配置
<code> 规划: 系统: CentOS 6.6 i686 node1: 192.168.0.212 安装 mogstord node2: 192.168.0.213 安装 mogstord tracker: 192.168.0.47 安装 mysql ,mogilefsd </code>
1,配置tracker节点:
<code> [root@localhost ~]# yum -y install make gcc unzip perl-DBD-MySQL perl perl-CPAN perl-YAML perl-Time-HiRes perl-IO-AIO #安装依赖 [root@localhost ~]# yum install mysql-server -y #安装mysql </code>
MogileFS的安装需要用到以下包,可以在此处下载 MogileFS rpm包 。
<code> MogileFS-Server-2.46-2.el6.noarch.rpm Perlbal-doc-1.78-1.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm perl-MogileFS-Client-1.14-1.el6.noarch.rpm MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm Perlbal-1.78-1.el6.noarch.rpm [root@localhost ~]# yum install *.rpm -y #安装以上包 </code>
也可以使用cpan在线下载,首先需要将依赖包安装完,使用cpan下载默认不提供启动脚本,需要自己添加所需脚本。
安装完 MogileFS::Server 后还需要安装 MogileFS-Utils 。
安装完成后首先为其在数据库中创建授权用户:
<code> mysql> grant all on *.* to 'root'@'%' identified by 'feiyu' ; mysql> flush privileges; [root@localhost ~]# mogdbsetup --dbhost=192.168.0.47 --dbport=3306 --dbname=mogilefs --dbrootuser=root --dbrootpass=feiyu --dbuser=moguser --dbpass=mogpass #开始连接 This will attempt to setup or upgrade your MogileFS database. It won't destroy existing data. Run with --help for more information. Run with --yes to shut up these prompts. Continue? [N/y]: y Create/Upgrade database name 'mogilefs'? [Y/n]: y Grant all privileges to user 'moguser', connecting from anywhere, to the mogilefs database 'mogilefs'? [Y/n]: y Failed to grant privileges: Access denied for user 'root'@'%' to database 'mogilefs' --------------------------------->连接出错 mysql> grant all on mogilefs.* to moguser@'%' identified by 'mogpass'; #对moguser进行授权 </code>
将其配置文件作如下修改,配置文件放在/etc/mogilefs下:
<code> [root@localhost ~]# cat mogilefsd.conf |grep -v '#' daemonize=1 #默认以守护进程方式运行 pidfile=/var/run/mogilefsd/mogilefsd.pid db_dsn = DBI:mysql:mogilefs:host=192.168.0.47 db_user = moguser db_pass = mogpass listen = 192.168.0.47:7001 #监听接口 conf_port = 7001 #配置接口 query_jobs=10 #工作进程数 delete_jobs=10 #输出文件的线程个数 replicate_jobs=5 #复制线程个数 [root@localhost ~]# useradd mogilefs #此服务必须以普通用户来启动 [root@localhost ~]# service mogilefsd start #启动服务,如果启动出现错误,很可能是配置文件有问题,仔细检查下 </code>
如果使用在线安装,没有启动脚本时,使用此方法启动,另外可以使用“pkill mogilefsd”来停止mogilefsd服务。
<code> [root@localhost ~]# su mogile -c "mogilefsd -c /etc/mogilefs/mogilefsd.conf --daemon" </code>
查看端口,若7001已经开始监听了说明启动成功了!
<code> [root@node1 ~]# ss -tlnp LISTEN 0 128 192.168.0.47:7001 *:* users:(("mogilefsd",30079,6)) </code>
附:MogileFS服务启动脚本
<code> #!/bin/bash # # mogilefsd - Startup script for the MogileFS tracker # # chkconfig: - 85 15 # description: MogileFS tracker # processname: mogilefsd # config: /etc/mogilefs/mogilefsd.conf # pidfile: /var/run/mogilefsd/mogilefsd.pid # Source function library. . /etc/rc.d/init.d/functions # Path to the apachectl script, server binary, and short-form for messages. lockfile=${LOCKFILE-/var/lock/subsys/mogilefsd} RETVAL=0 prog=$(which mogilefsd) start() { ulimit -n 65535 echo -n $"Starting mogilefsd" su - mogilefs -c "$prog -c /etc/mogilefs/mogilefsd.conf --daemon" RETVAL=$? [ $RETVAL = 0 ] && success && touch ${lockfile} || failure echo return $RETVAL } stop() { echo -n $"Stopping mogilefsd" netstat -nlp|grep "mogilefsd"|grep -v grep|awk '{print $7}'|awk -F"/" '{print $1}'|xargs kill -9 RETVAL=$? [ $RETVAL = 0 ] && success && rm -f ${lockfile} || failure echo } reload() { echo -n $"Reloading mogilefsd: " killall mogilefsd -HUP RETVAL=$? [ $RETVAL = 0 ] && success || failure echo } case "$1" in start) start ;; stop) stop ;; status) status mogilefsd RETVAL=$? ;; restart) stop sleep 1 start ;; reload) reload ;; *) echo $"Usage: mogilefsd {start|stop|restart|reload|status}" exit 1 esac exit $RETVAL </code>
2,配置存储节点
节点1和节点2都使用以下方法安装,首先安装和上面一样,只需要安装MogileFS-Server,不需要安装mysql:
<code> [root@localhost ~]# yum -y install make gcc unzip perl-DBD-MySQL perl perl-CPAN perl-YAML perl-Time-HiRes perl-IO-AIO #安装依赖 </code>
然后选择在线安装还是使用rpm包安装,我都测试过,以下使用rpm包安装:
<code> [root@localhost ~]# yum install *.rpm -y [root@node1 mogilefs]# mkdir -p /dfs/mogdata/dev1/ #创建存储位置,节点2的位置为/dfs/mogdata/dev2/ </code>
在/etc/mogilefs下修改配置文件:
<code> [root@node1 mogilefs]# cat mogstored.conf maxconns = 10000 httplisten = 0.0.0.0:7500 mgmtlisten = 0.0.0.0:7501 docroot = /dfs/mogdata/ ------------>1,2节点存储位置相同 [root@node1 mogilefs]# chown -R mogilefs.mogilefs /dfs/mogdata/ [root@node1 mogilefs]# useradd mogilefs [root@node1 mogilefs]# service mogstored start #启动服务 </code>
如果使用在线安装,没有启动脚本时,使用此方法启动,另外可以使用“pkill mogstored”来停止mogstored服务。
<code> [root@node1 mogilefs]# mogstored --daemon </code>
启动MogileFS Storage节点后,查看端口,看到7500和7501说明启动成功。
<code> [root@node2 ~]# ss -tlnp LISTEN 0 128 192.168.0.212:7500 *:* users:(("mogstored",6594,4)) LISTEN 0 128 192.168.0.212:7501 *:* users:(("mogstored",6594,9)) </code>
附:MogileFS Storage 服务启动脚本
<code> #!/bin/bash # # mogstored - Startup script for the MogileFS storage # # chkconfig: - 86 14 # description: MogileFS storage # processname: mogstored # config: /etc/mogilefs/mogstored.conf # pidfile: /var/run/mogilefsd/mogstored.pid # Source function library. . /etc/rc.d/init.d/functions # Path to the apachectl script, server binary, and short-form for messages. lockfile=${LOCKFILE-/var/lock/subsys/mogstored} RETVAL=0 configfile='/etc/mogilefs/mogstored.conf' prog=$(which mogstored) start() { ulimit -n 65535 echo -n $"Starting mogstored" su - mogilefs -c "$prog -c $configfile --daemon" &> /dev/null RETVAL=$? [ $RETVAL = 0 ] && success && touch ${lockfile} || failure echo return $RETVAL } stop() { echo -n $"Stopping mogstored" netstat -nlp|grep "mogstored"|grep -v grep|awk '{print $7}'|awk -F"/" '{print $1}'|xargs kill -9 RETVAL=$? [ $RETVAL = 0 ] && success && rm -f ${lockfile} || failure echo } reload() { echo -n $"Reloading mogstored: " killall mogstored -HUP RETVAL=$? [ $RETVAL = 0 ] && success || failure echo } case "$1" in start) start ;; stop) stop ;; status) status mogstored RETVAL=$? ;; restart) stop sleep 1 start ;; reload) reload ;; *) echo $"Usage: mogstored {start|stop|restart|reload|status}" exit 1 esac exit $RETVAL </code>
三、管理配置MogileFS
<code> [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 host list #列出主机 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 host add 192.168.0.211 --ip=192.168.0.212 --status=alive #添加一个主机,主机名为192.168.0.212 [root@localhost ~]# mogadm --trackers=192.168.0.47:701 host list #再列出主机,会显示添加的主机 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 device add 192.168.0.212 dev1 #添加设备,dev1 表示设备号,设备号只能以dev开头,也可以直接写成1 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 device list 192.168.0.212 [1]: alive used(G) free(G) total(G) weight(%) dev1: alive 4.448 11.998 16.446 100 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 host add 192.168.0.213 --ip=192.168.0.213 --status=alive #添加第二个主机 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 host list 192.168.0.212 [1]: alive IP: 192.168.0.212:7500 192.168.0.213 [2]: alive IP: 192.168.0.213:7500 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 device add 192.168.0.213 dev2 #添加第二个设备 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 device list 192.168.0.212 [1]: alive used(G) free(G) total(G) weight(%) dev1: alive 4.449 11.997 16.446 100 192.168.0.213 [2]: alive used(G) free(G) total(G) weight(%) dev2: alive 4.658 11.788 16.446 100 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 domain add files #添加一个files的domain,domain内复制的最小单位为class,一个doamin默认一个class,可以自己多做几个class,通常一个复制单位不会大于64M [root@localhost ~]# mogupload --trackers=192.168.0.47:7001 --domain=files --key='/fstab.html' --file='/etc/fstab' #上传文件,key为url [root@localhost ~]# moglistkeys --trackers=192.168.0.47:7001 --domain=files #查看上传的文件 fstab.html </code>
有两个存储节点,但此处只有一个文件副本,我从网上查到出错的原因可能是由于Sys::Syscall这个模块造成的。我们看到现在此模块的版本为0.25。我上网搜索其解决办法,发现如果将此软件降为0.23版本可能会修复此问题:
<code> [root@localhost ~]# wget http://search.cpan.org/CPAN/authors/id/B/BR/BRADFITZ/Sys-Syscall-0.23.tar.gz [root@localhost ~]# tar xf Sys-Syscall-0.23.tar.gz [root@localhost ~]# cd Sys-Syscall-0.23 [root@localhost ~]# perl Makefile.PL [root@localhost ~]# make && make install </code>
再次查看:
<code> [root@localhost ~]# mogupload --trackers=192.168.0.47:7001 --domain=files --key='/inittab.html' --file='/etc/inittab' #再上传一个文件 [root@localhost ~]# mogfileinfo --trackers=192.168.0.47:7001 --domain=files --key='/inittab.html' - file: /inittab.html class: default devcount: 2 domain: files fid: 8 key: /inittab.html length: 884 - http://192.168.0.213:7500/dev2/0/000/000/0000000008.fid ------------------------->已经成为两个副本了 - http://192.168.0.212:7500/dev1/0/000/000/0000000008.fid </code>
在浏览器中访问文件:
<code> [root@node1 mogilefs]# mogadm --trackers=192.168.0.47:7001 host mark 192.168.0.211 down #将一个主机下线维护,但是还是会显示其设备为alive, 以后上传的文件只能在一个节点中显示 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 device list 192.168.0.212 [1]: down ---------------------------------------------------》显示为 down used(G) free(G) total(G) weight(%) dev1: alive 4.448 11.998 16.446 100 192.168.0.213 [2]: alive used(G) free(G) total(G) weight(%) dev2: alive 4.658 11.788 16.446 100 [root@localhost ~]# mogdelete --trackers=192.168.0.47 --domain=files --key='/inittab.html' #删除文件 [root@localhost ~]# mogupload --trackers=192.168.0.47:7001 --domain=images --key="1.png" --file='/usr/share/backgrounds/default.png' #上传图片 [root@localhost ~]# mogdelete --trackers=192.168.0.47 --domain=images --key='/logo.png' #删除文件 [root@localhost ~]# moglistkeys --trackers=192.168.0.47 --domain=images #查看所有的key </code>
要删除一个host时,需要先将其设备删掉然后再删除host,直接删除主机会出错:
<code> [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 device mark 192.168.0.212 dev1 dead #先将设备标记为不可用的 mysql> delete from device devid=1; #然后从数据库中删除设备 [root@localhost ~]# mogadm --trackers=192.168.0.47:7001 host delete 192.168.0.212 #最后再删除主机 </code>
注意, 建议一个类的最小存储份数建议 3 份, 因为这样可以保证你整个集群挂掉二台机器还能正常的工作. 同时挂三台服务器的机率会比较小. 但同时挂二个机器或者二个硬盘的机会还是比较高, 所以一定要存 3分.
在加入和修改的时候, 都可以加上如 mindevcount , replpolicy 和 hashtype 的参数, 分别指的是本类中最少要存储的文件份数, 文件存储的复制规则和是否进行文件比较.
下一篇:基于Nginx反向代理实现Mogilefs分布式存储与访问