分布式存储

您所在的位置:网站首页 文件存储系统 分布式存储

分布式存储

2023-08-17 06:57| 来源: 网络整理| 查看: 265

1. 单机文件系统 vs 分布式文件系统

传统单机文件系统是计算机中一个非常重要的组件,为存储设备提供一致的访问和管理方式。在不同的操作系统中,文件系统会有一些差别,但也有一些共性几十年都没怎么变化:

数据是以文件的形式存在,提供 Open、Read、Write、Seek、Close 等API 进行访问;文件以树形目录进行组织,提供原子的重命名(Rename)操作改变文件或者目录的位置。

文件系统提供的访问和管理方法支撑了绝大部分的计算机应用,Unix 的“万物皆文件”的理念更是凸显了它的重要地位。

随着互联网企业的高速发展,这些企业对数据存储的要求越来越高,而且模式各异,如淘宝主站的大量商品图片,其特点是文件较小,但数量巨大;而类似于youtube,优酷这样的视频服务网站,其后台存储着大量的视频文件,尺寸大多在数十兆到数吉字节不等。这些应用场景都是传统文件系统不能解决的。

单机文件系统的问题:

(1)共享:无法同时为分布在多个机器中的应用提供访问,于是有了 NFS 协议,可以将单机文件系统通过网络的方式同时提供给多个机器访问。 (2)容量:无法提供足够空间来存储数据,数据只好分散在多个隔离的单机文件系统里。 (3)性能:无法满足某些应用需要非常高的读写性能要求,应用只好做逻辑拆分同时读写多个文件系统。 (4)可靠性:受限于单个机器的可靠性,机器故障可能导致数据丢失。 (5)可用性:受限于单个操作系统的可用性,故障或者重启等运维操作会导致不可用。

分布式文件系统将数据存储在物理上分散的多个存储节点上,对这些节点的资源进行统一的管理与分配,并向用户提供文件系统访问接口。

2. 分布式文件系统原理

目前比较主流的分布式文件系统架构,如下图所示。 分布式文件系统

主控服务器(或称元数据服务器、名字服务器等,通常会配置备用主控服务器以便在故障时接管服务,也可以两个都为主的模式)多个数据服务器(或称存储服务器,存储节点等)以及多个客户端,客户端可以是各种应用服务器,也可以是终端用户。

这种方式简单易实现,目前很多分布式文件系统都采用这种方式如GFS、TFS、MooseFS 等。 主控服务器在负载较大时会出现单点,较多的解决方案是配置备用服务器,以便在故障时接管服务,如果需要,主备之间需要进行数据的同步。 分布式系统原理

2.1 主控服务器

(1)命名空间的维护

Master负责维护整个文件系统的命名空间,并暴露给用户使用,命名空间的结构主要有典型目录树结构如MooseFS等,扁平化结构如淘宝TFS(目前已提供目录树结构支持),图结构(主要面向终端用户,方便用户根据文件关联性组织文件,只在论文中看到过)。

为了维护名字空间,需要存储一些辅助的元数据如文件(块)到数据服务器的映射关系,文件之间的关系等,为了提升效率,很多文件系统采取将元数据全部内存化(元数据通常较小)的方式如GFS, TFS;有些系统借则助数据库来存储元数据如DBFS,还有些系统则采用本地文件来存储元数据如MooseFS。

(2)数据服务器管理

除了维护文件系统的命名空间,Master还需要集中管理数据DS, 可通过轮询DS或由DS报告心跳的方式实现。在接收到客户端写请求时,Master需要根据各个DS的负载等信息选择一组(根据系统配置的副本数)DS为其服务;当Master发现有DS宕机时,需要对一些副本数不足的文件(块)执行复制计划;当有新的DS加入集群或是某个DS上负载过高,Master也可根据需要执行一些副本迁移计划。

如果Master的元数据存储是非持久化的,则在DS启动时还需要把自己的文件(块)信息汇报给Master。在分配DS时,基本的分配方法有随机选取,RR轮转、低负载优先等,还可以将服务器的部署作为参考(如HDFS分配的策略),也可以根据客户端的信息,将分配的DS按照与客户端的远近排序,使得客户端优先选取离自己近的DS进行数据存取.

