什么是分布式存储:

    分布式存储系统,是将数据分散存储在多台独立的设备上。传统的网络存储系统采用集中的存储服务器存放所有数据,存储服务器成为系统性能的瓶颈,也是可靠性和安全性的焦点,不能满足大规模存储应用的需要。分布式网络存储系统采用可扩展的系统结构,利用多台存储服务器分担存储负荷,利用位置服务器定位存储信息,它不但提高了系统的可靠性、可用性和存取效率,还易于扩展。

分布式文件系统设计目标

  • 访问透明

  • 位置透明   

  • 并发透明

  • 失效透明

  • 硬件透明

  • 可扩展性

  • 复制透明

  • 迁移透明

CAP理论:

    C:Consistency(一致性)  任何一个读操作总是能够读取之前完成的写操作。

    A:Availability(可用性) 每一次操作总是能够在确定的时间返回。

    P:Partition Tolerance (分区容错性)  在出现网络分区的情况下,仍然能够满足一致性和可用性。

wKioL1P4hvXjxLBRAAGPSBz30a0268.jpg


    所有科学家都在致力于CAP三元素并存的时候,Eric.Brewer教授指出CAP永远无法兼顾,只能根据具体应用来权衡和取舍,并且至多两个元素可以共存,后来由两位麻省理工学院的科学家证明此观点是具有前瞻性的,由此形成Brewer的CAP定理

    正所谓鱼和熊掌不可兼得,关注一致性就需要处理因系统不可用而带来写操作失败的情况,反之关注可用性就无法保证每次都能读取到最新的写入操作。传统关系型数据库侧重于CA,而非关系型键值数据库则侧重于AP

    强一致性(ACID)在单机环境中,强一致性可以由数据库的事务来保证;在分布式环境中,强一致性很难做到,即便是做到也会因为分布式事物所带来的性能低下,不适合在互联网的环境中应用。

       弱一致性(包括最终一致性)系统不能保证后续访问返回最新的值,在访问到最新值之前这段时间称之为不一致窗口

       最终一致性:是弱一致性的一种特例,存储系统保证如果对象有多次更新,在渡过不一致窗口之后必将放回最后更新的值。

       服务器的一致性N代表节点的个数;W代表更新的时候需要确认已经被更新的节点个数;R代表读取数据需要的节点数量。

               W + R > N  ---->  强一致性(通常N=3,W=R=2)

               W=N,R=1   ---->  最佳读

               W=1,R=N   ---->  最佳写

               W + R <= N ---->  弱一致性


分布式存储文件系统


Google Filesystem

GFS擅长处理单个大文件

GFS+MapReduce (编程模型-运行框架-API)可以实现程序切割到多节点运行,实现分布式处理

Hadoop Distributed Filesystem

根据GFS思想开发的,擅长处理单个大文件

ClusterFS擅长处理单个大文件
Taobao Filesystem淘宝开源的文件系统,擅长处理海量小文件,适用于大规模场景。
MogileFS是一个高性能的分布式存储,擅长处理海量小文件
Ceph是一个 Linux PB级别的分布式文件系统,测试中
MooseFS分布式文件系统,兼容POSIX(FUSE),可以直接挂载使用,当节点多,并发量大环境中,可扩展性差,性能一般。
Lustre一种平行分布式文件系统


Mogilefs工作原理:

   MogileFS是一个开源的分布式文件系统。其特性包括:应用层的组件、无单点故障、自动文件复制主要由mogilefsd和mogstored两个程序组成。前者即是mogilefsd的tracker,它将一些全局信息保存在数据库里,例如站点domain,class,host等。后者即是存储节点(store node),它其实是个HTTP Daemon,默认侦听在7500端口,接受客户端的文件备份请求。在安装完后,要运行mogadm工具将所有的store node注册到mogilefsd的数据库里,mogilefsd会对这些节点进行管理和监控。


    tracker节点:借助数据库保存各节点文件的元数据信息保存每个域中所有键的存储位置分布,方便检索定位数据位置的同时监控各节点,告诉客户端存储区位置并指挥storage节点复制数据副本,进程名为mogilefsd(7001)

    database节点:tracker节点提供数据存取服务。

    storage节点:将指定域中的键转换为其特有的文件名存储在指定的设备文件中,转换后的文件名为值,storage节点自动维护键值的对应关系,storage节点由于使用http进行数据传输,因此依赖于perlbalstorage节点前端可以使用nginx进行反向代理,但需要安装nginx-mogilefs-module-master模块进行名称转换。

    Domain一个域中的键值是惟一的,一个MogileFS可以有多个域,域可以用来存储不同应用类型的数据的容器。

    Host每一个存储节点称为一个主机,一个主机上可以有多个存储设备(单独的硬盘),每个设备都有ID号,Domain+Fid用来定位文件。

    Class:复制最小单位,文件属性管理,定义文件存储在不同设备上份数。


