转自http://ximenfeibing.blog.51cto.com/8809812/1668596

参考http://guoting.blog.51cto.com/8886857/1561354

内容概述

1、分布式文件系统介绍

2、CAP理论

3、常见分布式文件系统介绍

4、MogileFS详细介绍

    4、1MogileFS组成

    4、2MogileFS特性

5、MogileFS实现

     5、1 node1配置Mariadb(过程略)

     5、2 node1配置tracker

     5、3 node2配置storage

     5、4  node3配置storage

     5、5 配置分布式集群

          5、5、1 添加主机

          5、5、2 添加设备

          5、5、3 定义domain和class

     5、6  验证分布式集群

6、MogileFS高可用

     6、1 node1配置storage

     6、2 node2配置tracker

     6、3 node3配置tracker

     6、4 验证MogileFS高可用

7、nginx反向代理MogileFS

    7、1 安装nginx

    7、2 设置反向代理

    7、3 设置负载均衡

1、分布式文件系统介绍

定义分布式存储系统是大量普通PC服务器通过Internet互联,对外作为一个整体提供存储服务

特性

·        可扩展:分布式存储系统可以扩展到几百台至几千台的集群规模,且随着集群规模的增长,系统整体性能表现为线性增长;

·        低成本:分布式存储系统的自动容错、自动负载均衡机制使其可以构建在普通PC机之上;另外,线性扩展能力也使得增加、减少机器非常方便,可以实现自动运维;

·        高性能:无论是针对整个集群还是单台服务器,都要求分布式系统具备高性能;

·        易用:分布式存储系统需要能够提供易用的对外接口;另外,也要求具备完善的监控、运维工具,并能方便的与其他系统集成,如从Hadoop云计算系统导入数据;

挑战:在于数据、状态信息的持久化,要求在自动迁移、自动容错、并发读写的过程中保证数据的一致性;

2、CAP理论

来自Berkerly的Eric Brewer教授提出了一个著名的CAP理论:一致性(Consistency),可用性(Availability)和分区容忍性(Tolerance of networkPartition)三者不能同时满足:

·        C:读操作总是能读取到之前完成的写操作结果,满足这个条件的系统成为强一致系统,这里的“之前”一般对同一个客户端而言;

·        A:读写操作在单台机器发生故障的情况下依然能够正常执行,而不需要等待发生故障的机器重启或者其上的服务迁移到其他机器;

·        P:机器故障、网络故障、机房停电等异常情况下仍然能够满足一致性和可用性;

分布式存储系统要求能够自动容错,即分区可容忍性总是需要满足的,因此,一致性和写操作的可用性就不能同时满足了,需要在这二者间权衡,是选择不允许丢失数据,保持强一致,还是允许少量数据丢失以获得更好的可用性;

3、常见的分布式文件系统介绍

GFS(Google File System):Google公司为了满足本公司需求而开发的基于Linux的专有分布式文件系统。由于其元数据是存储在内存中,所以在存储文件数量上注定不可能达到海量存储,主要是存储大文件使用。

HDFS (Hadoop Distributed File System):Hadoop的重要组成之一,几乎完全山寨GFS

TFS:淘宝自主研发,将元数据存储于关系型数据库或其它高性能存储中,从而能维护海量文件元数据;主要用于存储海量小文件,维护难度大

GlusterFS:去中心化的设计模式;擅长处理单个大文件

Ceph:Linux内核级实现的文件系统,而已经被直接收录进Linux内核;bug较多,稳定性不佳

MooseFS:FUSE,相对比较轻量级,对master服务器有单点依赖,用perl编写,性能相对较差,国内用的人比较多

MogileFS:元数据放在数据库中,擅长处理海量小文件,性能较好

FastDFS:轻量级分布式系统,擅长处理海量小文件

备注:此处介绍不是很详细,如果需要详细了解,可以参考百度百科

4、MogileFS详细介绍

4、1 MogileFS组成

MogileFS组成的三个组件:

    tracker:追踪元数据   元数据访问路由器

    database:存储元数据 

    storage:存储数据

traker:

    mogilefsd(守护进程),它的主要职责包括:

        replication:节点间文件的复制;

        deletion:删除文件

        queryworker:响应客户请求的文件元数据访问请求

        reaper:在存储失败后将文件复制请求重新放置于队列中

        monitor:监测主机和设备的健康状态

database:

    存储mogilefs的元数据,一般使用MySQL; 建议使用冗余方案以保证其可用性;(MMM, MHA)

    mogilefs专门提供了数据结构管理工具mogdbsetup;

storage:

    mogstored(进程名),一个准备停当的mogstored节点可通过mogadm命令添加至现在的集群中;

    存储节点需定义“设备(dev)”用作存储空间;每个“设备”在当前集群都需要通过一个惟一的DevID来标识;

client:

    客户端用于与mogilefs建立通信,完成数据存取;


架构拓扑如下所示:

wKioL1W7EIzAV-gLAAFVon5oj2A706.jpg