(3)服务调度

Master最终的目的还是要服务好客户端的请求,除了一些周期性线程任务外,Master需要服务来自客户端和DS的请求,通常的服务模型包括单线程、每请求一线程、线程池(通常配合任务队列)。

单线程模型下,Master只能顺序的服务请求,该方式效率低,不能充分利用好系统资源;每请求一线程的方式虽能并发的处理请求,但由于系统资源的限制,导致创建线程数存在限制,从而限制同时服务的请求数量,另外,线程太多,线程间的调度效率也是个大问题;线程池的方式目前使用较多,通常由单独的线程接受请求,并将其加入到任务队列中,而线程池中的线程则从任务队列中不断的取出任务进行处理。

(4)主备(主)容灾

Master在整个分布式文件系统中的作用非常重要。

为了避免Master的单点问题,通常会为其配置备用服务器,以保证在主控服务器节点失效时接管其工作。通常的实现方式是通过HA、UCARP等软件为主备服务器提供一个虚拟IP提供服务,当备用服务器检测到主宕机时,会接管主的资源及服务。

如果Master需要持久化一些数据,则需要将数据同步到备用Master,对于元数据内存化的情况,为了加速元数据的构建,有时也需将主上的操作同步到备Master。 处理方式可分为同步和异步两种。

同步方式将每次请求同步转发至备Master,这样理论上主备时刻保持一致的状态,但这种方式会增加客户端的响应延迟(在客户端对响应延迟要求不高时可使用这种方式),当备Master宕机时,可采取不做任何处理,等备Master起来后再同步数据,或是暂时停止写服务,管理员介入启动备Master再正常服务(需业务能容忍);异步方式则是先暂存客户端的请求信息(如追加至操作日志),后台线程重放日志到备Master,这种方式会使得主备的数据存在不一致的情况,具体策略需针对需求制定。 2.2 数据服务器

(1) 数据本地存储

数据服务器负责文件数据在本地的持久化存储,最简单的方式是将客户每个文件数据分配到一个单独的DS上作为一个本地文件存储,但这种方式并不能很好的利用分布式文件系统的特性,很多文件系统使用固定大小的块来存储数据如GFS, TFS, HDFS,典型的块大小为64M。

对于小文件的存储,可以将多个文件的数据存储在一个块中,并为块内的文件建立索引,这样可以极大的提高存储空间利用率。 Facebook用于存储照片的HayStack系统的本地存储方式为,将多个图片对象存储在一个大文件中,并为每个文件的存储位置建立索引,其支持文件的创建和删除,不支持更新(通过删除和创建完成),新创建的图片追加到大文件的末尾并更新索引,文件删除时,简单的设置文件头的删除标记,系统在空闲时会对大文件进行compact把设置删除标记且超过一定时限的文件存储空间回收(延迟删除策略)。 淘宝的TFS系统采用了类似的方式,对小文件的存储进行了优化,TFS使用扩展块的方式支持文件的更新。对小文件的存储也可直接借助一些开源的KV存储解决方案,如Tokyo Cabinet(HDB, FDB, BDB, TDB)、Redis等。

对于大文件的存储,则可将文件存储到多个块上,多个块所在的DS可以并行服务,这种需求通常不需要对本地存储做太多优化。

(2)状态维护

DS除了简单的存储数据外,还需要维护一些状态,首先它需要将自己的状态以心跳包的方式周期性的报告给Master,使得Master知道自己是否正常工作,通常心跳包中还会包含DS当前的负载状况(CPU、内存、磁盘IO、磁盘存储空间、网络IO等、进程资源,视具体需求而定),这些信息可以帮助Master更好的制定负载均衡策略。

很多分布式文件系统如HDFS在外围提供一套监控系统,可以实时的获取DS或Master的负载状况,管理员可根据监控信息进行故障预防。

(3)副本管理

