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高可用分佈式文件系統配置完成。