海量圖片存儲--MogileFS分佈式存儲集羣的實現

分佈式存儲html


    當下互聯網飛速發展,海量併發所產生的數據量以幾何方式增加,隨着信息連接方式日益多樣化,數據存儲的結構也發生了變化,在這樣的壓力下咱們不得不從新審視大量數據的存儲所帶來的挑戰,好比:數據採集、數據存儲、數據搜索、數據共享、數據傳輸、數據分析、數據可視化等一些列問題node

   傳統存儲在面對海量數據存儲時已經力不從心,好比縱向擴展受陣列空間限制、橫向擴展受交換設備限制、節點受文件系統限制mysql


   分佈式存儲的出如今在必定程度上緩解了這一問題nginx



分佈式存儲基礎介紹     算法


(一)多線程與進程的執行模式
#互不通訊的多線程模式;
#基於共享容器協同的多線程模式;
#經過事件協同的多線程模式;
(二)基於輸入設備變化、運算器的變化、存儲器的變化分類
1)控制器的變化
# 透明模式
# 旁路模式
# 名稱模式
# 規則服務器
2)存儲器的變化
#  代理模式
#  名稱服務
#  規則服務器
#  master模型:前段節點存放元數據(name node),後端節點存放數據(data node)
(三)分佈式系統的難點
# 缺少全局時鐘
# 面對故障的獨立性
# 處理單點故障:①作冗餘②下降單點故障的影響範圍
#事務的挑戰(ACID):①2pc兩端式提交、②最終一致③BASE方法④CAP理論⑤Paxos
(四)分佈式文件系統的設計目標
# 訪問透明
# 位置透明
# 併發透明
# 失效透明
# 硬件透明
# 可拓展性
# 複製透明
# 遷移透明
(五)分佈式文件系統的注重的特性
# Scalable 伸縮性
# Reliable 可靠性
# Cheap    性價比


(六)分佈式事務的模型及規範
X/open: XA-----XA規範是開放羣組關於分佈式事務處理 (DTP)的規範
#DTP:Distributed Transaction Processing Reference Model 分佈式事務處理
XA規範 定義了三個組件
#AP :Appliacation Program 應用程序
#RM :Resource Manager    資源管理器
#TM :Transaction Manager 事務管理器
簡單來說:AP經過RM來實現資源操做,若是AP當中執行一個完整的事務,則經過TM控制事務都執行或者不執行,若是事務執行失敗則回滾;
其中TM管理哪些資源的事務須要事先向RM資源管理器註冊申請


(七)面對事務挑戰(ACID)的協調方式
#2PC(兩段式提交):事務管理中雙方都完成,或者都不完成
#CAP理論:C表明一致性,A表明可用性,P表明分區容錯性
 CAP理論通常知足以上二者,沒法保證三者都知足;其中關係型數據庫屬於AC,其餘環境通常爲AP
#BASE :BA(Basically)表示基本可用,S(Soft state)表示接受一段時間內的狀態不一樣步,E(Eventually consistent)最終一致性
#Paxos : 比2PC提交更輕量級的分佈式事務的協調方式


分佈式事務處理的一致性問題
sql



強一致性
#ACID
#在單機環境中,強一致性能夠由數據庫的事務來保證
#在多級環境中,強一致性很難作到
#分佈式事務:性能太差,在化聯網的應用中不適合
弱一致性(包括最終一致性)
#經過提交處理的半同步、半異步或全異步,取得最終一致性效果
#最終一致性使得數據的提交具備延時性,而在必定範圍時的延時性範圍內(好比一秒),應用的可用性時正常的
集羣內一致性算法實施過程案例
#基於合法票數(Quorum)和向量時鐘(Vector Clock)
Quorum算法
#N :數據複製的節點量
#R :成功讀取所依賴的最少節點數
#W :成功寫操做所依賴的最少節點數
#W+R>N 表示強一致性 ;W+R<=N 屬於弱一致性(保證最終一致性)



分佈式存儲文件系統類別數據庫



各類分佈式存儲文件系統介紹
#Google Filesystem :GFS+MapReduce擅長處理單個大文件
#Hadoop Distibuted Filesystem :GFS山寨版+MapReduce 擅長處理單個大文件
#GlusterFS :擅長處理單個大文件
#Taobao Filesystem :擅長處理海量小文件
#MogileFS:擅長處理海量小文件
#Ceph    :PB級別的分佈式文件系統
#MooseFS :通用簡單
#Lustre  :一種平行分佈式文件系統




