|
大纲:
一、关于MogileFS
二、常见分布式文件系统
三、MogileFS基本原理
四、MogileFS的实现
一、关于MogileFS
当下我们处在一个互联网飞速发展的信息社会,在海量并发连接的驱动下每天所产生的数据量必然以几何方式增长,随着信息连接方式日益多样化,数据存储的结构也随着发生了变化。在这样的压力下使得人们不得不重新审视大量数据的存储所带来的挑战,例如:数据采集、数据存储、数据搜索、数据共享、数据传输、数据分析、数据可视化等一系列问题。
传统存储在面对海量数据存储表现出的力不从心已经是不争的事实,例如:纵向扩展受阵列空间限制、横向扩展受交换设备限制、节点受文件系统限制。
然而分布式存储的出现在一定程度上有效的缓解了这一问题,之所以称之为缓解是因为分布式存储在面对海量数据存储时也并非十全十美毫无压力,依然存在的难点与挑战例如:节点间通信、数据存储、数据空间平衡、容错、文件系统支持等一系列问题仍处在不断摸索和完善中。
在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点:
* 一致性(Consistency)---所有节点在同一时间具有相同的数据
* 可用性(Availability)---保证每个请求不管成功或者失败都有响应
* 分隔容忍(Partition tolerance)---系统中任意信息的丢失或失败不会影响系统的继续运作
根据定理,分布式系统只能满足三项中的两项而不可能满足全部三项。
对于大型站点,可用性(Availability)与分隔容错性(Partition Tolerance)的优先级会高于一致性(Consistency),这里并不是指完全舍弃一致性,而是通过其他手段实现数据的弱一致性,例如:用户微博的浏览数和评论可以容忍相对长时间的不一致,几乎不会影响用户体验,而股票价格的数据则异常敏感,即便是10秒钟的数据不一致也无法容忍下面列出了"各种一致性".
强一致性
ACID
在单机环境中,强一致性可以由数据库的事务来保证
在多级环境中,强一致性很难做到
分布式事务:性能太差,在化联网的应用中不适合
弱一致性(包括最终一致性)
通过提交处理的半同步、半异步或全异步,取得最终一致性效果
最终一致性使得数据的提交具有延时性,而在一定范围时的延时性范围内(比如一秒),应用的可用性时正常的
集群内一致性算法实施过程案例
基于合法票数(Quorum)和向量时钟(Vector Clock)
Quorum算法:
N :数据复制的节点量
R :成功读取所依赖的最少节点数
W :成功写操作所依赖的最少节点数
W+R>N 表示强一致性 ;W+R use mysql
#删除有安全隐患的账户
MariaDB [mysql]> DELETE FROM user WHERE host = '::1';
MariaDB [mysql]> DELETE FROM user WHERE user = '';
#授权root用户能远程登录
MariaDB [mysql]> GRANT ALL ON *.* TO 'root'@'172.16.%.%' IDENTIFIED BY '123.com'
#授权moguser用户
MariaDB [mysql]> GRANT ALL ON mogdb.* TO 'moguser'@'172.16.%.%' IDENTIFIED BY '123.com';
#刷新授权表
MariaDB [mysql]> FLUSH PRIVILEGES;(2)在后端各节点安装tracker以及storege
下载相应软件包.
#→下面三个是Tracker和Storage端必装的程序包.
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时使用的工具包
MogileFS-Utils-2.19-1.el6.noarch.rpm
#→MogileFS客户端程序
perl-MogileFS-Client-1.14-1.el6.noarch.rpm
#→这个软件包是在跨网络或者跨机房是所使用的包
perl-Net-Netmask-1.9015-8.el6.noarch.rpm
#→这是用perl所编写的web程序,它是在mostored上提供webDAV的方式接受客户web服务请求的.
perl-Perlbal-1.78-1.el6.noarch.rpm
#这是perl程序所依赖的包
perl-IO-AIO.x86_64
#→说明如果在配置安装过程当中遇依赖关系时,解决就行了.
#→然后将几个软件包都拷贝至其它两个节点上.
[root@node1 ~]# scp *.rpm 172.16.41.2:/root/
[root@node1 ~]# scp *.rpm 172.16.41.3:/root/
安装.
[root@node1 ~]# yum install *.rpm perl-IO-AIO
#→其他两个节点的安装过程在node1上面的一样.
(3)配置node1.example.com
配置tracker
#→安装好tracker后会在/var/run/下面生成该目录,改变目录属主.属组
[root@node1 ~]# chown -R mogilefs.mogilefs /var/run/mogilefsd
初始数据库设置[root@node1 ~]# mogdbsetup --dbrootuser=root --dbname=mogdb --dbhost=172.16.41.5 --dbport=3306 --dbrootpass=123.com --dbuser=moguser --dbpass=123.com --yes
验证初始化数据库结果:
修改tracker配置文件,如下内容:
[root@node1 ~]# vim /etc/mogilefs/mogilefsd.conf
#→修改下面4项即可其它参数根据工作环境自定
db_dsn = DBI:mysql:mogdb:host=172.16.41.5
db_user = moguser
db_pass = 123.com
listen = 172.16.41.1:7001 修改storage配置文件,如下内容:
[root@node1 ~]# vim /etc/mogilefs/mogstored.conf
maxconns = 10000 #→存储系统的最大连接数.
httplisten = 0.0.0.0:7500 #→这个就是webDAV服务使用的端口,但是这里我们不知使用它.
mgmtlisten = 0.0.0.0:7501 #→mogilefs的管理端口.
docroot = /data/mogdata #→该项决定了数据的在storage上存储的实际位置,建议使用的是一个单独挂载使用的磁盘.这里我就不用演示了.
[root@node1 ~]# mkdir -p /data/mydata/dev1
#→这里一定要改变数据存放目录的属主属组,应为mogilefs服务程序必须是以普通用户来运行的,否则服务启动将失败!
[root@node1 ~]# chown -R mogilefs.mogilefs /data/mogdata/dev1 启动tracker和storage服务:
[root@node2 ~]# service mogilefsd start
Starting mogilefsd [ OK ]
[root@node2 ~]# service mogstored start
Starting mogstored [ OK ]
[root@node2 ~]#
在node1上面将自己添加mogstore存储主机
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 host add 172.16.41.1 --ip=172.16.41.1 --status=alive
此时,node1.example.com这个节点既是tracker也是storage服务端了.
下面继续配置:
现将两个配置文件拷贝至两个节点中--要保证各个程序包都已经安装了,否则在拷贝后安装会覆盖两个配置文件.
[root@node1 ~]# scp /etc/mogilefs/* 172.16.41.2:/etc/mogilefs/
mogilefsd.conf 100% 1462 1.4KB/s 00:00
mogstored.conf 100% 93 0.1KB/s 00:00
[root@node1 ~]# scp /etc/mogilefs/* 172.16.41.3:/etc/mogilefs/
mogilefsd.conf 100% 1462 1.4KB/s 00:00
mogstored.conf 100% 93 0.1KB/s 00:00
[root@node1 ~]#
(4)配置node2.example.com
程序包已经安装
设定数据库已经完毕,该节点与node3节点无需重复此操作
配置tracker.
#→安装好tracker后会在/var/run/下面生成该目录,改变目录属主.属组
[root@node2 ~]# chown -R mogilefs.mogilefs /var/run/mogilefsd
修改tracker配置文件,如下内容:
[root@node2 ~]# vim /etc/mogilefs/mogilefsd.conf
#→修改下面4项即可其它参数根据工作环境自定
db_dsn = DBI:mysql:mogdb:host=172.16.41.5
db_user = moguser
db_pass = 123.com
listen = 172.16.41.2:7001 修改storage配置文件,如下内容:
[root@node2 ~]# vim /etc/mogilefs/mogstored.conf
maxconns = 10000
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /data/mogdata#→该项决定了数据的在storage上存储的实际位置,建议使用的是一个单独挂载使用的磁盘.这里我就不用演示了.
[root@node2 ~]# mkdir -p /data/mydata/dev2
#→这里一定要改变数据存放目录的属主属组,应为mogilefs服务程序必须是以普通用户来运行的,否则服务启动将失败!
[root@node2 ~]# chown -R mogilefs.mogilefs /data/mogdata/dev2 启动tracker和storage服务:
[root@node2 ~]# service mogilefsd start
Starting mogilefsd [ OK ]
[root@node2 ~]# service mogstored start
Starting mogstored [ OK ]
[root@node2 ~]#