实验一、使用MySQL+MogileFS构建一个分布式存储

实验环境RHEL6.4

wKiom1P5QbOTfbOmAAFYgqz4_cs687.jpg

官方的介绍网站http://www.danga.com/mogilefs/

安装Perl模块:

App::cpanminus 

MogileFS::Server 

MogileFS::Utils 

IO::AIO 

IO::WrapTie 

Danga::Socket

我们可以使用CPAN工具安装也可到http://search.cpan.org/ 网站上下载安装,如安装Sys::Syscall模块。

#wget http://search.cpan.org/CPAN/authors/id/B/BR/BRADFITZ/Sys-Syscall-0.23.tar.gz

# tar zxvf Sys-Syscall-0.23.tar.gz

# cd Sys-Syscall-0.23

# perl Makefile.PL

# make

# make install

这里我们为了简便使用CPAN工具安装

yum -y install make gcc unzip perl-DBD-MySQL perl perl-CPAN perl-YAML perl-Time-HiRes
cpan -i App::cpanminus
cpan -i MogileFS::Server
cpan -i MogileFS::Utils
cpan -i IO::AIO
cpan -i IO::WrapTie
cpan -i Danga::Socket

:存储节点服务器不用安装DBD::mysql模块

提供文件夹,复制配置文件(配置文件模版可以在官网获取)

mkdir /etc/mogilefs

cp /home/mogstored.conf mogilefsd.conf  /etc/mogilefs/

以上操作每个节点都相同。

admin1:

编辑配置文件/etc/mogilefs/mogilefsd.conf

wKioL1P5eMqDP9fdAAPzUwSxiH0642.jpg

为mogilefsd程序提供服务启动脚本(略)

安装MySQL(略),创建数据库,添加管理用户。

create database mogfsdb;

grant all privileges on mogfsdb.* to 'moguser'@'127.0.0.1' identified by '123456';

grant all privileges on mogfsdb.* to 'moguser'@'192.168.18.202' identified by '123456';

flush privileges;

初始化数据库,创建mogilefs用户,创建pid文件目录并赋予权限,然后启动服务。

mogdbsetup --dbhost='127.0.0.1' --dbname=mogfsdb --dbuser=moguser --dbpass=123456 --type=MySQL

useradd -r mogilefs

mkdir /var/run/mogilefsd/ -p

chown -R mogilefs.mogilefs  /var/run/mogilefsd/

/etc/init.d/mogilefsd start

查看是否启动成功,端口是否监听。

wKioL1P5gSzSYYDMAAHNguQzCGY477.jpg

接下来配置mogstored

vim /etc/mogilefs/mogstored.conf

maxconns = 10000
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /mystore

为mogstored提供服务启动脚本(略)

分区,格式化,挂载文件系统,赋予权限。

fdisk /dev/sdb

mkfs.ext4 /dev/sdb1

mkdir /mystore/dev1 -pv

mount /dev/sdb1 /mystore/dev1

chown -R mogilefs.mogilefs /mystore/dev1

启动服务

service mogstored start

admin2和admin3配置和admin1都差不多,拷贝admin1的配置文件稍作修改即可(过程略)

由于admin3不用配tracker,所以只需启动mogstored服务就可以了。

添加存储节点主机,添加存储设备。

mogadm host add admin1 --ip=192.168.18.201 --status=alive --port=7500

mogadm host add admin2 --ip=192.168.18.202 --status=alive --port=7500

mogadm host add admin3 --ip=192.168.18.203 --status=alive --port=7500

mogadm device add admin1 1 --status=alive

mogadm device add admin2 2 --status=alive

mogadm device add admin2 5 --status=alive

mogadm device add admin3 3 --status=alive

mogadm device add admin3 4 --status=alive

查看检测状态

wKioL1P5riTzZKgtAAKu3Fqhgog565.jpg

查看设备列表

wKiom1P5rmSh3MKKAAKTw1qJ8yA745.jpg

添加两个域(domain)

mogadm domain add files

mogadm domain add images

wKioL1P5sQGR3-XvAAE0AS1FYQA281.jpg

上传文件

mogupload --trackers=192.168.18.201 --domain=files --key='rc.sysinit' --file='/etc/rc.d/rc.sysinit'

mogupload --trackers=192.168.18.202 --domain=images --key='hu.jpg' --file='/root/Desktop/hu.jpg'

跟踪文件信息

mogfileinfo --trackers=192.168.18.201 --domain=images --key='hu.jpg'

wKioL1P50K6TFC-YAAIRtqD19CY012.jpg

我们从以上三个路径中,随便挑一个访问。

wKioL1P50dmClylTAAMicaMZ6Uo584.jpg

实验二、使用Nginx代理请求至tackers,实现通过键就可以访问到文件。

wKiom1P51VagAKzSAAFJKbqqxqE474.jpg