MofileFS原理vim


     MofileFS是一個開源的分佈式文件系統,用於組件分佈式文件集羣。其主要特性包括:應用層組件、無單點故障、自動文件複製(複製單位不是文件而是class類)、傳輸中使用http協議,基於域的簡單命名方式、具備比RAID更好的可靠性後端



核心角色
(1)tracker節點:藉助於數據庫保存各節點文件的元數據信息,保存每一個域中全部鍵的存儲位置分佈,方便檢索定位數據位置的同時並監控各個節點,告訴客戶端存儲區位置並指揮storage節點複製數據副本,進程名mogilefsd/端口7001
(2)database節點:爲tracker節點提供數據存取
(3)storage節點:將指定域中的鍵轉換爲其特有的文件名存儲在指定的設備文件中,轉換後的文件名爲值,storage節點自動維護鍵值對應關係,storage節點因爲使用http進行數據傳輸,所以依賴於perlball,storage節點前段可使用nginx進行反向代理,但須要安裝nginx的第三方模塊nginx-mogilefs-module-master,進程mogstored/7500端口,perlbal/7500端口
(4)Domain:一個域中的鍵值是惟一的,一個MogileFS能夠有多個域,域能夠存儲不一樣應用類型的數據的容器
(5)Class:複製最小單位,文件屬性管理,定義文件存儲在不一樣設備上的分數


    客戶端、tracker、Database、mogstore的關係圖bash

wKioL1NteszwZd_rAADoCDRc0nk876.jpg


       流程圖


wKioL1NtfvugoCg4AAF2GLYjogk394.jpg



Nginx + MogileFS集羣的實現


   架構圖


wKiom1NtguKQRKMhAAC-KCfOFY4822.jpg


         1 應用層發起GET請求到Ningx

         2 Nginx根據負載均衡機制隨機代理到後臺的tracker服務器(其中之一)

         3 tracker服務器將查詢結果返回給Nginx

         4 Nginx將查詢結構根據模塊轉換爲合理的url發送給後端的mogstore存儲服務器

         5 mogstore存儲服務器將文件內容經過http協議返回給Nginx

         6 Nginx將結果返回給應用層客戶端


  實現步驟


 一、MySQL服務器配置



mysql的編譯安裝請參照個人博客
mysql配置
1)受權root用戶
#MariaDB [(none)]> grant all on *.* to root@'172.16.%.%' identified by '123456';
2)受權moguser用戶
#MariaDB [(none)]> grant all on mogdb.* to 'moguser'@'172.16.%.%' identified by 'mogpass';
3)沖刷受權表
#MariaDB [mogdb]> flush privileges;


  二、172.16.13.2服務器安裝tracker和mystore  


1)下載程序包:
MogileFS-Utils-2.19-1.el6.noarch.rpm
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
MogileFS-Server-2.46-2.el6.noarch.rpm
MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm
MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm
同時將全部rpm包 放到另外兩個服務器上一份
#scp  *.rpm 172.16.13.3:/root
#scp *.rpm 172.16.13.4:/root



2)安裝
#yum  -y install  *.rpm perl-IO-AIO
3)配置tracker
# chown -R mogilefs.mogilefs /var/run/mogilefsd/ 指定爲mogilefs用戶和組
# mogdbsetup --dbhost=172.16.249.39 --dbport=3306 --dbname=mogdb --dbrootuser=root --dbrootpass=123456 --dbuser=moguser --dbpass=mogpass --yes 數據庫初始化
MySQL服務器查看生成的數據庫
#MariaDB [(none)]> show databases;


wKioL1NthiigMGNNAACf0Bshkqw247.jpg



編輯tracker的配置文件
#cd /etc/mogilefs
#vim mogilefsd.conf 修改一下內容
  db_dsn = DBI:mysql:mogdb:host=172.16.249.39
  db_user = moguser
  db_pass = mogpass
  listen = 0.0.0.0:7001
#chmod -R mogilefs.mogilefs mogilefsd.conf
#service mogilefsd start  啓動mogilefsd服務
#ss -ntl | grep 7001


wKioL1Nthqizk9JEAABPxqONyQA177.jpg



4)配置mogstore
# mkdir /dfs/mogdata/dev1
# chown -R mogilefs.mogilefs /dfs/mogdata/dev1
# cd /etc/mogilefs
# vim mogstored.conf  修改以下內容
  docroot = /dfs/mogdata
# chown -R mogilefs.mogilefs mogstored.conf
# service mogstored start  啓動服務
# ss -tnlp