在node1上面将自己添加mogstore存储主机
[root@node2 ~]# mogadm --trackers=172.16.41.2:7001 host add 172.16.41.2 --ip=172.16.41.2 --status=alive
此时两个节点都加入到了MogileFS系统中,第三个节点配置与第二个一样,只是配置文件修改一下即可,这里不在赘述!
下面就可以在node1节点上控制其他两个节点即可!

(5)管理配置MogileFS集群系统
添加device
#→添加的第一个设备,设备号不能重名
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 device add 172.16.41.1 1
#→添加的第二个设备
[root@node1 ~]# mogadm --trackers=172.16.41.2:7001 device add 172.16.41.2 2
#→添加的第三个设备
[root@node1 ~]# mogadm --trackers=172.16.41.3:7001 device add 172.16.41.3 3
[root@node1 ~]# mogadm --trackers=172.16.41.3:7001 device list

添加域domain-----域用来存储不同应用类型的数据的容器
#→创建的图片存放域
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 domain add images
#→创建的html等文件存放域
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 domain add files
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 domain list

添加类class
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 class add images class0 --mindevcount=2
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 class add images class1 --mindevcount=2
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 class add images class3 --mindevcount=2
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 class add files class0 --mindevcount=2
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 class add files class1 --mindevcount=2
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 class add files class2 --mindevcount=2
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 class list

