一、分布式存储原理:
分布式存储系统,是将数据分散存储在多台独立的设备上。传统的网络存储系统采用集中的存储服务器存放所有数据,存储服务器成为系统性能的瓶颈,也是可靠性和安全性的焦点,不能满足大规模存储应用的需要。分布式网络存储系统采用可扩展的系统结构,利用多台存储服务器分担存储负荷,利用位置服务器定位存储信息,它不但提高了系统的可靠性、可用性和存取效率,还易于扩展。
1.分布式文件系统的特点:
• 节点间能相互通信
• 同一数据存储在多个节点上
• 数据空间平衡
• 具有容错能力
• 文件系统的支持
2.分布式文件系统设计目标:
• 访问透明
• 位置透明
• 并发透明
• 失效透明
• 硬件透明
• 可扩展性
• 复制透明
• 迁移透明
3.分布式系统的难点:
• 缺乏全局时钟
• 面对故障的独立性
• 处理单点故障
冗余
降低单点故障的影响
• 事务类的挑战
ACID
2pc(两段式提交)、最终一致、BASE、CAP、Paxos
事务要具有ACID. 但是这在分布式系统中很难实现:
-
A: Atomicity 原子性
-
C: Consistency 一致性
-
I: Isolation 隔离性
-
D: Durability 持久性
很多数据库都能实现单机事务, 但是一旦构建为分布式系统, 单机的ACID就不能实现了, 有两种选择, 1、放弃事务 2、引入分布式事务;
两段式提交:
事务管理器提交不止一个数据,第一阶段准备,第二阶段提交,如果出现错误,第二阶段回滚
CAP理论:
C:Consistency(一致性) 所有主机的数据都是同步的。
A:Availability(可用性) 能够保证系统的可用性(有主机宕机不影响用户)。
P: Partition Tolerance ( 分区容错性 ) 即使网络出现故障从而分区, 不影响系统运行。
有科学家都在致力于 CAP 三元素并存的时候,Eric.Brewer教授指出 CAP 永远无法兼顾,只能根据具体应用来权衡和取舍,并且至多两个元素可以共存,后来由两位麻省理工学院的科学家证明此观点是具有前瞻性的,由此形成Brewer的 CAP定理 。
正所 谓鱼和熊掌不可兼得 ,关注一致性就需要处理因系统不可用而带来写操作失败的情况,反之关注可用性就无法保证每次都能读取到最新的写入操作。传统 关系型数据库 侧重于 CA ,而 非关系型键值数据库 则侧重于 AP 。
强一致性(ACID) : 在单机环境中,强一致性可以由数据库的事务来保证;在分布式环境中,强一致性很难做到,即便是做到也会因为分布式事物所带来的性能低下,不适合在互联网的环境中应用。
弱一致性(包括最终一致性) : 系统不能保证后续访问返回最新的值,在访问到最新值之前这段时间称之为 不一致窗口 。
最终一致性 :是弱一致性的一种特例,存储系统保证如果对象有多次更新,在渡过 不一致窗口 之后必将放回最后更新的值。
服务器的一致性 : N 代表节点的个数; W 代表更新的时候需要确认已经被更新的节点个数; R 代表读取数据需要的节点数量。
W + R > N —-> 强一致性(通常N=3,W=R=2)
W=N,R=1 —-> 最佳读
W=1,R=N —-> 最佳写
W + R <= N —-> 弱一致性
BASE: 可替代ACID;
-
BA: Basically Availibale 基本可用性
-
S: Soft state 接受一段时间的状态不能同步
-
E: Eventually Consistent 最终一致性
相比于ACID而言, BASE并没有那么苛刻, BASE允许部分的失败但是不会引起系统的故障
DNS就是最著名的Eventually Consistent的实现
分布式存储或分布式文件系统
集中式:
共享存储:
NAS
SAN
分布式存储:
专用的元数据节点:集中元数据存储,数据节点至负责存储数据
无专用元数据几点:所有数据均完整存储元数据,存储了部分数据
分布式:
文件系统:有文件系统接口:一般挂载使用
存储:无文件系统接口,通过API访问
常见的分布式文件系统:
GFS:Google File System GFS擅长处理单个大文件 。
HDFS:Hadoop Distributed File System 根据GFS思想开发的,擅长处理单个大文件 ,使用场景,数据不太多的大文件。
将元数据存储于关系型数据库或其他高性能存储中,从而能维护海量文件元数据。
GlusterFS:去中心化设计:擅长处理单个大文件
ceph:整合到linux内核实现的文件系统,已经被收录在内核,是一个 Linux PB级别的分布式文件系统。
MogilesFS:MogileFS是一个开源的分布式文件系统,用于组建分布式文件集群
TFS:Taobao File System 淘宝开源的文件系统,擅长处理海量小文件,适用于大规模场景。
fastdfs:国产的分布式文件系统,基于mogliefs的实现理论而使用c/c++语言开发的。
MogileFS实现原理:
MogileFS是一个开源的分布式文件存储系统,由LiveJournal旗下的DangaInteractive公司开发。Danga团队开发了包括Memcached、MogileFS、Perlbal等多个知名的开源项目。目前使用MogileFS的公司非常多,如日本排名先前的几个互联公司及国内的yupoo(又拍)、digg、豆瓣、1号店、大众点评、搜狗和安居客等,分别为所在的组织或公司管理着海量的图片。
MogileFS的特性:
1.应用层提供服务,不需要使用核心组件
2.无单点(tracker(跟踪点)mogstore(存储节点)database(MySQL))
3.自动文件复制:复制的最小单位不是文件,而是class
4.传输中立:无特殊协议,可以通过NFS或HTTP实现通信
5.简单的命名空间:没有目录,直接存在存储空间上,通过域来实现,每个文件对应一个key
6.不共享任何数据:
Tracker:
MogileFS的核心,是一个调度器,服务进程为mogilefsd,职责:删除数据、复制数据、监控、查询等。可以使用简单的负载均衡,可以使用Haproxy,lvs,nginx等,监听端口7001
Dtabase:
用于为tracker存储元数据信息。
mogstore:
数据存储的位置,通常是一个HTTP(webDAV)服务器,用来做数据的创建(put)、删除(delete)、获取(get),监听端口7500, storage节点使用http进行数据传输, 依赖于perbal, 进程为mogstored。
MogileFS工作流程图:
存储主机(节点)
这个是 MogileFS 存储文件存放在这些机器上,也是 mogstored 节点,也叫 Storage Server,一台存储主要都要启动一个 mogstored 服务.扩容就是增加这些机器.
设备(device)
一个存储节点,以就是上面的主机,可以有多个 device, 就是用来存放文件的目录(比较挂载的目录),每个设备都有一个设备 id,需要在 mogstored 的配置文件中的 docroot 配置的项目 指定的目录下面创建相应的设备的目录,目录名为 $docroot/dev$id,设备是不能删除的.只能将其设备的状态的值置为dead,当一个设备 dead 之后,就真的 dead了,里面的数据也无法恢复了,且这个dead了的设备的 id 也不能再用.
域(domain)
在一个 MogileFS 中,可以有多个域,用来存放不同的文件,比如,不同大小的文件,不同类型的文件.在上图中所有 alive 的"设备"是一个大的整体,形成一个统一的存储空间,里面的数据可以根据 "域" domain 和类 class 来分类管理,属于同一个 domain,即使是属于不同的class,文件的key也必须是唯一的.不同域的 key 才能重复
类(class)
复制文件的最小单位 (最大为64M,如果一个单文件超出此大小将拆分为多个class存储)。在一个域中,可以有多个类,主要是用来控制复制单元的,类是用来做属性管理的,类是比域 domain 低一个级别,可以定义一个文件存储在不同 device 中的份数.一个文件必须通过 domain,class 和 key 才能找出来.我们可以给不同的重要程度的文件,不同热度的文件,来分别用类来控制份数.
mindevcount:最小复制文件的份数
MogileFS安装及基础配置:
实验环境:
host1.daixiang.com 192.168.80.129 tracker,database
mogstore1.daixiang.com 192.168.80.132 mogstored
mogstore2.daixiang.com 192.168.80.133 mogstored
mogstore3.daixiang.com 192.168.80.134 mogstored
rpm包下载地址:http://pan.baidu.com/s/1c1S0dJM
在tracker+database节点上进行如下操作:
[root@host1 ~]# yum install MogileFS-Server-2.46-2.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm perl-MogileFS-Client-1.14-1.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm -y [root@host1 ~]# yum install -y perl-IO-AIO [root@host1 ~]# yum install -y mysql-server mysql
[root@host1 ~]# scp *.rpm 192.168.80.132:/root/ [root@host1 ~]# scp *.rpm 192.168.80.133:/root/
配置数据库,给用户授权:
[root@host1 ~]# service mysqld start mysql> grant all on *.* to 'root'@'192.168.80.%' identified by 'passwd'; mysql> grant all on mogilefs.* to 'mogilefs'@'192.168.80.%' identified by 'passwd'; mysql> flush privileges;
注意:在centos6.7上,yum安装的mysql-server需要在my.cnf配置文件中需要添加“skip-name-resolve”,不实用dns解析反解,即只能使用ip地址授权。否则生成mogilefs库时会出现错误。
生成mogilefs库:
[root@host1 ~]# mogdbsetup --dbhost=192.168.80.129 --dbport=3306 --dbname=mogilefs --dbrootuser=root --dbrootpass=passwd --dbuser=mogilefs --dbpass=passwd --yes mysql> use mogilefs Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +----------------------+ | Tables_in_mogilefs | +----------------------+ | checksum | | class | | device | | domain | | file | | file_on | | file_on_corrupt | | file_to_delete | | file_to_delete2 | | file_to_delete_later | | file_to_queue | | file_to_replicate | | fsck_log | | host | | server_settings | | tempfile | | unreachable_fids | +----------------------+ 17 rows in set (0.00 sec)
修改mogilefsd的配置文件:
[root@host1 ~]# vim /etc/mogilefs/mogilefsd.conf
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
daemonize = 1 # Where to store the pid of the daemon (must be the same in the init script) pidfile = /var/run/mogilefsd/mogilefsd.pid # Database connection information db_dsn = DBI:mysql:mogilefs:host=192.168.80.129 db_user = mogilefs db_pass = passwd # 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
[root@host1 ~]# service mogilefsd start
在tracker上添加被管理的mogstore节点:
[root@host1 ~]# mogadm --trackers=192.168.80.129:7001 host add mogstore1 --ip=192.168.80.132 --status=alive [root@host1 ~]# mogadm --trackers=192.168.80.129:7001 host add mogstore2 --ip=192.168.80.133 --status=alive [root@host1 ~]# mogadm --trackers=192.168.80.129:7001 host add mogstore3 --ip=192.168.80.134 --status=alive
配置mogstore节点:
在每个mogstore节点上安装所需rpm包:
[root@mogstore1 ~]# yum install MogileFS-Server-2.46-2.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm perl-MogileFS-Client-1.14-1.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm -y [root@mogstore1 ~]# yum install perl-IO-AIO -y [root@mogstore2 ~]# yum install MogileFS-Server-2.46-2.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm perl-MogileFS-Client-1.14-1.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm -y [root@mogstore2 ~]# yum install perl-IO-AIO -y [root@mogstore3 ~]# yum install MogileFS-Server-2.46-2.el6.noarch.rpm MogileFS-Server-mogilefsd-2.46-2.el6.noarch.rpm MogileFS-Server-mogstored-2.46-2.el6.noarch.rpm MogileFS-Utils-2.19-1.el6.noarch.rpm perl-MogileFS-Client-1.14-1.el6.noarch.rpm perl-Net-Netmask-1.9015-8.el6.noarch.rpm perl-Perlbal-1.78-1.el6.noarch.rpm -y [root@mogstore3 ~]# yum install perl-IO-AIO -y
对每个mogstore节点进行如下配置:
[root@mogstore1 ~]# vim /etc/mogilefs/mogstored.conf maxconns = 10000 httplisten = 0.0.0.0:7500 mgmtlisten = 0.0.0.0:7501 docroot = /dfs/mogdata [root@mogstore1 ~]# mkdir -pv /dfs/mogdata/dev1 [root@mogstore1 ~]# chown -R mogilefs.mogilefs /dfs/mogdata/ [root@mogstore1 ~]# service mogstored start
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[root@mogstore2 ~]# vim /etc/mogilefs/mogstored.conf maxconns = 10000 httplisten = 0.0.0.0:7500 mgmtlisten = 0.0.0.0:7501 docroot = /dfs/mogdata [root@mogstore2 ~]# mkdir -pv /dfs/mogdata/dev2 [root@mogstore2 ~]# chown -R mogilefs.mogilefs /dfs/mogdata/ [root@mogstore2 ~]# service mogstored start
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[root@mogstore3 ~]# vim /etc/mogilefs/mogstored.conf maxconns = 10000 httplisten = 0.0.0.0:7500 mgmtlisten = 0.0.0.0:7501 docroot = /dfs/mogdata [root@mogstore3 ~]# mkdir -pv /dfs/mogdata/dev3 [root@mogstore3 ~]# chown -R mogilefs.mogilefs /dfs/mogdata/ [root@mogstore3 ~]# service mogstored start
在tracker节点上添加设备:
[root@host1 ~]# mogadm --trackers=192.168.80.129:7001 device add mogstore1 001 [root@host1 ~]# mogadm --trackers=192.168.80.129:7001 device add mogstore2 002 [root@host1 ~]# mogadm --trackers=192.168.80.129:7001 device add mogstore3 003
对添加的设备进行验证:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[root@host1 ~]# mogadm check Checking trackers... 127.0.0.1:7001 ... OK Checking hosts... [ 1] mogstore1 ... OK [ 2] mogstore2 ... OK [ 3] mogstore3 ... OK Checking devices... host device size(G) used(G) free(G) use% ob state I/O% ---- ------------ ---------- ---------- ---------- ------ ---------- ----- [ 1] dev1 16.509 3.898 12.611 23.61% writeable 0.0 [ 2] dev2 16.509 3.897 12.612 23.61% writeable 0.0 [ 3] dev3 16.509 3.897 12.612 23.61% writeable 0.0 ---- ------------ ---------- ---------- ---------- ------ total: 49.527 11.692 37.835 23.61%
在tracker节点上创建两个域:
[root@host1 ~]# mogadm domain add images [root@host1 ~]# mogadm domain add files
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[root@host1 ~]# mogadm domain list domain class mindevcount replpolicy hashtype -------------------- -------------------- ------------- ------------ ------- files default 2 MultipleHosts() NONE images default 2 MultipleHosts() NON
在域中创建类:
[root@host1 ~]# mogadm class add files class1 --mindevcount=3 [root@host1 ~]# mogadm class add files class2 --mindevcount=2 [root@host1 ~]# mogadm class add images class3 --mindevcount=2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[root@host1 ~]# mogadm class list domain class mindevcount replpolicy hashtype -------------------- -------------------- ------------- ------------ ------- files class1 3 MultipleHosts() NONE files class2 2 MultipleHosts() NONE files default 2 MultipleHosts() NONE images class3 3 MultipleHosts() NONE images default 2 MultipleHosts() NONE
上传文件:
[root@host1 ~]# mogupload --trackers=192.168.80.129:7001 --domain=files --key='/fstab.html' --file='/etc/fstab' [root@host1 ~]# mogupload --trackers=192.168.80.129:7001 --domain=images --key='/1.jpg' --file='/root/mogilefs2.jpg'
查看域中的 某个域中的key对应的文件:
[root@host1 ~]# moglistkeys --trackers=192.168.80.129:7001 --domain=images [root@host1 ~]# mogfileinfo --trackers=192.168.80.129:7001 --domain=images --key='/1.jpg' - file: /1.jpg class: default devcount: 2 domain: images fid: 8 key: /1.jpg length: 39704 - http://192.168.80.133:7500/dev2/0/000/000/0000000008.fid - http://192.168.80.132:7500/dev1/0/000/000/0000000008.fid
访问效果图:
扩展管理工具命令:
[root@host1 ~]# mogdelete --trackers=192.168.80.129:7001 --domain=files --key='/1.jpg' #删除files域中key值为'/1.jpg'对应的文件 [root@host1 ~]# mogadm --trackers=192.168.80.129:7001 host mark mogstore1 down #让mogstore2主机离线 [root@host1 ~]# mogadm --trackers=192.168.80.129:7001 host mark mogstore1 alive #让mogstore2主机上线
作者是菜鸟一只,请大家多多指点,如有错误请指出,我会在第一时间更正,谢谢!!