如何打造运维友好的存储系统

本文内容来自于 Juicedata 合伙人苏锐在上海举办的 CNutCon 2018 全球运维技术大会上的主题演讲。

大家好,我叫苏锐。今天分享的题目叫《打造运维友好的存储系统》,我们的团队过去一年半的时间里做了一个云上的分布式共享 POSIX 文件系统,说通俗点就是一个无限容量、弹性伸缩、多机共享的云硬盘。在我们最初设计这个产品的时候就定了一个目标:用户体验好。

谈用户体验,首先要明确谁是用户?日常工作中,和存储系统打交道最多的就是运维工程师啊。所以,我们的首要目标就是运维友好。今天我也主要分享下过去一年多在打造 JuiceFS 过程中做了哪些提升运维体验的事情。

回顾过去 20 年,每隔五年就有一次明显的数据爆发,2000年门户网站、2005年 Web2.0、2010年大数据、2015年人工智能、2020年有智能制造、IoT。但无论怎么涨,存储上最关心的的几个方面没变:容量、安全、性能。

接下来的分享我也会围绕这三方面。容量方面一项很重要的工作就是容量规划和空间管理。安全少不了备份。性能会围绕监控和性能分析。

首先说容量规划,一直都是个两难的问题。少了,业务增长快,不断要扩容。多了,资源利用率低,成本高。

机房时代还要涉及到采购,流程更长。上云了快一些,但是云盘空间仍然要做容量监控,手动扩容,手动做分区扩展等,有些云上还需要重启机器,整个过程也不轻松。

我们就思考云时代,一定要容量规划么? 我们的想法是:不需要。

云最大的优势之一就是按需使用,弹性伸缩啊。云上有这样的存储么?很自然想到对象存储。但是对象存储的 key-value 结构不能满足很多业务场景的需要,需要专门的 API,没有目录数据管理困难。大家不要小看没有目录这个问题,因为对象存储空间无限,用着特别爽,所以大家习惯把各种数据都丢进去,包括一些临时需要的,用完忘了删,我同事在 Facebook 工作时内部就做过一次数据大扫除,猜猜删掉多少无用数据?几十PB。再举一个例子,如果想知道一个 bucket 里都有哪些数据,遍历扫描一下也不轻松,同事在 Databrick 工作时也做过,工作量至少是“周”级别的。

我们认为在单机操作系统中文件管理、使用的体验是更好的。所以,JuiceFS 就完全继承了单机文件系统的使用体验,同时提供了无限容量、弹性伸缩。

回到刚才的例子,如果是文件系统就简单多了,ls 一下,或者 du 列出整体的目录容量分布。但是一个层次很深,文件数量很多的目录用 du 统计也是很慢的。这样的用户体验不好,我们想做个改变,目标有两个,一要快,二要更直观。

JuiceFS 有一个 Web 管理界面,在上面我们提供了一个图形化的数据分布展示,可以实时展示出当前的容量或 inodes 的分布情况。图片中的圆环有四层,代表顶部的四层目录,每个小色块是一个目录,鼠标放上去会显示目录名,这样一眼就能看出哪里最大。

假设图里红色的部分是个 /tmp 目录,里面有很多的子目录和文件,我要删掉它。用 rm -rf 会出现 du 命令一样的情况,等很久,因为也是层层递归的遍历删除。这种体验不好,我们希望能秒删,所以做了一个 juicefs rmr 的命令,任何目录可以秒删。而且,删错了也不怕,JuiceFS 有回收站,删错了去回收站恢复就行了。

接下来咱们聊聊备份。

以前在机房里,第一个数据安全机制就是 RAID。现在到云上,云硬盘是有多副本冗余的,但并不代表它 100% 安全,AWS 有官方数据:EBS 年损坏率 0.1%~0.2%,意味着如果你有 1000 块盘,每年会坏掉 1~2 块,而是这里的坏掉就是指数据部分或全部丢失。

做备份也不是复制一份到别处就OK了,很多应用的数据备份有逻辑正确性问题,比如数据库。2017 GitLab 线上维护误删了数据库,但是咱们有备份机制,而且是五份备份,结果发现没有一份能用的,就是因为这些备份没有去验证过,到需要做故障恢复的时候才发现。

备份完,验证过的数据就万事大吉了么?还不够,重要的数据还必须做异地备份,2015 年 Google 欧洲的数据中心被雷劈了,经过各种恢复之后仍然有一部分数据丢失了,就是因为这部分数据所有的副本都在这个数据中心,没有做异地备份。

刚才说的备份验证,我展开说一下,图中是一个 MySQL 物理备份的标准流程。在一个 MySQL 从库上用 xtrabackup 做物理备份,先写到本地盘,然后做压缩、加密后上传到对象存储或 HDFS。然后开始验证流程,从对象存储或 HDFS 再下载/拷贝出来,解密、解压,之后用一个新的 MySQL 实例加载这份数据,如果能成功启动,检查和 MySQL 主库的复制状态也正常,则说明这是一份有效的备份。

