一:什么是分布式文件系统
分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源不一定直接连接在本地节点上,而是通过计算机网络与节点相连,也就是集群文件系统,可以支持大数量的节点以及PB级的数量存储。相对地,在一个分享的磁盘文件系统中,所有节点对数据存储区块都有相同的访问权,在这样的系统中,访问权限就必须由客户端程序来控制。分布式文件系统可能包含的功能有:通透的数据复制与容错。也就是说,即使系统中有一小部份的节点脱机,整体来说系统仍然可以持续运作而不会有数据损失.
二:分布式文件系统存在的意义.
当下互联网飞速发展,海量并发所产生的数据量以几何方式增长,随着信息链接方式日益多样化,数据存储的结构也发生了变化,在这样的压力下我们不得不重新审视大量数据的存储所带来了巨大的挑战,现在单个文件系统存储出现向上扩展的性价比越来越低,单机扩展存在性能上升的临界点,单机存储会出现许多不安全因素.在这种情况下分布式文件系统的存储能够很好解决这些问题.
三:实现分布式文件系统存在的难点
缺乏全局时钟
面对故障时的独立性(一个节点出现故障了不会影响其他节点出现问题)
处理单点故障(避免单点故障最好方法是要有冗余)
事务处理(事务需要满足:ACID A:原子性不可分割 C:一致性变化前后数据一直 I:隔离性执行动作分为有先有后 D:持久性)
解决事务处理方法有
2PC:两段式提交,先保证第一阶段完成后才执行第二阶段,第一阶段出现问题后第二阶段一定不会执行,有时也会进行回滚.
CAP理论:一致性,可用性,分区容错性;指一个分布式系统不可以满足一致性,可用性和分区容错性这三个需求,最多只能同时满足其中的两个,目前主要是在A 和P上,在一致性C上进行妥协.
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
四:分布式文件系统的类别
GFS :Google File System
HDFS:适合存储大文件;
TFS:在名称节点上将元数据存储于关系型数据中,文件数量不再受限于名称节点的内存空间;可以存储海量小文件;
Lustre: 企业级应用,重量级;
GlusterFS: 适用于存储少量大文件 ,流媒体,云
MooseFS: 通用简便,适用于存储小文件,大文件也不错
Mogilefs: 使用Perl语言,FastDFS 适合存储海量小文件
FastDFS:在内存中存储
Ceph:内核级别,支持PB级别存储
五:MogileFS
MogileFS 是一个开源的分布式文件系统,用于组建分布式文件集群,由 LiveJournal 旗下 Danga Interactive 公司开发,Danga 团队开发了包括 Memcached、MogileFS、Perlbal 等不错的开源项目:(注:Perlbal 是一个强大的 Perl 写的反向代理服务器)。目前国内使用 MogileFS 的有图片托管网站 yupoo 等.
六:MogileFS实现过程
1)试验拓扑图
①客户端向nginx发送请求
②而后通过nginx反向代理向后挑选一台trachers服务器进行响应.
③通过trackers向后查询请求数据的存放位置
④Mysql返回数据的存放位置信息给trackers
⑤trackers把数据信息交给代理服务器Nginx
⑥Nginx在根据Mysql响应的数据存储位置信息去取得实际文件存储位置信息.
⑦实际存储文件信息交给Nginx代理服务器
⑧Nginx代理服务器拿到信息后交给客户端
第一步:配置node3和node4节点
node3和node4的配置过程是一样的所以配置好一个节点后把配置文件交给另一个节点.
获得MogileFS安装包 [root@node3 mogilefs]# ls MogileFS-Server-2.46-2.el6.noarch.rpm Perlbal-doc-1.78-1.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm perl-MogileFS-Client-1.14-1.el6.noarch.rpm MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm Perlbal-1.78-1.el6.noarch.rpm [root@node3 mogilefs]# yum install MogileFS-* perl-* perl-IO-AIO [root@node3 mogilefs]# vim /etc/mogilefs/mogilefsd.conf #修改配置文件 db_dsn = DBI:mysql:mogilefs:host=172.16.16.3 #指定安装数据库的地址 db_user = moguser #指登录mogilefs所用的用户名和密码 db_pass = 123 # IP:PORT to listen on for mogilefs client requests listen = 0.0.0.0:7001 #监听在所有端口 # Optional, if you don't define the port above. conf_port = 7001 编辑mogstored.conf [root@node3 mogilefs]# vim /etc/mogilefs/mogstored.conf maxconns = 10000 httplisten = 0.0.0.0:7500 mgmtlisten = 0.0.0.0:7501 docroot = /mdfs/mogdata #修改为你要存储数据的地址 [root@node3 mogilefs]# mkdir -pv /mdfs/mogdata/dev1 #创建存放数据的文件夹 [root@node3 mogilefs]# chown -R mogilefs.mogilefs /mdfs/mogdata/dev1 #给文件夹符属主数组的权限 [root@node3 mogilefs]# chown -R mogilefs.mogilefs /var/run/mogilefsd/ 配置node4 (前提node4上的mogstore和mogilefsd已经安装) scp mogilefsd.conf mogstored.conf 172.16.16.4:/etc/mogilefs/ [root@node4 mogilefs]# mkdir -pv /mdfs/mogdata/dev2 [root@node4 mogilefs]# chown -R mogilefs.mogilefs /mdfs/mogdata/dev2 [root@node4 mogilefs]# chown -R mogilefs.mogilefs /var/run/mogilefsd/
第二步:安装nginx和MariaDB,这里安装Nginx需要编译安装,因为他需要装载第三方模块才可以使用mogilefs,MariaDB安装这里就不再说明了;
编译安装nginx 配置编译环境 yum -y groupinstall "Development Tools" "Server Platform Development" [root@node2 ~]# yum -y install openssl-devel pcre-devel [root@node2 ~]# groupadd -r nginx [root@node2 ~]# useradd -r -g nginx nginx 下载支持分布式文件系统的模块nginx_mogilefs_module-1.0.2.tar.gz [root@node2 ~]# tar xf nginx_mogilefs_module-1.0.2.tar.gz [root@node2 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-1.0.4 #编译安装此模块 [root@node2 ~]# make && make install 给nginx提供一个服务脚本 [root@node2 ~]# 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@node2 ~]# chmod +x /etc/rc.d/init.d/nginx [root@node2 ~]# chkconfig --add nginx 安装mysql [root@node2 ~]# yum install mysql-server mysql [root@node2 ~]# yum install mysql-server mysql #安装mysql 启动mysql和nginx服务
访问nginx
nginx正常启动
第三部:连接数据库给用户授权
[root@node2 ~]# mysql #在node2上连接数据库 mysql> GRANT ALL ON mogilefs.* TO 'moguser'@'node3' IDENTIFIED BY '123'; #给访问的用户授权,这里的用户名和密码要和上面/etc/mogilefs/mogilefsd.conf配置文件里的用户名和密码保持一致. mysql> GRANT ALL ON *.* TO 'root'@'node3' IDENTIFIED BY '123'; Query OK, 0 rows affected (0.01 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) 在节点node3上连接mysql [root@node3 ~]# mogdbsetup --dbhost=172.16.16.2 --dbport=3306 --dbname=mogilefs --dbrootuser=bpass=123 --yes
分别启动node3和node4上的mogilefsd 和mogstore服务
[root@node3 ~]# service mogilefsd start [root@node4 ~]# service mogilefsd start [root@node3 ~]# service mogstored start [root@node4 ~]# service mogstored start
在另个节点上期中一个上面添加主机
[root@node3 ~]# mogadm --trackers=172.16.16.3:7001 host add 172.16.16.3 --ip=172.16.16.3 --status=alive [root@node3 ~]# mogadm --trackers=172.16.16.3:7001 host add 172.16.16.4 --ip=172.16.16.4 --status=alive 查看添加的主机 [root@node3 ~]# mogadm --trackers=172.16.16.3:7001 host list 172.16.16.3 [1]: alive IP: 172.16.16.3:7500 172.16.16.4 [2]: alive IP: 172.16.16.4:7500
添加设备
[root@node3 ~]# mogadm --trackers=172.16.16.3:7001 device add 172.16.16.3 1 [root@node3 ~]# mogadm --trackers=172.16.16.3:7001 device add 172.16.16.4 2 查看添加的设备 [root@node3 mogilefs]# mogadm --trackers=172.16.16.3:7001 device list 172.16.16.3 [1]: alive used(G) free(G) total(G) weight(%) dev1: alive 1.565 17.120 18.686 100 172.16.16.4 [2]: alive used(G) free(G) total(G) weight(%) dev2: alive 0.395 18.291 18.686 100
添加域
[root@node3 ~]# mogadm --trackers=172.16.16.3:7001 domain add p_w_picpaths [root@node3 ~]# mogadm --trackers=172.16.16.3:7001 domain add files [root@node3 ~]# mogadm --trackers=172.16.16.3:7001 domain add html
查看添加的域
[root@node3 ~]# mogadm --trackers=172.16.16.3:7001 domain list domain class mindevcount replpolicy hashtype -------------------- -------------------- ------------- ------------ ------- files default 2 MultipleHosts() NONE html default 2 MultipleHosts() NONE p_w_picpaths default 2 MultipleHosts() NONE
上传照片进行测试
[root@node3 ~]# mogupload --trackers=172.16.16.3:7001 --domain=p_w_picpaths --key='1.png' --file='/usr/share/backgrounds/default_1920x1200.png' 查看上传的照片信息 [root@node3 ~]# moglistkeys --trackers=172.16.16.3:7001 --domain=p_w_picpaths 1.png #上传的照片
查看上传照片的路径信息
[root@node3 ~]# mogfileinfo --trackers=172.16.16.3:7001 --domain=p_w_picpaths --key='1.png' - file: 1.png class: default devcount: 2 domain: p_w_picpaths fid: 5 key: 1.png length: 1470177 - http://172.16.16.3:7500/dev1/0/000/000/0000000005.fid - http://172.16.16.4:7500/dev2/0/000/000/0000000005.fid
复制这个路径进行测试一下
说明mogilefs搭建成功
第四部:在nginx进行访问控制配置
upstream mogcluster { # 定义多个上游服务器 server 172.16.16.3:7001; server 172.16.16.4:7001; } server { # 定义一个虚拟主机 listen 80; server_name www.llh.com; location /p_w_picpaths/ { mogilefs_tracker mogcluster; mogilefs_domain p_w_picpaths; 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; } } }
OK 这样就可以通过nginx服务器访问上传的图片了.