关于hadoop:存算分离实践构建轻量云中立的大数据平台

3次阅读

共计 7783 个字符,预计需要花费 20 分钟才能阅读完成。

明天咱们将分享社区用户多点 DMALL 的案例。多点 DMALL 是亚洲当先的全渠道数字批发解决方案服务商,目前已与 380 家批发企业达成单干,笼罩 6 个国家和地区。

面对 B 端客户日益增长的企业数据,存算一体的架构显得力不从心。计算资源冗余节约、所依附的 CDH 发行版技术栈简单、部署运维艰难及计算资源潮汐景象重大等问题,迫使多点启动架构降级的过程。同时,为满足 B 端客户多样化的需要,多点须要构建一个能够在多云环境下更具性价比、可复用的大数据底层基座和平台工具链。基于此,多点的大数据团队开始搭建存算拆散的云原生大数据架构

本文深刻分析这次革新的架构设计与演进过程,分享多点 DMALL 在此过程中的教训和挑战。值得一提的是,他们利用 JuiceFS 社区版实现了与 Ranger 组件进行权限的对接,心愿此教训能为其余应用 JuiceFS 的企业提供参考。

一、存算一体架构下的痛点和挑战

1.1 架构原生存在的痛点

存算一体架构带来的老本和运维挑战,是大部分企业在大数据倒退中肯定会面对的问题。

传统的 Hadoop 生态体系中,数据存储角色与计算角色通常会部署在雷同的机器上,一个占据硬盘提供存储,一个利用 CPU 和内存做计算。为此,MapReduce 和 Spark 也适应性的设计了多层级的数据本地化策略,即工作尽可能被调配到存储所需数据的对应节点上做计算,以缩小两头数据交互产生的网络开销和额定的存储压力,晋升整体的大数据利用效率。

可是,随着企业业务的倒退,大数据存储量的增长速率与计算所需节点数量的增长速率很难保持一致。尤其是在“数据就是企业外围资产”的思维下,大量历史数据、冷数据的积攒,导致企业数据存储量的增长诉求远远高于计算资源。最初企业只好一直新增机器存储更多数据,但大量计算资源得不到充分利用造成了闲置与节约

同样是减少存储资源,存算一体架构下会闲置局部计算资源,存算拆散则不会有这个问题。

此外,数据量的一直增长还带来了 HDFS NameNode 元数据压力、集群节点规模扩张受限等问题。这些问题也时时刻刻牵动着各个大数据团队紧绷的神经。

1.2 多点 DMALL 面临的挑战

多点 DMALL 的大数据体系在构建之初,也是采纳传统 Hadoop 存算一体的技术栈。除了上述企业倒退中架构原生带来的窘境外,面对 To B 多样化的业务场景,多点 DMALL 大数据团队面临更多场景化的挑战:

  • 组件多技术栈简单:之前次要依赖 CDH 发行版本,该套架构组件繁多,架构简单,共包含 11 类服务(存储、计算、运维、监控、平安等),22 种角色类型。并且随着时间推移,很多新技术引入异样麻烦,须要思考十分多兼容性问题。
  • 部署简单 & 运维艰难:私有化部署、SaaS 服务模式一度给大数据团队带来了微小的工作量,交付效率不高,包含网络布局、容量布局、私有云机型抉择、破绽修复和多环境日常保护等。
  • 计算资源潮汐景象重大:存算一体的架构下大数据集群和业务集群是互相独立的,资源应用有着不同的特点。大数据集群资源应用的顶峰在凌晨,白天只有零散的即席查问占资源不多;业务集群的峰值在白天,早晨流量很少,这也是畛域内陈词滥调的“潮汐景象”,因而计算资源节约和闲置始终没有彻底解决。

二、存算拆散的架构设计

随着多点 DMALL 全面 To B 转型,为越来越多的 B 端客户提供批发全渠道解决方案,须要具备在多云环境下提供更具性价比、可复用的大数据底层基座和平台工具链 。多点 DMALL 大数据团队联合已有教训和后续业务需要, 设计搭建存算拆散、轻量级、可扩大、云中立大数据集群架构

而存算拆散的第一步,便是要解决数据如何从 HDFS 集群上疾速切换到云服务商存储服务的问题。