这样的 MySQL 备份是高度串行化的。在生产环境实践中,1.5T 的数据走完上面的流程需要 18 小时。如果换用 JuiceFS 来存储备份,xtrabackup 做的物理备份文件可以直接写入 JuiceFS,这个写入过程中会自动完成压缩和加密,而且是高度并行化的。备份数据写入完成,1 秒创建一个 snapshot,用一个空的 MySQL 实例加载这个快照,就可以验证完毕了。总共需要 2 小时,提升接近一个数量级。(附上详细说明文档和相关代码

时间的节省在故障恢复时是最宝贵的,前一段 Github 停机 24 小时的事故中,恢复过程里有 10 小时就是用来下载数据库备份,如果他们用了 JuiceFS,就不用这么久了。

说完 MySQL 的备份,再说一下 JuiceFS 自己是如何做备份的。下面是 JuiceFS 的架构图,数据通过 JuiceFS 客户端写入后,数据内容会存到客户自己云平台的对象存储中,JuiceFS 永远接触不到,同时这部分数据的持久性安全也有对象存储提供,通常是 99.99999999%。Inodes 信息保存到 JuiceFS 的元数据服务中,这个服务部署三个节点,它们用 Raft 协议保证强一致性和高可用,每一个写入事物都需要两个节点 确认才算完成,数据首先保存在内存中,满足高性能访问的需求,同时写一份到硬盘上作为备份,同时有两个节点会各自推送两份事物日志到不同云平台、不同可用区的 logger 中做异地容灾。除了事物日志,元数据服务还会每 8 小时把内存里的元数据信息创建一份快照进行备份。

现在来说一下异地备份,假设一家做出海业务的中国企业,服务部署在美国加州,想在国内做一个异地备份。通常的方式是运维同学自己配几个 cronjobscp、rsync 之类的工具做定时同步。使用 JuiceFS 后异地备份是什么样呢?

只需要在 JuiceFS 网站控制台上给 “复制” 功能打个勾,选一下要复制到哪个云、哪个服务区,之后所有写入的数据就会自动复制过去,整个异地备份过程对使用者完全透明,而且在目的地的云平台上也能高性能的访问这些数据。

前面咱们提到过对象存储,如果我想给自己的对象存储做个备份呢?我们最近开源了一个工具 JuiceSync,它可以在两个任意的对象存储中做复制,目前支持全球 13 个对象存储服务商。

最后咱们来讲讲监控,先问大家一个问题:运维一个 HDFS 集群需要多少监控指标?下面的幻灯片中只列了一小部分核心指标,而且每次扩容 DataNode 节点还会加一批新指标进来。这些指标的采集、监控配置并不是最头疼的,头疼的是夜里有一个指标报警,就得爬起来处理。

我们认为维护分布式系统不是一件轻松的事情,这些复杂的运维过程也并没有为用户创造价值。所以, 我们把 JuiceFS 做成了一个全托管服务,用户不用部署,不用运维,只要在网站上点击两下,安装下客户端就能使用了。同时,JuiceFS 面向用户也不是一个黑盒子,而是通过 API 的方式把所有的关键指标暴露给用户,对于主流的监控系统,比如 Prometheus,我们还有预定义好的专用 API,只要添加一下就能监控到 JuiceFS 的各项指标了。

对于存储系统,除了监控健康状态,确保它能持续可靠的提供服务,还有一个重要方面是性能。存储系统经常成为性能瓶颈,但是在下这个结论的时候,我们需要能分析出上层应用使用存储系统的方式是否存在不合理的地方。很多时候 IO 瓶颈并不是存储系统的锅,而是应用用错了。

JuiceFS 在性能分析上同样提供了一个图形化的方式,下面举个例子。这是一个真实的客户案例,问题出在 logstash-output-file 这个插件,问题来自于客户说他们日志写入压力太大,JuiceFS 支持不了,出现了写入瓶颈。

用 JuiceFS 图形化的性能分析工具分析一段时间的读写特征。这里显示的是所有文件系统上的系统调用,当时这个文件系统只有 logstash 在写入,所以也很简单的做系统调用的隔离,确保不会混入其他无关信息影响分析。

在下图中,每一行代表一个线程,每一块有颜色的地方就是一个文件系统访问,不同颜色代表不同的系统访问函数。

从图中我们可以看出两个问题,第一是色块里绝大多数是蓝色的,蓝色是代表了 lookup 操作。另一个问题是对 JuiceFS 的操作已经沾满了整个进程时间,确实说明存储环节是瓶颈。

根据第一问题我们想为什么绝大部分的调用是 lookup?应用层在做什么?带着这个问题我们查看 logstash-output-file 的源代码。发现这里是 logstash 在写文件,lookup 调用是每次写文件之前要先判断一下文件是否存在,在 POSIX 中这个判断会按照目录层级一级级的查找,产生了大量的 lookup 操作。这里的问题是 logstash-output-file 虽然开启了写入缓存,但仍然会在每次写入新数据时检查文件是否被删除。这种频繁判断文件是否存在的操作非常低效,跟它的写入缓存并不一致,于是我们做了一个修改:把数据写入的 buffer 由它自己管理(而不是 JRuby的默认 buffer),这样可以只在要将数据写入文件时才做是否被删除的检查,大大减少了它的调用频次,提升了整体性能。

做完这个修改后的效果如下图,写文件的操作合并在一起,整个进程已经不再被 IO 操作沾满,存储已经不再是瓶颈。这个改进请见图中的 Pull Request 链接

但是还看到一个问题,在多个线程中,IO 操作并没有并行,线程之间在互相等待,这是为什么呢?我们有个假设,程序中用了全局锁,导致了上述情况。

带着问题,我们继续看 logstash-output-file 的源代码,果然找到一把全局锁,并且通过分析判断这把全局锁粒度过大了。我们做了修改,将锁粒度降低到文件级,再运行应用,截取到下图这一段性能日志,可见多个线程之间的 IO 操作已经可以并行起来,性能得到进一步提升。这里对锁的修改我们也提交了 Pull Request

以上是我今天要分享的内容,再让我们回顾一下。

在容量方面,JuiceFS 提供了弹性容量,不再需要容量规划。同时提供完全兼容 POSIX 的使用体验,有目录结构、文件权限、所有 Linux 命令行工具和脚本都兼容等体验上的优势,还提供了图形化管理、优化的命令来加速执行时间。

安全方面,JuiceFS 非常适合做各种应用的数据备份,可以简单的完成备份验证,可以全透明的做压缩、加密、异地备份容灾等,效率比以往提升一个数量级。

性能与监控方面,JuiceFS 提供了监控 API 来让用户了解各方面指标,还提供了图形化的方式做性能分析,让性能优化工作变得更加简单直观。

今天的分享就到这里,谢谢大家。

JuiceFS 第三季的重要更新

Hi,好久不见

 

秋意已来,JuiceFS 也好久没跟大家联络了,这里向各位汇报一下过去三个月的进展。

首先 JuiceFS 启用了新域名 https://juicefs.com,之前的 .io 域名不能在国内备案,所以一直有部分国内用户会偶尔访问不畅的问题。新域名访问速度杠杠的,希望大家喜欢。PS. 旧域名已经做了自动跳转,不会影响正常使用。

下面说几项 JuiceFS 重要的更新:

  1. 支持数据存储加密,详细的介绍和原理请查看 JuiceFS 文档中的“安全”章节。数据安全对每个人都非常重要,所以此特性不是收费版的特权,我们向所有用户开放。使用这个功能需要将客户端升级到 4.3.0 或以上。
  2. 为了让各位运维大大可以更好的管理和控制,从 4.3.0 开始 JuiceFS 客户端不再自动更新,需要执行 juicefs version —upgrade 手动更新版本。
  3. 增加了文件搜索 juicefs grep,使用方法和 Linux grep 一样,但是可以快几倍到十几倍。
  4. 可以在创建文件系统时指定数据分块大小和是否自动压缩数据,这样可以提高随机读的性能,更好地支撑 MySQL、Parity、Prometheous 等对随机读性能要求较高的应用。
  5. 提供了 Prometheus API,方便大家把 JuiceFS 的各项监控指标接入到自己的 Prometheus 系统中。
  6. 记录在客户端的统计信息(/.stats)可以通过 API 获取了,详情查看文档中“监控”一章

 

除了以上的新特性,还有很多性能优化,详情请看版本更新列表

为什么说存储和计算分离的架构才是未来?

这篇文章的标题是我们过去几个月经常和客户探讨的一个问题,也是很多大公司正在思考的问题,在这里分享一下我们的观点和经验。

二十年前,大规模存储一般使用的是专有硬件设备方案(NAS),通过特殊的高性能通讯硬件给其他应用提供访问接入。这种方案不太容易扩展,而且价格昂贵,无法满足互联网的高速下的超大规模数据存储需求。

让我们回到 2001 年,Google 的 GFS 开创了先河,第一次用普通的 x86 机器和普通硬盘搭建了大规模存储。当时的 HDD 的吞吐量大概在 50MB/s,通过接入多个硬盘的方式可以提高单机吞吐量到 1GB/s 。但当时的主流网络只有 100Mb,通过网络远程访问数据实在是太慢了。为了解决数据的快速访问,Google 创造性地提出来了计算和存储耦合的架构,在同一个集群中实现计算和存储功能,并将计算的代码移动到数据所在的地方,而不是将数据传输到计算节点,有效解决了分散在各个弱连接的存储节点间的海量数据访问的困难。后来者 Hadoop 等也是完全照搬了这个架构,数据本地化是其中一个非常重要特性来保证整体的性能。还做了很多优化来进一步降低机器间、机柜间的网络带宽消耗。

经过 10 年的发展,网络的性能发生了巨大的变化,从之前主流 100Mb 到 10Gb,增长了100倍,而同时期的 HDD 硬盘的性能基本没有太大变化,倒是单盘的容量增大了很多。由于各种社交网络应用对网络的带宽要求很高,加上核心交换机和 SDN 的强力支撑,不少公司实施了点对点的 10Gb 网络架构(任意两个机器之间都有 10Gb 带宽保障)。另外,各种高效的压缩算法和列存储格式也进一步减少了 IO 数据量,将大数据的瓶颈逐渐由 IO 变成了 CPU。在数据本地化优化得很好的大数据计算集群中,大量网络带宽是闲置的,而因为存储和计算耦合在一个集群中,带来了一些其它问题:

  1. 在不同的应用或者发展时期,需要不同的存储空间和计算能力配比,使得机器的选型会比较复杂和纠结;
  2. 当存储空间或计算资源不足时,只能同时对两者进行扩容,导致扩容的经济效率比较低(另一种扩容的资源被浪费了);
  3. 在云计算场景下,不能实现真正的弹性计算,因为计算集群中也有数据,关闭闲置的计算集群会丢失数据。

因为以上这些存储和计算耦合导致的问题,不少公司开始思考这种耦合以及数据本地化的必要性。2013 年我初到 Facebook 时,隔壁组的同事就做了一个这方面的研究,看在关闭 Hadoop 的数据本地化优化的情况下,对性能究竟有多少影响。实测表明,对计算任务的整体影响在 2%以内,对数据的本地读优化已经不那么重要了。后来 Facebook 就逐渐往计算和存储分离的架构迁移,也对所用的大数据软件做了些调整以适应这种新的架构,他们在今年的 Apache Spark & AI Summit 上做了主题为 Taking Advantage of a Disaggregated Storage and Compute Architecture 详细的分享,他们把这种架构称为 DisAgg。Google 在这方面应该是做得更早,只是没有太多公开信息可供参考。

在 AWS 等公有云上,基于网络的块存储逐步取代了单机的本地存储,使得公有云上的计算和存储耦合架构更加不合理(数据本地化并不是真实的,DataNode 内的本地读其实在物理层也是远程读)。针对公有云设计的大数据分析服务 Databricks 一开始就是采用了计算和存储分离的架构(直接使用 S3 作为存储),给产品带来了非常大的灵活性,按需创建和自动弹性伸缩的 Spark 集群是一大卖点(还能最大限度使用 Spot 节点来大大降低计算成本),非常受客户欢迎。因为 S3 只是对象存储,用于大数据计算时会有很多问题,Databricks 以及它的客户也被坑过很多次。Databricks 花了不少精力去改进和适配,使得 Databricks 上的 Spark 任务可以更快更稳定。AWS 上的先驱 Netflix 也是使用 S3 作为大数据的存储,他们针对 Hive 等做了很多改造才能稳定使用 (不是开源的S3mper)。JuiceFS 则是把这些改进进一步抽象和产品化,让它们能够更好地服务于包括大数据在内的更多场景,帮助更多的公司改善云上大数据体验,而不用重复地去解决 S3 等对象存储带来的问题。

因为网络的高速发展,以及大数据计算框架对 IO 的优化,使得数据本地化已经不再重要,存储和计算分离的架构才是未来。JuiceFS 正是顺应了这种发展趋势,是架构落后的 HDFS 的更好替代,为云上的大数据提供完全弹性的存储解决方案,让云上的大数据获得真正的弹性(完全按需使用)。

分布式文件系统架构对比

本文源自 Juicedata 创始人 & CEO Davies 在上海 Linux 用户组(SHLUG)的月度分享(2018/6/23)。

什么是文件系统?

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

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

文件系统提供的访问和管理方法支撑了绝大部分的计算机应用,Unix 的“万物皆文件”的理念更是凸显了它的重要地位。文件系统的复杂性使得它的可扩展性未能跟得上互联网的高速发展,极大简化了的对象存储及时填补了空缺得以快速发展起来。因为对象存储缺乏树状结构也不支持原子重命名操作,跟文件系统有很大的差别,本文暂不讨论。

单机文件系统的挑战

绝大多数文件系统都是单机的,在单机操作系统内为一个或者多个存储设备提供访问和管理。随着互联网的高速发展,单机文件系统面临很多的挑战:

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

随着互联网的高速发展,这些问题变得日益突出,涌现出了一些分布式文件系统来应对这些挑战。

 

下面介绍几个我了解过的分布式文件系统的基本架构,并比较不同架构的优点和局限。

GlusterFS

GlusterFS 是由美国的 Gluster 公司开发的 POSIX 分布式文件系统(以 GPL 开源),2007年发布第一个公开版本,2011年被 Redhat 收购。

它的基本思路就是通过一个无状态的中间件把多个单机文件系统融合成统一的名字空间(namespace)提供给用户。这个中间件是由一系列可叠加的转换器(Translator)实现,每个转换器解决一个问题,比如数据分布、复制、拆分、缓存、锁等等,用户可以根据具体的应用场景需要灵活配置。比如一个典型的分布式卷如下图所示:

来源:https://docs.gluster.org/en/latest/Quick-Start-Guide/Architecture/

Server1 和 Server2 构成有 2 副本的 Volume0,Server3 和 Server4 构成 Volume1,它们再融合成有更大空间的分布式卷。

优点:

  1. 数据文件最终以相同的目录结构保存在单机文件系统上,不用担心 GlusterFS 的不可用导致数据丢失。
  2. 没有明显的单点问题,可线性扩展。
  3. 对大量小文件的支持估计还不错。

挑战:

  1. 这种结构是相对静态的,不容易调整,也要求各个存储节点有相同的配置,当数据或者访问不均衡时没法进行空间或者负载调整。故障恢复能力也比较弱,比如 Server1 故障时,Server2 上的文件就没办法在健康的 3 或者 4上增加拷贝保障数据可靠。
  2. 因为缺乏独立的元数据服务,要求所有存储节点都会有完整的数据目录结构,遍历目录或者做目录结构调整时需要访问所有节点才能得到正确结果,导致整个系统的可扩展能力有限,扩展到几十个节点时还行,很难有效地管理上百个节点。

CephFS

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

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

图片来源:https://en.wikipedia.org/wiki/Ceph_(software)

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

CephFS 的架构如下图所示:

图片来源:https://en.wikipedia.org/wiki/Ceph_(software)

CephFS 是由 MDS(Metadata Daemon) 实现的,它是一个或者多个无状态的元数据服务,从底层的 OSD 加载文件系统的元信息,并缓存到内存中以提高访问速度。因为 MDS 是无状态的,可以配置多个备用节点来实现 HA,相对比较容易。不过备份节点没有缓存,需要重新预热,有可能故障恢复时间会比较长。

因为从存储层加载或者写入数据会比较慢,MDS 必须使用多线程来提高吞吐量,各种并发的文件系统操作导致复杂度大大上升,容易发生死锁,或者因为 IO 比较慢导致的性能大幅下降。为了获得比较好的性能,MDS 往往需要有足够多的内存来缓存大部分元数据,这也限制了它实际的支撑能力。

当有多个活跃的 MDS 时,目录结构中的一部分(子树)可以动态的分配到某个MDS并完全由它来处理相关请求,以达到水平扩展的目的。多个活跃之前,不可避免地需要各自锁机制来协商对子树的所有权,以及通过分布式事务来实现跨子树的原子重命名,这些实现起来都是非常复杂的。目前最新的官方文档仍然不推荐使用多个 MDS(作为备份是可以的)。

GFS

Google 的 GFS 是分布式文件系统中的先驱和典型代表,由早期的 BigFiles 发展而来。在 2003 年发表的论文中详细阐述了它的设计理念和细节,对业界影响非常大,后来很多分布式文件系统都是参照它的设计。

顾名思义,BigFiles/GFS 是为大文件优化设计的,并不适合平均文件大小在 1MB 以内的场景。GFS的架构入下图所示:

图片来源:https://en.wikipedia.org/wiki/Google_File_System

GFS 有一个 Master 节点来管理元数据(全部加载到内存,快照和更新日志写到磁盘),文件划分成 64MB 的 Chunk 存储到几个 ChunkServer 上(直接使用单机文件系统)。文件只能追加写,不用担心 Chunk 的版本和一致性问题(可以用长度当做版本)。这个使用完全不同的技术来解决元数据和数据的设计使得系统的复杂度大大简化,也有足够的扩展能力(如果平均文件大小大于 256MB,Master 节点每 GB 内存可以支撑约 1PB 的数据量)。放弃支持 POSIX 文件系统的部分功能(比如随机写、扩展属性、硬链接等)也进一步简化了系统复杂度,以换取更好的系统性能、鲁棒性和可扩展性。

因为 GFS 的成熟稳定,使得 Google 可以更容易地构建上层应用(MapReduce、BigTable等)。后来,Google 开发了拥有更强可扩展能力的下一代存储系统 Colossus,把元数据和数据存储彻底分离,实现了元数据的分布式(自动 Sharding),以及使用Reed Solomon编码来降低存储空间占用从而降低成本。

HDFS

出自 Yahoo 的 Hadoop 算是 Google 的 GFS、MapReduce 等的开源Java实现版,HDFS 也是基本照搬 GFS 的设计,这里就不再重复了,下图是HDFS的架构图。

HDFS的可靠性和可扩展能力还是非常不错的,有不少几千节点和 100PB 级别的部署,支撑大数据应用表现还是很不错的,少有听说丢数据的案例(因为没有配置回收站导致数据被误删的除外)。

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

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

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

MooseFS

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

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

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

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

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

JuiceFS

上面说的 GFS、HDFS 和 MooseFS 都是针对自建机房这种软硬件环境设计的,将数据的可靠性和节点可用性合在一起用多机多副本的方式解决。但是在公有云或者私有云的虚拟机里,块设备已经是具有三副本可靠性设计的虚拟块设备,如果再通过多机多副本的方式来做,会导致数据的成本居高不下(实际上是 9 个拷贝)。

于是我们针对公有云,改进 HDFS 和 MooseFS 的架构,设计了 JuiceFS,架构如下图所示:

 

JuiceFS 使用公有云中已有的对象存储来替换 DataNode 和 Chunk Server,实现一个完全弹性的 Serverless 的存储系统。公有云的对象存储已经很好地解决了大规模数据的安全高效存储,JuiceFS 只需要专注元数据的管理,也大大降低了元数据服务的复杂度(GFS 和 MooseFS 的 master 要同时解决元数据的存储和数据块的健康管理)。我们也对元数据部分做了很多改进,从一开始就实现了基于 Raft 的高可用。要真正提供一个高可用高性能的服务,元数据的管理和运维仍然是很有挑战的,元数据是以服务的形式提供给用户。因为 POSIX 文件系统 API 是应用最最广泛的 API,我们基于 FUSE 实现了高度 POSIX 兼容的客户端,用户可以通过一个命令行工具把 JuiceFS 挂载到 Linux 或者 macOS 中,像本地文件系统一样快速访问。

上图中右边虚线部分是负责数据存储和访问的部分,涉及用户的数据隐私,它们是完全在客户自己的账号和网络环境中,不会跟元数据服务接触。我们(Juicedata)没有任何方法接触到客户的内容(元数据除外,请不要把敏感内容放到文件名里)。

小结

以上简要介绍了下我所了解的几个分布式文件系统的架构,把他们按照出现的时间顺序放在下面的图里(箭头表示后参考了前者或者是新一代版本):

上图中上部分蓝色的几个文件下主要是给大数据场景使用的,实现的是 POSIX 的子集,而下面绿色的几个是 POSIX 兼容的文件系统。

他们中以 GFS 为代表的元数据和数据分离的系统设计能够有效平衡系统的复杂度,有效解决大规模数据的存储问题(通常也都是大文件),有更好的可扩展性。这个架构下支持元数据的分布式存储的 Colossus 和 WarmStorage 更是具有无限的可扩展能力。

JuiceFS 作为后来者,学习了 MooseFS 实现分布式 POSIX 文件系统的方式,也学习了 Facebook 的 WarmStorage 等元数据和数据彻底分开的思路,希望为公有云或者私有云等场景下提供最好的分布式存储体验。JuiceFS 通过将数据存储到对象存储的方式,有效避免了使用以上分布式文件系统时的双层冗余(块存储的冗余和分布式系统的多机冗余)导致的成本过高问题。JuiceFS 还支持所有的公有云,不用担心某个云服务锁定,还能平滑地在公有云或者区之间迁移数据。

最后,如果你手上有公有云账号,来 JuiceFS 注册一下,5 分钟就可以给你的虚拟机(甚至自己的 macOS)挂载上一个 PB 级容量的文件系统了。

客户案例:下厨房 基于 JuiceFS 的 MySQL 备份实践

今天这篇文章来自 ushuz (GitHub),他 2014 年加入下厨房,目前负责下厨房平台和基础设施方面的工作。

下厨房是 JuiceFS 第一批客户之一,从最早用 JuiceFS 做 Nginx 日志和 MySQL 备份,到现在将 JuiceFS 用作 Hadoop / Hive / HBase 的主力存储,使用场景已经非常广泛。今天的这篇文章的实践性非常强,最早听说他们利用 JuiceFS Snapshot 特性做 MySQL 备份验证的时候,我们自己也觉得这个脑洞特别赞!

下面请看文章:

下厨房是国内最大的专注于家庭美食领域的社区,以菜谱和作品分享为核心,业务涉及电商、付费内容、短视频等,目前拥有超过 2000 万注册用户,全平台日活接近 300 万,用户上传了超过 100 万道菜谱、接近 4000 万个作品,赞和收藏量均接近 10 亿。

下厨房从创立已经走过 7 年时间,公司和业务都经历了很多的变化和成长,到现在仍然保持着一个精简的团队,用最务实的方案来支撑业务增长,借此机会和大家分享一下小团队如何高效构建数据库冗余、备份及备份验证机制。

数据库架构概览

下厨房使用的是最常见的主备架构。

在迁移至云服务之前,我们使用 2 台物理机专门作为数据库机器,每台物理机上只运行 1 个 MySQL 实例,按业务划分 database,2 个实例互为主备。迁移至云服务后,对 database 按负载和业务可用性要求进行了分组。每组包括至少 2 个 MySQL 实例(每台云主机只运行 1 个实例)互为主备,分别放在不同的可用区,以减少因出现火灾、雷击等致命事故导致数据丢失的可能性。对于负载较大的分组,增设了若干只读实例,通过部分读写分离分担负载。

随着业务增长,我们的数据库规模也在不断增加,目前大概有 10 个主备对,总数据量近 2T,最大表有近 10 亿行,峰值数据库总 QPS 接近 15 万。

目前使用数据库的主要姿势有:

冗余和备份

冗余不做,日子甭过;备份不做,十恶不赦!

– Xin Li (@delphij) 2010年1月6日

下厨房对此深有体会。在 2013 年 6 月误删数据库文件后,由于冗余和备份中断长达 2 个月,不得不花费了大量时间精力从硬盘恢复数据。

冗余和备份是数据库管理工作的重中之重:一方面天有不测风云,从手抖删库到自然灾害,都可能导致数据库数据损失;另一方面数据是一家互联网公司最重要的资产,留得青山在,不怕没柴烧,但如果青山没了,恐怕就得散伙了。

有惨痛教训在前,我们对冗余和备份格外重视,以最大限度避免数据丢失。在实践中,Percona XtraBackupJuiceFS 两款工具为我们带来了极大便利。

冗余方面,跨可用区主备架构提供了第一层保障,即使主节点数据库文件被误删、宿主机灭失、甚至所在可用区灭失,备节点也仍保有几乎全部数据。Percona XtraBackup 支持热备份,主节点无需停机,简单几步操作即可创建一个 slave,让架设主备变得得心应手。

# on master, take a backup to /backup/mysql
root@master $ juicefs mount <volume> /backup
root@master $ innobackupex --no-timestamp --slave-info /backup/mysql/

# on slave, copy back the backup
# before copying, shutdown mysql on slave
root@slave $ juicefs mount <volume> /backup
root@slave $ rsync -avP /backup/mysql/ /path/to/mysql/datadir

# prepare the backup
# it’s faster to apply logs on SSD than on a network filesystem (in our case JuiceFS)
root@slave $ innobackupex --apply-log --use-memory=16G /path/to/mysql/datadir

# make sure datadir ownership
# then start mysql on slave, setup replication based on /backup/mysql/xtrabackup_binlog_info
# if the backup was taken from a slave, use /backup/mysql/xtrabackup_slave_info
root@slave $ chown -R mysql:mysql /path/to/mysql/datadir

备份方面,每天定时备份整库及 binlog 提供了第二层保障,在第一层保障失效,如手抖误 DROP 时,仍能恢复全部数据。但是,整库备份体积较大,每日定时备份产生的数据量相当可观。JuiceFS 依托对象存储提供了近乎无限的存储空间,十分适合备份的场景,这样一来可以按需长期保留备份而不必过多担心空间占用。我们目前的策略是保留 7 天内的 Percona XtraBackup 整库备份、3 年内的 binlog 以及 1 年内的周级 mysqldump。

相比于自建 NFS,JuiceFS 是与对象存储同等级的高可用服务,它还可以实现跨云的数据冗余,便于跨地域甚至跨云传输。跨地域或跨云访问 JuiceFS 时是通过对象存储的公网出口来传输数据,带宽十分充足,我们曾在 AWS 北京从基于 UCloud UFile 的 JuiceFS 中拷贝数据,传输速度能达到 800+Mbps。

备份验证

终于明白为啥我们公司的数据库备份有检查大小的 alert 了

– 荡师傅 (@inntran) 2016年8月13日

定时备份不意味着高枕无忧,因为备份也可能出问题,因此验证备份是十分必要的。检查备份的大小是一种最简单的方法,但对于数据库备份而言,备份是否真的可用,只有用备份进行一次恢复才知道。一次恢复成功的标志是:MySQL 进程启动且 replication 正常。

常规恢复流程中需要拷贝备份,对于体积较大的备份,拷贝过程会耗时很久,用于运行测试的目标机器也要有足够的硬盘空间,这样的话备份测试的时间成本相当高。

好在 JuiceFS 提供了快照(snapshot)功能,可以为 JuiceFS 上某个路径快速创建一份快照,对快照进行的修改不会影响原路径下的文件。利用 JuiceFS 的快照功能,可以节约大量时间成本。

下厨房基于 Docker 和 JuiceFS 快照构建了一套简单易用的备份测试方案:主要包括在云主机上运行的,执行创建快照、启动容器及清理快照的 verify-backup.sh

#!/usr/bin/env bash
juicefs snapshot /backup/mysql /backup/snapshot

# run a percona:5.7 container to verify the backup
# make sure container can reach master with --add-host or --network
docker run --rm \
    -v /path/to/my-cnf:/root/.my.cnf:ro \
    -v /path/to/report.sh:/report.sh:ro \
    -v /backup/snapshot:/var/lib/mysql \
    percona:5.7 \ 
    /report.sh

juicefs snapshot -d /backup/snapshot

以及在容器中运行的,执行准备备份、配置 replication 并报告 replication 状态的 report.sh

#!/usr/bin/env bash
set -e

# switch to domestic mirrors
sed -i 's|deb.debian.org/debian|ftp.cn.debian.org/debian|g' /etc/apt/sources.list
sed -i 's|security.debian.org|ftp.cn.debian.org/debian-security|g' /etc/apt/sources.list

# install percona-xtrabackup-24
apt-get update && apt-get install -y percona-xtrabackup-24

# prepare backup
innobackupex --apply-log --use-memory=16G /var/lib/mysql > /dev/null
chown -R mysql:mysql /var/lib/mysql

# start mysql
mysqld \
  --default-storage-engine=InnoDB \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci \
  --server-id=1234 \
  --gtid-mode=on \
  --enforce-gtid-consistency=on \
  --read-only=on \
  --transaction-isolation=READ-COMMITTED \
  --binlog-format=ROW \
  --master-info-repository=TABLE \
  --relay-log-info-repository=TABLE \
  --log-bin=/var/log/mysql/mysql-bin \
  --relay-log=mysqld-relay-bin \
  --log-error=/var/log/mysql/error.log \
  --innodb-lru-scan-depth=256 \
  --disable-partition-engine-check &

# check mysql ready, timeout 300s
# it seems that commands inside loop aren't affected by "set -e"
n=0
until [ $n -ge 100 ]; do
  mysqladmin ping && break
  n=$[$n+1]
  sleep 3
done

# setup gtid, connect to mysql server using /root/.my.cnf to avoid password input
mysql < <(printf "RESET SLAVE;\nRESET MASTER;\n$(cat /var/lib/mysql/xtrabackup_slave_info);\nSTART SLAVE;\n")

# check replication status
#   Slave_IO_Running / Slave_SQL_Running should be Yes
#   Seconds_Behind_Master should be reasonable
sleep 10
mysql -e 'SHOW SLAVE STATUS\G' | grep -E '(Running:|Seconds)'

# report and exit
exit $?

在备份完成后,通过定时任务,或其他方式触发 verify-backup.sh 运行。如果备份验证成功,脚本应打印出 MySQL replication 线程的状态及落后于 master 的时间,replication 线程应都处于 Running 状态,且落后于 master 的时间应在合理范围内。

             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
        Seconds_Behind_Master: 3625

另外鉴于备份及备份验证任务的特殊性和重要性,需要额外关注下通知策略。如果只在报错时通知,那当没有收到通知时可能是任务运行成功,也可能是任务根本没有运行。对于备份及备份验证任务而言,没有运行也算任务失败。

总结

下厨房技术团队规模不大,技术资源较为有限。但是借助 Percona 全家桶及 JuiceFS,他们快速地实现了数据库冗余和备份,以及一套有效易用的备份验证方案,从而使他们可以更加专注且有信心地推进业务开发,助力业务增长。

这篇原文发布在下厨房技术团队博客,也欢迎其他 MySQL DBA 和对基础设施感兴趣的工程师一起探讨,可以通过网站右下角的聊天窗口联络我们,或者发邮件到 success@juicedata.io

用 JuiceFS 备份 Nginx 日志可以这么简单

前一段,我们写了一篇讲异地备份重要性的文章,一周之后北京真的地震了,当时的时间是傍晚 6 点多一点,大部分工程师写代码正嗨的时候,地震之后就看到朋友圈里有人说感觉到地震的第一反应就是 git push,多么冰雪聪明、尽职尽责,可是你的线上数据做好备份了么?

在我们线上的生产环境中要备份的东西很多,各种服务日志、数据库数据、用户上传数据、代码等等。用 JuiceFS 来备份可以节省你大量时间,我们会围绕这个主题写一系列的教程,整理出一套最佳实践,方便大家。

今天第一篇就写写最常用的 Nginx 日志备份。

如何用 JuiceFS 备份 Nginx 日志

生产环境中的 Nginx 经常作为反向代理,配置多台,用来对接后面的各种应用服务。日志主要有两类,访问日志 (access.log) 和错误日志 (error.log)。

日志是分散在每个 Nginx 节点的磁盘上的,每台机器自己的磁盘并不安全,而且分散的日志也难以维护和使用。所以,我们都会将日志汇总在一个更靠谱的存储系统中,一方面长期存储安全可靠,一方面也方便做分析使用。

在日志的存储上需要里,容量扩展性强,稳定安全,方便运维操作,价格便宜,最好按使用量付费是重点,对于存储性能的要求会低一些。目前常用的有 NFS、HDFS、对象存储等,把这些存储与 JuiceFS 做个比较:

说到日志的收集方式,主要有两种:定时收集 实时收集,我们在下面分别说明。JuiceFS 使用客户自己的对象存储保存文件数据,所以也自然继承了对象存储的好处,在此之上,我们提供了高性能的元数据服务和完整的 POSIX 兼容,使用上又比对象存储便利的多。

定时收集

通常按照 小时、天,把日志拷贝到一个统一的存储点。这方面的工具集很多,我们用 Linux 默认安装的 logrotate 举例说明。

首先,要在 JuiceFS 网站 注册个账号,并创建了一个文件系统,假设叫 super-backup。

第一步,每台机器安装 JuiceFS 客户端,挂载到 /jfs。

下载 JuiceFS 客户端

$ curl -L juicefs.io/static/juicefs -o juicefs && chmod +x juicefs

挂载文件系统

$ sudo ./juicefs mount super-backup /jfs

在自动化配置管理中使用 JuiceFS 也同样方便,具体方法请在上手指南中查看 如何通过命令行认证开机自动挂载,我们支持 Docker 中挂载Kubernates 中挂载

第二步,在每台机器上用 logrotate 配置日志的滚动策略,修改 /etc/logrotate.d/nginx

/var/log/nginx/*.log {
    daily    # 每天滚动一次
    compress
    dateext # 把日期添加到文件名中
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid` # 重新加载日志文件
    endscript
    lastaction
        rsync -au *.gz /jfs/nginx-logs/`hostname -s`/ # 把压缩好的日志同步到 JuiceFS
    endscript
}

到此,Nginx 日志就可以每天 rotate 并保存到 JuiceFS 中了。增加 Nginx 节点时,只需要在新增节点上做同样的配置即可。

如果使用 NFS,在 logrotate 中的配置是基本一样的。但是 NFS 有几个不足之处:

  • 大部分 NFS 存在单点故障,而 JuiceFS 是高可用的(专业版承诺 99.95% SLA)。
  • NFS 协议传输不加密,所以你需要保证 NFS 和 Nginx 在同一个 VPC 中,如果还有其他要备份的服务,部署上就很麻烦。JuiceFS 传输有 SSL 加密,不受 VPC 限制。
  • NFS 需要事先容量规划,JuiceFS 是弹性扩容,按容量付费的,更省心,更便宜。

如果使用 HDFS 或者 对象存储,日后访问备份数据时,就比较麻烦。JuiceFS 就简单很多,比如可以直接用 zgrep 查询。

再分享几个 Tips:

  1. 执行 logrotate -f /etc/logrotate.d/nginx 立即执行对 logrotate 配置做个验证。还可以用 -d 做调试。
  2. Logrotate 基于 cron 运行,无论你设置 weekly、daily 还是 hourly,具体的执行时间可以在 /etc/crontab 中修改。
  3. 如果你觉得日志文件太多,我们还提供了 juicefs merge 命令可以快速合并 gzip 压缩过的日志文件。

说完定时汇总,下一节我们再说说日志实时收集。

实时收集

日志的实时收集已经有了很多开源工具,常用的有 LogstashFlumeScribeKafka 等。

在集群不是很大的时候,日志收集、分析、索引、展示有个全家桶方案 ELK,其中用 Logstash 做日志收集和分析。

需要下面的部署方式:

  1. 在每台机器上部署一个 Logstash Agent(Flume 等其他工具同理);
  2. 部署一个 Logstash Central 做日志汇总;
  3. 部署一个 Redis 做整个服务的 Broker,目的是在日志收集和写入中间做个缓冲,避免 Central 挂了导致日志丢失;
  4. 然后再配置 Central 的落盘方式,将日志存储到 JuiceFS / NFS / 对象存储 / HDFS 等。

先看看架构图:

这里不讲 Logstash 在收集、分析、过滤环节的配置了,网络上有很多文章可查(比如:Logstash 最佳实践),说一下输出环节。

把 Logstash 收集处理好的日志保存到 JuiceFS 只要在配置的 output 部分设置一下:

output {
   file {
       path => "/jfs/nginx-logs/%{host}-%{+yyyy/MM/dd/HH}.log.gz"
       message_format => "%{message}"
       gzip => true
   }
}

存储到 NFS 也可以用上面的配置,缺点和上文定时收集部分提到的相同

如果要保存到对象存储、HDFS,需要再配置 Logstash 的第三方插件,大部分是非官方的,随着 Logstash 版本的升级,使用时可能需要折腾一下。

最简单的实时收集方案

其实还有更简单的实时日志收集方法,就是直接让 Nginx 把日志输出到 JuiceFS 中,省去了维护和部署日志收集系统的麻烦。使用这个方案可能会担心 JuiceFS 出问题时影响 Nginx 的正常运行,有两方面可以帮大家减少一些顾虑:

1)JuiceFS 本身是一个高可用的服务,专业版承诺 99.95%的可用性,应该跟你的数据库等服务在一个可用性级别;

2)Nginx 的日志输出是使用异步IO来实现的,即使 JuiceFS 出现暂时性的抖动,也基本不影响 Nginx 的正常运行(restart 或者 reload 可能会受影响)。

如果不喜欢运维复杂的日志收集系统,这个方案值得一试。

给 Nginx 日志加一份异地备份

定时收集和实时收集都讲完了,在 super-backup 中存储的 Nginx 日志如何做个异地备份呢?

只要两步:

一、去 JuiceFS 网站控制台中,访问你文件系统的设置菜单,勾选 “启动复制”,然后选择你要复制到的对象存储,保存。

二、在所有挂载 super-backup 的机器上重新挂载 super-backup 即可。之后新写入的数据会很快同步到要复制的 Bucket 中,旧的数据也会在客户端定时扫描(默认每周一次)时同步。

这样可以全自动的在另外一个对象存储中同步一份数据,有效防止单一对象存储的故障或者所在区域的灾难。

你一定会问:JuiceFS 挂了怎么办?元数据访问不了,光有对象存储里的数据也没用啊。

我们最近发布了一个重要功能 – 兼容模式的 JuiceFS,所有的文件会按原样保存在对象存储中,脱离 JuiceFS 的元数据服务,也仍然可以访问里面的文件。对于备份这类一次写入不做修改的场景适合使用。

后记

上面我们详细讲解了在 JuiceFS 备份 Nginx 日志的方法,后续还会介绍如何备份 Gitlab、MySQL、MongoDB、用户上传数据等等,欢迎大家踊跃提需求和投稿

让 JuiceFS 帮你做好「异地备份」


Photo credit: Images by John ‘K’ / CC BY-NC-ND

 

家住北京西二旗的小张是一家互联网金融公司的运维工程师,金融行业的数据可是很值钱的,任何的损坏和丢失都不能容忍。

为此,小张选了北京品质最高的机房,买了品质最好的硬件,做了全面的数据备份容灾策略:

每 24 小时做一次全量备份,每 1 小时做一次快照备份,还有每 5 分钟的增量备份。备份的数据存于专门的备份服务器,在分布式系统中会有 3 拷贝冗余,而且还考虑了跨机架的副本放置策略。每个环节都有监控和报警,系统运转良好,各种故障都能及时锁定及时处理。

但这样,数据容灾策略可以万无一失么?

在一个炎炎夏日的傍晚,小张结束一天的工作,终于可以回家享受啤酒小龙虾了。谁想天气突变,狂风暴雨电闪雷鸣,小张电话响起:

机房被雷劈了!还被劈了三次!!!!

小张赶紧赶回去抢救,经过万般努力,得以恢复大部分数据,但是仍有少量数据无法恢复,因为这部分数据的所有副本所在的硬盘损坏了 …

这个故事看上去不可思议,但是生活往往比真实更戏剧化,这种「被雷劈」的故事真实发生过,我身边有人遇到过,连 Google 这种大公司也遇到过。

2015 年 8 月,Google 欧洲的数据中心 europe-west1-b 就遭遇了天灾,被雷劈了!尽管 Google 的灾备方案十分严密,但仍然有少量的数据永久丢失了。 Google 在官方的事故报告的最后给出了一段关于备份安全策略的建议原文如下

We would like to take this opportunity to highlight an important reminder for our customers: GCE instances and Persistent Disks within a zone exist in a single Google datacenter and are therefore unavoidably vulnerable to datacenter-scale disasters. Customers who need maximum availability should be prepared to switch their operations to another GCE zone.

大意是 Google 云平台上一个区的计算实例和存储盘存在单一数据中心风险,无法避免数据中心级别的灾难。提醒客户做好自己的异地备份,以保证最佳的数据安全。

除了雷劈这样的自然灾害,我们的系统每天都会面临各种数据安全威胁,比如机房断电、UPS故障、被拔网线、系统被入侵、人为误操作等等。

另一个更让人扼腕的数据是,根据资讯安全机构 Ponemon Institute 调查研究,在发生重要数据丢失之后,仅有 6% 的公司能在缺乏灾难恢复计划的情况下幸存。

灾难随时都有可能发生,面对这个现实,能最大程度降低风险系数的,不是在灾难发生后寻找解决方案,而是让「重要数据永远有备份」

重要数据备份到一个相对隔离的系统中(异地数据中心),是一个非常有效的备份方案,能规避上面提到的大部分风险,保障公司业务数据的安全。

如何做异地备份?

异地备份,顾名思义,就是把数据备份到物理隔离的另外一个地方。

在已有本地备份(同机房)的情况下,异地备份意味着要把数据完整地在其他地方再复制一份。根据主业务是自建机房还是使用公有云的不同,异地备份在地点选择上通常有下面几种:

  1. 有两个或以上的数据中心,数据可以在不同数据中心之间互备;
  2. 主业务系统在自己的(或者租用的)数据中心,备份数据在共有云上;
  3. 主业务系统在公有云上,备份一个副本在另一个服务区(Region/Zone);
  4. 主业务系统在公有云上,备份一个副本在另一家公有云上;

自建多个数据中心并不多见,周期长、人力成本高。对于中小型公司,甚至大公司的部分非核心业务部门来说,目前的主流做法是选择公有云作为异地备份方案,因为它容易实施,能最快速保证数据安全。

那怎么用公有云来实施异地备份呢?

异地备份的理想与现实

在实施「异地备份」之前,一般会先做「本地备份」,即备份到同一个数据中心内,方便恢复。本地备份的存储方案通常有以下这些:

  1. 自建分布式文件系统;
    1. 优点:大多选用 HDFS。它是 Hadoop 生态的默认存储方案,有 3 副本冗余的策略,还有机架感知特性,对大数据分析的支持也很友好。
    2. 缺点:HDFS 需要自己维护高可用的 Name Node 集群,容量规划和扩容工作也会占消耗运维团队资源。如果你的 HDFS 集群还肩负业务计算和数据备份需求,基于 JVM 的 Name Node 在高负载工作下垃圾回收机制会造成存储系统的卡顿。存在 HDFS 的数据计算时很方便,但是在数据恢复时就复杂了,要先把对应的数据通过 HDFS CLI 拷贝到本地才行,这对运维工程师来说来说是个噩梦。
  2. 自有机房中多机互备:
    1. 优点:备份在本机文件系统上,可以使用全套的 Linux 工具集,文件备份、恢复都很方便。另外还能充分利用本地磁盘空间,极大的节约成本。
    2. 缺点:机器多了以后,所有备份不在一起,对于管理和恢复是个麻烦事。另外数据安全要依赖 RAID 方案,一旦 RAID 卡损坏,数据就有丢失风险。
  3. 公有云上的云硬盘、NAS:
    1. 优点:这类存储方案通常基于 NFS 协议访问,如果某台机器需要恢复数据,可以直接挂载(要求在一个 VPC 内),省去了拷贝过程。
    2. 缺点:大多有单点问题,另外很多云硬盘容量上限不大,如果你的数据量大,就需要频繁创建新盘,管理很麻烦。
  4. 公有云上的对象存储:
    1. 优点:存储容量弹性扩展,按需付费,价格便宜,数据安全可靠。
    2. 缺点:存取都需要通过专用的 SDK 或 API,没有真正的目录结构,不支持改名。很多系统不支持直接存取对象存储,数据恢复时需要先下载到本地,当数据量很大时会耽误紧急数据恢复的时间。另外,对象存储缺乏各种一致性保证,会带来难以预期的困扰。
  5. 公有云 VM 上挂载本地磁盘(强烈不推荐):虚拟主机上的本地磁盘不保证数据安全,在 VM 重启、迁移时数据可能会丢失,通常是用来存储临时数据,强烈不建议用本地盘做备份。

总的来说,这 5 种「本地备份」方案本身各有优劣,在考虑到基于「本地备份」进行「异地备份」时候,方案 3 和方案 4 稍好,但是在实施「异地备份」时也各自的问题。方案 3 中,无论使用公有云的 NFS 存储还是基于云硬盘自建 NFS,因为协议不支持传输加密,跨公网直接挂载很不安全,需要再搭配 VPN 或者其他网关来解决。方案 4 需要额外学习所选择的公有云的 API 和 SDK。如果要换云平台,API 和 SDK 还得重新学一遍。

在设计异地备份方案时,还得考虑因备份的存储位置不在同一个高速内网内时带来的传输问题,传输会比较慢而且不稳定,还容易被窃听。如果存储系统不支持从公网直接访问(比如 HDFS 和 NAS 等),还需要设计专线或者 VPN 来连通。

我们针对这个问题很多团队的做过交流,只有少数团队实施了异地备份。他们的实施办法,大多是设定一个定期任务,使用 rsync 将本地备份的数据全量异步复制到另外一个 POSIX 兼容的存储系统中。

这种方式非常容易实施,但对存储系统有一定的要求:

  1. 兼容 POSIX,没有额外的学习成本,方便紧急情况下做数据恢复;
  2. 配置简单,维护简单。工作中 99% 的时间,我们不需要和备份系统打交道,所以最理想的情况是不用维护又非常稳定可靠;
  3. 适用于多个公有云/区域,不被某个云绑定。可以根据业务的具体需求有更多的选择;
  4. 最重要的是稳定、可靠、安全,价格便宜当然更加分了;

我们在设计 JuiceFS 时,充分考虑到上了上面几点,希望为异地备份提供更好的选择。简单来说,它既可以像云硬盘一样挂载到虚拟机上,又同时拥有对象存储的弹性扩容和便宜的价格。方便实用,灵活且门槛低,价格对比同类其它方案,也相当有竞争力(以单机的云硬盘的价格得到比 NAS 还好的服务)。

如何用 JuiceFS 来做异地备份呢?

JuiceFS 是专为公有云而生的分布式 POSIX 文件系统,它将数据保存在你自己的公有云对象存储中,通过由我们维护的强一致高性能的元数据服务变成一个 POSIX 兼容的分布式文件系统。

无论你的主业务在自建机房还是公有云上,都可以利用 JuiceFS 来做异地备份。参照 JuiceFS 使用指南将 JuiceFS 挂载到你主机房或者所用的公有云主机上,然后使用 rsync 等工具将备份数据直接写入即可。JuiceFS 的传输都是加密的,并且会自动将大文件分块并行传输,即使通过不可靠的公网进行备份也可以获得很好的性能和体验。

如果你使用 JuiceFS 来直接存储数据或者做本地备份,它还有个更厉害的功能支持你轻松完成异地备份:复制(Replication),它会自动将写入的数据异步复制到指定的另一个对象存储中(可以是任意公有云和服务区)。假设你的主业务在 AWS 北京区,数据需要备份到 UCloud 广州区,只需要创建一个在 AWS 北京区的文件系统,再启用复制功能(并选择 UCloud 广州区),所有写入到 AWS S3 的数据(包括启用复制功能前)都会被自动复制到 UCloud 广州区的 UFile 中。当你需要在 UCloud 广州区进行数据恢复时,它会直接从 UFile 读取数据,速度快且不需要付流量费。

企业版 JuiceFS 的另一个大杀器是全球数据镜像,它可以帮你实现超远距离的近实时数据镜像(只读),比如从美国镜像到中国,或者反过来。相比上面说的数据复制功能,数据镜像还会建议元数据的只读镜像,以保证在超远距离的镜像数据也能获得很好的性能。我们在测试中发现,从 AWS 美东区同步到腾讯云上海区,元数据只有秒级延迟,绝大部分数据在 30 秒内完成同步,偶尔被某墙阻断加密连接导致数据同步滞后,客户端也会主动修复同步,保证数据的正确和一致访问(访问时会略慢)。目前数据镜像功能只开放给企业客户,感兴趣的同学可以联系我们了解更多技术细节。

我们相信,JuiceFS 是目前市场上能找到的最好的数据备份方案,没有之一,因为它:

  1. 支持全球 13 个公有云平台 69 个服务区间自动复制,支持平台还在陆续增加;
  2. 保证数据一致性,和 99.95% 的高可用性(企业版为 99.99%);
  3. 传输加密,企业版支持存储加密;
  4. 兼容 POSIX,JuiceFS 可以通过 FUSE 挂载到 VM 上,使用体验和本地磁盘一致;
  5. Serverless,完全由我们和公有云维护,客户无需维护;
  6. 提供丰富的监控数据,可集成在客户自己的监控系统中;
  7. 复制(Replication)功能可帮你实现轻松的跨云跨服务区备份或者迁移;
  8. 回收站机制,有效防止误删除,可以自己设置回收站保存时间;
  9. 节省大量成本。综合考虑人力和时间成本,比其他方案节省 50% 至 80%。

对了,如果你是 Linux 和 Mac 的个人用户,JuiceFS 可以直接挂载到你自己的电脑上,上面的方法同样适用于备份你的个人数据,我们还提供了1TiB 永久免费容量(对象存储可能不是免费的)。

像这样的使用指南文章,我们会快马加鞭的出更多,也希望大家大开脑洞,想出更多 JuiceFS的好玩用法,或者投稿 success@juicedata.io 给我们,或者通过JuiceFS 网站(https://juicefs.io)右下角的客服在线聊天窗口告诉我们。

JuiceFS 的十一月,提升性能和小文件支持,支持微软 Azure 和网易云,支持 Kubernetes

2017 November Update

题图版权:GotCredit / CC BY 2.0

 

亲爱的 JuiceFS 用户,你们好!

过去这段时间里 ,JuiceFS 又有了很多进步,我们希望与你一起分享,因为每个进步的脚印背后都有你们的支持。我们一直在努力让它成为公有云最好的存储解决方案。

近期 JuiceFS 引入了不少改进和升级:

  1. 采用新的算法大幅提升了随机写性能;
  2. 实现无拷贝的快速文件合并,对于大数据分析场景下的性能优化大有益处;
  3. 实现客户端缓存共享,提升热点数据的读性能;
  4. 增加垃圾回收机制,确保各种意外情况下产生的碎片能够被有效清理;
  5. 支持 Kubernetes 的 Flex 存储卷;
  6. 支持了微软 Azure 和网易云;

更详细的更新日志请见我们的版本更新页。建议你重新挂载以升级到最新版获得这些改进,以便让我们更好的为你服务。

另外,我们对文档中心 做了一次升级,你在这里可以找到详细的架构介绍、上手指南,在 Hadoop 和 Spark 中使用 JuiceFS 的方法,以及在 Kubernetes 中使用 JuiceFS 的解决方案等等。

如果你在使用 JuiceFS 时有什么疑问,或者在数据存储方面遇到新的挑战,可以在网站右下角的绿色图标找到我们,在线交流。

嗨,JuiceFS

startup in the morning

Credit: Robert Lowe © Flickr

JuiceFS 在今年 6 月正式上线,那时还是一个 MVP,有几个技术上喜欢追求卓越的公司在使用,转眼到 11 月的今天第一批客户付费账单产生了,这是个重要的日子,意味着 JuiceFS 正式开始提供商业服务。

在这段时间里,客户创建的文件系统已经超过 100 个,管理了超过 2 千万的文件,累计完成超过 10 亿次数据修改操作,请求峰值超过1万次每秒。

我们组建了一直小而精悍的跨国团队,人人都提交代码,同时也肩负着 CEO、市场拓展、客户支持、行政后勤等各种工作。远程代码协作,远程会议沟通都不是难事,远程庆祝一下却不容易。最终我们还是决定写代码来庆祝,用 Sphinx 重构了之前两个简单的文档页面,变成了一个文档中心,并有中英文支持,同时上线了这个官方博客。

今后,这个博客也将成为 JuiceFS 和大家沟通的窗口,我们再通俗的介绍一下 JuiceFS 是什么,能干嘛 XD

名字结尾的 FS 说明这是一个文件系统产品。对于文件系统,虽然是一直是我们电脑里最重要的部分之一,却一直没有多少存在感,大概只有系统工程师能说清楚它是什么(所以过年回家估计也很难给亲戚们解释我的工作)

JuiceFS 是为云端设计的 POSIX 共享文件系统,包含三方面的意思:

  1. 为云端设计:JuiceFS 完全是为云计算而生的,用现在流行的叫法是 Cloud Native,目标是成为云计算领域最好的存储解决方案。我们已经支持了全球主流的云平台,包括 AWS、微软 Azure、阿里云、腾讯云、UCloud、青云、金山云、网易云、Google Cloud Platform,还有存储平台七牛,使用这些云平台的工程师可以很简单的上手 JuiceFS。JuiceFS 将数据保存在客户自己的对象存储中账号中,数据安全有了很大保障,而且弹性扩容,无需运维。
  2. 兼容 POSIX:JuiceFS 没有自己的 API,而是兼容存储领域历史最悠久使用最广泛的 POSIX API,也就是几乎所有编程语言都支持的 open, read, write 和 close 等 API,不用担心被 API 绑定。JuiceFS 也没有 SDK,而是提供一个通过 FUSE 实现的客户端直接挂在到主机上,大量已有应用和工具无需任何修改就可以直接访问,和使用本地磁盘一样简单。
  3. 共享:这是 JuiceFS 与很多云硬盘最大的不同,它可以被多机(支持 1000 个节点以上,没有单一 VPC 限制)同时挂载,同时读写,并提供强一致性保证。

这三点提供什么价值?一个几乎无限容量的存储系统,可以从任何地方访问,使用它几乎没有学习成本,还无需维护,让很多曾经头疼的分布式系统问题变得非常简单了:

  • JuiceFS 可以用做数据备份和恢复,因为 POSIX 是运维工程师最喜欢的接口,没有之一。
  • JuiceFS 可以提供一个全局的共享空间,方便工程师或者主机之间互通有无,省去很多 scp 的麻烦。
  • JuiceFS 可以用作 Hadoop 或者 Spark 集群的海量数据存储,包括 Hive 等数据仓库。
  • JuiceFS 可以作为存储卷(Volume)挂载在容器集群里,轻松实现容器数据的持久化和共享。
  • JuiceFS 可以替换掉你原有的 NFS、NAS,并有无限容量。
  • JuiceFS 可以帮你实现数据多地备份,就像 RAID-1 那么简单,即使整个区没了也不用担心数据丢失。
  • JuiceFS 可以帮你实现全球数据镜像,简化数据在多地搬来搬去的麻烦。

 

简单可依赖是 JuiceFS 的目标,希望可以帮助工程师同学们更轻松的访问和管理数据,如果您在数据方面遇到什么挑战,有什么建议,请告诉我们 吧 (hello at juicedata.io)!