• centos 6.5环境下分布式文件系统MogileFS工作原理及分布式部署实现过程


    MogileFS是一套高效的文件自动备份组件,由Six Apart开发,广泛应用在包括LiveJournal等web2.0站点上
    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。
       当下互联网飞速发展,海量并发所产生的数据量以几何方式增长,随着信息链接方式日益多样化,数据存储的结构也发生了变化,在这样的压力下我们不得不重新审视大量数据的存储所带来了巨大的挑战:
       1、数据采集:对于社交网站一般都是由用户上传的;
       2、数据存储:现在是数据量大爆炸时代,每天都会产生大量的数据,所以数据存储就成了一个大问题;
       3、数据搜索:如果说存储是考验数据的存储能力的话,那搜索就是考量计算机能力了,从大量的数据中搜索出来;
       4、数据共享:数据存储下来之后还要进行数据的共享问题,大量的数据该怎么共享这些数据呢;
       5、数据传输:而海量数据存储下来之后数据怎么用户与用户之间进行安全的传输;
       6、数据分析:数据的分析是了解我们过去的一些行为规范;
       7、数据可视化:而海量数据存储下来之后怎么样可以直观的展示在人们面前呢;
    分布式文件系统的几个难点:
       1、缺乏全局时钟、不过同步本身就存在时间差,很难做到步调一致,
       2、面对故障的独立性,分布式是由多个节点组成的,而每个节点都是独立工作的,一个节占故障度不会影响其它节点正常工作,
       3、如何去处理单点故障, 一是:做冗余,对单点做备份;二是:降低单点故障的影响范围
       4、事务类的挑战,在分布环境中怎么处理事务呢;ACID或2PI(两段式提交)、最终一致、BASE法则、CAP理论、Paxos算法;


    什么是两段式提交: 
       通过使用某种协议进行通信来完成分布式事务,被称为两段式提交。从名字上看,您可能已经知道有两个阶段:
    第一个阶段,即预提交:
       事务协调器给每个事务管理器发送准备操作的信号。
       事务管理器将操作(通常是数据更新)步骤(或细节)写入事务日志。如果失败,事务管理器使用这些步骤重复操作。
       事务管理器本地创建事务并通知资源管理器对资源(例如,数据库或消息服务器)执行操作。
       资源管理器执行操作并向事务管理器报告成功(准备提交信号)或失败(准备回滚)。
       资源管理器等待事务管理器进一步的指令。
       事务管理器向事务协调器报告成功或失败。
    第二阶段,即提交阶段:在第二阶段中,第一阶段的结果将传送给所有事务管理器。
       如果任何事务管理器报告失败,所有的事务参与者都必须回滚。
       事务协调器让所有事务管理器提交(或回滚)。
       所有事务管理器将提交或回滚信息传递给其资源管理器。
       资源管理器将成功或失败提示返回给事务管理器。
       事务管理器向事务协调器报告成功或失败。


    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的分布式过程,按照下图构建MogileFS分布式文件系统的结构,这里限于机器的原因,一些服务都整合在一起;

     第一步:安装MogileFS软件

    我们前面提到,它是由三部分组成,所以三个组件都得安装上,并且每个节点都做MogileFS和Mogstored;

       在这里先说此次的基本布局,192.168.8.39上安装nginx,192.168.8.40上安装MariaDB数据库,192.168.8.41和192.168.8.43上都安装了MogileFS和Mogstored,8.41和8.43都共同使用8.40上的MariaDB数据库,nginx做为前端接收用户请求并负载均衡到后端两个节点上


       在8.41上的安装和配置过程,修改好配置文件之后复制一份相同的配置文件到8.43节点上,因为它们的配置参数都是一样的:

    在 8.41 和8.43 分别安装 mofilefs和mofstored服务

      
    # yum install -y epel-release
    # yum install -y perl-Net-Netmask perl-IO-AIO
    # yum localinstall -y 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 MogileFS-Utils-2.19-1.el6.noarch.rpm  Perlbal-1.78-1.el6.noarch.rpm Perlbal-doc-1.78-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 


       # 安装好之后修改配置文件,只需要修改以下几项就可以了
       # mysql指使用的数据库是什么,MariaDB也是写mysql;mogdb指数据库名;host=192.168.8.40指定安装数据的地址

    # vim /etc/mogilefs/mogilefsd.conf
    db_dsn = DBI:mysql:mogdb:host=192.168.8.40
    db_user = moguser  # 指登录mogdb数据所使用的用户名
    db_pass = mogpass    # 登录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   # 把这项改一个特定的目录,以便存储数据,为提升系统性能最好是一个独立分区
    
    
    # mkdir -pv /dfs/mogdata/dev1  # 创建修改的docroot目录
    # chown -R mogilefs.mogilefs /dfs/mogdata/dev1 # 修改属主属组
    # chown -R mogilefs.mogilefs /var/run/mogilefsd/
    # cd /etc/mogilefs
    # scp mogilefsd.conf mogstored.conf root@192.168.8.43:/etc/mogilefs/  # 复制修改好的配置文件到node2的mogilefs目录下,覆盖即可,两个节点都安装配置好之后先不要启动服务,数据库还没有安装


    在8.43上的安装和配置,这里的配置文件由node1上复制过来就可以了;
    # mkdir -pv /dfs/mogdata/dev2  # 创建修改的docroot目录
    # chown -R mogilefs.mogilefs /var/run/mogilefsd/
    # chown -R mogilefs.mogilefs /dfs/mogdata/dev2 # 修改属主属组


    第二步:安装nginx和MariaDB

    这里安装Nginx需要编译安装,因为他需要装载第三方模块才可以使用mogilefs,MariaDB安装这里就不再说明了;

       在8.39节点上的安装步骤:


    # 解决依赖关系
    # yum -y groupinstall "Development Tools" "Server Platform Development"
    # yum -y install openssl-devel pcre-devel
    # groupadd -r nginx
    # useradd -r -g nginx nginx
    # tar xf nginx-1.4.7.tar.gz 


    下载nginx-mogilefs-module-master.zip 地址:https://github.com/vkholodkov/nginx-mogilefs-module
    # unzip nginx-mogilefs-module-master.zip 
    # cd nginx-1.4.7
    # ls
    auto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  man  README  src

    # ./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  # 这里要指定编译的模块
    # make && make install


    # 这里MariaDB安装过程不再说明了,可以参数前面的博文 centos6.5下编译安装mariadb-10.0.20:http://blog.csdn.net/reblue520/article/details/50562099
    编译安装好之后就可以可以启动MariaDB和去配置Nginx的相关配置了,还要给nginx提供一个服务脚本;
    # service mysqld start


    # 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


    测试访问一下nginx的页面:


    # chmod +x /etc/init.d/nginx
    # vim /etc/profile.d/nginx.sh
    export PATH=/usr/sbin/nginx:$PATH
    # . /etc/profile.d/nginx.sh
    
    
    # service nginx start
    
    
    # ss -tnl
    State       Recv-Q Send-Q                                                               Local Address:Port                                                                 Peer Address:Port 
    LISTEN      0      128                                                                              *:38573                                                                           *:*     
    LISTEN      0      128                                                                             :::111                                                                            :::*     
    LISTEN      0      128                                                                              *:111                                                                             *:*     
    LISTEN      0      128                                                                              *:80                                                                              *:*     
    LISTEN      0      128                                                                             :::22   :::* 
    



    第三步:连接上数据库,给两个用户授权:

    # mysql -uroot -p


    MariaDB [(none)]> GRANT ALL ON *.* TO 'root'@'192.168.%.%' IDENTIFIED BY 'mysqlpass';
    MariaDB [(none)]> GRANT ALL ON mogdb.* TO 'moguser'@'192.168.%.%' IDENTIFIED BY 'mogpass';
    MariaDB [(none)]> FLUSH PRIVILEGES;


    第四步:再到两个节点上初始化数据库,在其中一个上设置即可:

    # mogdbsetup --dbhost=192.168.8.40 --dbport=3306 --dbname=mogdb --dbrootuser=root --dbrootpass=mysqlpass --dbuser=moguser --dbpass=mogpass --yes


    # 可以再回到8.40上验证一下生成的数据库

    MariaDB [(none)]> 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     |
    +----------------------+

    第五步:在两个节点的其中一个上添加主机:

    将两个节点的mogilefsd和mogstored服务都启动起来
    # service mogilefsd start
    # service mogstored start
    # ss -tnl
    State      Recv-Q Send-Q                                                              Local Address:Port                                                                Peer Address:Port 
    LISTEN     0      128                                                                             *:7500                                                                           *:*     
    LISTEN     0      128                                                                             *:7501                                                                           *:*     
    LISTEN     0      128                                                                            :::111                                                                           :::*     
    LISTEN     0      128                                                                             *:111                                                                            *:*     
    LISTEN     0      128                                                                            :::22                                                                            :::*     
    LISTEN     0      128                                                                             *:22                                                                             *:*     
    LISTEN     0      128                                                                     127.0.0.1:631                                                                            *:*     
    LISTEN     0      128                                                                           ::1:631                                                                           :::*     
    LISTEN     0      128                                                                             *:7001                                                                           *:*     
    LISTEN     0      100                                                                           ::1:25                                                                            :::*     
    LISTEN     0      100                                                                     127.0.0.1:25                                                                             *:*     
    LISTEN     0      128                                                                             *:42848                                                                          *:*     
    LISTEN     0      128                                                                            :::56905                                                                         :::* 


    # 添加主机
    # mogadm --trackers=192.168.8.41:7001 host add 192.168.8.41 --ip=192.168.8.41 --status=alive
    # mogadm --trackers=192.168.8.41:7001 host add 192.168.8.43 --ip=192.168.8.43 --status=alive
    # mogadm --trackers=192.168.8.41:7001 host list
    192.168.8.41 [1]: alive
      IP:       192.168.8.41:7500
    
    
    192.168.8.43 [2]: alive
      IP:       192.168.8.43:7500

    # 再添加设备
    
    # mogadm --trackers=192.168.8.41:7001 device add 192.168.8.41 1
    # mogadm --trackers=192.168.8.41:7001 device add 192.168.8.43 2
    # mogadm --trackers=192.168.8.41:7001 device list
    192.168.8.41 [1]: alive
                        used(G)    free(G)   total(G)  weight(%)
       dev1:   alive      0.000      0.000      0.000        100
    
    
    192.168.8.43 [2]: alive
                        used(G)    free(G)   total(G)  weight(%)
       dev2:   alive      0.000      0.000      0.000        100
    
    
    # 添加域
    
    
    # mogadm --trackers=192.168.8.41:7001 domain add images
    # mogadm --trackers=192.168.8.41:7001 domain add files
    # mogadm --trackers=192.168.8.41:7001 domain add html
    # mogadm --trackers=192.168.8.41:7001 domain list
     domain               class                mindevcount   replpolicy   hashtype
    -------------------- -------------------- ------------- ------------ -------
     files                default                   2        MultipleHosts() NONE   
    
    
     html                 default                   2        MultipleHosts() NONE   
    
    
     images               default                   2        MultipleHosts() NONE  
    
    
    # 添加类
    # mogadm --trackers=192.168.8.41:7001 class add images class0 --mindevcount=2
    # mogadm --trackers=192.168.8.41: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   




    # 上传几张图片和测试的页面上去


    # mkdir -pv /var/www/html
    mkdir: created directory `/var/www'
    mkdir: created directory `/var/www/html'
    # vim /var/www/html/index.html
    
    
    <h1>www.chinasoft.com</h1>
    
    
    # mogupload --trackers=192.168.8.41:7001 --domain=images --key='1.png' --file='/usr/share/backgrounds/default_1920x1200.png' 
    # mogupload --trackers=192.168.8.41:7001 --domain=images --key='2.png' --file='/usr/share/backgrounds/wallpaper-six-2560x1240.png' 
    # mogupload --trackers=192.168.8.41:7001 --domain=images --key='/images/3.png' --file='/usr/share/backgrounds/centos_wallpaper_01_1920x1200.png' 
    # mogupload --trackers=192.168.8.41:7001 --domain=html --key='/files/index.html' --file='/var/www/html/index.html'
    # mogupload --trackers=192.168.8.41:7001 --domain=files --key='/files/index.html' --file='/var/www/html/index.html'
    # moglistkeys --trackers=192.168.8.41:7001 --domain=images
    /images/3.png
    1.png
    2.png
    # moglistkeys --trackers=192.168.8.43:7001 --domain=images
    /images/3.png
    1.png
    2.png
    # mogfileinfo --trackers=192.168.8.41: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://192.168.8.41:7500/dev1/0/000/000/0000000005.fid
     - http://192.168.8.43:7500/dev2/0/000/000/0000000005.fid




     可以复制这个地址在页面上测试一下,这里是每上传一个文件就都会在两个节点是都存一份,如果节点多的话它会根据定义的devcount自己选择节点存储几份,这样在一个节点掉了也可以在别的节点在有相同的资源可用;


    第六步:在前端的Nginx上配置访问控制,修改配置文件:

    # vim /etc/nginx/nginx.conf
     
    upstream mogcluster {
            server 192.168.8.41:7001;
            server 192.168.8.43:7001;
        }
    
    
        server {
            location / {
                root   html;
                index  index.html index.htm;
            }
    
    
            listen 80;
            server_name www.chinasoft.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;
                    }
            }




    然后在页面上测试访问刚才上传的文件以及图片:


    总结:
       最后还可以测试一下把一个节点mogstoed服务关闭,试着访问一下看另外正常工作的节点可不可以正常提供服务。


  • 相关阅读:
    [转]经典SQL语句大全
    listview分页
    verticalalign属性和用法
    在后台.cs页面往前台插入html代码的方法
    前台js改变Session的值(用ajax)
    2012.10笔记
    添加收藏夹(兼容部分)
    使textbox无法手动修改,但可以代码修改
    题目审批表
    任务书
  • 原文地址:https://www.cnblogs.com/reblue520/p/6239791.html
Copyright © 2020-2023  润新知