2.1 小试牛刀:间接对接对象存储

在架构降级探索期,能想到最间接的计划就是通过 API 对接云厂商的对象存储。

从架构图上看这逻辑十分简洁清晰。思考到各大云厂商都提供了稳固的对象存储服务以及欠缺的 API,间接加以利用应该会升高架构降级的难度。为了疾速测验这一思路的可行性,咱们首先抉择了大数据平台上,与 HDFS 会产生交互的局部性能做切换,将其换成与对象存储进行交互的形式。

疾速测验的后果是,这样的设计不仅没有达到预期,反而使大数据平台开发的复杂度成倍增加

呈现问题的外围点在于:

  • 局部 B 端客户可能会抉择本人信赖 / 单干的云服务商,而抉择的后果不可控。
  • 尽管底层都是 S3 的协定,为了构建技术壁垒,各大云服务商的对象存储 API 依然存在肯定差别。
  • 为了满足不同客户的不同云服务商需要,大数据平台工具链将须要适配开发多套代码,开发工作量微小。

通过验证,上述摸索计划只能进行小型试点,无奈撑持整个大数据架构的规模化调整,还需探寻新的解决方案。于是,JuiceFS 进入了咱们的眼帘。

2.2 JuiceFS:平滑过渡利器

多点大数据团队很早便开始关注 JuiceFS 了。在间接应用对象存储的计划宣告不可行之后,咱们就始终在寻找能帮忙大数据利用及引擎平滑切换到对象存储的形式。侥幸的是,咱们留神到了 JuiceFS 合伙人苏锐的一篇分享:从 Hadoop 到云原生,大数据平台如何做存算拆散。而后通过一直摸索与验证,咱们意识到这就是始终在寻找的问题解决之道。

采纳 JuiceFS 的劣势如下:

  • 已对接市面支流私有云对象存储:为了将存储和计算剥离,对象存储是最佳抉择,其自身是私有云最根底服务之一。JuiceFS 底层存储对接了市场上绝大部分云服务厂商提供的对象存储服务,能够帮忙咱们彻底剥离存储和计算资源,做到存算拆散的成果。
  • 完满兼容 HDFS 协定,大数据引擎平滑切换:JuiceFS 提供了 Hadoop Java SDK,帮忙所有应用传统的 HDFS API 的计算引擎和利用平滑切换,根本能够做到只须要批改相应的配置便能够间接执行,大大降低了新架构下引擎间调试适配的复杂性。
  • 独立元数据引擎,解决 NameNode 瓶颈问题:JuiceFS 的元数据存储在独立的存储引擎中,彻底解决了 NameNode 内存限度及单点问题。元数据引擎独立部署,对其独自的调优和运维也更加便当。没有元数据扩大的压力,集群扩张的限度也不再存在。
  • 提供 CSI 形式,反对云原生设计:在构建云原生架构的路线上,JuiceFS 提供的 Kubernetes CSI 驱动,让这个架构设计实现更加欠缺,在 K8s 上应用 JuiceFS 更加不便。

2.3 最终架构设计

以下是多点大数据最终的存算拆散架构设计:

咱们将整体架构逻辑分为以下几层:

  • 工具层:最上层是多点大数据团队自研的 UniData 大数据平台工具链,提供欠缺的大数据开发治理能力,包含数据集成、数据开发、任务调度、数据资产等,实现了“用”。
  • 计算层:接下来是由 Kubernetes 治理的数据计算层,提供 Spark、Flink 等计算组件。这一层就是“存算拆散”中的“算”。
  • 管控层:再下一层中,提供了除了数据计算外,元数据的存储、权限的管控、查问代理等性能,负责了架构中的“管”这一层。
  • 存储层:最初就是 JuiceFS 和各个云服务提供的对象存储,提供协定适配和减速能力,实现了“存”。

在一直摸索和尝试中,咱们最终确定 JuiceFS 的引入和应用。JuiceFS 作为存储中间层,对下屏蔽了底层理论存储介质,隔离了不同的云环境,对上提供了对立的 HDFS API,保障了引擎执行和利用性能的一致性和稳定性,从而保障了集群整体对外服务的品质。

三、JuiceFS 的深刻使用实际

