1、分佈式文件系統html
分佈式文件系統(Distributed File System)是指文件系統管理的物理存儲資源不必定直接鏈接在本地節點上,而是經過計算機網絡與節點相連,也就是集羣文件系統,能夠支持大數量的節點以及PB級的數量存儲。
相對地,在一個分享的磁盤文件系統中,全部節點對數據存儲區塊都有相同的訪問權,在這樣的系統中,訪問權限就必須由客戶端程序來控制。
分佈式文件系統可能包含的功能有:透通的數據複製與容錯。也就是說,即便系統中有一小部份的節點脫機,總體來講系統仍然能夠持續運做而不會有數據損失前端
分佈式文件系統類別node
名稱 |
特性 |
MogileFS | 適用於處理海量小文件 |
Ceph | 是一個 Linux PB級別的分佈式文件系統 |
MooseFS | 通用簡便,適用於研發能力不強的公司 |
Taobao Filesystem | 適用於處理海量小文件 |
ClusterFS | 適用於處理單個大文件 |
Google Filesystem | GFS+MapReduce擅長處理單個大文件 |
Hadoop Distributed Filesystem | GFS的山寨版+MapReduce,擅長處理單個大文件 |
MogileFS 是一個開源的分佈式文件系統,用於組建分佈式文件集羣,由 LiveJournal 旗下 Danga Interactive 公司開發,Danga 團隊開發了包括 Memcached、MogileFS、Perlbal 等不錯的開源項目:(注:Perlbal 是一個強大的 Perl 寫的反向代理服務器)。目前國內使用 MogileFS 的有圖片託管網站 yupoo 等mysql
MogileFS由3個部分組成:
第1個部分: 是server端,包括mogilefsd和mogstored兩個程序。前者便是mogilefsd的tracker,它將一些全局信息保存在數據庫 裏,例如站點domain,class,host等。後者便是存儲節點(store node),它實際上是個HTTP Daemon,默認偵聽在7500端口,接受客戶端的文件備份請求。在安裝完後,要運行mogadm工具將全部的store node註冊到mogilefsd的數據庫裏,mogilefsd會對這些節點進行管理和監控。
第2個部分:是utils(工具集),主要是MogileFS的一些管理工具,例如mogadm等。
第3個部分:是客戶端API,目前只有Perl API(MogileFS.pm)、PHP,用這個模塊能夠編寫客戶端程序,實現文件的備份管理功能,提供MogileFS.pm。linux
當下互聯網飛速發展,海量併發所產生的數據量以幾何方式增加,隨着信息連接方式日益多樣化,數據存儲的結構也發生了變化,在這樣的壓力下咱們不得不從新審視大量數據的存儲所帶來了巨大的挑戰:
一、數據採集:對於社交網站通常都是由用戶上傳的;
二、數據存儲:如今是數據量大爆炸時代,天天都會產生大量的數據,因此數據存儲就成了一個大問題;
三、數據搜索:若是說存儲是考驗數據的存儲能力的話,那搜索就是考量計算機能力了,從大量的數據中搜索出來;
四、數據共享:數據存儲下來以後還要進行數據的共享問題,大量的數據該怎麼共享這些數據呢;
五、數據傳輸:而海量數據存儲下來以後數據怎麼用戶與用戶之間進行安全的傳輸;
六、數據分析:數據的分析是瞭解咱們過去的一些行爲規範;
七、數據可視化:而海量數據存儲下來以後怎麼樣能夠直觀的展現在人們面前呢;nginx
分佈式文件系統的幾個難點:
一、缺少全局時鐘、不過同步自己就存在時間差,很難作到步調一致,
二、面對故障的獨立性,分佈式是由多個節點組成的,而每一個節點都是獨立工做的,一個節佔故障度不會影響其它節點正常工做,
三、如何去處理單點故障, 一是:作冗餘,對單點作備份;二是:下降單點故障的影響範圍
四、事務類的挑戰,在分佈環境中怎麼處理事務呢;ACID或2PI(兩段式提交)、最終一致、BASE法則、CAP理論、Paxos算法;算法
什麼是兩段式提交:
經過使用某種協議進行通訊來完成分佈式事務,被稱爲兩段式提交。從名字上看,您可能已經知道有兩個階段:
第一個階段,即預提交:
事務協調器給每一個事務管理器發送準備操做的信號。
事務管理器將操做(一般是數據更新)步驟(或細節)寫入事務日誌。若是失敗,事務管理器使用這些步驟重複操做。
事務管理器本地建立事務並通知資源管理器對資源(例如,數據庫或消息服務器)執行操做。
資源管理器執行操做並向事務管理器報告成功(準備提交信號)或失敗(準備回滾)。
資源管理器等待事務管理器進一步的指令。
事務管理器向事務協調器報告成功或失敗。
第二階段,即提交階段:在第二階段中,第一階段的結果將傳送給全部事務管理器。sql
若是任何事務管理器報告失敗,全部的事務參與者都必須回滾。
事務協調器讓全部事務管理器提交(或回滾)。
全部事務管理器將提交或回滾信息傳遞給其資源管理器。
資源管理器將成功或失敗提示返回給事務管理器。
事務管理器向事務協調器報告成功或失敗。數據庫
CAP理論:一致性,可用性,分區容錯性;指一個分佈式系統不能夠知足一致性,可用性和分區容錯性這三個需求,最多隻能同時知足其中的兩個;
C(Consistency):一致性,任何一個讀操做老是可以讀取以前完成的寫操做;就是一個數據寫入一立馬被讀到;
A(Availability):可用性,每一次操做老是可以 在肯定的時間返回;不管成功或失敗都能收到一個返回值的;
P(Tolerance of network Partition):分區容錯性,在出現網絡分區的狀況下,仍然可以知足一致性和可用性;vim
BASE法則模型反ACID模型,徹底不一樣ACID模型,犧牲高一致性,得到可用性或可靠性:
BA:Basically Available,基本能夠用,支持分區失敗(sharding碎片劃分數據庫);
S:Soft state,軟狀態,接受一段時間內的狀態不一樣步,異步;
E:Eventually consistent:最終一致性,弱一致性的表現;
BASE思想主要強調基本的可用性,若是你須要High 可用性,也就是純粹的高性能,那麼就要以一致性或容錯性爲犧牲,BASE思想的方案在性能上仍是有潛力可挖的。
Paxos算法:比2PC提交更輕量級的分佈式事務的協調方式;大概是指不出現故拜占庭將軍的前提下,要取得數據的一致性,在通訊信道不安全的時候,咱們數據傳輸可能會被人劫持,這樣就不能保證數據的可信了,因此必須保證通訊信道安全下Paxos算法纔可行;
實現MogileFS的分佈式過程,按照下圖構建MogileFS分佈式文件系統的結構,這裏限於機器的緣由,一些服務都整合在一塊兒;
第一步:安裝MogileFS軟件,咱們前面提到,它是由三部分組成,因此三個組件都得安裝上,而且每一個節點都作MogileFS和Mogstored;
在這裏先說一個筆者的基本佈局,node0(172.16.27.88)上安裝nginx和MariaDB,node1(172.16.27.1)和 node2(172.16.27.2)上分別安裝了MogileFS和Mogstored,node1和node2都共同使用node0上的 MariaDB數據庫,nginx作爲前端接收用戶請求並負載均衡到後端兩個節點上;
在node1上的安裝和配置過程,修改好配置文件以後複製一份相同的配置文件到node2節點上,由於它們的配置參數都是同樣的:
[root@node1 ~]# rpm -ivh perl-MogileFS-Client-1.14-1.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm [root@node1 ~]# yum -y install MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm MogileFS-Server-2.46-2.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm perl-IO-AIO # 安裝好以後修改配置文件,只須要修改如下幾項就能夠了 # mysql指使用的數據庫是什麼,MariaDB也是寫mysql;mogdb指數據庫名;host=172.16.27.88指定安裝數據的地址 [root@node1 ~]# vim /etc/mogilefs/mogilefsd.conf db_dsn = DBI:mysql:mogdb:host=172.16.27.1 db_user = moguser # 指登陸mogdb數據所使用的用戶名 db_pass = linux # 登陸mogdb數據所使用密碼 listen = 0.0.0.0:7001 # 0.0.0.0表示監聽全部地址 # 再編輯mogstored.conf這個配置文件 maxconns = 10000 httplisten = 0.0.0.0:7500 mgmtlisten = 0.0.0.0:7501 docroot = /dfs/mogdata # 把這項改一個特定的目錄,以便存儲數據,最好是一個獨立分區 [root@node1 ~]# mkdir -pv /dfs/mogdata/dev1 # 建立修改的docroot目錄 [root@node1 ~]# chown -R mogilefs.mogilefs /dfs/mogdata/dev1 # 修改屬主屬組 [root@node1 ~]# chown -R mogilefs.mogilefs /var/run/mogilefsd/ [root@node1 ~]# cd /etc/mogilefs [root@node1 ~]# scp mogilefsd.conf mogstored.conf root@172.16.27.2:/etc/mogilefs/ # 複製修改好的配置文件到node2的mogilefs目錄下,覆蓋便可,兩個節點都安裝配置好以後先不要啓動服務,數據庫尚未安裝
在node2上的安裝和配置,這裏的配置文件由node1上覆制過來就能夠了;
[root@node2 ~]# rpm -ivh perl-MogileFS-Client-1.14-1.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm [root@node2 ~]# yum -y install MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm MogileFS-Server-2.46-2.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm perl-IO-AIO [root@node2 ~]# mkdir -pv /dfs/mogdata/dev2 # 建立修改的docroot目錄 [root@node1 ~]# chown -R mogilefs.mogilefs /var/run/mogilefsd/ [root@node2 ~]# chown -R mogilefs.mogilefs /dfs/mogdata/dev2 # 修改屬主屬組
第二步:安裝nginx和MariaDB,這裏安裝Nginx須要編譯安裝,由於他須要裝載第三方模塊纔可使用mogilefs,MariaDB安裝這裏就再也不說明了;
在node0節點上的安裝步驟:
# 解決依賴關係 [root@node0 ~]# yum -y groupinstall "Development Tools" "Server Platform Development" [root@node0 ~]# yum -y install openssl-devel pcre-devel [root@node0 ~]# groupadd -r nginx [root@node0 ~]# useradd -r -g nginx nginx [root@node0 ~]# tar xf nginx-1.4.2.tar.gz [root@node0 ~]# unzip nginx-mogilefs-module-master.zip [root@node0 ~]# cd nginx-1.4.2 [root@node0 nginx-1.4.2]# ls auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src [root@node0 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 \ > --with-debug \ > --add-module=/root/nginx-mogilefs-module-master # 這裏要指定編譯的模塊 [root@node0 nginx-1.4.2]# make && make install # 這裏MariaDB安裝過程再也不說明了,能夠參數前面的博文,編譯安裝好以後就能夠能夠啓動MariaDB和去配置Nginx的相關配置了,還要給nginx提供一個服務腳本; [root@node0 support-files]# service mysqld start Starting MySQL... [ OK ] [root@node0 nginx-1.4.2]# vim /etc/rc.d/init.d/nginx #!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chkconfig: - 85 15 # description: Nginx is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /etc/nginx/nginx.conf # config: /etc/sysconfig/nginx # pidfile: /var/run/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 nginx="/usr/sbin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/etc/nginx/nginx.conf" [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx lockfile=/var/lock/subsys/nginx make_dirs() { # make required directories user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` options=`$nginx -V 2>&1 | grep 'configure arguments:'` for opt in $options; do if [ `echo $opt | grep '.*-temp-path'` ]; then value=`echo $opt | cut -d "=" -f 2` if [ ! -d "$value" ]; then # echo "creating" $value mkdir -p $value && chown -R $user $value fi fi done } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac [root@node0 nginx-1.4.2]# chmod +x /etc/init.d/nginx [root@node0 nginx-1.4.2]# vim /etc/profile.d/nginx.sh export PATH=/usr/sbin/nginx:$PATH [root@node0 nginx-1.4.2]# . /etc/profile.d/nginx.sh [root@node0 nginx-1.4.2]# service nginx start Starting nginx: [ OK ] [root@node0 nginx-1.4.2]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 :::111 :::* LISTEN 0 128 *:111 *:* LISTEN 0 128 *:80 *:*
測試訪問一下nginx的頁面:
第三步:鏈接上數據庫,給兩個用戶受權:
[root@node0 ~]# mysql -uroot -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 46 Server version: 10.0.10-MariaDB-log MariaDB Server Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> USE mysql; Database changed MariaDB [mysql]> GRANT ALL ON *.* TO 'root'@'172.16.%.%' IDENTIFIED BY 'linux'; Query OK, 0 rows affected (0.20 sec) MariaDB [mysql]> GRANT ALL ON mogdb.* TO 'moguser'@'172.16.%.%' IDENTIFIED BY 'linux'; Query OK, 0 rows affected (0.00 sec) MariaDB [mysql]> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.21 sec) MariaDB [mysql]>
第四步:再到兩個節點上,在其中一個上設置便可:
[root@node1 mogilefs]# mogdbsetup --dbhost=172.16.27.88 --dbport=3306 --dbname=mogdb --dbrootuser=root --dbrootpass=linux --dbuser=moguser --dbpass=linux --yes # 能夠再回到node0上查看一下生成的數據庫 MariaDB [mysql]> USE mogdb; Database changed MariaDB [mogdb]> SHOW TABLES; +----------------------+ | Tables_in_mogdb | +----------------------+ | checksum | | class | | device | | domain | | file | | file_on | | file_on_corrupt | | file_to_delete | | file_to_delete2 | | file_to_delete_later | | file_to_queue | | file_to_replicate | | fsck_log | | host | | server_settings | | tempfile | | unreachable_fids | +----------------------+ 17 rows in set (0.03 sec)
第五步:在兩個節點的其中一個上添加主機:
[root@node1 ~]# mogadm --trackers=172.16.27.1:7001 host add 172.16.27.1 --ip=172.16.27.1 --status=alive [root@node1 ~]# mogadm --trackers=172.16.27.1:7001 host add 172.16.27.2 --ip=172.16.27.2 --status=alive [root@node1 mogilefs]# mogadm --trackers=172.16.27.1:7001 host list 172.16.27.1 [1]: alive IP: 172.16.27.1:7500 172.16.27.2 [2]: alive IP: 172.16.27.2:7500 # 再添加設備 [root@node1 mogilefsd]# mogadm --trackers=172.16.27.1:7001 device add 172.16.27.1 1 [root@node1 mogilefsd]# mogadm --trackers=172.16.27.1:7001 device add 172.16.27.2 2 [root@node1 mogilefsd]# mogadm --trackers=172.16.27.1:7001 device list 172.16.27.1 [1]: alive used(G) free(G) total(G) weight(%) dev1: alive 2.799 15.887 18.686 100 172.16.27.2 [2]: alive used(G) free(G) total(G) weight(%) dev2: alive 1.476 17.210 18.686 100 # [root@node1 ~]# mogadm --trackers=172.16.27.1:7001 domain add images # 添加域 [root@node1 ~]# mogadm --trackers=172.16.27.1:7001 domain add files [root@node1 ~]# mogadm --trackers=172.16.27.1:7001 domain add html [root@node1 ~]# mogadm --trackers=172.16.27.1:7001 domain list # 查看域 domain class mindevcount replpolicy hashtype -------------------- -------------------- ------------- ------------ ------- files default 2 MultipleHosts() NONE html default 2 MultipleHosts() NONE images default 2 MultipleHosts() NONE [root@node1 ~]# mogadm --trackers=172.16.27.1:7001 class add images class0 --mindevcount=2 [root@node1 ~]# mogadm --trackers=172.16.27.1:7001 class list domain class mindevcount replpolicy hashtype -------------------- -------------------- ------------- ------------ ------- files default 2 MultipleHosts() NONE html default 2 MultipleHosts() NONE images class0 2 MultipleHosts() NONE #添加類 images default 2 MultipleHosts() NONE # 上傳幾張圖片和測試的頁面上去 [root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=images --key='1.png' --file='/usr/share/backgrounds/default_1920x1200.png' [root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=images --key='2.png' --file='/usr/share/backgrounds/wallpaper-six-2560x1240.png' [root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=images --key='/images/3.png' --file='/usr/share/backgrounds/centos_wallpaper_01_1920x1200.png' [root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=html --key='/files/index.html' --file='/var/www/html/index.html' [root@node1 ~]# mogupload --trackers=172.16.27.1:7001 --domain=files --key='/files/index.html' --file='/var/www/html/index.html' [root@node1 ~]# moglistkeys --trackers=172.16.27.1:7001 --domain=images /images/3.png 1.png 2.png [root@node1 ~]# mogfileinfo --trackers=172.16.27.1:7001 --domain=images --key='/images/3.png' - file: /images/3.png class: default devcount: 2 domain: images fid: 5 key: /images/3.png length: 202652 - http://172.16.27.2:7500/dev2/0/000/000/0000000005.fid - http://172.16.27.1:7500/dev1/0/000/000/0000000005.fid [root@node1 ~]# mogfileinfo --trackers=172.16.27.1:7001 --domain=files --key='/files/index.html' - file: /files/index.html class: default devcount: 2 domain: files fid: 9 key: /files/index.html length: 53 - http://172.16.27.2:7500/dev2/0/000/000/0000000009.fid - http://172.16.27.1:7500/dev1/0/000/000/0000000009.fid [root@node1 ~]#
能夠複製這個地址在頁面上測試一下,這裏是每上傳一個文件就都會在兩個節點是都存一份,若是節點多的話它會根據定義的devcount本身選擇節點存儲幾份,這樣在一個節點掉了也能夠在別的節點在有相同的資源可用;
第六步:以上的都配置好了就能夠在前端的Nginx上配置訪問控制了,修改配置文件:
[root@node0 nginx]# vim nginx.conf upstream mogcluster { # 定義多個上游服務器 server 172.16.27.1:7001; server 172.16.27.2:7001; } server { # 定義一個虛擬主機 listen 80; server_name www.tanxw.com; location /images/ { mogilefs_tracker mogcluster; mogilefs_domain images; mogilefs_pass { proxy_pass $mogilefs_path; proxy_hide_header Content-Type; proxy_buffering off; } } location ~* ^(/files/.*)$ { mogilefs_tracker mogcluster; mogilefs_domain files; mogilefs_pass $1 { proxy_pass $mogilefs_path; proxy_hide_header Content-Type; proxy_buffering off; } } } # 修改好配置文件後保存退出重啓服務 [root@node0 nginx]# service nginx restart nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful Stopping nginx: [ OK ] Starting nginx: [ OK ] [root@node0 nginx]#
而後在頁面上測試訪問剛纔上傳的文件以及圖片:
總結:
最後還能夠測試一下把一個節點掉了,試着訪問一下看另外正常工做的節點可不能夠正常提供服務,這裏還能夠添加不少功能的,後續還會更新相關的基礎網站服務器架構搭建的文章,在此,若是發如今什麼不妥或作得不到的還望你們多提點建議。