前端nginx反代后端mogilefs存储实战教程
网络上很多文章,都有些不完善,自己整理了一下,并对一些已知的错误,进行修改处理,已经完善了MogileFS的特点:
1).工作于应用层,没有特殊的组件要求;
2).无单点,tracker节点可以高可用,存储节点可以存储多个数据副本,对应数据库有高可用方案;
3).实现自动文件复制,默认副本是2份;建议存三份;
4).传输中立,无须特殊协议,MogileFS客户端可以通过NFS或HTTP来和MogileFS的存储节点来通信,但首先需要告知跟踪器一下。
5).使用名称空间(命名空间),每个文件通过key来确定,domain,切割成不同的空间,单个空间的名称不重复,也可以根据应用来分空间;
domain内部有多个小的组件组成,成为class类,整个空间由不同节点提供的,每个文件需要存副本,在数据库中保存元数据,也适用于存储海量小文件,class把多个文件合并起来当作一个复制最小单元;
6).无需raid,但比raid更优,MogileFS在不同的机器之间进行文件复制,因此文件始终是可用的。
7).不共享任何数据,MogileFS不需要依靠昂贵的SAN来共享磁盘,每个机器只用维护好自己的磁盘。
工作流程:
1).客户端向服务器发送请求,nginx服务器将请求接收;
2).nginx服务器通过反向代理挑选后端一台trackers服务器响应请求;
3).trackers接收到请求后再向后端数据库获取数据存储的位置;
4).数据库返回数据存储位置给trackers;
5).trackers接收到数据库响应回来的数据位置后再响应给nginx;
6).nginx服务器接收到trackers响应回来的数据位置后再到Stored服务器上获取实际的存储数据;
7).stored服务器再响应数据给nginx代理服务器;
8).nginx服务器拿到最终数据之后再发送给客户端;
一、MogileFS存储
1、MogileFS分布式文件存储系统
MogileFS是一个开源的分布式文件存储系统,由LiveJournal旗下的Danga Interactive公司开发。Danga团队开发了包括 Memcached、MogileFS、Perlbal 等多个知名的开源项目。目前使用MogileFS 的公司非常多,如日本排名先前的几个互联公司及国内的yupoo(又拍)、digg、豆瓣、1号店、大众点评、搜狗和安居客等,分别为所在的组织或公司管理着海量的图片。
2、MogileFS由3个部分组成:
MogileFS结构
(1) server:主要包括mogilefsd和mogstored两个应用程序。mogilefsd实现的是tracker,它通过数据库来保存元数据信息,包括站点domain、class、host等;mogstored是存储节点(store node),它其实是个WebDAV服务,默认监听在7500端口,接受客户端的文件存储请求。在MogileFS安装完后,要运行mogadm工具将所有的store node注册到mogilefsd的数据库里,mogilefsd会对这些节点进行管理和监控。
(2) utils(工具集):主要是MogileFS的一些管理工具,例如mogadm等。
(3) 客户端API:MogileFS的客户端API很多,例如Perl、PHP、Java、Python等,用这个模块可以编写客户端程序,实现文件的备份管理功能等。
3、设备定义
存储主机(节点)这个是 MogileFS 存储文件存放在这些机器上,也是 mogstored 节点,也叫 Storage Server,一台存储主要都要启动一个 mogstored 服务.扩容就是增加这些机器.
设备(device)
[*]一个存储节点,以就是上面的主机,可以有多个 device, 就是用来存放文件的目录(例如挂载的目录),
[*]每个设备都有一个设备id,需要在 mogstored 的配置文件中的 docroot 配置的项目 指定的目录下面创建相应的设备的目录,目录名为 $docroot/dev$id,设备是不能删除的.
[*]只能将其设备的状态的值置为dead,当一个设备 dead 之后,就真的 dead了,里面的数据也无法恢复了,且这个dead了的设备的 id 也不能再用.
存储Domain域
[*]一个MogileFS可以有多个Domain
[*]用来存放不同的文件(大小、类型)
[*]同一个Domain内,key必需唯一
[*]不同的Domain内,key可以相同
存储Class类
[*]文件属性
[*]定义文件存储在不同设备上的分数
[*]存储key(Fid)文件地址
[*]Domain和文件的key(Fid)一起定位文件位置
二、MogileFS存储安装
三种安装方式:cpan安装、cpanm安装,rpm包安装
这里我们使用rpm包安装
1、cpan安装
[*]# yum -y install make gcc unzip perl-DBD-MySQL perl perl-CPAN perl-YAML perl-Time-HiRes
[*]
[*]# cpan
[*]App::cpanminus
[*]MogileFS::Server
[*]MogileFS::Utils
[*]IO::AIO
[*]IO::WrapTie
[*]Danga::Socket
2、cpanm安装
[*]wget http://xrl.us/cpanm -O /usr/bin/cpanm; sudo chmod +x /usr/bin/cpanm
[*]
[*]#cpanm DBD::mysql
[*]#cpanm MogileFS::Server
[*]#cpanm MogileFS::Utils
[*]#cpanm MogileFS::Client
[*]
[*]
[*]所有的perl程序可以编译运行:
[*]# perl Makefile.PL
[*]# make
[*]# make test
[*]# make install
[*]
[*]
[*]# cpan -i App::cpanminus
[*]cpan> install App:cpanminus
[*]
[*]
[*]# cpan MogileFS::Server
[*]
[*]conf:
[*]/etc/mogilefs/{mogifsd.conf, mogstored.conf}
3、rpm安装,centos6支持较好
rpm包下载地址:
MogileFS-Server-2.46-2.el6.noarch.rpm
perl-Danga-Socket-1.61-1.el6.rf.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-Perlbal-1.78-1.el6.noarch.rpm
MogileFS-Utils-2.19-1.el6.noarch.rpm
Perlbal-1.78-1.el6.noarch.rpm
三、nginx反代后端mogilefs存储示例
使用CentOS 7环境部署
172.31.225.243----节点1+mogilefsd+mogstored+marriadb
172.31.225.244----节点2+mogilefsd+mogstored
172.31.225.246----节点3+mogilefsd+mogstored
172.31.225.245----nginx代理
节点1
由于依赖于perl环境所以先安装epel源
#安装epel源和perl依赖包
# yum install epel-release
#yum install perl-Net-Netmask perl-IO-String perl-Sys-Syslog perl-IO-AIO -y
# ls *.rpm -l
-rw-r--r-- 1 root root 1916 Aug 11 2016 MogileFS-Server-2.46-2.el6.noarch.rpm
-rw-r--r-- 1 root root 176308 Aug 11 2016 MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm
-rw-r--r-- 1 root root 26872 Aug 11 2016 MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm
-rw-r--r-- 1 root root 75916 Aug 11 2016 MogileFS-Utils-2.19-1.el6.noarch.rpm
-rw-r--r-- 1 root root 5880 Aug 11 2016 Perlbal-1.78-1.el6.noarch.rpm
-rw-r--r-- 1 root root 28111 Nov 11 2010 perl-Danga-Socket-1.61-1.el6.rf.noarch.rpm
-rw-r--r-- 1 root root 30312 Aug 11 2016 perl-MogileFS-Client-1.14-1.el6.noarch.rpm
-rw-r--r-- 1 root root 268620 Aug 11 2016 perl-Perlbal-1.78-1.el6.noarch.rpm
#安装perl的rpm包
# yum install ./*.rpm -y
#安装数据库
# yum install mariadb-server -y
#查看文件目录属主属组
# ls -ld /var/run/mogilefsd/
drwxr-xr-x 2 mogilefs mogilefs 80 Oct 28 16:01 /var/run/mogilefsd/
#编辑配置文件
# cd /etc/mogilefs/
# cp mogilefsd.conf{,.bak}
# vim mogilefsd.conf
daemonize = 1
pidfile = /var/run/mogilefsd/mogilefsd.pid
DBI:mysql:mogilefs:host=172.31.225.243 #驱动格式:数据库类型:数据库名称:数据库主机ip
db_user = moguser #数据库用户
db_pass = mogpass #数据库密码
listen = 0.0.0.0:7001 #监听端口
conf_port = 7001
query_jobs = 10
delete_jobs = 1
replicate_jobs = 5
reaper_jobs = 1
#数据库初始化
# vim /etc/my.cnf.d/server.cnf
skip_name_resolve = ON
innodb_file_per_table = ON
# systemctl start mariadb
#自定义创建数据库用户
MariaDB [(none)]> GRANT ALL ON mogilefs.* TO 'root'@'172.31.225.%' IDENTIFIED BY 'cnblackhat';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> GRANT ALL ON mogilefs.* TO 'moguser'@'172.31.225.%' IDENTIFIED BY 'mogpass';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
#初始化
# mogdbsetup --dbhost=172.31.225.243 --dbrootpass='cnblackhat' --dbuser='moguser' --dbpass='mogpass'
Continue? : y #是否初始化数据库
Create/Upgrade database name 'mogilefs'? : y #是否创建数据库
Grant all privileges to user 'moguser', connecting from anywhere, to the mogilefs database 'mogilefs'? : y #是否创建数据库用户
!(https://upload-images.jianshu.io ... imageView2/2/w/1240)
#启动mogilefsd和mogstored会报错,以及当系统重启时,/var/run/mogilefsd目录会被自动删除
解决方案:直接修改/etc/rc.d/init.d/mogilefsd和/etc/rc.d/init.d/mogstored,以及添加/usr/lib/systemd/system/mogilefsd.service(因为mogilefsd以来mariadb服务,只有mariadb服务启动之后,mogilefsd服务才能启动成功),直接看截图:
mogilefsd添加的配置截图
mogstored添加的配置截图
mogilefsd添加的启动服务,以systemctl start mogilefsd启动服务
启动服务
# service mogilefsd start
Starting mogilefsd (via systemctl): [ OK ]
#设置
# cd /etc/mogilefs
# cp mogstored.conf {,.bak}
# vim mogstored.conf
maxconns = 10000 #最大连接数
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /mogilefs/data #储存路径
启动mogstored服务
# service mogstored start
Starting mogstored (via systemctl): [ OK ]
开机器自启动:
# systemctl enable mariadb
Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
# systemctl enable mogilefsd
Created symlink from /etc/systemd/system/multi-user.target.wants/mogilefsd.service to /usr/lib/systemd/system/mogilefsd.service.
# chkconfig mogstored on
#创建存储目录,设置属主组为mogilefs
# mkdir /mogilefs/data/dev1 -pv
# chown -R mogilefs.mogilefs /mogilefs/
#当其他节点启动后,添加主机
# mogadm host add 172.31.225.243 --ip=172.31.225.243 --port=7500 --status=alive
# mogadm host add 172.31.225.244 --ip=172.31.225.244 --port=7500 --status=alive
# mogadm host add 172.31.225.246 --ip=172.31.225.246 --port=7500 --status=alive
#检查主机情况
# mogadm check
Checking trackers...
127.0.0.1:7001 ... OK
Checking hosts...
[ 1] 172.31.225.243 ... OK
[ 2] 172.31.225.244 ... OK
[ 3] 172.31.225.246 ... OK
#添加储存设备
# mogadm device add 172.31.225.243 1
# mogadm device add 172.31.225.244 2
# mogadm device add 172.31.225.246 3
# mogadm device list
172.31.225.243 : alive
used(G) free(G) total(G) weight(%)
dev1: alive 1.267 6.720 7.986 100
172.31.225.244 : alive
used(G) free(G) total(G) weight(%)
dev2: alive 1.126 6.860 7.986 100
172.31.225.246 : alive
used(G) free(G) total(G) weight(%)
dev3: alive 1.126 6.860 7.986 100
节点2和节点3配置#同步时间 (不会的自行百度)
#安装epel源
# yum install epel-release
#yum install perl-Net-Netmask perl-IO-String perl-Sys-Syslog perl-IO-AIO -y
#安装rpm包 (同节点1一样的安装步骤)
节点1 拷贝配置文件和脚本至节点2和节点3上
#配置文件拷贝到其他节点上
# scp -r /etc/mogilefs/*.conf 172.31.225.244:/etc/mogilefs/
# scp -r /etc/mogilefs/*.conf 172.31.225.246:/etc/mogilefs/
脚本文件拷贝到其他节点上
# scp -r /etc/rc.d/init.d/mogilefsd 172.31.225.244:/etc/rc.d/init.d/
# scp -r /etc/rc.d/init.d/mogstored 172.31.225.246:/etc/rc.d/init.d/
节点2和节点3上启动
启动服务:
# service mogilefsd start
Starting mogilefsd (via systemctl): [ OK ]
# service mogstored start
Starting mogstored (via systemctl): [ OK ]
开机器自启动:
# chkconfig mogstored on
Created symlink from /etc/systemd/system/multi-user.target.wants/mogilefsd.service to /usr/lib/systemd/system/mogilefsd.service.
# chkconfig mogstored on
mog工具mogadm
mogdelete #删除文件
mogfileinfo #看文件信息
moglistkeys #列出所有文件的键
mogstored
mogautomount
mogfetch #获取文件
mogilefsd
mogrename
mogtool
mogdbsetup
mogfiledebug
moglistfids #列出所有文件的id
mogstats
mogupload #上传文件
mogilefs使用
#创建imgs域和text域
# mogadm domain add imgs
# mogadm domain add text
#查询当前域,副本存储2个
# mogadm domain list
domain class mindevcount replpolicy hashtype
-------------------- -------------------- ------------- ------------ -------
imgs default 2 MultipleHosts() NONE
text default 2 MultipleHosts() NONE
#在imgs域中创建png类,哈希类型为MD5,副本存储3个
# mogadm class add imgs png --hashtype=MD5 --mindevcount=3
#在imgs域中创建jpg类,哈希类型为空,副本存储2个
# mogadm class add imgs jpg --hashtype=NONE --mindevcount=2
#查询当前类
# mogadm class list
domain class mindevcount replpolicy hashtype
-------------------- -------------------- ------------- ------------ -------
imgs default 2 MultipleHosts() NONE
imgs jpg 2 MultipleHosts() NONE
imgs png 3 MultipleHosts() MD5
text default 2 MultipleHosts() NONE
mog上传文件
#上传图片文件到imgs域,key为linux0.jpg
# mogupload --trackers=172.31.225.243:7001 --domain=imgs --key='linux0.jpg' --file='./14.png'
#查询上传图片位置
# mogfileinfo --trackers=172.31.225.243 --domain=imgs --key='linux0.jpg'
- file: linux0.jpg
class: default
devcount: 2
domain: imgs
fid: 41
key: linux0.jpg
length: 139764
- http://172.31.225.243:7500/dev1/0/000/000/0000000041.fid
- http://172.31.225.244:7500/dev2/0/000/000/0000000041.fid
#文件id位置,存储到节点1和节点2的服务器上
#上传图片文件到imgs域,jpg类中,key为linux4.jpg
# mogfileinfo --trackers=172.31.225.243 --domain=imgs --key='linux4.jpg'
- file: linux4.jpg
class: default
devcount: 2
domain: imgs
fid: 36
key: linux4.jpg
length: 28448
- http://172.31.225.243:7500/dev1/0/000/000/0000000036.fid
- http://172.31.225.244:7500/dev2/0/000/000/0000000036.fid
测试两个tracker可用# mogfileinfo --trackers=172.31.225.244 --domain=imgs --key='linux0.jpg'
- file: linux0.jpg
class: default
devcount: 2
domain: imgs
fid: 41
key: linux0.jpg
length: 139764
- http://172.31.225.243:7500/dev1/0/000/000/0000000041.fid
- http://172.31.225.244:7500/dev2/0/000/000/0000000041.fid
# mogfileinfo --trackers=172.31.225.246 --domain=imgs --key='linux0.jpg'
- file: linux0.jpg
class: default
devcount: 2
domain: imgs
fid: 41
key: linux0.jpg
length: 139764
- http://172.31.225.243:7500/dev1/0/000/000/0000000041.fid
- http://172.31.225.244:7500/dev2/0/000/000/0000000041.fid
访问一下:
安装nginx反代服务器(172.31.225.245)
#安装开发组件
# yum groupinstall "Development Tools" "Server Platform Development" -y
#安装支持正则表达式组件
# yum install pcre-devel openssl-devel -y
#添加nginx用户
# useradd -r nginx
# id nginx
uid=998(nginx) gid=996(nginx) groups=996(nginx)
#下载编译安装nginx
# wget http://nginx.org/download/nginx-1.6.3.tar.gz
nginx_mogilefs_module-1.0.4.tar.gz下载地址:
# tar xf nginx_mogilefs_module-1.0.4.tar.gz
# cd nginx-1.6.3
# ./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
#跳过编译错误
# make CFLAGS="-pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -g"
#安装
# make install
#启动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
# chmod +x /etc/rc.d/init.d/nginx
# service nginx start
Reloading systemd: [ OK ]
#添加至服务管理列表,并让其开机自动启动:
# chkconfig --add nginx
# chkconfig nginx on
#编辑nginx反代规则
# cd /etc/nginx
# cp nginx.conf{,.bak}
# vim nginx.conf
......
worker_processes auto;
......
upstream mogsrvs { #定义服务器组
server 172.31.225.243:7001;
server 172.31.225.244:7001;
server 172.31.225.246:7001;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
location /imgs/ {
mogilefs_tracker mogsrvs; #调用服务器组
mogilefs_domain imgs; #默认域
mogilefs_methods GET PUT DELETE;
mogilefs_class png jpg; #默认类
mogilefs_pass {
proxy_pass $mogilefs_path;
proxy_hide_header Content-Type;
proxy_buffering off;
}
}
# nginx -t #语法检查
# nginx -s reload #重载nginx
测试访问
附:
MogileFS表说明
MogileFS大致的表说明如下
checksum:用来存放文件的校验和
class:文件分类定义
device:主机上的可用设备定义,包括设备可用空间,使用的权重等信息
domain:域定义信息
file:记录文件的基本信息,属于什么类别,key和文件大小等信息
file_on:记录什么设备上有什么文件,一个文件在不同设备上的存储各有一条记录
file_on_corrupt:损坏的文件,哪一个文件在哪个设备上损坏了
file_to_delete:记录要做删除的文件
file_to_delete2:记录做删除失败的信息,包括下次重试时间和失败次数
file_to_delete_later:要延迟删除的文件
file_to_queue:队列中的文件,通常是操作失败了,进入队列等待下次操作
file_to_replicate:要做复制的文件,记录来源设备,失败次数和下次重试的时间等信息
fsck_log:文件检查日志
host:主机定义,主机的ip,存储节点服务所开的端口等信息
server_settings:服务器的一些配置信息,采用key=>value的记录方式保存
tmpfile:复制的临时文件信息
unreachable_fids:不可到达的文件列表
参考链接:https://www.jianshu.com/p/afe2977dc538
页:
[1]