要实现Nginx代理tackers,需要在编译Nginx的时候加入第三方模块nginx_mogilefs_module.

下载地址:http://wiki.nginx.org/3rdPartyModules

编译Nginx

./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=/home/nginx_mogilefs_module-1.0.4

make && make install


编辑/etc/nginx/nginx.conf

定义后端tracker,实现负载均衡。

upstream trackers {
        server 192.168.18.201:7001;
        server 192.168.18.202:7001;
        }

定义location代理至domain

location  /files/ {
        mogilefs_tracker trackers;
        mogilefs_domain files;
        mogilefs_methods GET;
        mogilefs_noverify on;

        mogilefs_pass {
                proxy_pass $mogilefs_path;
                proxy_hide_header Content-Type;
                proxy_buffering off;
        }
}

        location  /images/ {
        mogilefs_tracker trackers;
        mogilefs_domain images;
        mogilefs_methods GET;
        mogilefs_noverify on;

        mogilefs_pass {
                proxy_pass $mogilefs_path;
                proxy_hide_header Content-Type;
                proxy_buffering off;
        }
}

配置完成后,启动nginx。

上传文件到mogilefs。

mogupload --trackers=192.168.18.202 --domain=images --key='qier.jpg' --file='/root/Desktop/qier.jpg'

mogupload --trackers=192.168.18.202 --domain=files --key='test.html' --file='test.html'


然后使用浏览器访问nginx服务器,location后面跟key。

wKiom1P559fjPZIhAACeu3LIhNQ730.jpg


wKioL1P56a3zR8ShAAIHq4WAYUc263.jpg


实验成功!

接下来补充一下mogadm命令的额外指令。

mogadm slave //由于文件元数据信息是保存在MySQL中的,每次请求文件需要读取MySQL一旦请求量太大,MySQL必定会成为性能瓶颈,这时我们要给MySQL做主从,这个指令就是用来添加从节点的,可以实现tracker与主从架构的MySQL交互时,实现读写分离。

mogadm fsck  //文件系统检测,一般不要使用,除非集群意外断电,在上线时执行。

mogadm rebalance  // 重新平衡,当数据出现热区时使用,在执行之前需要定义平衡策略。

mogadm rebalance start // 启动平衡策略。

mogadm rebalance policy  //定义平衡策略。

mogadm rebalance test  //用于测试是否出现数据不平衡的问题。

mogadm settings  //定义mogilefs工作属性。

mogadm class modify <domain> <class> --mindevcount= //定义文件最小的副本份数

再总结两个技巧,这我在写这篇博文做实验碰到的问题。

技巧一、MogileFS 中怎么删除主机

        在机器坏了的时候,就会给这些标坏掉了,但还是不能删除.下面是我建议的方式,当你给所有的硬盘设备标成不可用后,你然后在 fsck ,这样会同步文件到其它的机器同样的份数.接着为了确认进入 MySQL 中查一下。

select count(*) from file_on where devid=11;

看看是不是去掉的硬盘设备,真的没有文件的记录在上面了.接着我们就可以安全的删除这个设备了.
delete from device where devid=11;

当对那个主机上的硬盘操作完时,你就可以删除你的主机了.

技巧二、MogileFS 复制不正常,发现文件少于指定的份数解决方法

在安装最新的 MogileFS 时,会发现测试的时候,怎么样复制文件的过程都不正常.使用 telnet 到 7001 中使用 !watch 来查看时会不断的报下面的错(详细使用见 MogileFS 高级排错).

!watch
Added you to watcher list.
.
:: Child 10106 (replicate) died: 256 (UNEXPECTED)
:: Job replicate has only 9, wants 10, making 1.
:: Child 10091 (replicate) died: 256 (UNEXPECTED)
:: Job replicate has only 9, wants 10, making 1.
:: Child 10121 (replicate) died: 256 (UNEXPECTED)
:: Job replicate has only 9, wants 10, making 1.
:: Child 10134 (replicate) died: 256 (UNEXPECTED)
:: Job replicate has only 9, wants 10, making 1.
:: Child 10120 (replicate) died: 256 (UNEXPECTED)
:: Job replicate has only 9, wants 10, making 1.

使用 MogileFS 的 DEBUG 模式跟这个问题,是由于 Sys::Syscall 这个模块升级成 0.25 的新版本引起的.
我们可以使用下面的命令来检查当前的版本

perl -MSys::Syscall -e 'print $Sys::Syscall::VERSION'

如果发现是显示上面的 0.25 就一定会出问题.建议退回到 0.23 就不会在出问题了.所以建议大家在安装完 MogileFS 后,先退回这个模块到 0.23.

cpan http://search.cpan.org/CPAN/authors/id/B/BR/BRADFITZ/Sys-Syscall-0.23.tar.gz

笔者花了一整天时间整理出来的,终于可以完结了。