1、关于MogileFS html
MongileFS是一个由Perl开发的分布式文件系统,遵循CAP理论,即Consistency:数据的一致性;Availability:数据的可用性;Tolerance of network Partition:数据的容错性;而这里的MongileFS知足了后俩者,也就是只知足数据的可用性和容错性,对于大型网站,数据的可用性和容错性要优先于数据的一致性。前端
MongileFS使用一致性hash来解决数据的可用性,使用虚拟节点来解决数据倾斜的问题;MongileFS特别适合存储海量小文件的数据,与之相似的分布式文件系统还有:FastDFS,MooseFS等,也适合存储海量小文件。node
MongileFS的特性:mysql
一、应用层实现,不须要特殊的核心组件;
linux
二、无单点失败,MogileFS分布式文件存储系统安装的三个组件(存储节点、跟踪器、跟踪用的数据库),都可运行在多个机器上,所以没有单点失;nginx
三、自动的文件复制 — 基于不一样的文件“分类”,文件能够被自动的复制到多个有足够存储空间的存储4节点上,这样能够知足这个“类别”的最少复制要求;git
四、简单的命名空间 –文件经过一个给定的key来肯定,是一个全局的命名空间.你能够本身生成多个命名空间,只要你愿意,不过这样可能在同一MogileFS中会形成key冲突;github
五、不用共享任何东西 — MogileFS分布式文件存储系统不须要依靠昂贵的SAN来共享磁盘,每一个机器只用维护好本身的磁盘;sql
实现MogileFS分布文件系统所须要的主机角色:
数据库
一、Tracker(MogileFSd 进程):这个是 MogileFS 的核心部分,他是一个调度器,MogileFSd 进程就是trackers进程程序,trackers 作了不少工做:Replication ,Deletion,Query,Reaper,Monitor 等等,这个是基于事件的( event-based ) 父进程/消息总线来管理全部来之于客户端应用的交互(requesting operations to be performed),,包括将请求负载平衡到多个“query workers”中,而后让 MogileFSd 的子进程去处理;
二、MySQL:用来存放 MogileFS 的元数据 (命名空间, 和文件在哪里),是Trackers 来操做和管理它,能够用mogdbsetup程序来初始化数据库,由于数据库保存了MogileFS的全部元数据,建议作成HA架构;
三、Storage Nodes:实际文件存放的地方,存储节点是一个HTTP服务器,用来作删除,存放,重命名等事情,任何WebDAV服务器均可以, 不过推荐使用mogstored,MogileFSd 能够配置到两个机器上使用不一样端口,mogstored来进行全部的DAV操做和流量,IO监测, 而且你本身选择的HTTP服务器(默认为 perlbal)用来作GET操做给客户端提供文件。
MogileFS管理的几个概念:
一、Domain:一个MogileFS能够有多个Domain,用来存放不一样文件(大小,类型),同一个Domain内key必须为一,不一样Domain内,key能够相同;
二、Class:文件属性管理,定位文件存储在不一样设备上的份数;
2、MongileFS工做原理图
3、实验环境
10.232.50.239 OS:CentOS 6.4 x86_64 node1.luojianlong.com
10.232.42.218 OS:CentOS 6.4 x86_64 node2.luojianlong.com
10.232.42.219 OS:CentOS 6.4 x86_64 node3.luojianlong.com
拓扑图
首先,分别在node1,node2,node3上面安装cpan以及依赖的包
[root@node1 ~]# yum -y install make gcc unzip perl-DBD-MySQL perl perl-CPAN perl-YAML perl-Time-HiRes cpan [root@node2 ~]# yum -y install make gcc unzip perl-DBD-MySQL perl perl-CPAN perl-YAML perl-Time-HiRes cpan [root@node3 ~]# yum -y install make gcc unzip perl-DBD-MySQL perl perl-CPAN perl-YAML perl-Time-HiRes cpan
使用cpan命令安装MogileFS::Server,MogileFS::Client,以及依赖的模块,前提是主机可以上互联网
# 安装过程当中,若有提示安装依赖的模块,直接回答yes便可 [root@node1 ~]# cpan -i install MogileFS::Server [root@node1 ~]# cpan -i install MogileFS::Client [root@node1 ~]# cpan -i install MogileFS::Utils [root@node2 ~]# cpan -i install MogileFS::Server [root@node2 ~]# cpan -i install MogileFS::Client [root@node2 ~]# cpan -i install MogileFS::Utils [root@node3 ~]# cpan -i install MogileFS::Server [root@node3 ~]# cpan -i install MogileFS::Client [root@node3 ~]# cpan -i install MogileFS::Utils
安装完成之后,在node1上面安装mysql
[root@node1 ~]# useradd -r mysql [root@node1 ~]# tar zxvf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local/ [root@node1 ~]# cd /usr/local/ [root@node1 local]# ln -s mysql-5.5.33-linux2.6-x86_64 mysql [root@node1 local]# cd mysql [root@node1 mysql]# chown -R root.mysql ./* [root@node1 mysql]# mkdir /mydata/data -p [root@node1 mysql]# chown -R mysql.mysql /mydata/data/ [root@node1 mysql]# cp support-files/mysql.server /etc/rc.d/init.d/mysqld [root@node1 mysql]# chmod +x /etc/rc.d/init.d/mysqld [root@node1 mysql]# chkconfig --add mysqld [root@node1 mysql]# chkconfig mysqld on [root@node1 mysql]# cp support-files/my-large.cnf /etc/my.cnf [root@node1 mysql]# ./scripts/mysql_install_db --user=mysql --datadir=/mydata/data [root@node1 mysql]# vi /etc/my.cnf # 添加以下俩行 datadir = /mydata/data innodb_file_per_table = 1 [root@node1 mysql]# vi /etc/profile.d/mysql.sh export PATH=/usr/local/mysql/bin:$PATH [root@node1 mysql]# . /etc/profile.d/mysql.sh [root@node1 mysql]# service mysqld start Starting MySQL.... SUCCESS!
建立Tracker链接mysql的远程用户
mysql> grant all on *.* to 'root'@'%' identified by '123456'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec)
配置Tracker
[root@node1 ~]# useradd -r mogilefs [root@node1 ~]# mkdir /var/run/mogilefsd/ -p [root@node1 ~]# chown -R mogilefs.mogilefs /var/run/mogilefsd [root@node1 ~]# mkdir /etc/mogilefs/ # 编辑配置文件:/etc/mogilefs/mogilefsd.conf [root@node1 ~]# vi /etc/mogilefs/mogilefsd.conf db_dsn = DBI:mysql:mogilefs:host=10.232.50.239;port=3306;mysql_connect_timeout=5 db_user = mogile db_pass = 123456 conf_port = 7001 listener_jobs = 5 node_timeout = 5 rebalance_ignore_missing = 1 # 编写mogilefsd启动脚本 [root@node1 ~]# vi /etc/rc.d/init.d/mogilefsd #!/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 [root@node1 ~]# chmod +x /etc/rc.d/init.d/mogilefsd [root@node1 ~]# chkconfig --add mogilefsd [root@node1 ~]# chkconfig mogilefsd on # 初始化数据库 [root@node1 ~]# mogdbsetup --dbhost=127.0.0.1 --dbrootuser=root --dbpass=123456 --dbname=mogilefs --dbuser=mogile --dbpassword=123456 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 'mogile', connecting from anywhere, to the mogilefs database 'mogilefs'? [Y/n]: y [root@node1 ~]# ln -s /usr/local/bin/mogilefsd /usr/bin/ [root@node1 ~]# ln -s /usr/local/bin/mogilefsd /usr/sbin/ [root@node1 ~]# service mogilefsd start Starting mogilefsd [ OK ] [root@node1 ~]# ss -anptl Recv-Q Send-Q Local Address:Port Peer Address:Port 0 128 :::22 :::* users:(("sshd",8066,4)) 0 128 *:22 *:* users:(("sshd",8066,3)) 0 128 *:7001 *:* users:(("mogilefsd",3444,6)) 0 50 *:3306 *:* users:(("mysqld",1003,11)) # 启动成功 # 在node2,node3上面执行相同的操做,安装mogilefsd,不须要初始化数据
配置mogstored
# 编辑mogstored配置文件 [root@node1 ~]# vi /etc/mogilefs/mogstored.conf maxconns = 10000 httplisten = 0.0.0.0:7500 mgmtlisten = 0.0.0.0:7501 docroot = /mogdata [root@node1 ~]# mkdir /mogdata/dev1 [root@node1 ~]# chown -R mogilefs.mogilefs /mogdata/dev1 # 编写mogstored启动脚本 [root@node1 ~]# vi /etc/rc.d/init.d/mogstored #!/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 [root@node1 ~]# chmod +x /etc/rc.d/init.d/mogstored [root@node1 ~]# chkconfig --add mogstored [root@node1 ~]# chkconfig mogstored on [root@node1 ~]# ln -s /usr/local/bin/mogstored /usr/bin/ [root@node1 ~]# ln -s /usr/local/bin/mogstored /usr/sbin/ [root@node1 ~]# service mogstored start Starting mogstored [ OK ] [root@node1 ~]# ss -anptl Recv-Q Send-Q Local Address:Port Peer Address:Port 0 128 *:7500 *:* users:(("mogstored",5108,4)) 0 128 *:7501 *:* users:(("mogstored",5108,9)) 0 128 :::22 :::* users:(("sshd",8066,4)) 0 128 *:22 *:* users:(("sshd",8066,3)) 0 128 *:7001 *:* users:(("mogilefsd",3444,6)) 0 50 *:3306 *:* users:(("mysqld",1003,11)) # 启动成功 # node2,node3执行相同的操做,对应的存储目录为/mogdata/dev2,/mogdata/dev3
在node2上面编译安装nginx
[root@node2 ~]# yum -y groupinstall "Development Tools" "Server Platform Deveopment" [root@node2 ~]# yum -y install openssl-devel pcre-devel [root@node2 ~]# groupadd -r nginx [root@node2 ~]# useradd -r -g nginx nginx # 解压nginx的第三方模块mogilefs模块 [root@node2 ~]# unzip nginx-mogilefs-module-master.zip [root@node2 ~]# tar zxvf nginx-1.4.2.tar.gz [root@node2 ~]# cd nginx-1.4.2 [root@node2 nginx-1.4.2]# ./configure \ > --prefix=/usr \ > --sbin-path=/usr/sbin/nginx \ > --conf-path=/etc/nginx/nginx.conf \ > --error-log-path=/var/log/nginx/error.log \ > --http-log-path=/var/log/nginx/access.log \ > --pid-path=/var/run/nginx/nginx.pid \ > --lock-path=/var/lock/nginx.lock \ > --user=nginx \ > --group=nginx \ > --with-http_ssl_module \ > --with-http_flv_module \ > --with-http_stub_status_module \ > --with-http_gzip_static_module \ > --http-client-body-temp-path=/var/tmp/nginx/client/ \ > --http-proxy-temp-path=/var/tmp/nginx/proxy/ \ > --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \ > --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \ > --http-scgi-temp-path=/var/tmp/nginx/scgi \ > --with-pcre \ > --add-module=/root/nginx-mogilefs-module-master [root@node2 nginx-1.4.2]# make && make install [root@node2 nginx-1.4.2]# mkdir /var/tmp/nginx/client -p [root@node2 nginx-1.4.2]# nginx
Nginx 作为 MogileFS 的前端客户端,咱们使用Nginx来吐文件,作前端的查询代理时,咱们须要使用到mogilefs的这个模块,能够下载这个模块编译进Nginx就好了,直接使用 ./configure -add-module=这个参数就能够了,最新的这个模块的下载地址是:https://github.com/vkholodkov/nginx-mogilefs-module
在node1上,使用mogadm添加节点
[root@node1 ~]# mogadm host add 10.232.50.239 --ip=10.232.50.239 --status=alive [root@node1 ~]# mogadm host add 10.232.42.218 --ip=10.232.42.218 --status=alive [root@node1 ~]# mogadm host add 10.232.42.219 --ip=10.232.42.219 --status=alive [root@node1 ~]# mogadm check Checking trackers... 127.0.0.1:7001 ... OK Checking hosts... [ 1] 10.232.50.239 ... OK [ 2] 10.232.42.218 ... OK [ 3] 10.232.42.219 ... OK Checking devices... host device size(G) used(G) free(G) use% ob state I/O% ---- ------------ ---------- ---------- ---------- ------ ---------- ----- ---- ------------ ---------- ---------- ---------- ------ total: 0.000 0.000 0.000 0.00% # 添加host成功
为每一个host添加device
[root@node1 ~]# mogadm device add 10.232.50.239 1 [root@node1 ~]# mogadm device add 10.232.42.218 2 [root@node1 ~]# mogadm device add 10.232.42.219 3 [root@node1 ~]# mogadm check Checking trackers... 127.0.0.1:7001 ... OK Checking hosts... [ 1] 10.232.50.239 ... OK [ 2] 10.232.42.218 ... OK [ 3] 10.232.42.219 ... OK Checking devices... host device size(G) used(G) free(G) use% ob state I/O% ---- ------------ ---------- ---------- ---------- ------ ---------- ----- [ 1] dev1 7.472 2.443 5.029 32.69% writeable N/A [ 2] dev2 7.472 1.839 5.633 24.61% writeable N/A [ 3] dev3 7.472 1.647 5.825 22.04% writeable N/A ---- ------------ ---------- ---------- ---------- ------ total: 22.416 5.928 16.488 26.45% # 添加成功
添加domain
[root@node1 ~]# mogadm domain add files [root@node1 ~]# mogadm domain add p_w_picpaths [root@node1 ~]# mogadm domain list domain class mindevcount replpolicy hashtype -------------------- -------------------- ------------- ------------ ------- files default 2 MultipleHosts() NONE p_w_picpaths default 2 MultipleHosts() NONE # 发现已经自动添加了default class
上传文件测试
[root@node1 ~]# mogupload --trackers=10.232.50.239 --domain=files --key='/fstab' --file='/etc/fstab' [root@node1 ~]# mogfileinfo --trackers=10.232.50.239 --domain=files --key='/fstab' - file: /fstab class: default devcount: 3 domain: files fid: 5 key: /fstab length: 463 - http://10.232.42.219:7500/dev3/0/000/000/0000000005.fid - http://10.232.42.218:7500/dev2/0/000/000/0000000005.fid # 能够看到文件被自动保存为2个副本 [root@node1 ~]# curl http://10.232.42.218:7500/dev2/0/000/000/0000000005.fid /dev/xvda1 / ext3 noatime,acl,user_xattr 1 1 /dev/xvdc swap swap defaults 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs noauto 0 0 debugfs /sys/kernel/debug debugfs noauto 0 0 devpts /dev/pts devpts mode=0620,gid=5 0 0 # 能够正常访问
模拟down掉一个节点,看文件会不会丢失
[root@node1 ~]# mogadm host mark 10.232.42.218 down [root@node1 ~]# mogadm check Checking trackers... 127.0.0.1:7001 ... OK Checking hosts... [ 1] 10.232.50.239 ... OK [ 2] 10.232.42.218 ... skipping; status = down [ 3] 10.232.42.219 ... OK Checking devices... host device size(G) used(G) free(G) use% ob state I/O% ---- ------------ ---------- ---------- ---------- ------ ---------- ----- [ 1] dev1 7.472 2.443 5.029 32.70% writeable N/A [ 3] dev3 7.472 1.648 5.824 22.05% writeable N/A ---- ------------ ---------- ---------- ---------- ------ total: 14.944 4.091 10.853 27.37% [root@node1 ~]# mogfileinfo --trackers=10.232.42.218 --domain=files --key='/fstab' - file: /fstab class: default devcount: 1 domain: files fid: 5 key: /fstab length: 463 - http://10.232.42.218:7500/dev2/0/000/000/0000000005.fid # 发现文件依然存在
下面使用Nginx来替换storage nodes上 mogstored中的Perlbal
[root@node2 ~]# vi /etc/nginx/nginx.conf # 添加以下 upstream trackers { server 10.232.50.239:7001; server 10.232.42.218:7001; server 10.232.42.219:7001; } location /files/ { mogilefs_tracker trackers; mogilefs_domain files; mogilefs_methods get; mogilefs_pass { proxy_pass $mogilefs_path; proxy_hide_header Content-Type; proxy_buffering off; } } [root@node2 ~]# nginx -s reload
关于如上配置解释一下,好比:
http://www.a.com/files/A6B00135E24AB17E043B9B5453762438.png
这个URL中的UUID是A6B00135E24AB17E043B9B5453762438.png.这时咱们使用这个作key来存到MogileFS中就行,再结合rewrite,只要key在url里有,就能直接代理到后端的mogilefs,若是使用了多个tracker的话,要配置使用多个tracker来进行负载均衡和备份,能够直接配置tracker到upstrame里面,而后后面配置tracker的链接时,直接加上mogilefs_tracker online_mogilefs就好了,若是你还想配置使用 mogilefs 的 Nginx 上传,使用其中的 put 功能而后就不要安装客户端上传送,就须要打个补丁,上面的配置同样,关键对于上传的配置,须要给方法修改成mogilefs_methods PUT DETEL。
上传文件测试
# 设置files domain的class复制份数为3 [root@node1 ~]# mogadm class modify files default --mindevcount=3 # 上传文件 [root@node1 ~]# echo "9966" > /tmp/index11.html [root@node1 ~]# mogupload --trackers=10.232.50.239 --domain=files --key='index11.html' --file='/tmp/index11.html' [root@node1 ~]# mogfileinfo --trackers=10.232.50.239 --domain=files --key='index11.html' - file: index11.html class: default devcount: 3 domain: files fid: 24 key: index11.html length: 5 - http://10.232.42.218:7500/dev2/0/000/000/0000000024.fid - http://10.232.50.239:7500/dev1/0/000/000/0000000024.fid - http://10.232.42.219:7500/dev3/0/000/000/0000000024.fid # 发现有3个副本 [root@node2 ~]# curl http://10.232.42.218/files/index11.html 9966
测试正常访问
下面模拟down掉一个节点
[root@node1 ~]# mogadm host mark 10.232.50.239 down [root@node1 ~]# mogadm check Checking trackers... 127.0.0.1:7001 ... OK Checking hosts... [ 1] 10.232.50.239 ... skipping; status = down [ 2] 10.232.42.218 ... OK [ 3] 10.232.42.219 ... OK Checking devices... host device size(G) used(G) free(G) use% ob state I/O% ---- ------------ ---------- ---------- ---------- ------ ---------- ----- [ 2] dev2 7.472 1.843 5.629 24.67% writeable N/A [ 3] dev3 7.472 1.652 5.820 22.11% writeable N/A ---- ------------ ---------- ---------- ---------- ------ total: 14.944 3.495 11.449 23.39% [root@node2 ~]# curl http://10.232.42.218/files/index11.html 9966
发现访问一切正常
若是想根据跨多机房多网段来复制不一样class份数,须要安装MogileFS::Network模块
[root@node1 ~]# cpan -i MogileFS::Network # 安装完成后 # 添加网段名称,这里添加2个 [root@node1 ~]# mogadm settings set network_zones near,far # 添加网段地址 [root@node1 ~]# mogadm settings set zone_near 10.0.0.0/8 # 修改class属性 [root@node1 ~]# mogadm class modify files default --replpolicy "HostsPerNetwork(near=2)" # 发现修改生效 [root@node1 ~]# mogadm class list domain class mindevcount replpolicy hashtype -------------------- -------------------- ------------- ------------ ------- files default 2 HostsPerNetwork(near=2) NONE files index 3 MultipleHosts() NONE p_w_picpaths default 2 MultipleHosts() NONE # 这里就实现了根据网段不一样复制不一样的class数量
注意:若是是多个tracker的话,每一个tracker主机上都须要安装MogileFS::Network模块。
常见问题及解决方法:
若是遇到class的devcount始终为1,修改class的mindevcount也无效的话,能够设置以下:
[root@node1 ~]# perl -MSys::Syscall -e 'print $Sys::Syscall::VERSION' 0.25 # 显示为0.25版本,这就会有问题 [root@node1 ~]# cpanm http://search.cpan.org/CPAN/authors/id/B/BR/BRADFITZ/Sys-Syscall-0.23.tar.gz [root@node1 ~]# perl -MSys::Syscall -e 'print $Sys::Syscall::VERSION' 0.23 # 降级为0.23的版本就能解决次问题了
到此,MogileFS, nginx-mogilefs高可用分布式文件系统配置完成。