大家好,欢迎来到IT知识分享网。
在分布式存储里面,比较常见的有kafka,Hbase,HDFS,fastDFS等,这里面涉及到文件的分布式存储以及数据的分布式存储。分布式存储的背景:就是将数据文件分散的存储到分布式集群的每一个节点,提升了存储的容量(大数据化);同时尽量凸显分布式的检索能力。分布式存储的原理:分层化的hash映射、数据组织的数据摘要以及块数据的叶子索引结构;这几种数据结构相结合的方式提供快速检索的能力和存储结构。
先说说HDFS,其实比较早的分布式存储解决方案;HDFS读写都是都是从NameNode点开始的,获取对应目录结构的region所有在的dataNode,然后从对应的dataNode读写数据。HDFS内部节点的管理是依据zookeeper. 每一个节点都会分配region(节点最多也就是1000个region),每一个节点的region信息存储到master节点,集群的NameNode节点存储每一个节点的元region、block(block默认大小是64MB;3.0版本是128MB)信息,还有目录树结构数据对应block信息,辅助master节点进行元数据的。region信息在master上生成一个hash结构,在读取数据的数据的时候可以很快定位到具体的节点和region, 网络通信是依靠NIO建立的socket通信,同时region文件读取是DMA技术(换句话说hdfs底层是依靠netty实现的通信)。
Hbase本质上在文件上存储也是基于HDFS,但是在管理region上,master节点上专门建立了一个table,来存储region对应位置region中包含block,block之间是靠着链表存储的。Hbase存储是默认将id按照顺序分割不同的region,然后region又会分为小的block。每一个block都有最大id来标记,类似于kafka patition存储一样,里面包含segment,segment信息描述文件,然后block依托着链表来存储连接。每一个block内部存储的数据也是按照id顺序存储的,然后每一个block都对应一个叶子索引就是B+树。对于某一列属性建立二级索引和列对应起来,那么就会建立另外以某列属性值为key,行的id为value建立B+树。
Hbase还有很重要的缓存机制,上面只是说了数据文件的存储机制,其实hbase的高性能很大一部分上来自于基于内存的缓存机制。在读写数据的时候,client都会请求zookeeper,获取最新的region metatable信息,也就是region信息,那么client才会知道去链接哪一个region。在写数据的时候(metatable也会记录每一个region对应的最大id),也会有对应的region节点选择和链接。
首先将数据写到write_ahead_log(简称WAL,这和mysql的binlog类似),然后write_ahead_log读到内存中,会在内存中按照对应id序列拍好序的(整个内存块mem-store),当mem-store到一定的大小就会IO写到Hfile中,不同的mem-store块对应写到不同的Hfile,Hfile达到一定的大小就会合并在一起形成新的Block。
读数据也有对应的内存块blcok-cache,每一个block都会有对应一到多个blcok-cache,每一个blcok-cache也是按照id组织好的。再次读取的时候会获取blcok-cache数据,同时也会获取mem-store数据综合覆盖(相同id数据条目,因为在内存中存储也是按照顺序的,所以在检索和获取的时候很高效),获取最新的数据。
下面说一下数据表文件存储的数据细节,首先每一个表文件都有表描述文件,里面有字段的顺序,字段的所占的字节数(字段长度,该表描述文件一般是表名.tb)。其次就是表数据文件(一般就是表名.data),每一条数据就是按照字段的顺序排列存储,每一条数据结束有结束符号。数据库(mysql存储引擎innodb/mySAM)都是按照数据页来存储数据的,也就是每1000条(默认页数据数)放在一个文件里面,这就是一页数据。页数据有对应得目录描述,就是每一页起始id信息,页信息在目录文件中按照顺序存储得,内存加载目录信息,按照每一页得描述字段长度在内存形成一个双向链表结构。(下图是内存加载目录结构文件,形成得双向链表)
所有的数据依据建立的索引的字段建立B+树结构(主键默认会创建索引),然后我们知道这个索引结构是B+树,关键这个树结构是怎么存储到存盘文件中的,以xx.idx来命名。这个索引结构存储到磁盘文件之后,我们还能很多读取这个文件在内存中很快映射解析出这个树结构。首先我们看下二叉树磁盘存储的案例:
完全二叉树从根结点到倒数第二层满足完美二叉树,最后一层可以不完全填充,其叶子结点都靠左对齐。
30 / \ 20 40 / \ / \ 15 25 35 45 / \ 5 10
换句话说,对于完全二叉树,将层次顺序遍历的序列存储到文件中。当我们从文件读取时,可以推断出第一个元素是根节点,然后接下来2个元素是级别1的二个节点,接下来读出的4个元素是级别2的节点,依此类推。因此可以非常容易地构造这棵完全二叉树。
30 20 40 15 25 35 45 5 10
但是对于给定的树,并不是完全二叉树,即中间节点可能有缺失。比如,下面的二叉树中节点40的左子节点有缺失。在这种情况下,当层次遍历并序列化至文件时,需要人为添加一个值(比如-1)来表达当前节点的缺失。前提是,我们树的所有节点的值都是正数。
30 / \ 20 40 / \ \ 15 25 45 \ 10
基于上述想法,我们将-1添加到缺失的节点中,从而将一个普通的二叉树转换成完全二叉树:
30 / \ 20 40 / \ / \ 15 25 -1 45 / \ -1 10
对应地,上面转换后的完全二叉树持久化到文件的内容如下:
30 20 40 15 25 -1 45 -1 10
那么B+树也按照层级来顺序存储到文件中,解析的时候按照层级标识符来逐层构建B+树。上述就算完全讲述完了数据库表数据文件存储的方案,以及如何快速查询的方案。但是具体到mysql上还存在一些差异,可能对于某一些数据库每一页也存储了对应的B+树索引结构。当然对于全面的B+索引结构文件需要尽可能的小,需要一次性加载到内存中,然后遍历树结构,定位到叶子链表中不同的行数据(条件区间在双向链表中是连续的一段),然后再去目录查到对应的页,把数据查询出来。
对于分布式文件存储,文件被分割成很多块,每一个块都对应一个子文件。这些子文件会被记录到块目录中,然后查询的时候会通过目录找到对应的文件信息。
我们知道内存中数据存储都是有条目数据记录数据存储的起始位置;在内存中存储也是有页(页管理)进行管理的,有页表记录页的位置和顺序。对于磁盘存储也是有最小的单元–扇区,一个扇区最小的存储大小是4KB,文件在磁盘存储的时候也是有记录的,也有所在目录映射表,创建一个目录的时候,会分配存储空间和范围,创建一个文件会记录目录信息以及存储大小(存储所涉及到扇区范围)。
ceph存储原理
Ceph是⼀种为优秀的性能、可靠性和可扩展性⽽设计的统⼀的、分布式的存储系统。可同时提供三种接⼝:
Object:也称为基于对象的存储,其中的文件被拆分成多个部分并散布在多个存储服务器,在对象存储中,数据会被分解为称为“对象”的离散单元,并保存在单个存储库中(存储到数据文件的某一行,非关系型数据库表文件数据的存储机制),而不是作为文件夹中的文件或服务器上的块来保存,对象存储需要一个简单的HTTP 应用编程接口(API),以供大多数客户端(各种语言)使用。有原⽣的API,⽽且也兼容Swift和S3的API。
(1)对象存储:也就是通常意义的键值存储,其接口就是简单的GET、PUT、DEL 和其他扩展,代表主要有 Swift 、S3 以及 Gluster 等。
(2)块存储:这种接口通常以 QEMU Driver 或者 Kernel Module 的方式存在,这种接口需要实现 Linux 的 Block Device 的接口或者 QEMU 提供的 Block Driver 接口,如 Sheepdog,AWS 的 EBS,青云的云硬盘和阿里云的盘古系统,还有 Ceph 的 RBD(RBD是Ceph面向块存储的接口)。在常见的存储中 DAS、SAN 提供的也是块存储。
(3)文件系统存储:通常意义是支持 POSIX 接口,它跟传统的文件系统如 Ext4 是一个类型的,但区别在于分布式存储提供了并行化的能力,如 Ceph 的 CephFS (CephFS是Ceph面向文件存储的接口),但是有时候又会把 GlusterFS ,HDFS 这种非POSIX接口的类文件存储接口归入此类。当然 NFS、NAS也是属于文件系统存储。
ceph存储具备高性能、高可用性、高扩展特性、特性丰富:
高性能:
高可用性:
⾼可扩展性:
(1)去中⼼化 (2)扩展灵活 (3)随着节点增加⽽线性增⻓
特性丰富:
ceph的基本架构:
ceph 是一个对象(object)式存储系统,它把每一个待管理的数据流(文件等数据)切分为一到多个固定大小(默认4 兆)的对象数据,并以其为原子单元(原子是构成元素的最小单元)完成数据的读写。 对象数据的底层存储服务是由多个存储主机(host)组成的存储集群,该集群也被称之为RADOS(reliable automatic distributed object store)存储集群,即可靠的、自动化的、分布式的对象存储系统。 librados 是RADOS 存储集群的API,支持C/C++/JAVA/python/ruby/php/go等编程语言客户端。
librados:librados库,为应用程度提供访问接口。同时也为块存储、对象存储、文件系统提供原生的接口。
RADOSGW:网关接口,提供对象存储服务。它使用librgw和librados来实现允许应用程序与Ceph对象存储建立连接。并且提供S3 和 Swift 兼容的RESTful API接口。
RBD:块设备,它能够自动精简配置并可调整大小,而且将数据分散存储在多个OSD上。
CephFS:Ceph文件系统,与POSIX兼容的文件系统,基于librados封装原生接口。
集群结构功能描述
Monitor(ceph-mon) ceph 监视器: 在一个主机上运行的一个守护进程,用于维护集群状态映射(maintains maps of the cluster state),比如ceph 集群中有多少存储池、每个存储池有多少PG 以及存储池和PG的映射关系等, monitor map, manager map, the OSD map, the MDS map, and the CRUSH map,这些映射是Ceph 守护程序相互协调所需的关键群集状态,此外监视器还负责管理守护程序和客户端之间的身份验证(认证使用cephX 协议)。通常至少需要三个监视器才能实现冗余和高可用性。监视器维护集群状态的多种映射,同时提供认证和日志记录服务,包括有关monitor 节点端到端的信息,其中包括 Ceph 集群ID,监控主机名和IP以及端口。并且存储当前版本信息以及最新更改信息,通过 “ceph mon dump”查看 monitor map。
Managers(ceph-mgr)的功能:在一个主机上运行的一个守护进程,Ceph Manager 守护程序(ceph-mgr)负责跟踪运行时指标和Ceph 集群的当前状态,包括存储利用率,当前性能指标和系统负载。Ceph Manager 守护程序还托管基于python 的模块来管理和公开Ceph 集群信息,包括基于Web的Ceph 仪表板和REST API。高可用性通常至少需要两个管理器。
Ceph OSDs(对象存储守护程序ceph-osd):即对象存储守护程序,但是它并非针对对象存储。提供存储数据,操作系统上的一个磁盘就是一个OSD 守护程序。是物理磁盘驱动器,将数据以对象的形式存储到集群中的每个节点的物理磁盘上。OSD负责存储数据、处理数据复制、恢复、回(Backfilling)、再平衡。完成存储数据的工作绝大多数是由 OSD daemon 进程实现。在构建 Ceph OSD的时候,建议采用SSD 磁盘以及xfs文件系统来格式化分区。此外OSD还对其它OSD进行心跳检测,检测结果汇报给Monitor。通常至少需要3 个Ceph OSD 才能实现冗余和高可用性。
MDS(ceph 元数据服务器ceph-mds):Ceph 元数据,主要保存的是Ceph文件系统(NFS/CIFS)的元数据。注意:ceph的块存储和ceph对象存储都不需要MDS。
ceph节点逻辑结构
pool:存储池、分区,存储池的大小取决于底层的存储空间。
PG(placement group):一个pool 内部可以有多个PG 存在,pool 和PG 都是抽象的逻辑概念,一个pool 中有多少个PG 可以通过公式计算。
OSD(Object Storage Daemon,对象存储设备):每一块磁盘都是一个osd,一个主机由一个或多个osd 组成。
ceph 集群部署好之后,要先创建存储池才能向ceph 写入数据,文件在向ceph 保存之前要先进行一致性hash 计算,计算后会把文件保存在某个对应的PG 的,此文件一定属于某个pool 的一个PG,在通过PG 保存在OSD 上。数据对象在写到主OSD 之后再同步对从OSD 以实现数据的高可用。
ceph数据写入流程
第一步: 计算文件到对象的映射:
第二步:通过hash 算法计算出文件对应的pool 中的PG:
第三步: 通过CRUSH 把对象映射到PG 中的OSD:
第四步:PG 中的主OSD 将对象写入到硬盘。
第五步: 主OSD 将数据同步给备份OSD,并等待备份OSD 返回确认。
第六步: 备份OSD返回确认后,主OSD 将写入完成返回给客户端。
Ceph中数据写入,会有三次映射
CRUSH算法介绍
CRUSH,Controlled Replication Under Scalable Hashing,它表示数据存储的分布式选择算法, ceph 的高性能/高可用就是采用这种算法实现。CRUSH 算法取代了在元数据表中为每个客户端请求进行查找,它通过计算系统中数据应该被写入或读出的位置。CRUSH能够感知基础架构,能够理解基础设施各个部件之间的关系。并CRUSH保存数据的多个副本,这样即使一个故障域的几个组件都出现故障,数据依然可用。CRUSH 算是使得 ceph 实现了自我管理和自我修复。
Ceph 使用CRUSH 算法来准确计算数据应该被保存到哪里,以及应该从哪里读取,和保存元数据不同的是,CRUSH 按需计算出元数据,因此它就消除了对中心式的服务器/网关的需求,它使得Ceph 客户端能够计算出元数据,该过程也称为CRUSH 查找,然后和OSD 直接通信。
对象存储与文件存储:
文件存储和对象存储底层都是块存储,但是文件存储在管理文件上是文件树,对象存储是扁平化的小文件存储,管理上不能单单靠文件树结构
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/132807.html