新技术的引入总是随同着折腾的过程。在摸索和应用 JuiceFS 的过程中,多点 DMALL 大数据团队不出意外地踩了一些坑,幸亏最终都找到了较为正当的解决方案。在此将遇到的局部典型问题整顿分享进去,心愿给所有打算和正在应用 JuiceFS 的同学一些启发和帮忙。

3.1 增加基于 Ranger 的平安管控

开源的 JuiceFS 我的项目中,Hadoop Java SDK 没有平安管控的性能。因而在抉择应用 JuiceFS 时,平安成为咱们最关注的问题。

通过对该模块代码的粗疏钻研,参考 HDFS 的鉴权逻辑计划,咱们在 JuiceFS 的 FileSystem 的实现类中,对每个 API 的实现实际操作触发前都增加了权限拦挡的解决

“权限”一词的计算机语言外延就是“实体 + 动作”,Ranger 的权限设计实质也是一样的。咱们将拦挡的对应操作(例如创立)和相干门路转化为 Ranger HDFS 模块所需鉴权的动作和实体,并与操作用户组合成 RangerAccessRequest 与 Ranger HDFS 模块买通进行鉴权。这个改变解决了 JuiceFS 在零碎中“裸奔”的状况,为数据的平安做了一道防护。

当然,从整体的权限体系设计来讲,思考到 Ranger 始终被人所诟病的 Ranger Admin 连贯风暴和策略本地化等问题,咱们设计减少了权限鉴权的代理层,来进行鉴权的分流、权限映射和缓存等。但这些架构上的优化不影响 JuiceFS 接入 Ranger 的权限管控的实质指标。

除了失常的权限管控,对于可能存在的歹意应用咱们也做了筹备。思考到 JuiceFS 开源代码的公开性,为了防止局部用户在理解到底层架构和引擎抉择后,歹意破解调用以非法获取数据,咱们对 JuiceFS 还做了额定的代码调整,包含批改外围参数的取值形式等。在保留和充分利用 JuiceFS 的外围性能前提下增加防护墙,晋升整体的平安程度。

3.2 Spark 的 Shuffle 数据处理

在 Spark on K8s 的云原生设计中,Shuffle 数据的解决是须要重点关注的。相比于通过机器堆进去的 YARN 集群能够间接利用超大的本地磁盘存储 Shuffle 数据而言,试图防止依赖底层机器、存算拆散设计下 K8s 上的工作只能另谋他路。

在看到 JuiceFS 提供的的 K8s CSI 驱动时,咱们最后以此作为突破点。在构想中,能够利用 JuiceFS K8s CSI 驱动的 writeback 模式,Shuffle 数据先搁置长期存储目录,超过阈值后载入远端对象存储中。这样的逻辑下,Spark 的 Shuffle 数据就无需依赖本地机器磁盘大小,有海量对象存储作为最终存储介质,实践上不再放心执行压力和数据长期存储压力。

但通过理论验证,在进行 on YARN 和 on K8s 的性能测试比照时发现,应用这个计划的实际效果是:慢得不止一点点。

以下为测试中最典型的一个 Query 后果:

在深入分析钻研后,咱们发现 Shuffle 场景自身会存在大量小文件及随机读操作,JuiceFS K8s CSI 并不适宜这种场景,会产生较大的性能瓶颈。在与 JuiceFS 社区沟通探讨后,咱们开始调研开源的 Remote Shuffle Service,将 CSI 的形式切换为利用独立的 Shuffle 服务,并依据测试最终选用了 Apache Celeborn(后简称 Celeborn)反对这一场景,其整体性能体现跟 on YARN 差别不大。Apache Celeborn 本身反对分级存储能力,极大晋升了各类理论负载适配能力,咱们将 JuiceFS 作为内存 / 磁盘容量有余状况下最初的兜底 Shuffle 数据存储。

3.3 Alpine 镜像问题

上文提到,咱们有一些大数据平台利用是间接通过 Hadoop Java SDK 与 HDFS 进行交互的。这些利用都是 Java 利用,在云原生的转换过程中发现以下报错:

`initial-exec TLS resolves to dynamic definition in /tmp/libjfs-amd64.7.so`

通过摸索,并与 JuiceFS 社区沟通后,咱们发现这个问题,是因为应用的根底镜像 openjdk-Alpine 自身的 bug,起初咱们换成了 eclipse-temurin 解决了问题。

