什么是分布式存储
分布式存储系统,是将数据分散存储在多台独立的设备上。传统的网络存储系统采用集中的存储服务器存放所有数据,存储服务器成为系统性能的瓶颈,也是可靠性和安全性的焦点,不能满足大规模存储应用的需要。分布式网络存储系统采用可扩展的系统结构,利用多台存储服务器分担存储负荷,利用位置服务器定位存储信息,它不但提高了系统的可靠性、可用性和存取效率,还易于扩展
CAP理论
C:Consistency(一致性) 任何一个读操作总是能够读取之前完成的写操作。
A:Availability(可用性) 每一次操作总是能够在确定的时间返回。
P: Partition Tolerance ( 分区容错性 ) 在出现网络分区的情况下,仍然能够满足一致性和可用性。
有科学家都在致力于 CAP 三元素并存的时候,Eric.Brewer教授指出 CAP 永远无法兼顾,只能根据具体应用来权衡和取舍,并且至多两个元素可以共存,后来由两位麻省理工学院的科学家证明此观点是具有前瞻性的,由此形成Brewer的 CAP定理 。
正所谓鱼和熊掌不可兼得,关注一致性就需要处理因系统不可用而带来写操作失败的情况,反之关注可用性就无法保证每次都能读取到最新的写入操作。传统 关系型数据库 侧重于CA ,而 非关系型键值数据库 则侧重于 AP 。
强一致性(ACID) :在单机环境中,强一致性可以由数据库的事务来保证;在分布式环境中,强一致性很难做到,即便是做到也会因为分布式事物所带来的性能低下,不适合在互联网的环境中应用。
弱一致性(包括最终一致性) : 系统不能保证后续访问返回最新的值,在访问到最新值之前这段时间称之为 不一致窗口 。
最终一致性 :是弱一致性的一种特例,存储系统保证如果对象有多次更新,在渡过 不一致窗口之后必将放回最后更新的值。
MogilesFS介绍
MogilesFS简介
MogileFS是一个开源的分布式文件系统,用于组建分布式文件集群,由LiveJournal旗下DangaInteractive公司开发,Danga团队开发了包括 Memcached、MogileFS、Perlbal等不错的开源项目:(注:Perlbal是一个强大的Perl写的反向代理服务器)。MogileFS是一个开源的分布式文件系统。
目前使用 MogileFS 的公司非常多,比如国外的一些公司,日本前几名的公司基本都在使用这个,国内所知道的使用 MogileFS 的公司有图片托管网站 yupoo又拍,digg, 土豆, 豆瓣,1 号店, 大众点评,搜狗,安居客等等网站.分别为所在的组织或公司管理着海量的图片。
MogileFS特性
1 ) 支持多节点冗余
2)可实现自动的文件复制
3)使用名称空间(命名空间),每个文件通过key来确定,比如123.jpg是一个key,真正存储的位置可能是/000/000/00/01/md5hash.fid
4)不需要RAID,应用层可直接实现RAID,不共享任何东西,通过”集群接口”提供服务
5)工作于应用层,没有特殊的组件要求
6)不用共享任何数据,MogileFS不需要依靠昂贵的SAN来共享磁盘,每个机器只用维护好自己的磁盘
MogileFS的工作原理
MogileFS的架构
MogileFS主要由三部分构成:tracker节点、database节点、storage节点
1)Tracker–跟踪器,调度器
MogileFS的核心,是一个调度器,mogilefsd进程就是trackers进程程序,trackers的主要职责有:删除数据、复制数据、监控、查询等等,这个是基于事件的( event-based ) 父进程/消息总线来管理所有来自于客户端应用的交互, 包括将请求负载平衡到多个”query workers”中,然后让 mogilefs的子进程去处理,mogadm,mogtool的所有操作都要跟trackers打交道,Client的一些操作也需要定义好trackers,因此最好同时运行多个trackers来做负载均衡,trackers也可以只运行在一台机器上,使用负载均衡时可以使用一些简单的负载均衡解决方案,如haproxy,lvs,nginx等,tarcker的配置文件为/etc/mogilefs/mogilefsd.conf,监听在TCP的7001端口
2)Database–数据库部分
主要用来存储mogilefs的元数据(命名空间和文件在哪里等),是trackers来操作和管理它,可以用mogdbsetup程序来初始化数据库,所有的元数据都存储在数据库中,因此,这个数据相当重要,如果数据库挂掉,所有的数据都不能用于访问,因此,建议应该对数据库做高可用
3)storage–存储节点
这个是MogileFS存储数据的真正节点,也是mogstored节点,也叫storage server,一台存储节点要启动一个mogstored服务,扩容就是增加这些主机节点实际存放数据的地方
配置文件为/etc/mogilefs/mogstored.conf,监听在TCP的7500端口
MogileFS管理
1、Domain:一个mogilefs可以有多个domain,用来存放不同文件(大小、类型),同一个domain内key必须唯一,不同domain内key可以是相同的
2、每个存储节点称为一个host主机,一个主机上可以有多个存储设备dev(单独的硬盘),每个设备都有一个ID号,Domain+Fid来定位文件
3、Class:文件属性管理,复制文件的最小单位不是文件,而是class,定位文件存储在不同设备上的份数,也就是定义副本的数量
环境
准备三台主机
node1: tracker节点、database节点、storage节点
node2: storage节点
node3: storage节点
注意关掉防火墙和selinux,iptables -F && setenforce 0
安装
安装 mogilefs-server
三台主机下载安装 MogileFS rpm
链接: https://pan.baidu.com/s/1lJqligm7yQlaD6dQM2DcMg 密码: m4m31
2
3
4
5
6
7
8
9
10
11
12[root@node0 mogilefs]# ls -l
total 648
-rw-r--r-- 1 root root 1916 Feb 21 2017 MogileFS-Server-2.46-2.el6.noarch.rpm
-rw-r--r-- 1 root root 176308 Feb 21 2017 MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm
-rw-r--r-- 1 root root 26872 Feb 21 2017 MogileFS-Server-mogstoraged-2.46-2.el6.noarch.rpm
-rw-r--r-- 1 root root 75916 Feb 21 2017 MogileFS-Utils-2.19-1.el6.noarch.rpm
-rw-r--r-- 1 root root 5880 Feb 21 2017 Perlbal-1.78-1.el6.noarch.rpm
-rw-r--r-- 1 root root 1624 Feb 21 2017 Perlbal-doc-1.78-1.el6.noarch.rpm
-rw-r--r-- 1 root root 28111 Feb 21 2017 perl-Danga-Socket-1.61-1.el6.rf.noarch.rpm
-rw-r--r-- 1 root root 30312 Feb 21 2017 perl-MogileFS-Client-1.14-1.el6.noarch.rpm
-rw-r--r-- 1 root root 25140 Feb 21 2017 perl-Net-Netmask-1.9015-8.el6.noarch.rpm
-rw-r--r-- 1 root root 268620 Feb 21 2017 perl-Perlbal-1.78-1.el6.noarch.rpm
1 | yum install -y perl-Net-Netmask perl-IO-String perl-Sys-Syslog perl-IO-AIO |
配置 tracker
tracker配置 1
2
3
4
5
6vim /etc/mogilefs/mogilefsd.conf
db_dsn = DBI:mysql:mogilefs:host=192.168.10.101
db_user = mogilefs
db_pass = mogilefs
listen = 192.168.10.101:7001
MySQL配置 1
2
3
4
5
6
7
8yum install -y mariadb-server
systemctl start mariadb
MySQL [(none)]> grant all privileges on mogilefs.* to 'mogilefs'@'192.168.10.101' identified by 'mogilefs';
MySQL [(none)]> flush privileges;
mogdbsetup --dbpass=mogilefs #一路按Y即可
MySQL [(none)]> use mogilefs;
MySQL [mogilefs]> show tables; #查看到有表就成功了
启动tracker服务 1
systemctl start mogilefsd
配置 storage
创建存储目录
storage节点添加设备,生产环境最好单独挂载一个新的磁盘,专门用来存储数据
node1创建目录dev1,node2创建目录dev2,node3创建目录dev3
注:dev 1、2、3为设备的ID号,必须唯一。1
2mkdir -p /data/mogdata
chown -R mogilefs.mogilefs /data/mogdata
1 | mkdir /data/mogdata/dev1 |
1 | vim /etc/mogilefs/mogstoraged.conf |
启动storaged服务 1
systemctl start mogstoraged
添加 管理 storage 节点
添加storage节点 1
2
3mogadm --tracker=192.168.10.101:7001 host add node1 --ip=192.168.10.101 --port=7500 --status=alive
mogadm --tracker=192.168.10.101:7001 host add node2 --ip=192.168.10.102 --port=7500 --status=alive
mogadm --tracker=192.168.10.101:7001 host add node3 --ip=192.168.10.103 --port=7500 --status=alive
添加存储设备 1
2
3mogadm --tracker=192.168.10.101:7001 device add node1 1
mogadm --tracker=192.168.10.101:7001 device add node2 2
mogadm --tracker=192.168.10.101:7001 device add node3 3
查看状态1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17mogadm --tracker=192.168.10.101:7001 check
Checking trackers...
192.168.10.101:7001 ... OK
Checking hosts...
[ 1] node1 ... OK
[ 2] node2 ... OK
[ 3] node3 ... OK
Checking devices...
host device size(G) used(G) free(G) use% ob state I/O%
---- ------------ ---------- ---------- ---------- ------ ---------- -----
[ 1] dev1 16.986 2.636 14.350 15.52% writeable N/A
[ 2] dev2 16.986 1.796 15.191 10.57% writeable N/A
[ 3] dev3 16.986 1.739 15.247 10.24% writeable N/A
---- ------------ ---------- ---------- ---------- ------
total: 50.959 6.171 44.788 12.11%
1 | mogadm --tracker=192.168 :7001 host list |
修改storage节点1
2
3
4mogadm --trackers=192.168 :7001 host mark node3
mogadm --trackers=192.168 :7001 host list | grep node3
node3 [3]:
mogadm --trackers=192.168 :7001 host mark node3 alive
创建域
1 | mogadm --trackers=192.168.10.101:7001 domain add file |
domain:区域
class:复制文件的最小单位 (最大为64M,如果一个单文件超出此大小将拆分为多个class存储)
mindevcount:最小复制文件的份数
replpolicy:复制份数
hashtype:采用的hash的类型
创建类
默认最小复制文件的份数 1
mogadm --trackers=192.168.10.101:7001 class add img png
指定默认最小复制文件为3份 1
mogadm --trackers=192.168.10.101:7001 class add img jpeg --mindevcount=3
1 | mogadm --trackers=192.168.10.101:7001 class list |
class限制,不要副本 1
2
3mogadm --trackers=192.168.10.101:7001 class add file text --mindevcount=1
mogadm --trackers=192.168.10.101:7001 class list | grep text
file text 1 MultipleHosts() NONE
设置class至少3个保留副本 1
2
3
4
5
6
7
8
9
10
11mogadm --trackers=192.168.10.101:7001 class add file html --replpolicy="MultipleHosts(3)"
mogadm --trackers=192.168.10.101:7001 class list
domain class mindevcount replpolicy hashtype
-------------------- -------------------- ------------- ------------ -------
file default 2 MultipleHosts() NONE
file html 2 MultipleHosts(3) NONE
file text 1 MultipleHosts() NONE
img default 2 MultipleHosts() NONE
img jpeg 3 MultipleHosts() NONE
img png 2 MultipleHosts() NONE
文件上传
1 | mogupload --trackers=192.168.10.101 --domain=img --class=png --key='1.jpg' --file='/root/clara.jpg' |
1 | mogupload --trackers=192.168.10.101:7001 --domain=img --class=jpeg --key='2.jpg' --file='/root/clara.jpg' |
1 | mogupload --trackers=192.168.10.101:7001 --domain=file --class=html --key='fstab.txt' --file='/etc/fstab' |
如何解决MogileFS的无法复制 bug问题
注:MogileFS在centos7上有个致命的错误,就是没有复制副本到其他的节点上,解决如下(每台)1
2
3
4
5
6yum install -y make gcc unzip perl-DBD-MySQL perl perl-CPAN perl-YAML perl-Time-HiRes
wget http://pkgs.fedoraproject.org/repo/pkgs/perl-Sys-Syscall/Sys-Syscall-0.23.tar.gz/be6dc2d791684a6f8abb3dd39ff2d1de/Sys-Syscall-0.23.tar.gz
tar -xf Sys-Syscall-0.23.tar.gz
cd Sys-Syscall-0.23/
perl Makefile.PL
make && make install
若mogilefs已配置运行,重启这两个服务,重新上传文件就可以生效1
2systemctl restart mogilefsd
systemctl restart mogstoraged
MogileFS的只读模式和耗尽(Drain) 模式
如果你想要冻结设备上所有的文件,你要使用只读模式就行了。这将停掉 MogileFS 存放新文件到这个设备上,但它也将阻止删除文件,代替的删除的操作是会给这些内容放到队列中等待为您标记为’alive’着或’drain’。1
2mogadm device mark node1 1 readonly
mogadm device mark node2 2 drain
耗尽(Drain) 模式, 在 2.40 和更高以上,告诉 MogileFS不会有新的文件应写入设备. 但是在耗尽(Drain) 模式文件可能被删除,所以如果你不希望写文件到这个设备上,可以设置为drain 的模式
注:耗尽(Drain) 模式在 MogileFS 的早期版本,将会从设备删除 FIDS现在它已经被重新均衡的功能取代。
重新复制文件
如果有一个硬盘坏了,MogileFS 可以自动的让请求不在访问这个设备,但是不会自动的重新复制这个硬盘的文件,你必须通过 mogadm 来手工来标志成 ‘dead’. 只要你这样做, MogileFS 将开始删除设备上的文件,并试图在集群间重新复制它们到其它的设备上.
MogileFS的rebalance功能
MogileFS的rebalance功能可以平衡各个storage节点磁盘的使用情况,将磁盘剩余空间很少的磁盘中的数据搬到磁盘剩余空间大的磁盘上,使磁盘的使用率基本达到平衡1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26[root@node1 dev1]#mogadm check
Checking trackers...
192.168.10.101:7001 ... OK
Checking hosts...
[ 1] node1 ... OK
[ 2] node2 ... OK
[ 3] node3 ... OK
Checking devices...
host device size(G) used(G) free(G) use% ob state I/O%
---- ------------ ---------- ---------- ---------- ------ ---------- -----
[ 1] dev1 49.976 0.039 49.936 0.08% writeable 0.2
[ 2] dev2 49.976 0.531 49.445 1.06% writeable N/A
[ 3] dev3 49.976 0.065 49.911 0.13% writeable 0.0
[root@node1 app]#mogadm rebalance policy --options="from_hosts=2 to_percent_free=99" #设置rebalance策略,表示从设备id为2,搬到剩余空间为99%的存储设备
[root@node1 app]#mogadm rebalance test #查看一下策略
Tested rebalance policy...
Policy: from_hosts=2 to_percent_free=99
Source devices:
- 2
Destination devices:
- 1
- 3
[root@node1 app]#mogadm rebalance start #运行此策略
[root@node1 app]#mogadm rebalance stop #停止rebalance策略
命令
1 | 列出所有keys |
删除操作
先删除文件 全部1
2mogdelete --trackers=192.168.10.101:7001 --domain=img --key='11.jpg'
...
删除类 全部
1 | mogadm --trackers=192.168.10.101:7001 class delete img jpg |
删除域 1
mogadm domain delete img
删除storaged节点 1
2
3
4
5
6mogadm --tracker=192.168.10.101:7001 host mark node3 down
mogadm --tracker=192.168.10.101:7001 host delete node3
Failure deleting host: host_not_empty Unable to delete host; it contains devices still #需删除数据库信息,才能移除
mysql -e "delete from mogilefs.device where hostid!=4"
mogadm --tracker=192.168.10.101:7001 host delete node3
nginx-mogilefs-module
1 | cd /usr/local/src/nginx_module |
http://www.grid.net.ru/nginx/mogilefs.en.html1
2
3
4
5
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
36upstream trackers {
server 192.168.10.101:7001;
}
server{
listen 80;
server_name 192.168.10.101;
location /upload/img/ {
allow 192.168.2.0/24;
deny all;
mogilefs_tracker trackers;
#mogilefs_domain img;
mogilefs_methods GET PUT DELETE;
#mogilefs_class jpeg png;
mogilefs_noverify on;
mogilefs_pass {
proxy_pass $mogilefs_path;
proxy_hide_header Content-Type;
proxy_buffering off;
}
}
location /upload/file/ {
mogilefs_tracker 192.168.10.101:7001;
mogilefs_domain file;
mogilefs_methods GET PUT DELETE;
mogilefs_noverify on;
mogilefs_pass {
proxy_pass $mogilefs_path;
proxy_hide_header Content-Type;
proxy_buffering off;
}
}
}
访问:
http://192.168.10.101/upload/img/1.jpg
http://192.168.10.101/upload/file/fstab.txt1
2curl -X PUT -T './3.jpg' http://192.168.10.101/upload/img/3.jpg #上传不能实现
curl -X DELETE http://192.168.10.101/upload/img/1.jpg #删除可以实现的
坑
若上传的--key指定/,则nginx localtion img后不带/1
2
3
4mogupload --trackers=192.168.10.101:7001 --domain=img --class=jpeg --key='2.jpg' --file='/root/clara.jpg'
location ~* /img {
...
}
若上传的--key未指定/,则localtion ~* /img { } img需带/1
2
3
4mogupload --trackers=192.168.10.101:7001 --domain=img --class=jpeg --key='2.jpg' --file='/root/clara.jpg'
location ~* /img/ {
...
}
报错解决
启动报错1
2
3
4
5
6
7journalctl -xe
Sep 07 11:48:08 node1 systemd[1]: PID file /var/run/mogilefsd/mogstoraged.pid not readable (yet?) after start.
Sep 07 11:48:08 node1 systemd[1]: Failed to start SYSV: MogileFS storage.
解决:
mkdir /var/run/mogilefsd/
chown -R mogilefs.mogilefs /var/run/mogilefsd/
nginx-mogilefs-module报错1
2
3
4
5
6
7
8
9
10
11
12/usr/local/src/nginx_module/nginx_module/nginx_mogilefs_module-1.0.4/ngx_http_mogilefs_module.c: In function ‘ngx_http_mogilefs_create_request’:
/usr/local/src/nginx_module/nginx_module/nginx_mogilefs_module-1.0.4ngx_http_mogilefs_module.c:748:37: error: variable ‘request’ set but not used [-Werror=unused-but-set-variable]
ngx_str_t request, domain;
^
/usr/local/src/nginx_module/nginx_module/nginx_mogilefs_module-1.0.4/ngx_http_mogilefs_module.c: In function ‘ngx_http_mogilefs_create_spare_location’:
/usr/local/src/nginx_module/nginx_module/nginx_mogilefs_module-1.0.4/ngx_http_mogilefs_module.c:1541:39: error: variable ‘pclcf’ set but not used [-Werror=unused-but-set-variable]
ngx_http_core_loc_conf_t *clcf, *pclcf, *rclcf;
vim objs/Makefile
CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g
修改为
CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -g
https://www.jianshu.com/p/f3b47de0d9c0