首页 > 代码库 > MogileFS的分布式文件系统的实现
MogileFS的分布式文件系统的实现
MogileFS:是一套分布式文件存储的解决方案,它不需要特殊的核心组件、无单点失败、自动的文件复制、比RAID好多了、传输中立,无特殊协议(客户端可以通过NFS或HTTP来和MogileFS通信)、简单的命名空间、不用共享任何东西、不需要RAID、不会碰到文件系统本身的不可知情况 等等优点。
server端由mogilefsd和mogstored两个程序组成,mogilefsd既tracker,用来存数全局元数据放在数据库中,mogstored既存储节点。
实验目的:
实现mogilefs分布式文件系统的实现
实验环境:
node1: 172.16.18.1 程序:mogstord
node2: 172.16.18.2 程序:mogstord
node3: 172.16.18.3 程序:mysql , mogilefsd(tracker)
实验模型:模型一
实验内容:
1.1 配置Tracker
安装MySQL,yum安装
安装Mogilefs
[root@node3 mogilefs]# yum install MogileFS-Server-* perl-Perlbal-1.78-1.el6.noarch.rpm
Dependency Installed:
perl-BSD-Resource.x86_64 0:1.29.03-3.el6
perl-Danga-Socket.noarch 0:1.61-5.el6
perl-Sys-Syscall.noarch 0:0.23-1.el6
perl-Time-HiRes.x86_64 4:1.9721-136.el6
perl-Net-Netmask.noarch 0:1.9015-8.el6
Complete!
1.2:在数据库创建用户
mysql> GRANT ALL ON mogilefs.* TO ‘mogile‘@‘172.16.%.%‘ IDENTIFIED BY ‘mogile‘;
Query OK, 0 rows affected (0.02 sec)
查看mogilefs的帮助
[root@node3 ~]# mogdbsetup --help Usage: mogdbsetup [opts] Options: Default Description ============ =========================================== --verbose <off> Be verbose about what‘s happening. --dbhost= localhost hostname or IP to database server. --dbport= dbd default port number to database server. --dbname= mogilefs database name to create/upgrade. --dbrootuser= root Database administrator username. Only needed for initial setup, not subsequent upgrades. --dbrootpass= <blank> Database administrator password. Only needed for initial setup, not subsequent upgrades. --dbuser= mogile Regular database user to create and/or use for MogileFS database. This is what the mogilefsd trackers connect as. --dbpass= <blank> You should change this, especially if your database servers are accessible to other users on the network. But they shouldn‘t be if you‘re running MogileFS, because MogileFS assumes your network is closed. --type= MySQL Which MogileFS::Store implementation to use. Available: MySQL, Postgres --yes Run without questions.
如果默认的参数和自己设定的参数一样的话就不需要指定了。
2.1尝试连接
[root@node3 ~]# mogdbsetup --dbhost=172.16.18.3 --dbpass=mogile
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 ‘mogilefs‘? [Y/n]: y
Grant all privileges to user ‘mogile‘, connecting from anywhere, to the mogilefs database ‘mogilefs‘? [Y/n]: y
Failed to connect to database as regular user, even after creating it and setting up permissions as the root user. at /usr/share/perl5/vendor_perl/MogileFS/Store.pm line 108, <STDIN> line 3.
报错,我们数据库的root用户没有设定允许远程连接,那我们来授权一个root用户的远程连接
mysql> GRANT ALL ON *.* TO root@‘172.16.%.%‘ IDENTIFIED BY ‘aolens‘;
Query OK, 0 rows affected (0.00 sec)
[root@node3 ~]# mogdbsetup --dbhost=172.16.18.3 --dbpass=mogile --dbrootuser=root --dbrootpass=aolens;
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
Failed to connect to DBI:mysql:mysql;host=172.16.18.3;port=3306 as specified root user (root): Access denied for user ‘root‘@‘node3.aolens.com‘ (using password: YES)
又报出错误,解析用的是node3.aolens.com
mysql> GRANT ALL ON mogilefs.* TO ‘mogile‘@‘node3.aolens.com‘ IDENTIFIED BY ‘mogile‘;
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
[root@node3 ~]# mogdbsetup --dbhost=172.16.18.3 --dbpass=mogile --dbrootuser=root --dbrootpass=aolens;
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
OK.连接成功
查看数据库中生成的数据
mysql> show tables;
有生成数据即可
我们是yum安装的MySQL,version:5.1.71的,
mysql> show tables status\G 查看存储引擎是不是innodb,若是则OK
2.2,编辑MogileFS的配置文件,配置一下参数。
[root@node3 ~]# vim /etc/mogilefs/mogilefsd.conf
db_dsn = DBI:mysql:mogilefs:host=172.16.18.3 #如果使用的数据库不是mogilefs,则修改mogilefs为自己定义的数据库 db_user = mogilef db_pass = mogile listen = 172.16.18.3:7001 #监听的地址和端口
2.3 尝试启动mogilefs
[root@node3 ~]# service mogilefsd start Starting mogilefsd [FAILED]
无法启动?我们尝试连接数据库看能否连接
[root@node3 ~]# mysql -uroot -h172.16.18.3 -p Enter password: ERROR 1045 (28000): Access denied for user ‘root‘@‘node3.aolens.com‘ (using password: YES) 数据库连接出错,解析用的是主机名。创建下边用户 mysql> GRANT ALL ON *.* TO root@‘node3.aolens.com‘ IDENTIFIED BY ‘aolens‘; Query OK, 0 rows affected (0.06 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec)
再次启动
[root@node3 ~]# service mogilefsd restart
Starting mogilefsd [ OK ]
启动成功了。
3.1下来我们来配置mogstord
首先来安装需要的程序包
perl-IO-AIO.x86_64 0:3.71-2.el6
MogileFS-Server-2.46-2.el6.noarch
MogileFS-Server-mogilefsd-2.46-2.el6.noarch
MogileFS-Server-mogstored-2.46-2.el6.noarch
perl-Net-Netmask-1.9015-8.el6.noarch
perl-Perlbal-1.78-1.el6.noarch
3.2第二步来配置mogstored.conf ,在node1 ,node2上同时配置。
[root@node1 mogilefs]# vim /etc/mogilefs/mogstored.conf maxconns = 10000 #最大连接并发数 httplisten = 0.0.0.0:7500 mgmtlisten = 0.0.0.0:7501 docroot = /mogilefs/data
3.3,创建需要的数据目录
[root@node1 ~]# mkdir /mogilefs/data
[root@node1 ~]# chown -R mogilefs.mogilefs /mogilefs/
3.4 启动mogstored
[root@node1 mogilefs]# service mogstored start
Starting mogstored [ OK ]
[root@node1 mogilefs]# ss -tnl
LISTEN 0 128 *:7500 *:*
LISTEN 0 128 *:7501 *:*
3.5 要实现对此节点的控制需要在node1:tracker上安装
MogileFS-Utils-2.19-1.el6.noarch.rpm
perl-MogileFS-Client-1.14-1.el6.noarch.rpm
4.1下来我们来为tracker添加主机
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 host add node1 --ip=172.16.18.1 --status=alive
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 host add node2 --ip=172.16.18.2 --status=alive
查看添加的主机:
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 host list
node1 [1]: alive
IP: 172.16.18.1:7500
node2 [2]: alive
IP: 172.16.18.2:7500
可以标记那个节点软下线
mogadm --trackers=172.16.18.3:7001 host mask node1 down
4.2添加设备
查看设备。可以看到有两个节点,但是上边什么设备都没有
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 device list
node1 [1]: alive
used(G) free(G) total(G) weight(%)
node2 [2]: alive
used(G) free(G) total(G) weight(%)
添加设备的语法
mogadm device add <hostname> <devid> [opts] Add a device to a host.
<devid> Numeric devid. Never reuse these.
<hostname> Hostname to add a device
--status=s One of ‘alive‘ or ‘down‘. Defaults to ‘alive‘.
添加设备并查询
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 device add node1 1 --status=alive
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 device add node2 2 --status=alive
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 device list
node1 [1]: alive
used(G) free(G) total(G) weight(%)
dev1: alive 0.000 0.000 0.000 100
node2 [2]: alive
used(G) free(G) total(G) weight(%)
dev2: alive 0.000 0.000 0.000 100
设备添加进来了,可是设备的大小都为0
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 device summary
Hostname HostID Status used(G) free(G) total(G) %Used
node1 [ 1]: alive 0.000 0.000 0.000
node2 [ 2]: alive 0.000 0.000 0.000
那么在node1创建/mogilefs/data/dev1 并修改权限
在node2创建/mogilefs/data/dev2 同上
[root@node1 ~]# chown -R mogilefs.mogilefs /mogilefs/
[root@node2 data]# chown -R mogilefs.mogilefs /mogilefs/
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 device summary
Hostname HostID Status used(G) free(G) total(G) %Used
node1 [ 1]: alive 0.536 18.149 18.686 2.87
node2 [ 2]: alive 0.537 18.148 18.686 2.87
存储大小出来了
4.3 添加domain名称空间
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 domain add file
[root@node3 mogilefs]# mogadm --trackers=172.16.18.3:7001 domain list
domain class mindevcount replpolicy hashtype
-------------------- -------------------- ------------- ------------ -------
file default 2 MultipleHosts() NONE
其中的2是复制时保存几份副本。在class中定义
4.4 上传数据,mogupload
[root@node3 mogilefs]# mogupload --trackers=172.16.18.3:7001 --domain=file --key=‘/fstab‘ --file=‘/etc/fstab‘
4.5 查询上传数据文件mogfileinfo
[root@node3 mogilefs]# mogfileinfo --trackers=172.16.18.3:7001 --domain=file --key=‘/fstab‘
- file: /fstab
class: default
devcount: 2
domain: file
fid: 2
key: /fstab
length: 805
- http://172.16.18.2:7500/dev2/0/000/000/0000000002.fid
- http://172.16.18.1:7500/dev1/0/000/000/0000000002.fid
在浏览器上输入路径,查看内容
再来上传一个图片
[root@node3 mogilefs]# mogupload --trackers=172.16.18.3:7001 --domain=images --key=‘/images‘ --file=‘/usr/share/backgrounds/default.png‘
[root@node3 mogilefs]# mogfileinfo --trackers=172.16.18.3:7001 --domain=images --key=‘/images‘
- file: /images
class: default
devcount: 2
domain: images
fid: 3
key: /images
length: 1470177
- http://172.16.18.2:7500/dev2/0/000/000/0000000003.fid
- http://172.16.18.1:7500/dev1/0/000/000/0000000003.fid
4.6 下载命令语法
[root@node3 mogilefs]# mogfetch --help
Usage: /usr/bin/mogfetch --trackers=host --domain=foo --key=‘/hello.jpg‘ --file=‘./output‘
4.7 重命名语法
[root@node3 mogilefs]# mogrename --help
Usage: /usr/bin/mogrename --trackers=host --domain=foo --class=bar --old_key=‘/hello.jpg‘ --new_key=‘/bye.jpg‘
4.8 列出所有的KEY
[root@node3 mogilefs]# mogrename --help
Usage: /usr/bin/mogrename --trackers=host --domain=foo --class=bar --old_key=‘/hello.jpg‘ --new_key=‘/bye.jpg‘
[root@node3 mogilefs]# moglistkeys --help
Usage: /usr/bin/moglistkeys --trackers=host --domain=foo --key_prefix=‘bar/‘
模型二:
这种模型既可以实现tracker的高可用
但是此时访问存储的数据太过复杂,那么我们又该如何部署使得访问变得简单,不用直接面对设备中的fid数据文件呢?
nginx这个程序具有第三方模块mogilefs就可以实现将url转为存储设备中的fid文件,也可以将fid数据转为url.所以我们只需要基于http协议在浏览器上直接访问数据的url就可以直观的查看到数据文件了。
nginx需要支持第三方模块的话需要自己编译nginx将第三方模块添加进来。
为node1,node2安装tracker.
5.1 编译安装nginx以及第三方模块nginx_mogilefs_module-1.0.4.tar.gz
解压nginx源码包和模块
进入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= ../nginx_mogilefs_module-1.0.4/ #第三方模块的位置
检测有问题,缺少依赖关系
yum install pcre-devel
# make && make install
3、为nginx提供SysV init脚本:
新建文件/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=http://www.mamicode.com/`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@node3 ~]# chmod +x /etc/rc.d/init.d/nginx
添加至服务管理列表,并让其开机自动启动:
[root@node3 ~]# chkconfig --add nginx
[root@node3 ~]# chkconfig nginx off
[root@node3 ~]# service nginx start
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Starting nginx: [ OK ]
启动成功,下边我们来配置nginx的配置文件,让他可以代理tracker,并转换fid格式为url
首先备份一份配置文件,再来编辑
[root@node3 ~]# vim /etc/nginx/nginx.conf http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location /file { mogilefs_tracker 172.16.18.3:7001; mogilefs_domain file; mogilefs_pass { proxy_pass $mogilefs_path; proxy_hide_header Content-Type; proxy_buffering off; } } location /images { mogilefs_tracker 172.16.18.3:7001; mogilefs_domain images; mogilefs_pass { proxy_pass $mogilefs_path; proxy_hide_header Content-Type; proxy_buffering off; } } } }
重启一下nginx
root@node3 nginx-1.6.1]# service nginx restart
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Stopping nginx: [ OK ]
Starting nginx: [ OK ]
访问http://172.16.18.3/file/fstab,可是没有打开,直接下载了?这是为什么呢?
查看一下上传的file中的fstab没有加后缀,可能网页无法识别
再次上传文件,这次给加上后缀.html
[root@node3 ~]# mogupload --trackers=172.16.18.3:7001 --domain=file --key=‘/passwd.html‘ --file=‘/etc/passwd‘
访问没有问题。也重新上传一个图片
[root@node3 ~]# mogupload --trackers=172.16.18.3:7001 --domain=images --key=‘/image.png‘ --file=‘/usr/share/backgrounds/wallpaper-six-2048x1536.png‘
此时基于GET方法的请求文件打开就没有问题了。
mogilefs模块的put方法无法再nginx1.0以上的版本上运行,此处不做介绍。
实现到此结束
本文出自 “aolens·程超” 博客,请务必保留此出处http://aolens.blog.51cto.com/7021142/1560364
MogileFS的分布式文件系统的实现