这里再次提一下关于这两个概念

域(domain)
在一个 MogileFS 中,可以有多个域,用来存放不同的文件,比如,不同大小的文件,不同类型的文件.在上图中所有 alive 的"设备"是一个大的整体,形成一个统一的存储空间,里面的数据可以根据 "域" domain 和类 class 来分类管理,属于同一个 domain,即使是属于不同的class,文件的key也必须是唯一的.不同域的 key 才能重复.
类(class)
在一个域中,可以有多个类,主要是用来控制复制单元的,类是用来做属性管理的,类是比域 domain 低一个级别,可以定义一个文件存储在不同 device 中的份数.一个文件必须通过 domain,class 和 key 才能找出来.我们可以给不同的重要程度的文件,不同热度的文件,来分别用类来控制份数.
使用mogupload工具在这里是为了测试,实际环境中上传是由程序员在代码中使用mogilefs的API进行交互的。
[root@node1 ~]# mogupload --trackers=172.16.41.1:7001 --domain=images --key='tux_1.jpg' --file='/root/my_test_data/1.jpg'
#→--key='tux_1.jgp' 是我要上传后的键是什么
#→ --file 指的是我要上传的文件

通过将它给出的路径来访问一下看能不能正常的访问到?

模拟某个节点故障,看文件是否还在?