wKiom1Nth8bC8FrSAAAmi7Yscdo950.jpg


在trakers 中添加 mogstore存儲主機
#mogadm --trackers=172.16.13.2:7001 host add 172.16.13.2 --ip=172.16.13.2 --status=alive
# mogadm --trackers=172.16.13.2:7001 host list

wKioL1NtiDbydDFcAAAsT3JsUXE420.jpg

   此時已經實現172.16.13.2服務器便是tracker,也是mogstore存儲



將配置文件mogilefsd.conf  mogstored.conf 複製到 172.16.13.3 與172.16.13.4 上
#cd /etc/mogilefs
#scp * 172.16.13.3:/etc/mogilefs
#scp * 172.16.13.4:/etc/mogilefs


 三、172.16.13.3服務器配置



1) 安裝
 # cd /root  (該目錄已經有從 172.16.13.2傳送的全部rpm包)
 # yum -y install  *.rpm  perl-IO-AIO
2) 配置cheker
 # service mogilefsd start
 # ss -ntl | grep 7001
3)配置mogstore
 # mkdir -pv /dfs/mogdata/dev2  
 # chown -R mogilefs.mogilefs /dfs/mogdata/dev2
 # service mogstored start
 # ss -ntlp  查看 7500 7501端口偵聽
4)tracker中添加mogstore存儲主機
 # mogadm --trackers=172.16.13.3:7001 host add 172.16.13.3 --ip=172.16.13.3 --status=alive
 # mogadm --trackers=172.16.13.3:7001 host list

wKiom1NtiZPil1i7AACX7V6heCY780.jpg


  四、172.16.13.4服務器配置


1)安裝
 #cd  /root
 #yum -y install *.rpm perl-IO-AIO
2)配置tracker
 #service  mogilefsd start
 #ss -ntl | grep 7001
 配置文件無需更改
3)配置mogstore
 #mkdir -pv /dfs/mogdata/dev3
 #chown -R mogilefs.mogilefs /dfs/mogdata/dev3  建立mogstore數據目錄
 #service mogstored start
 # ss -ntlp  查看7500 7501端口
                                                                                                                                                                                                                                                                                                                                                                     
4)添加mystore存儲主機
# mogadm --trackers=172.16.13.4:7001 host add 172.16.13.4 --ip=172.16.13.4 --status=alive
# mogadm --trackers=172.16.13.4:7001 host list


wKioL1NtigviQINlAACly1pzuZE540.jpg


以上三個節點所有配置完 trackers 與 mystore ,接下來咱們添加三個節點上的設備、添加域、添加類文件

5)添加存儲設備
在172.16.13.4 tracker服務器配置便可 
# mogadm --trackers=172.16.13.4:7001 device add 172.16.13.2 1
# mogadm --trackers=172.16.13.4:7001 device add 172.16.13.3 2
# mogadm --trackers=172.16.13.4:7001 device add 172.16.13.4 3
# mogadm --trackers=172.16.13.4:7001 device list

wKiom1NtixzCp8YWAAEFgyezmZU111.jpg


6)分佈式系統添加domain 域
# mogadm --trackers=172.16.13.4:7001 domain add files
# mogadm --trackers=172.16.13.4:7001 domain add p_w_picpaths
# mogadm --trackers=172.16.13.4:7001 domain list

wKioL1Nti6iQUfKdAACI0eMYfl0595.jpg



7)在域(domain)中添加類(class)文件
### class 是在mystore中最小存儲與複製單元
   爲p_w_picpaths域建立幾個class文件
# mogadm --trackers=172.16.13.4:7001 class add p_w_picpaths class0 --mindevcount=2  至少2個副本
# mogadm --trackers=172.16.13.4:7001 class add p_w_picpaths class1 --mindevcount=2
# mogadm --trackers=172.16.13.4:7001 class add p_w_picpaths class2 --mindevcount=2
# mogadm --trackers=172.16.13.4:7001 class add p_w_picpaths class3 --mindevcount=2
# mogadm --trackers=172.16.13.4:7001 class list 查看建立的類文件

wKioL1NtjJDwkSSWAAFSmhkGqh0894.jpg


如今爲止,終於將mogilefs 集羣搭建完畢,接下來咱們配置nginx反向代理服務器


     五、Nginx服務器配置

基於第三方模塊ningx-mogilefs-mudule=master 實現http反向代理

