一,简介
MogileFS是一款开源的分布式文件存储系统,由LiveJournal旗下的Danga Interactive公司开发。Danga团队开发了包括 Memcached、MogileFS、Perlbal 等多个知名的开源项目。目前MogileFS的日益成熟使用此解决方法的公司越来越多,例如日本的又拍、digg、中国的豆瓣、1号店、大众点评、搜狗和安居客等,分别为所在的组织或公司管理着海量的图片。和传统网络存储不一样的是分布式文件系统是将数据分散存储至多台服务器上,而网络文件系统往往是将所有的数据存放在一起,存储服务器将成为系统可用性的瓶颈,不能满足大规模的存放所有数据需求。分布式文件系统采用可扩展的系统结构,利用多台存储设备分别存储,分担服务器负荷,利用位置服务器定位存储信息,因此不仅能够提升系统性能同时还易于扩展。
二、实现组件
MogileFS主要有三个部分组成:
①server端,包括两个部分,mogilefsd和mogstored两个应用程序,tracker是mogilefsd的实现方式,它通过数据库来保证元数据信息,比如站点的domian、class、host等,mogstored则为存储节点,默认监听7500端口,接受客服端的文件存储请求,在MogileFS安装完后,要运行mogadm工具将所有的store node注册到mogilefsd的数据库里,mogilefsd会对这些节点进行管理和监控。
②utils工具集,主要是MogileFS的一些管理工具如mogadm等。
③客服端API,MogileFS的API接口很多,常用的的时间方式有php,perl,python,java等,使用这些语言可进行编写客服端程序,实现文件的备份管理功能。
三、MogileFS的特性及原理
MogileFS特性:
1.应用层服务,不需要使用和兴组件
2.无单点故障,tracker为跟踪点,mogstored为存储节点,mysql为储存元数据节点,建议使用MySQL做高可用
3.传输中立,无特殊协议,可用通过nfs和http实现通信
4.简单的命名空间,没有目录,直接存储在存储空间上,通过域来实现,不共享任何数据
MogileFS工作原理:MogileFS主要由mogilefsd和mogstored两应用程序提供服务,tracker节点借助数据库保存各个节点文件的元数据信息,保存每个域中所哟的存储位置分布,用于实现快速定位同时监控各个节点,通知客户端存储区域位置并指挥storaged节点复制数据副本,进程名为mogilefsd监听与7001端口。storage节点为实际存放文件的地方,存储节点可以是http服务器,及其其他web服务,storage节点可自动维护键值的对应关系,storage节点前端可使用nginx进行反代,此时需要nginx-mogilefs-module-master模块,此服务监听与7501端口,进程名为mogstored.一个域中的键值是唯一的,一个mogilefs可以有多个域,域可以有多个存储设备,每个设备都有数据的容器,称之为domain.每个存储节点为一个主机(host),一个主机上可以有多个存储设备,每个设备有id号,用来定位。复制的最小单元为class,文件属性管理,定义文件存储在不同的设备上的份数。
四、MogileFS安装及其配置实现
安装说明:此实验可以仅适用两台服务进行,一台服务即当做server端,又当做存储节点同时还是mysql服务器,在每台服务器上部署tracker管理并监控节点。
1
2
3
4
5
<code>#在两服务器上均安装如下rpm包</code>
<code>yum -y </code><code>install</code> <code>per-IO-AIO </code><code>#mogilefsd和mogstored依赖于此包,先解决依赖关系。</code>
<code>yum -y </code><code>install</code> <code>MogileFS-Server-2.46-2.el6.noarch.rpm </code><code>#安装sever端</code>
<code>yum -y </code><code>install</code> <code>MogileFS-server-mogilefsd-2.46-2.el6.noarch.rpm </code><code>#安装mogilefsd </code>
<code>yum -y </code><code>install</code> <code>MogileFS-Server-mogstored-2.46-2.rl6.noarch.rpm </code><code>#安装mogstored</code>
创建数据库及授权修改相应的配置文件
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<code>grant all privileges on mogdb.* to </code><code>'moguser'</code><code>@</code><code>'127.0.0.1'</code> <code>identified by </code><code>'pass'</code><code>; </code>
<code>grant all privileges on mogdb.* to </code><code>'moguser'</code><code>@</code><code>'localhost'</code> <code>identified by </code><code>'pass'</code><code>; </code>
<code>flush privileges; </code>
<code>#修改mogilefsd.conf配置文件</code>
<code># Enable daemon mode to work in background and use syslog</code>
<code>daemonize = 1</code>
<code># Where to store the pid of the daemon (must be the same in the init script)</code>
<code>pidfile = </code><code>/var/run/mogilefsd/mogilefsd</code><code>.pid</code>
<code># Database connection information</code>
<code>db_dsn = DBI:mysql:mogdb:host=127.0.0.1 </code><code>#修改为上面授权的账号密码及其主机</code>
<code>db_user = moguser </code><code>#修改为上面授权的账号密码及其主机</code>
<code>db_pass = pass </code><code>#修改为上面授权的账号密码及其主机</code>
<code># IP:PORT to listen on for mogilefs client requests</code>
<code>listen = 0.0.0.0:7001 </code><code>#其他参数可根据自己需求做相应的修改</code>
<code># Optional, if you don't define the port above.</code>
<code>conf_port = 7001</code>
<code># Number of query workers to start by default.</code>
<code>query_jobs = 10</code>
<code># Number of delete workers to start by default.</code>
<code>delete_jobs = 1</code>
<code># Number of replicate workers to start by default.</code>
<code>replicate_jobs = 5</code>
<code># Number of reaper workers to start by default.</code>
<code># (you don't usually need to increase this)</code>
<code>reaper_jobs = 1</code>
<code># Number of fsck workers to start by default.</code>
<code># (these can cause a lot of load when fsck'ing)</code>
<code>#fsck_jobs = 1</code>
<code># Minimum amount of space to reserve in megabytes</code>
<code># default: 100</code>
<code># Consider setting this to be larger than the largest file you</code>
<code># would normally be uploading.</code>
<code>#min_free_space = 200</code>
<code># Number of seconds to wait for a storage node to respond.</code>
<code># default: 2</code>
<code># Keep this low, so busy storage nodes are quickly ignored.</code>
<code>#node_timeout = 2</code>
<code># Number of seconds to wait to connect to a storage node.</code>
<code># Keep this low so overloaded nodes get skipped.</code>
<code>#conn_timeout = 2</code>
<code># Allow replication to use the secondary node get port,</code>
<code># if you have apache or similar configured for GET's</code>
<code>#repl_use_get_port = 1</code>
<code>#mogstored配置文件,一般无需修改,自行根据业务需求做决定 </code>
<code>maxconns = 10000</code>
<code>httplisten = 0.0.0.0:7500</code>
<code>mgmtlisten = 0.0.0.0:7501</code>
<code>docroot = </code><code>/data/mogstored</code>
<code>#将上诉配置考别一份至其他主机,并且启动服务,安装后默认在Init.d下有启动脚本</code>
<code>service mogilefsd start </code>
<code>service mogstored start </code>
<code>[root@centos6 mogilefs]</code><code># ss -tnl |grep *.7.* #默认mogilefsd监听7001,mogstored监听7501及其7501</code>
<code>LISTEN 0 128 *:7500 *:*</code>
<code>LISTEN 0 128 *:7501 *:*</code>
<code>LISTEN 0 128 *:7001 *:*</code>
<code>[root@node mogilefs]</code><code>#</code>
<code>#设置数据库,存储元数据</code>
<code>mogdbsetup --dbhost=127.0.0.1 --dbpass=pass </code>
<code>mogdbsetup --dbname=mogdb --dbuser=moguser --dbhost=127.0.0.1 --dbpass=pass </code>
<code>mogadm host add 10.1.100.1 --ip=10.1.100.1 --port=7500 --status=alive </code><code>#添加host,storaged</code>
<code>mogadm domain add files </code><code>#添加域</code>
<code>mogadm domain add images </code>
<code>[root@centos6 ~]</code><code># mogstats --db_dsn="DBI:mysql:mogdb:host=localhost" --db_user="moguser" --db_pass="pass" --stats="all"</code>
<code>Fetching statistics... (all)</code>
<code>Statistics </code><code>for</code> <code>devices... </code><code>#表示此storage设备存活 </code>
<code> </code><code>device host files status</code>
<code> </code><code>---------- ---------------- ------------ ----------</code>
<code> </code><code>dev1 10.1.100.1 2 alive </code>
<code> </code><code>dev3 10.1.100.2 1 alive</code>
<code> </code><code>dev4 10.1.100.2 1 alive</code>
<code>Statistics </code><code>for</code> <code>file</code> <code>ids...</code>
<code> </code><code>Max </code><code>file</code> <code>id</code><code>: 9</code>
<code>Statistics </code><code>for</code> <code>files... </code><code>#添加的域显示结果</code>
<code> </code><code>domain class files size (m) fullsize (m)</code>
<code> </code><code>-------------------- ----------- ---------- ----------- -------------</code>
<code> </code><code>files default 1 0 0</code>
<code> </code><code>images default 1 0 0</code>
<code>Statistics </code><code>for</code> <code>replication... </code><code>#默认的类示结果</code>
<code> </code><code>domain class devcount files</code>
<code> </code><code>-------------------- ----------- ---------- ----------</code>
<code> </code><code>files default 2 1</code>
<code> </code><code>images default 2 1</code>
<code>Statistics </code><code>for</code> <code>replication queue...</code>
<code> </code><code>status count</code>
<code> </code><code>-------------------- ------------</code>
<code>Statistics </code><code>for</code> <code>delete queue...</code>
<code>Statistics </code><code>for</code> <code>general queues...</code>
<code> </code><code>queue status count</code>
<code> </code><code>--------------- -------------------- ------------</code>
<code>done</code>
<code>[root@node ~]</code><code>#</code>
<code>[root@node~]</code><code># mogupload --trackers=10.1.100.1 --domain=files --key='/issue' --file='/etc/issue' #上传文件至files域内,指明可Key和上传的文件目录</code>
<code>[root@node ~]</code><code># moglistkeys --trackers=10.1.100.1 --domain=files #显示域内文件</code>
<code>/fstab</code><code>.txt</code>
<code>/issue</code>
<code>[root@node ~]</code><code># mogfetch --trackers=10.1.100.1 --domain=files --key='/issue' --file='/tmp/issue' #下载域内文件至某目录 </code>
<code>[root@node ~]</code><code># ll /tmp/issue</code>
<code>-rw-r--r--. 1 root root 47 11月 25 16:48 </code><code>/tmp/issue</code>
<code>-</code><code>bash</code><code>: ogfileinfo: </code><code>command</code> <code>not found</code>
<code>[root@node2 ~]</code><code># mogfileinfo --tracker=10.1.100.1 --domain=files --key='/fstab.txt'</code>
<code>- </code><code>file</code><code>: </code><code>/fstab</code><code>.txt</code>
<code> </code><code>class: default</code>
<code> </code><code>devcount: 2</code>
<code> </code><code>domain: files</code>
<code> </code><code>fid: 5</code>
<code> </code><code>key: </code><code>/fstab</code><code>.txt</code>
<code> </code><code>length: 1115</code>
<code> </code><code>-http:</code><code>//10</code><code>.1.100.2:7500</code><code>/dev4/0/000/000/0000000005</code><code>.fid </code><code>#可通过此URL访问到相应的资源</code>
<code> </code><code>-http:</code><code>//10</code><code>.1.100.1:7500</code><code>/dev1/0/000/000/0000000005</code><code>.fid </code><code>#可通过此URL访问到相应的资源</code>
<code>[root@node2 ~]</code><code>#</code>
实验结果图示:
五、实战nginx前端反代mogfilefs及负载均衡
要求说明:在前期那配置nginx做反代将用户的请求调度至后端的MogileFS,此实验依赖于nginx-mogilefs-module模块,需在编译时加上此模块。
130
131
132
133
134
<code>#实战配置如下所示:</code>
<code>#user nobody;</code>
<code>worker_processes 1;</code>
<code>#error_log logs/error.log;</code>
<code>#error_log logs/error.log notice;</code>
<code>#error_log logs/error.log info;</code>
<code>#pid logs/nginx.pid;</code>
<code>events {</code>
<code> </code><code>worker_connections 1024;</code>
<code>}</code>
<code>http {</code>
<code> </code><code>include mime.types;</code>
<code> </code><code>default_type application</code><code>/octet-stream</code><code>;</code>
<code> </code><code>#log_format main '$remote_addr - $remote_user [$time_local] "$request" '</code>
<code> </code><code># '$status $body_bytes_sent "$http_referer" '</code>
<code> </code><code># '"$http_user_agent" "$http_x_forwarded_for"';</code>
<code> </code><code>#access_log logs/access.log main;</code>
<code> </code><code>sendfile on;</code>
<code> </code><code>#tcp_nopush on;</code>
<code> </code><code>#keepalive_timeout 0;</code>
<code> </code><code>keepalive_timeout 65;</code>
<code> </code><code>#gzip on;</code>
<code> </code><code>#</code>
<code> </code><code>upstream mogtrackers { </code><code>#定义一个upstream组</code>
<code> </code><code>server 10.1.100.1:7001;</code>
<code> </code><code>server 10.1.100.2:7001;</code>
<code> </code><code>}</code>
<code> </code><code>server {</code>
<code> </code><code>listen 80;</code>
<code> </code><code>server_name localhost;</code>
<code> </code><code>#charset koi8-r;</code>
<code> </code><code>#access_log logs/host.access.log main;</code>
<code> </code><code>location / {</code>
<code> </code><code>root html;</code>
<code> </code><code>index index.html index.htm;</code>
<code> </code><code>}</code>
<code> </code><code>location </code><code>/images/</code> <code>{</code>
<code> </code><code>mogilefs_tracker mogtrackers; </code><code>#在此调用此mogtrackers即可实现反代至mogilefs后端</code>
<code> </code><code>mogilefs_domain images; </code><code>#域为images域 </code>
<code> </code><code>mogilefs_methods get; </code><code>#请求的方法为get</code>
<code> </code><code>mogilefs_pass {</code>
<code> </code><code>proxy_pass $mogilefs_path;</code>
<code> </code><code>proxy_hide_header Content-Type;</code>
<code> </code><code>proxy_buffering off;</code>
<code> </code><code>}</code>
<code> </code><code>expires 1h;</code>
<code> </code><code>#error_page 404 /404.html;</code>
<code> </code><code># redirect server error pages to the static page /50x.html</code>
<code> </code><code>#</code>
<code> </code><code>error_page 500 502 503 504 </code><code>/50x</code><code>.html;</code>
<code> </code><code>location = </code><code>/50x</code><code>.html {</code>
<code> </code><code># proxy the PHP scripts to Apache listening on 127.0.0.1:80</code>
<code> </code><code>#location ~ \.php$ {</code>
<code> </code><code># proxy_pass http://127.0.0.1;</code>
<code> </code><code>#}</code>
<code> </code><code># pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000</code>
<code> </code><code># root html;</code>
<code> </code><code># fastcgi_pass 127.0.0.1:9000;</code>
<code> </code><code># fastcgi_index index.php;</code>
<code> </code><code># fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;</code>
<code> </code><code># include fastcgi_params;</code>
<code> </code><code># deny access to .htaccess files, if Apache's document root</code>
<code> </code><code># concurs with nginx's one</code>
<code> </code><code>#location ~ /\.ht {</code>
<code> </code><code># deny all;</code>
<code> </code><code># another virtual host using mix of IP-, name-, and port-based configuration</code>
<code> </code><code>#server {</code>
<code> </code><code># listen 8000;</code>
<code> </code><code># listen somename:8080;</code>
<code> </code><code># server_name somename alias another.alias;</code>
<code> </code><code># location / {</code>
<code> </code><code># root html;</code>
<code> </code><code># index index.html index.htm;</code>
<code> </code><code># }</code>
<code> </code><code>#}</code>
<code> </code><code># HTTPS server</code>
<code> </code><code># listen 443 ssl;</code>
<code> </code><code># server_name localhost;</code>
<code> </code><code># ssl_certificate cert.pem;</code>
<code> </code><code># ssl_certificate_key cert.key;</code>
<code> </code><code># ssl_session_cache shared:SSL:1m;</code>
<code> </code><code># ssl_session_timeout 5m;</code>
<code> </code><code># ssl_ciphers HIGH:!aNULL:!MD5;</code>
<code> </code><code># ssl_prefer_server_ciphers on;</code>
图示:此时可通过http://uri/images/aqua.jpg进行访问,而不是原来很长的路径名进行访问。
<a href="http://s2.51cto.com/wyfs02/M01/8A/E0/wKiom1g9jpeBs6vPAAZv02hKaYM494.png" target="_blank"></a>
总结:在大型站点中,mogilefs的重要性不言而喻,尤其是图片存储量很大的网站例如:某宝,某东等,此配置过程中,mysql易于成为单点故障,所以可将其做主从复制,同时结合MySQL半同步复制,可降低数据的丢失风险。在配置nginx做反向代理时,大部分步骤和其他反代类是不同的是,需将模块编译进nginx中才能使用此模块功能。
本文转自chengong1013 51CTO博客,原文链接:http://blog.51cto.com/purify/1878002,如需转载请自行联系原作者