3.4 root 不会被设置为 Owner

在 Celeborn 的应用中发现一个破绽。Celeborn 会主动创立其存储 Shuffle 数据的 HDFS 目录,当该服务的启动用户是 root 时,主动创立的 HDFS 目录并没有被主动设置 Owner 为 root。在下面提到的咱们模拟 HDFS 鉴权思路中,对于一些目录的操作会去校验是否是这个目录的 Owner。root 没有被设置,天然后续 Celeborn 很多针对这个 HDFS 目录的操作都会被权限拦挡。

尽管咱们能够通过切换 Celeborn 的启动用户,或者给他独自设置权限等形式绕过这个拦挡。思考到创立后设置 Owner 是正当行为,而且除了 root 外的其余用户都会被失常设置,咱们还是将这个疑难向 JuiceFS 社区提出来。感激 JuiceFS 社区第一工夫的响应和反对,很快就修复了这个小破绽。

3.5 数据缓存使用与 OOM 问题

将 CSI 驱动切换成 Celeborn 后,咱们又一次开始做 Spark on YARN 和 on K8s 的性能测试。比照中发现,雷同的工作和资源,on K8s 的工作总是会报错 OOM。通过粗疏的 Spark 内存剖析,并一直比照多个环境工作和差别点后,团队内一位同学发现了 JuiceFS 的数据缓存参数设置区别,深刻开掘,最终找到答案。

Spark 工作执行时,须要特地配置juicefs.cache-dir,不然 JuiceFS 就会默认将数据缓存放进内存中,从而对每一个 executor 多出好几百兆的额定内存占用。如果不做非凡配置,那就须要在 Spark 工作切换到 on K8s 的环境时,多配一些 off-heap 堆外内存,用以反对 JuiceFS 的额定数据缓存。

3.6 数据缓存目录的权限

在应用数据缓存目录(后简称 cache 目录)的利用中,咱们还遇到了另一个问题。Spark on K8s 的 Jupyter 利用中咱们应用 JuiceFS K8s CSI 驱动建设的 PVC,与应用 JuiceFS Hadoop Java SDK 挂载 cache 目录,当二者应用同一个目录,会产生权限抵触的问题,在 Spark 运行日志中呈现 warn 日志无奈落地 / 获取缓存数据。认真跟踪后发现,是因为两条链路生成的缓存文件目录默认权限不同,互相批改权限最终导致了文件写入失败,这样相当于基本没利用上 JuiceFS 客户端缓存,每次都间接与对象存储交互,这样对 Spark 工作性能而言影响很大。

该问题在反馈给 JuiceFS 社区后,社区通过对 JuiceFS K8s CSI 驱动减少参数“cache-mode”进行了修复。

3.7 TiKV & Write Conflict

在做容量布局的时候思考到线上集群规模,TiKV 一开始就被咱们抉择为 JuiceFS 的元数据存储引擎。在咱们对云原生架构开发测试的大部分工夫内,TiKV 的体现始终很稳固,直到咱们抉择 Celeborn 作为独立 Shuffle 服务。

依据 Celeborn 的功能设计,在当本地磁盘存储 Shuffle 数据满时,将把数据下推到 HDFS 中(当然咱们在这里利用 JuiceFS 让其理论下推到了对象存储)。但在具体测试时发现,多个 Celeborn 的 Worker 同时写一个 JuiceFS 的目录会呈现 Write Conflict 问题并触发重试操作。重试操作会有次数极限,而且一直重试很明显降低了整体 Shuffle 效率缩短了工作执行时长,在很长一段时间内这个问题也困扰着咱们。

最终,社区的另一位 JuiceFS 用户给出了计划。Write Conflict 的根本原因是所有的写文件都要批改父目录的更新工夫,这个报错并非是因为写文件,而是批改同一个目录属性产生的异样。再进一步,产生 Write Conflict 的不是 JuiceFS 治理的数据,而是元数据,也就是 TiKV 的锁问题。最终,思考到除了 Shuffle 场景,这样高并发的批改同一个目录的属性并不常见,咱们决定为 Celeborn 部署提供独自的 JuiceFS 的 Hadoop Java SDK,这个 SDK 是独自解决的,写数据不再更新父目录的属性。