为了保证数据的安全性,分布式文件系统中的文件会存储多个副本到DS上,写多个副本的方式,主要分为3种。

最简单的方式是客户端分别向多个DS写同一份数据,如DNFS采用这种方式;第2种方式是客户端向主DS写数据,主DS向其他DS转发数据,如TFS采用这种方式;第三种方式采用流水复制的方式,client向某个DS写数据,该DS向副本链中下一个DS转发数据,依次类推,如HDFS、GFS采取这种方式。

当有节点宕机或节点间负载极不均匀的情况下,Master会制定一些副本复制或迁移计划,而DS实际执行这些计划,将副本转发或迁移至其他的DS。DS也可提供管理工具,在需要的情况下由管理员手动的执行一些复制或迁移计划。

2.3 客户端

(1)接口

用户最终通过文件系统提供的接口来存取数据,linux环境下,最好莫过于能提供POSIX接口的支持,这样很多应用(各种语言皆可,最终都是系统调用)能不加修改的将本地文件存储替换为分布式文件存储。

要想文件系统支持POSIX接口,

一种方式时按照VFS接口规范实现文件系统,这种方式需要文件系统开发者对内核有一定的了解;另一种方式是借助FUSE(http://fuse.sourceforge.net)软件,在用户态实现文件系统并能支持POSIX接口,但是用该软件包开发的文件系统会有额外的用户态内核态的切换、数据拷贝过程,从而导致其效率不高。很多文件系统的开发借助了fuse,参考http://sourceforge.net/apps/mediawiki/fuse/index.php?title=FileSystems。

如果不能支持POSIX接口,则为了支持不同语言的开发者,需要提供多种语言的客户端支持,如常用的C/C++、java、php、python客户端。使用客户端的方式较难处理的一种情况时,当客户端升级时,使用客户端接口的应用要使用新的功能,也需要进行升级,当应用较多时,升级过程非常麻烦。

目前一种趋势是提供Restful接口的支持,使用http协议的方式给应用(用户)访问文件资源,这样就避免功能升级带来的问题。

另外,在客户端接口的支持上,也需根据系统需求权衡,比如write接口,在分布式实现上较麻烦,很难解决数据一致性的问题,应该考虑能否只支持create(update通过delete和create组合实现),或折中支持append,以降低系统的复杂性。

(2)缓存

分布式文件系统的文件存取,要求客户端先连接Master获取一些用于文件访问的元信息,这一过程一方面加重了Master的负担,一方面增加了客户端的请求的响应延迟。

为了加速该过程,同时减小Master的负担,可将元信息进行缓存,数据可根据业务特性缓存在本地内存或磁盘,也可缓存在远端的cache系统上如淘宝的TFS可利用tair作为缓存(减小Master负担、降低客户端资源占用)。

维护缓存需考虑如何解决一致性问题及缓存替换算法,一致性的维护可由客户端也可由服务器完成:

一种方式是客户端周期性的使cache失效或检查cache有效性(需业务上能容忍)或由服务器在元数据更新后通知客户端使cache失效(需维护客户端状态)。使用得较多的替换算法如LRU、随机替换等。

(3)其他 客户端还可以根据需要支持一些扩展特性,如将数据进行加密保证数据的安全性、将数据进行压缩后存储降低存储空间使用,或是在接口中封装一些访问统计行为,以支持系统对应用的行为进行监控和统计。

3. 分布式文件系统对比 3.1 HDFS

出自 Yahoo 的 Hadoop 算是 Google 的 GFS、MapReduce 等的开源Java实现版,HDFS 也是基本照搬 GFS 的设计,这里就不再重复了,下图是HDFS的架构图。 hdfs HDFS的可靠性和可扩展能力还是非常不错的,有不少几千节点和 100PB 级别的部署,支撑大数据应用表现还是很不错的,少有听说丢数据的案例(因为没有配置回收站导致数据被误删的除外)。

HDFS 的 HA 方案是后来补上的,做得比较复杂,以至于最早做这个 HA 方案的 Facebook 在很长一段时间(至少3年)内都是手动做故障切换(不信任自动故障切换)。

因为 NameNode 是 Java 实现的,依赖于预先分配的堆内存大小,分配不足容易触发 Full GC 而影响整个系统的性能。有一些团队尝试把它用 C++ 重写了,但还没看到有成熟的开源方案。

HDFS 也缺乏成熟的非 Java 客户端,使得大数据(Hadoop等工具)以外的场景(比如深度学习等)使用起来不太方便。

3.2 MooseFS

MooseFS 是来自波兰的开源分布式 POSIX 文件系统,也是参照了 GFS 的架构,实现了绝大部分 POSIX 语义和 API,通过一个非常成熟的 FUSE 客户端挂载后可以像本地文件系统一样访问。MooseFS 的架构如下图所示:

moosefs

MooseFS 支持快照,用它来做数据备份或者备份恢复等还是恢复方便的。

MooseFS 是由 C 实现的,Master 是个异步事件驱动的单线程,类似于 Redis。不过网络部分使用的是 poll 而不是更高效的 epoll,导致并发到 1000 左右时 CPU 消耗非常厉害。

开源的社区版没有HA,是通过 metalogger 来实现异步冷备,闭源的收费版有 HA。

为了支持随机写操作,MooseFS 中的 chunk 是可以修改的,通过一套版本管理机制来保证数据一致性,这个机制比较复杂容易出现诡异问题(比如集群重启后可能会有少数 chunk 实际副本数低于预期)。

3.3 CephFS

CephFS 始于 Sage Weil 的博士论文研究,目标是实现分布式的元数据管理以支持 EB 级别数据规模。2012年,Sage Weil 成立了 InkTank 继续支持 CephFS 的开发,于 2014年被 Redhat 收购。直到 2016 年,CephFS 才发布可用于生产环境的稳定版(CephFS 的元数据部分仍然是单机的)。现在,CephFS 的分布式元数据仍然不成熟。

Ceph 是一个分层的架构,底层是一个基于 CRUSH(哈希)的分布式对象存储,上层提供对象存储(RADOSGW)、块存储(RDB)和文件系统(CephFS)三个API,如下图所示。 在这里插入图片描述 在这里插入图片描述

用一套存储系统来满足多个不同场景的存储需求(虚拟机镜像、海量小文件和通用文件存储)还是非常吸引人的,但因为系统的复杂性需要很强的运维能力才能支撑,实际上目前只有块存储还是比较成熟应用得比较多,对象存储和文件系统都不太理想,听到不少负面的使用案例(他们用过一段时间Ceph 后就放弃了)。

3.4 分布式块存储 vs 分布式文件存储 vs 分布式对象存储

块设备速度快,对存储的数据没有进行组织管理,但在大多数场景下,用户数据读写不方便(以块设备位置offset + 数据的length来记录数据位置,读写数据)。

而在块设备上构建了文件系统后,文件系统帮助块设备组织管理数据,数据存储对用户更加友好(以文件名来读写数据)。Ceph文件系统接口解决了“Ceph块设备+本地文件系统”不支持多客户端共享读写的问题,但由于文件系统结构的复杂性导致了存储性能较Ceph块设备差。

对象存储接口是一种折中,保证一定的存储性能,同时支持多客户端共享读写。

4. 分布式数据库

根据不同的应用的领域,分布式存储系统有下面的类别:

分布式协同系统(分布式日志复制)分布式任务调度框架流计算框架分布式文件/对象系统分布式NoSQL存储分布式关系数据库(OLAP、OLTP);各种消息队列mq

分布式数据库有那些类别?

Key-Value 存储: Redis类BigTable存储: Apache HBase, Apache Cassandra文档数据库: MongoDB nosql Key-Value 键值对存储是非常简单而强大的。下面的很多技术基本上都是基于这个技术开始发展的。但是,Key-Value有一个非常致命的问题,那就是如果我们需要查找一段范围内的key。(陈皓注:学过hash-table数据结构的人都应该知道,hash-table是非序列容器,其并不像数组,


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3