4、2 MogileFS特性:

    (1)工作于应用层:http, nfs;

    (2)无单点:三大组件(tracker,mogstore,database)皆可实现高可用;

    (3)自动完成文件复制:复制的最小单位不是文件,而是class;基于不同的class,文件可以被自动的复制到多个有足够存储空间的存储节点上

    (4)传输无需特殊协议:可以通过NFS或HTTP协议进行通信;

    (5)名称空间:文件通过一个给定的key来确定,是一个全局的命名空间;没有目录,基于域实现文件隔离

    (6)不共享任何数据:无需通过昂贵的SAN来共享磁盘,每个存储节点只需维护自己所属的存储设备(device)即可

两个关键术语:

    domain:name space,命名空间

         一个MogileFS可以有多个Domain用来存放不同文件(大小、类型),同一个Domain内,key必须唯一

         不同Domain内,key可以相同

    class:最小复制单元

        文件属性管理器,定义文件存储在不同设备上的份数

5、MogileFS实现

环境拓扑

wKiom1W7E47SXuqcAADAxjkezA4949.jpg

IP地址配置情况:

node1    192.168.3.75

node2    192.168.3.76

node2    192.168.3.77

系统环境

[root@node1 ~]# cat /etc/redhat-release 
CentOS release 6.4 (Final)
[root@node1 ~]# uname -r
2.6.32-358.el6.x86_64
[root@node1 ~]# uname -m
x86_64

5、1 node1配置mysql

这里使用脚本进行编译安装,脚本内容如下

[root@node1 ~]# cat mysql_install.sh 
#!/bin/bash
 
DATADIR='/data/mysql/data'
VERSION='mysql-5.5.37'
export LANG=zh_CN.UTF-8
 
#Source function library.
. /etc/init.d/functions
 