看到我们的文件还有一份保存在另外一节点上面的,通过那个路径也能访问到该文件,而且在每个storage节点上都能看到这个文件,之前说过啦,他们用的都是一个数据库;
OK!此时我们MogileFS系统基本上部暑基本完毕;
下面介绍Nginx做为MogileFS的前端客户端是如何实现的!
Nginx做为MogileFS的前端客户端,我们使用Nginx来吐文件,做前端的查询代理时,我们需要使用到mogilefs的这个模块,可以下载这个模块编译进Nginx就行了,直接使用 ./configure -add-module=这个参数就可以了,最新的这个模块的下载地址是:https://github.com/vkholodkov/nginx-mogilefs-module
1.编译安装Nginx.
#这里需要安装个pcre-devel包
[root@node4 ~]# yum install -y pcre-devel
#解压获取到的mogilefs模块包
[root@node4 ~]# unzip nginx-mogilefs-module-master.zip
#解压、编译安装nginx
[root@node4 ~]# tar -xf nginx-1.4.7.tar.gz -C /usr/src/
[root@nginx ~]# cd /usr/src/nginx-1.4.7/
[root@nginx 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=/root/nginx-mogilefs-module-master
2.为nginx提供SysV init脚本:
[root@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
[root@nginx ~]# chmod +x /etc/rc.d/init.d/
[root@nginx ~]# chkconfig --add nginx
[root@nginx ~]# chkconfig nginx on
#启动nginx
[root@nginx ~]# service nginx start
Starting nginx: [ OK ]
[root@nginx ~]# ss -tnl | grep :80
LISTEN 0 128 *:80 *:*
[root@nginx ~]#
3.修改nginx主配置文件:
[root@nginx ~]# vim /etc/nginx/nginx.conf
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name www.magelinux.com;
location / {
root html;
index index.html index.htm;
}
################About images###############
location /images/ {
mogilefs_tracker 172.16.41.1:7001;
mogilefs_domain images;
mogilefs_pass {
proxy_pass $mogilefs_path;
proxy_hide_header Content-Type;
proxy_buffering off;
}
}
################About files###############
location /files/ {
mogilefs_tracker 172.16.41.1:7001;
mogilefs_domain images;
mogilefs_pass {
proxy_pass $mogilefs_path;
proxy_hide_header Content-Type;
proxy_buffering off;
}
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
4.测试:

下面我上传一个html文档看能否代理成功?

此时我查看到了在两个域类有两个key,注意它们在上传的时候输入的类容,以及在去观察在nginx反代中的书写方法有是有一定区别的,先测试,稍后说

ok!fiels测试没有问题,但是我们可以将nginx的配置修改一下,让我在定义键的时候也改一下.
nginx中只需要修改 location /files/ 和proxy pass这段内容即可,这种方式定义images也一样适用,先看看效果吧.

保存退出、重新加载nginx、再次访问测试:

重新上传测试文件:

重新加载nginx、再次访问测试:

这两种定义方法可根据实际场景应用!
朋友们大概注意到了我在nginx的配置文件中,只是配置了将客户端请求代理到后端的一台tracker上面,如果要将多个tracker基于负载均衡的方式来提供服务,于是我们就需要定义upstream啦;请看以下配置:
  
重新加载nginx、再次访问测试:

如果我将某两个(不止一个),tracker+storage模拟宕机后一样能访问到!这应该就叫"分布式文件系统"的功能吧!
最后在介绍一下mogilefs的常用命令:
####################################################################
#→显示当前mogilefs的配置信息(host,domain,class)状态,如果加上--stats="domains"可以只显示domian相关的信息.
[root@node1 ~]# mogstats --config=/etc/mogilefs/mogilefsd.conf
####################################################################
#→显示一个具体文件的信息,包括所在域、副本数、文件ID、key、复制到了哪些tracker上面.
[root@node1 ~]# mogfileinfo --trackers=172.16.41.1:7001 --domain=images --key="tux_1.jpg"
####################################################################
#→上传一个本地文件到指定的域内,同时必须指定key.
[root@node1 ~]# mogupload --trackers=172.16.41.1:7001 --domain=images --key='tux_1.jpg' --file='/root/my_test_data/1.jpg'
####################################################################
#→删除指定域内的一个key.
[root@node1 ~]# mogdelete --trackers=172.16.41.1:7001 --domain=images --key='test1.html
####################################################################
#→查看指定域内的文件有哪些.
[root@node1 ~]# moglistkeys --trackers=172.16.41.1:7001 --domain=files
####################################################################
#→检查整个mogilefs系统.
[root@node1 ~]# mogadm --trackers=172.16.41.1:7001 check
####################################################################
................................
................................
#→以上工具使用较为方便,其他工具使用请找"man"! 至此,mogilefs的部署已经完成,后续还有许多地方需要改进;
以上内容若有错误,请朋友们指出!
写博、不易,比不了别人,就做好自己!
|
|