3.8 TiKV 垃圾回收机制

退出 JuiceFS 社区群后,咱们也时常关注群内其余企业应用的问题反馈,能够帮忙咱们在正式上线前笼罩更多的测试案例。TiKV 的垃圾回收机制问题就是其中一个。当看到群里有其他同学反馈后,咱们疾速剖析了该问题产生的起因,并查看补充了部署策略。TiKV 的独立服务并不会主动触发垃圾回收机制,只有同步装置 TiDB 这个组件才会失常运行。而咱们在元信息服务 TiKV 部署策略中会同步装置 TiDB,不会遇到这个问题。另外,JuiceFS 1.0.4 版本开始曾经新增 TiKV gc worker 后盾线程适时触发垃圾回收动作。

3.9 HDFS 回收站文件无奈清理

当 HDFS 配置文件中开启了 HDFS 回收站性能(fs.trash.intervalfs.trash.checkpoint.interval),只有存活的客户端实例都会查看并触发回收站中文件清理工作。然而最开始咱们测试发现,清理线程总是报错提醒没有文件操作权限。跟 JuiceFS 社区沟通后发现,确实存在 bug 导致过期文件没法清理,并迅速提供了 PR 修复。

四、最终测试后果

正如上文中提到的,咱们在架构降级过程中屡次在公司开发环境进行了 Spark on YARN 和 on K8s 的性能测试比照,别离执行屡次 TPC-DS SQL。以下为最终的比照后果:

上述测试是通过大数据平台 UniData 配置工作进行数据计算比照,变量蕴含平台调度策略的调整、Spark 版本升级等。排除其余变量,深入分析工夫差别后,咱们得出以下论断:

  1. Spark 工作基于 HDFS 的 on YARN 执行时长与基于 JuiceFS 的 on K8s 执行时长根本持平,性能差别较小。
  2. JuiceFS 的数据缓存设计对数据查问存在显著的减速作用,同样的 SQL 在屡次执行后,执行速度显著晋升。
  3. JuiceFS 会占用局部内存,总体而言比基于 HDFS 的工作所需内存更多。

从上述测试后果来看,曾经达到了咱们新架构正式上线的要求。目前这套架构已在多个私有云环境中安稳运行,接下来咱们会启动现有历史 CDH 存算一体集群下线,并降级为新的存算拆散新架构的动作。另外,为进一步晋升 Spark 执行性能,咱们也在积极开展引入向量化执行引擎框架 Gluten 的测试验证工作。

五、小结

在多点 DMALL 从传统 Hadoop 存算一体到存算拆散的降级过程中,JuiceFS 的呈现填补了存储设计的空缺,推动了降级闭环。它对上放弃了同样的 HDFS 协定,升高各个利用和引擎适配复杂度,对下完满对接各个云服务厂商提供的对象存储服务,晋升了整体架构的降级效率。

通过整体向云原生的存算拆散架构的降级,咱们取得了多方面的收益:

  • 节约老本:存算拆散能够为企业客户节约大量硬件或云服务商的老本,从而晋升客户满意度,这也推动了咱们服务续约率的晋升。
  • 技术扩展性好:咱们之前应用 CDH 发行版进行组件的治理,因为引擎间版本限度,和重要组件降级带来的危险低等问题,客户有些技术升级诉求无奈响应。存算拆散后咱们也解脱了这个限度。当初,咱们能够针对性地降级和调试繁多组件,甚至在同一集群内进行 AB 测试,大大降低了降级危险。
  • 部署和运维效率晋升 :降级前咱们的交付最快只能达到天级,这还不算后期的集群设计和筹备工作。当初能够达到小时级,资源是按需应用的,随用随取,没有之前那些简单的预投入,大数据平台一键拉起,开释了大量人力老本。
    咱们很侥幸在整体架构降级的过程中遇到了 JuiceFS 这个我的项目,也心愿通过这篇实际分享能帮忙到更多的企业更好的使用 JuiceFS。将来咱们也会继续关注 JuiceFS 社区,继续为社区建设做出更多的奉献。

心愿这篇内容可能对你有一些帮忙,如果有其余疑难欢送退出 JuiceFS 社区与大家独特交换。

正文完
 0