#camke install mysql5.5.X
install_mysql(){
        read -p "please input a password for root: " PASSWD
        if [ ! -d $DATADIR ];then
                mkdir -p $DATADIR
        fi
        yum install cmake make gcc-c++ bison-devel ncurses-devel -y
        id mysql &>/dev/null
        if [ $? -ne 0 ];then
                useradd mysql -s /sbin/nologin -M
        fi
        #useradd mysql -s /sbin/nologin -M
        #change datadir owner to mysql
        chown -R mysql.mysql $DATADIR
        cd
        #wget http://mirrors.sohu.com/mysql/MySQL-5.5/mysql-5.5.38.tar.gz
        tar xf $VERSION.tar.gz
        cd $VERSION
        cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/$VERSION \
        -DMYSQL_DATADIR=$DATADIR \
        -DMYSQL_UNIX_ADDR=$DATADIR/mysql.sock \
        -DDEFAULT_CHARSET=utf8 \
        -DDEFAULT_COLLATION=utf8_general_ci \
        -DENABLED_LOCAL_INFILE=ON \
        -DWITH_INNOBASE_STORAGE_ENGINE=1 \
        -DWITH_FEDERATED_STORAGE_ENGINE=1 \
        -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
        -DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 \
        -DWITHOUT_PARTITION_STORAGE_ENGINE=1
        make && make install
        if [ $? -ne 0 ];then
                action "install mysql is failed"  /bin/false
                exit $?
        fi
        sleep 2
        #link
        ln -s /usr/local/$VERSION/ /usr/local/mysql
        ln -s /usr/local/mysql/bin/* /usr/bin/
        #copy config and start file
        /bin/cp /usr/local/mysql/support-files/my-small.cnf /etc/my.cnf
        cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
        chmod 700 /etc/init.d/mysqld
        #init mysql
        /usr/local/mysql/scripts/mysql_install_db  --basedir=/usr/local/mysql --datadir=$DATADIR --user=mysql
        if [ $? -ne 0 ];then
                action "install mysql is failed"  /bin/false
                exit $?
        fi
        #check mysql
        /etc/init.d/mysqld start
        if [ $? -ne 0 ];then
                action "mysql start is failed"  /bin/false
                exit $?
        fi
        chkconfig --add mysqld
        chkconfig mysqld on
        /usr/local/mysql/bin/mysql -e "update mysql.user set password=password('$PASSWD') where host='localhost' and user='root';"
        /usr/local/mysql/bin/mysql -e "update mysql.user set password=password('$PASSWD') where host='127.0.0.1' and user='root';"
        /usr/local/mysql/bin/mysql -e "delete from mysql.user where password='';"
        /usr/local/mysql/bin/mysql -e "flush privileges;"
        #/usr/local/mysql/bin/mysql -e "select version();" >/dev/null 2>&1
        if [ $? -eq 0 ];then
                echo "+---------------------------+"
                echo "+------mysql安装完成--------+"
                echo "+---------------------------+"
        fi
        #/etc/init.d/mysqld stop
}
 
install_mysql

配置root用户允许远程连接

mysql> grant all on *.* to 'root'@'192.168.3.%' identified by 'mogilefs' with grant option;
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

5、2 node1配置tracker

安装如下软件包,虽然只是配置tracker,但还是安装了storage的包,是因为后面做高可用时用到

MogileFS-Server-2.46-2.el6.noarch.rpm            #通行组件
MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm  #traker
MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm  #storage
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               #依赖包

安装命令如下,需要epel源的依赖

[root@node1 ~]# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@node1 ~]# sed -i 's@#b@b@g' /etc/yum.repos.d/epel.repo
[root@node1 ~]# sed  -i 's@mirrorlist@#mirrorlist@g' /etc/yum.repos.d/epel.repo
[root@node1 ~]# yum --nogpgcheck localinstall *.rpm -y

由于node1是做tracker的,用到的主要程序包是MogileFS-Server-mogilefsd,其他和配置tracker没有太大关系,MogileFS-Server-mogilefsd生成的主要文件

[root@node1 ~]# rpm -ql MogileFS-Server-mogilefsd
/etc/mogilefs/mogilefsd.conf    #主配置文件
/etc/rc.d/init.d/mogilefsd      #启动脚本
/usr/bin/mogdbsetup              #数据库初始化工具
/usr/bin/mogilefsd               #mogilefsd主进程

初始化MogileFS数据库:使用可以连接到Mariadb的用户和密码,创建一个MogileFS使用的数据库和数据库的管理用户以及设置密码

[root@node1 ~]# mogdbsetup --dbhost=192.168.3.75 --dbrootuser=root --dbrootpass=mogilefs --dbname=mogdb --dbuser=moguser --dbpass=mogpass

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 'mogdb'? [Y/n]: y

Grant all privileges to user 'moguser', connecting from anywhere, to the mogilefs database 'mogdb'? [Y/n]: y

验证初始化mysql:登录数据库查看mogdb数据库自动创建,而且库中自动创建了一些表

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mogdb              |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> use mogdb;
Database changed

mysql> 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.01 sec)

修改mogilefsd.conf文件设置连接Mariadb的用户名和密码,mogilefsd监听的地址和端口,启用的一些线程

[root@node1 ~]# egrep -v "^$|^#" /etc/mogilefs/mogilefsd.conf 
daemonize = 1
pidfile = /var/run/mogilefsd/mogilefsd.pid
db_dsn = DBI:mysql:mogdb:host=192.168.3.75        #DBI:perl连接mysql的驱动,mysql数据库类型,mogdb连接的数据库,host不解释
db_user = moguser                                 #连接数据库的用户,初始化的时候创建的
db_pass = mogpass                                 #连接数据库的密码,初始化的时候创建的
listen = 192.168.3.75:7001                        #mogilefsd监听的地址
conf_port = 7001                                  #监听的端口
query_jobs = 10                                   #启用的请求线程,为10表示只能并发10个客户端;注意客户端不是用户访问量,而是连接使用mogilefsd的服务器
delete_jobs = 1                                   #用于删除的线程
replicate_jobs = 5                                #用于作复制的线程数量
reaper_jobs = 1                                   #在存储失败后将文件复制请求重新放置于队列中的线程

设置完成启动服务并验证7001端口已经启动

[root@node1 ~]# service mogilefsd start
Starting mogilefsd                                         [  OK  ]
[root@node1 ~]# netstat -tunlp |grep mogile
tcp        0      0 192.168.3.75:7001           0.0.0.0:*                   LISTEN      11543/mogilefsd     
[root@node1 ~]# chkconfig mogilefsd on

5、3 node2配置storage

安装如下软件包,配置storage主要用到的软件包是MogileFS-Server-mogstored

MogileFS-Server-2.46-2.el6.noarch.rpm             #通用组件
MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm  #tracker
MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm  #storage
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               #依赖包

安装命令如下,需要epel源的依赖

[root@node2 ~]# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@node2 ~]# sed -i 's@#b@b@g' /etc/yum.repos.d/epel.repo
[root@node2 ~]# sed  -i 's@mirrorlist@#mirrorlist@g' /etc/yum.repos.d/epel.repo
[root@node2 ~]# yum install --nogpgcheck localinstall *.rpm -y

Mogstored依赖与perl-IO-AIO这个包,需要额外安装,否则mogstored无法正常启动

[root@node2 ~]# yum -y install perl-IO-AIO

MogileFS-Server-mogstored生成的文件

[root@node2 ~]# rpm -ql MogileFS-Server-mogstored
/etc/mogilefs/mogstored.conf    #主配置文件
/etc/rc.d/init.d/mogstored      #脚本文件
/usr/bin/mogautomount            #自动挂载的工具
/usr/bin/mogstored                #主程序

创建一个目录准备存储文件,并且设置属主和属组为mogilefs,否则tracker节点会无法读取数据

[root@node2 ~]# mkdir /mogstore
[root@node2 ~]# chown -R mogilefs.mogilefs /mogstore/

将存储目录挂载到单独的分区

[root@node2 ~]# tail -1 /etc/fstab 
/dev/sdb1		/mogstore               ext4    defaults        0 0
[root@node2 ~]# mount -a
[root@node2 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda3             195G  1.3G  184G   1% /
tmpfs                 242M     0  242M   0% /dev/shm
/dev/sda1             194M   28M  156M  16% /boot
/dev/sdb1              20G  172M   19G   1% /mogstore

在存储目录创建设备编号目录,注意此目录各个节点不能重名

[root@node2 ~]# mkdir /mogstore/dev2

修改配置文件

[root@node2 ~]# cat /etc/mogilefs/mogstored.conf 
maxconns = 10000                        #最大并发连接数
httplisten = 0.0.0.0:7500               #http协议监听的端口
mgmtlisten = 0.0.0.0:7501               #管理监听的端口
docroot = /mogstore                     #文件存储的目录

设置完成启动服务,并验证端口是否正常启动

[root@node2 ~]# chkconfig mogstored on
[root@node2 ~]# service mogstored start
Starting mogstored                                     [  OK  ]
[root@node2 ~]# netstat -tunlp |grep mogs
tcp        0      0 0.0.0.0:7500                0.0.0.0:*                   LISTEN      1552/mogstored      
tcp        0      0 0.0.0.0:7501                0.0.0.0:*                   LISTEN      1552/mogstored

5、4 node3配置storage

安装如下软件包

MogileFS-Server-2.46-2.el6.noarch.rpm            #通用组件
MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm  #tracker
MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm  #storage
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               #依赖包

安装命令如下,需要epel依赖包

[root@node3 ~]# rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[root@node3 ~]# sed -i 's@#b@b@g' /etc/yum.repos.d/epel.repo 
[root@node3 ~]# sed  -i 's@mirrorlist@#mirrorlist@g' /etc/yum.repos.d/epel.repo
[root@node3 ~]# yum --nogpgcheck localinstall *.rpm -y

Mogstored依赖与perl-IO-AIO这个包,所以需要额外安装

[root@node3 ~]# yum -y install perl-IO-AIO

创建一个目录准备存储文件,并设置属主和属组为mogilefs

[root@node3 ~]# mkdir /mogstore
[root@node3 ~]# chown -R mogilefs.mogilefs /mogstore/

将存储目录挂载到单独的分区

[root@node3 ~]# tail -1 /etc/fstab 
/dev/sdb1		/mogstore               ext4    defaults        0 0
[root@node3 ~]# mount -a
[root@node3 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda3             195G  1.3G  184G   1% /
tmpfs                 242M     0  242M   0% /dev/shm
/dev/sda1             194M   28M  156M  16% /boot
/dev/sdb1              20G  172M   19G   1% /mogstore

在存储目录创建设备编号目录,注意此目录各个节点不能重名

[root@node3 ~]# mkdir /mogstore/dev3

修改配置文件

[root@node3 ~]# cat /etc/mogilefs/mogstored.conf 
maxconns = 10000
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /mogstore

设置完成启动服务,并验证端口是否正常启动

[root@node3 ~]# chkconfig mogstored on
[root@node3 ~]# service mogstored start
Starting mogstored                                         [  OK  ]
[root@node3 ~]# netstat -tunlp |grep mogs
tcp        0      0 0.0.0.0:7500                0.0.0.0:*                   LISTEN      1597/mogstored      
tcp        0      0 0.0.0.0:7501                0.0.0.0:*                   LISTEN      1597/mogstored

5、5 配置分布式集群

查看MogileFS-Utils生成的命令,只列出常用的命令

#node1上的操作
[root@node1 ~]# rpm -ql MogileFS-Utils
/usr/bin/mogadm            #MogileFS管理工具,可以实现将mogstored加入到mogilefsd
/usr/bin/mogdelete        #删除文件
/usr/bin/mogfetch         #获取文件
/usr/bin/mogfileinfo      #查看文件
/usr/bin/mogupload         #上传文件

Mogadm命令的常用功能:

mogadm check             #状态检测

mogadm stats             #显示MogileFS的状态统计信息

mogadm host ...         #管理主机

mogadm device ...       #管理设备

mogadm domain ...       #管理域

mogadm class ...        #管理类

mogadm slave ...        #管理复制

mogadm fsck ...         #文件系统检查和修复

mogadm rebalance ...   #重新均衡(MogileFS运行时间久了mogstored存储的数据量可能不一样,重新均衡一下各个节点的数据就差不多了)

mogadm settings ...    #设置文件复制数

说明:使用mogadm help或者man mogadm可以查看mogadm命令的详细使用说明

5、5、1 添加主机

向集群中添加主机,将node2和node3添加到集群中

[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 host add node2 --ip=192.168.3.76 --status=alive
[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 host add node3 --ip=192.168.3.77 --status=alive
#说明
add:表示添加主机
node2:表示主机名,这个可以随便写
--ip:表示添加的主机地址
--status=alive:表示添加之后的状态为上线

#添加完成查看主机列表已经有了主机
[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 host list
node2 [1]: alive
  IP:       192.168.3.76:7500

node3 [2]: alive
  IP:       192.168.3.77:7500

5、5、2 添加设备

节点虽然添加完成了,但是还不能存储数据,如果想存储数据需要追踪存储节点上面的设备

[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 device add node2 2
[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 device add node3 3

#说明
add:表示添加设备
node2:节点名称,必须和添加主机时保持一致
2:添加的dev设备编号,这是上文中要求保持唯一的设备号

#添加完成查看device列表就已经出现了设备
[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 device list
node2 [1]: alive
                    used(G)    free(G)   total(G)  weight(%)
   dev2:   alive      0.000      0.000      0.000        100

node3 [2]: alive
                    used(G)    free(G)   total(G)  weight(%)
   dev3:   alive      0.000      0.000      0.000        100

补充:一开始不小心将node3节点的设备,添加为了dev4,然后由添加了dev3,结果node3就出现了dev3和dev4两个设备

[root@node1 ~]# mogadm --trackers=172.16.4.100:7001device add node3 4
[root@node1 ~]# mogadm --trackers=172.16.4.100:7001device list
node2 [1]: alive
                   used(G)    free(G)   total(G) weight(%)
   dev2:   alive     0.000      0.000      0.000        100
  
node3 [2]: alive
                   used(G)    free(G)   total(G) weight(%)
   dev3:   alive     0.042      27.866      27.908        100
   dev4:   alive     0.042      27.866     27.908        100

删除方法:这里没有deleted命令,需要使用mark将dev4标记为dead状态就删除了

[root@node1 ~]# mogadm --trackers=172.16.4.100:7001device mark node3 4 dead

5、5、3 定义domain和class

定义名称空间(domain):

[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 domain add p_w_picpaths
[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 domain add conffiles
[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 domain list
 domain               class                mindevcount   replpolicy   hashtype
-------------------- -------------------- ------------- ------------ -------
 conffiles            default                   2        MultipleHosts() NONE   

 p_w_picpaths               default                   2        MultipleHosts() NONE 
 
#说明
domain:domain的名字
class:domain创建完成之后会自动创建一个class,所有的文件都存放在class中
mindevcount:最小复制单元;为2表示上传的文件最少存储两个副本
replpolicy:复制策略,MultipleHosts()表示多主机实现复制,这里不用管为默认即可
hashtype:class在命名时是使用哈希进行计算的,这里表示哈希算法,NONE表示没有使用哈希算法

定义class:

由于创建domain会自动创建class,所以会出现class

[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 class list
 domain               class                mindevcount   replpolicy   hashtype
-------------------- -------------------- ------------- ------------ -------
 conffiles            default                   2        MultipleHosts() NONE   

 p_w_picpaths               default                   2        MultipleHosts() NONE

新添加一个class

[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 class add p_w_picpaths nc1 --mindevcount=2
[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 class list
 domain               class                mindevcount   replpolicy   hashtype
-------------------- -------------------- ------------- ------------ -------
 conffiles            default                   2        MultipleHosts() NONE   

 p_w_picpaths               default                   2        MultipleHosts() NONE   
 p_w_picpaths               nc1                       2        MultipleHosts() NONE  
 #最下面的是新添加的class,只能添加在domain上面

5、6 验证分布式系统

这个时候分布式文件系统就搭建好了,可以使用mogupload命令上传文件测试

[root@node1 ~]# mogupload --trackers=192.168.3.75:7001 --domain=conffiles --key='/fstab.txt' --file='/etc/fstab'
Error opening MogileFS file: no_devices No devices found to store file at /usr/bin/mogupload line 83, <Sock_192.168.3.75:7001> line 1.

#报错,我查看了一下node2和node2的/mogstore权限
[root@node3 ~]# ll /mogstore/
total 20
drwxr-xr-x 2 root root  4096 Jul 31 15:44 dev3
drwx------ 2 root root 16384 Jul 31 15:43 lost+found

#执行命令node2和node3都要执行
[root@node3 ~]# chown -R mogilefs.mogilefs /mogstore/

#重新上传文件
[root@node1 ~]# mogupload --trackers=192.168.3.75:7001 --domain=conffiles --key='/fstab.txt' --file='/etc/fstab'

#说明
--domain=conffiles:表示存储到p_w_picpaths这个domain中
--key='/fstab.txt':访问文件的URL地址
--file:本地上传的文件

查看上传文件的信息,在node1和node2这两个节点都有了文件

[root@node1 ~]# mogfileinfo --trackers=192.168.3.75:7001 --domain=conffiles --key='/fstab.txt'
- file: /fstab.txt
     class:              default
  devcount:                    2
    domain:            conffiles
       fid:                    2
       key:           /fstab.txt
    length:                  805
 - http://192.168.3.76:7500/dev2/0/000/000/0000000002.fid
 - http://192.168.3.77:7500/dev3/0/000/000/0000000002.fid

这个时候分别访问下面的两个URL就可以出现刚刚上传的文件了

 - http://192.168.3.76:7500/dev2/0/000/000/0000000002.fid

 - http://192.168.3.77:7500/dev3/0/000/000/0000000002.fid

访问结果

#访问node2上的文件
[root@nginx ~]# curl http://192.168.3.76:7500/dev2/0/000/000/0000000002.fid

#
# /etc/fstab
# Created by anaconda on Fri Jul 31 13:49:48 2015
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=fe369058-0853-4ae2-bd3b-44a5f1f5eb43 /                       ext4    defaults        1 1
UUID=09090dff-3a43-4c6b-89d1-f976a41b542d /boot                   ext4    defaults        1 2
UUID=22651027-cd8f-4cb6-abb9-0b6d203894c5 swap                    swap    defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0

#访问node3上的文件
[root@nginx ~]# curl http://192.168.3.77:7500/dev3/0/000/000/0000000002.fid

#
# /etc/fstab
# Created by anaconda on Fri Jul 31 13:49:48 2015
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=fe369058-0853-4ae2-bd3b-44a5f1f5eb43 /                       ext4    defaults        1 1
UUID=09090dff-3a43-4c6b-89d1-f976a41b542d /boot                   ext4    defaults        1 2
UUID=22651027-cd8f-4cb6-abb9-0b6d203894c5 swap                    swap    defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0

不光可以上传文件,还可以下载文件,使用mogfetch指明domain是那个,key路径,使用file在指明下载之后存储到本地的那里即可

[root@node1 ~]# mogfetch --trackers=192.168.3.75:7001 --domain=conffiles --key='/fstab.txt' --file='/root/fstab'
[root@node1 ~]# ll /root/fstab 
-rw-r--r-- 1 root root 805 Jul 31 16:36 /root/fstab

6、Mogilefsd高可用

Node1,node2,node3这三个节点否启动mogilefsd和mogstored,使客户端无论访问那一个节点都可以获取到数据,而且replpolicy设置最少2份,计算是一台节点故障下线其他节点也可以继续提供服务。

wKioL1W7OECTvVipAAC_EWoAlEY911.jpg

6、1 node1配置mogstored

手动安装mogstored的依赖包,如果不安装此包,启动mogstroed时端口不会正常启动,存储的包前面已经安装过了

[root@node1 ~]# yum install perl-IO-AIO -y

创建存储目录并挂载

[root@node1 ~]# mkdir /mogstore
[root@node1 ~]# tail -1 /etc/fstab 
/dev/sdb1		/mogstore               ext4    defaults        0 0
[root@node1 ~]# mount -a
[root@node1 ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda3             195G  2.4G  183G   2% /
tmpfs                 242M     0  242M   0% /dev/shm
/dev/sda1             194M   28M  156M  16% /boot
/dev/sdb1              20G  172M   19G   1% /mogstore

创建设备目录并授权mogilefs用户

[root@node1 ~]# mkdir /mogstore/dev1
[root@node1 ~]# chown -R mogilefs.mogilefs /mogstore/

修改配置文件,指定存储目录位置

[root@node1 ~]# cat /etc/mogilefs/mogstored.conf 
maxconns = 10000
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /mogstore

启动服务

[root@node1 ~]# chkconfig mogstored on
[root@node1 ~]# service mogstored start
Starting mogstored                                         [  OK  ]
[root@node1 ~]# netstat -tunlp |grep mogst
tcp        0      0 0.0.0.0:7500                0.0.0.0:*                   LISTEN      1833/mogstored      
tcp        0      0 0.0.0.0:7501                0.0.0.0:*                   LISTEN      1833/mogstored

配置完成之后使用mogadm命令将自己也添加到集群中

[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 host add node1 --ip=192.168.3.75 --status=alive
[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 host list
node2 [1]: alive
  IP:       192.168.3.76:7500

node3 [2]: alive
  IP:       192.168.3.77:7500

node1 [3]: alive
  IP:       192.168.3.75:7500

添加node1的设备到集群中

[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 device add node1 1
[root@node1 ~]# mogadm --trackers=192.168.3.75:7001 device list
node2 [1]: alive
                    used(G)    free(G)   total(G)  weight(%)
   dev2:   alive      0.168     18.512     18.680        100

node3 [2]: alive
                    used(G)    free(G)   total(G)  weight(%)
   dev3:   alive      0.168     18.512     18.680        100

node1 [3]: alive
                    used(G)    free(G)   total(G)  weight(%)
   dev1:   alive      0.167     18.513     18.680        100

由于node2和node3节点需要配置mogilefsd需要把node1上面的配置文件直接拷贝过去,省的node2和node3节点修改

[root@node1 ~]# scp /etc/mogilefs/mogilefsd.conf 192.168.3.76:/etc/mogilefs/  
[root@node1 ~]# scp /etc/mogilefs/mogilefsd.conf 192.168.3.77:/etc/mogilefs/

6、2 node2配置mogilefsd

由于node1节点已经将配置文件拷贝过来了,所以直接修改配置文件的监听地址即可,其他选项无需修改

[root@node2 ~]# egrep -v "^$|^#" /etc/mogilefs/mogilefsd.conf 
daemonize = 1
pidfile = /var/run/mogilefsd/mogilefsd.pid
db_dsn = DBI:mysql:mogdb:host=192.168.3.75
db_user = moguser
db_pass = mogpass
listen = 192.168.3.76:7001
conf_port = 7001
query_jobs = 10
delete_jobs = 1
replicate_jobs = 5
reaper_jobs = 1

设置完成启动服务即可

[root@node2 ~]# chkconfig mogilefsd on
[root@node2 ~]# service mogilefsd start
Starting mogilefsd                                         [  OK  ]
[root@node2 ~]# netstat -tunlp |grep mogil
tcp        0      0 192.168.3.76:7001           0.0.0.0:*                   LISTEN      23707/mogilefsd

查看集群状态

[root@node2 ~]# mogadm --trackers=192.168.3.76:7001 host list
node2 [1]: alive
  IP:       192.168.3.76:7500

node3 [2]: alive
  IP:       192.168.3.77:7500

node1 [3]: alive
  IP:       192.168.3.75:7500

[root@node2 ~]# mogadm --trackers=192.168.3.76:7001 device list
node2 [1]: alive
                    used(G)    free(G)   total(G)  weight(%)
   dev2:   alive      0.168     18.512     18.680        100

node3 [2]: alive
                    used(G)    free(G)   total(G)  weight(%)
   dev3:   alive      0.168     18.512     18.680        100

node1 [3]: alive
                    used(G)    free(G)   total(G)  weight(%)
   dev1:   alive      0.168     18.512     18.680        100

[root@node2 ~]# mogadm --trackers=192.168.3.76:7001 class list
 domain               class                mindevcount   replpolicy   hashtype
-------------------- -------------------- ------------- ------------ -------
 conffiles            default                   2        MultipleHosts() NONE   

 p_w_picpaths               default                   2        MultipleHosts() NONE   
 p_w_picpaths               nc1                       2        MultipleHosts() NONE

6、3 node3配置mogilefsd

同node2只需要修改监听地址

[root@node3 ~]# egrep -v "^$|^#" /etc/mogilefs/mogilefsd.conf 
daemonize = 1
pidfile = /var/run/mogilefsd/mogilefsd.pid
db_dsn = DBI:mysql:mogdb:host=192.168.3.75
db_user = moguser
db_pass = mogpass
listen = 192.168.3.77:7001
conf_port = 7001
query_jobs = 10
delete_jobs = 1
replicate_jobs = 5
reaper_jobs = 1

启动服务即可

[root@node3 ~]# chkconfig mogilefsd on
[root@node3 ~]# service mogilefsd start
Starting mogilefsd                                         [  OK  ]
[root@node3 ~]# netstat -tunlp |grep mogi
tcp        0      0 192.168.3.77:7001           0.0.0.0:*                   LISTEN      2344/mogilefsd

6、4 验证MogileFS的高可用

在三个节点各自配置好了tracker和storage之后高可用的MogileFS就配置完成了。

验证方法如下:无论使用mogadm连接那一个节点,都可以看到节点中包含了三个主机

[root@node3 ~]# mogadm --trackers=192.168.3.75:7001 host list
node2 [1]: alive
  IP:       192.168.3.76:7500

node3 [2]: alive
  IP:       192.168.3.77:7500

node1 [3]: alive
  IP:       192.168.3.75:7500

[root@node3 ~]# mogadm --trackers=192.168.3.76:7001 host list
node2 [1]: alive
  IP:       192.168.3.76:7500

node3 [2]: alive
  IP:       192.168.3.77:7500

node1 [3]: alive
  IP:       192.168.3.75:7500

[root@node3 ~]# mogadm --trackers=192.168.3.77:7001 host list
node2 [1]: alive
  IP:       192.168.3.76:7500

node3 [2]: alive
  IP:       192.168.3.77:7500

node1 [3]: alive
  IP:       192.168.3.75:7500

上传文件验证,由于只是设置两个复制份数,所以上传的文件会随机出现在两个节点中

[root@node3 ~]# mogupload --trackers=192.168.3.75:7001,192.168.3.76:7001,192.168.3.77:7001 --domain=conffiles --key='/issue' --file='/etc/issue'
[root@node3 ~]# mogfileinfo --trackers=192.168.3.75:7001,192.168.3.76:7001,192.168.3.77:7001 --domain=conffiles --key='/issue'
- file: /issue
     class:              default
  devcount:                    2
    domain:            conffiles
       fid:                    5
       key:               /issue
    length:                   47
 - http://192.168.3.75:7500/dev1/0/000/000/0000000005.fid
 - http://192.168.3.76:7500/dev2/0/000/000/0000000005.fid
[root@node3 ~]# mogfileinfo --trackers=192.168.3.75:7001,192.168.3.76:7001,192.168.3.77:7001 --domain=conffiles --key='/fstab.txt'
- file: /fstab.txt
     class:              default
  devcount:                    2
    domain:            conffiles
       fid:                    2
       key:           /fstab.txt
    length:                  805
 - http://192.168.3.77:7500/dev3/0/000/000/0000000002.fid
 - http://192.168.3.76:7500/dev2/0/000/000/0000000002.fid

7、使用nginx反向代理MogileFS

拓扑图:

wKioL1W7PzeChPysAADAnVuJgoA534.jpg

nginx IP地址:192.168.3.78

系统环境和node节点一致

7、1 安装nginx

Nginx默认不支持MogileFS的配置,需要在编译nginx时指定nginx_mogilefs_module模块才可以代理MogileFS

nginx的mogilefs模块官方配置地址http://www.grid.net.ru/nginx/mogilefs.en.html

下载mogilefs模块和nginx源码安装包

[root@nginx ~]# wget http://www.grid.net.ru/nginx/download/nginx_mogilefs_module-1.0.4.tar.gz
[root@nginx ~]# wget http://nginx.org/download/nginx-1.6.2.tar.gz

编译安装nginx

[root@nginx ~]# useradd nginx
[root@nginx ~]# mkdir /var/tmp/nginx/client -p
[root@nginx ~]# yum -y install pcre-devel
[root@nginx ~]# tar xf nginx-1.6.2.tar.gz 
[root@nginx ~]# tar xf nginx_mogilefs_module-1.0.4.tar.gz    #编译nginx之前需要先解压出来,编译nginx的时候需要用
[root@nginx ~]# cd nginx-1.6.2

编译配置,这里需要指定MogileFS的模块位置

[root@nginx nginx-1.6.2]# ./configure \
>  --prefix=/usr/local/nginx \
>  --sbin-path=/usr/local/nginx/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=../nginx_mogilefs_module-1.0.4    #编译时一定要使用这一项指明mogilefs模块的解压目录位置
[root@nginx nginx-1.6.2]# make && make install

编译完成提供nginx启动脚本

[root@nginx ~]# cat /etc/init.d/nginx 
#! /bin/sh
# chkconfig: 2345 55 25
# Description: Startup script for nginx webserver on Debian. Place in /etc/init.d and
# run 'update-rc.d -f nginx defaults', or use the appropriate command on your
# distro. For CentOS/Redhat run: 'chkconfig --add nginx'


PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=nginx
NGINX_BIN=/usr/local/nginx/sbin/$NAME
CONFIGFILE=/etc/nginx/nginx.conf
PIDFILE=/usr/local/nginx/logs/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

case "$1" in
	start)
		echo -n "Starting $NAME... "

		if netstat -tnpl | grep -q nginx;then
	        echo "$NAME (pid `pidof $NAME`) already running."
	        exit 1
		fi

		$NGINX_BIN -c $CONFIGFILE

		if [ "$?" != 0 ] ; then
			echo " failed"
			exit 1
		else
			echo " done"
		fi
	;;

	stop)
		echo -n "Stoping $NAME... "

		if ! netstat -tnpl | grep -q nginx; then
			echo "$NAME is not running."
			exit 1
		fi

		$NGINX_BIN -s stop

		if [ "$?" != 0 ] ; then
			echo " failed. Use force-quit"
			exit 1
		else
			echo " done"
		fi
	;;

	status)
		if netstat -tnpl | grep -q nginx; then
			PID=`pidof nginx`
			echo "$NAME (pid $PID) is running..."
		else
			echo "$NAME is stopped"
			exit 0
		fi
	;;

	force-quit)
		echo -n "Terminating $NAME... "

		if ! netstat -tnpl | grep -q nginx; then
			echo "$NAME is not running."
			exit 1
		fi

		kill `pidof $NAME`

		if [ "$?" != 0 ] ; then
			echo " failed"
			exit 1
		else
			echo " done"
		fi
	;;

	restart)
		$SCRIPTNAME stop
		sleep 1
		$SCRIPTNAME start
	;;

	reload)

		echo -n "Reload service $NAME... "

		if netstat -tnpl | grep -q nginx; then
			$NGINX_BIN -s reload
			echo " done"
		else
			echo "$NAME is not running, can't reload."
			exit 1
		fi
	;;

	configtest)

		echo -n "Test $NAME configure files... "

		$NGINX_BIN -t
	;;

	*)
		echo "Usage: $SCRIPTNAME {start|stop|force-quit|restart|reload|status|configtest}"
		exit 1
	;;

esac

设置执行权限,并加入服务列表

[root@nginx ~]# chmod +x /etc/init.d/nginx 
[root@nginx ~]# chkconfig --add nginx

启动nginx服务

[root@nginx ~]# service nginx start
Starting nginx...  done
[root@nginx ~]# netstat -tunlp |grep nginx
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      26057/nginx

7、2 设置反向代理

修改nginx配置文件添加一个location

location  /conffiles {
                mogilefs_tracker 192.168.3.75:7001;
                mogilefs_domain conffiles;
                mogilefs_methods GET;
                mogilefs_noverify on;
                mogilefs_pass {
                    proxy_pass $mogilefs_path;
                    proxy_hide_header Content-Type;
                    proxy_buffering off;
                }
        }

设置完成重启服务,配置生效

使用nginx访问/conffiles/下的fstab.txt,就可以看到文件

[root@node1 ~]# curl http://192.168.3.78/conffiles/fstab.txt

#
# /etc/fstab
# Created by anaconda on Fri Jul 31 13:49:48 2015
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
UUID=fe369058-0853-4ae2-bd3b-44a5f1f5eb43 /                       ext4    defaults        1 1
UUID=09090dff-3a43-4c6b-89d1-f976a41b542d /boot                   ext4    defaults        1 2
UUID=22651027-cd8f-4cb6-abb9-0b6d203894c5 swap                    swap    defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0

7、3 设置负载均衡

由于后端有3个tracker服务器,所以可以使用nginx的upstream实现负载均衡,配置方法如下所示:

upstream trackers{
        server 192.168.3.75:7001;
        server 192.168.3.76:7001;
        server 192.168.3.77:7001;
}
server {
        ..........
}