1)下載源碼包nginx-1.4.7.tar.bz (自行官網下載便可)  
  下載nginx支持mogfile的第三方模塊 nginx-mogilefs-module-master.zip
                                                                                                                                                                                                                                                                               
2)編譯安裝
# tar -xf  nginx-1.4.7.tar.bz
# unzip nginx-mogilefs-module-master.zip
 建立nginx用戶與組
# gourpadd -r nginx
# useradd -r -g nginx nginx
 開始編譯安裝
#cd  nginx-1.4.7
#./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=../nginx-mogilefs-module-master
# make && make install
3) 爲nginx 提供服務腳本
# 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
                                                                                                                                                                                                                                                                          
 爲此腳本賦予執行權限:
# chmod +x /etc/rc.d/init.d/nginx
                                                                                                                                                                                                                                                                          
 添加至服務管理列表,並讓其開機自動啓動:
# chkconfig --add nginx
# chkconfig nginx on
                                                                                                                                                                                                                                                                          
 啓動服務並測試:
# service nginx start
                                                                                                                                                                                                                                                                          
# ss -ntl | grep 80


4 )在分佈式集羣系統上上傳幾個圖片和文件
   172.16.13.2服務器上操做便可由於它是三個trackers之一
# mogupload --trackers=172.16.13.2:7001 --domain=p_w_picpaths --key='/p_w_picpaths/1.png' --file='/usr/share/backgrounds/default_1920x1200.png'
# mogupload --trackers=172.16.13.2:7001 --domain=p_w_picpaths --key='/p_w_picpaths/2.png' --file='/usr/share/backgrounds/default_1920x1440.png'
# mogupload --trackers=172.16.13.2:7001 --domain=files --key='/file/fstab.html --file='/etc/fstab' 
# moglistkeys --trackers=172.16.13.2:7001 --domain=p_w_picpaths

wKioL1NtjjOS2F6fAAAaVqyHzSU187.jpg


# mogfileinfo --trackers=172.16.13.3:7001 --domain=p_w_picpaths --key='/p_w_picpaths/1.png'  查看圖片信息

wKiom1NtjuXjwqaqAADLUqOY8-k044.jpg



5) 編輯nginx配置文件
    在server段添加兩個location,一個負責圖片文件的訪問,一個負責文本文件的訪問控制
                                                                                                                                                                                                                                                   
        location ~* ^(/p_w_picpaths/.*)$  {
           mogilefs_tracker 172.16.13.3:7001;
           mogilefs_domain p_w_picpaths;
           mogilefs_pass $1 {
                proxy_pass $mogilefs_path;
                proxy_hide_header Content-Type;
                proxy_buffering off;
           }
         }
                                                                                                                                                                                                                                             
        location ~* ^(/file/.*)$ {
            mogilefs_tracker 172.16.13.2:7001;
            mogilefs_domain files;
            mogilefs_pass $1 {
                 proxy_pass $mogilefs_path;
                 proxy_hide_header Content-Type;
                 proxy_buffering off;
            }
         }
# service nginx restart 重讀配置文件


    客戶端測試:文本文件

wKioL1Ntj6TA-Yp8AAEJ2qcDupg750.jpg

    客戶端測試:圖片文件

wKiom1NtkFXgU1ImAAB9XO9ciYQ874.jpg

wKioL1NtkDbyUws1AABYRtc4lbo446.jpg

     nginx的反向代理實現


6)nginx 實現負載均衡調度
   http段添加一個upstream,server中調用便可
 #vim  /etc/nginx/nginx.conf 從新編輯配置文件增長以下內容
                                                                                                                                                                                                        
   upstream mogcluster {
        server 172.16.13.2:7001;
        server 172.16.13.3:7001;
        server 172.16.13.4:7001;
    }
       其中一個location調用定義好的upstream
         location ~* ^(/p_w_picpaths/.*)$  {
           mogilefs_tracker mogcluster;
           mogilefs_domain p_w_picpaths;
           mogilefs_pass $1 {
                proxy_pass $mogilefs_path;
                proxy_hide_header Content-Type;
                proxy_buffering off;
           }
         }
 #service nginx  restart


    客戶端測試

wKiom1NtkZuisKFQAABi9pkGO04177.jpg


    nginx負載均衡調度實現


  PS:已實現nginx對後端mogileFS分佈式集羣的反向代理與負載均衡調度,水平有限,項目並不複雜,還需完善(mysql能夠實現主從複製和讀寫分離,nginx服務器存在單點故障)若有錯誤之處請指出!

相關文章
相關標籤/搜索