背景
一面数据创建于 2014 年,是一家当先的数据智能解决方案提供商,通过解读来自电商平台和社交媒体渠道的海量数据,提供实时、全面的数据洞察。长期服务寰球快消巨头(宝洁、联合利华、玛氏等),取得行业宽泛认可。公司与阿里、京东、字节单干共建多个我的项目,旗下知乎数据专栏“数据冰山”领有超 30 万粉丝。一面所属艾盛团体(Ascential)在伦敦证券交易所上市,在 120 多个国家为客户提供本地化业余服务。
公司在 2016 年线下机房部署了 CDH 集群,到 2021 年已存储和解决 PB 级的数据。公司自创建以来始终放弃每年翻一番的高增长,而比业务量增长更快的是 Hadoop 集群的数据量。
在这几年间,按 1 到 2 年布局的硬件,往往因数据增长超出预期而在半年后不得不再次扩容。每次扩容周期可达到一个月,除了破费大量精力跟进行政和技术流程,业务端也不得不安顿较多人日控制数据量。
为了升高运维难度,倒退可继续扩张的大数据处理计划,咱们从 2021 年 10 月份开始摸索取代现有 Hadoop 集群的计划。过后提出了这些需要:
- 上云,弹性伸缩、灵便运维
- 存储计算拆散
- 尽量应用开源组件,防止云厂商绑定
- 尽量升高业务迁徙工作量
最终抉择的计划是应用阿里云 EMR + JuiceFS + 阿里云 OSS 来搭建存算拆散的大数据平台,将云下数据中心的业务逐渐迁徙上云。截至目前(2022 年 7 月)整体迁徙进度约 40%,打算在 2022 年内实现全副业务的搬迁,届时云上 EMR 的数据量预计会超过单正本 1 PB.
技术选型
首先是决定应用哪家云厂商。因为业务需要,AWS、Azure 和阿里云都有在用,综合思考后认为阿里云最适宜,有这些因素:
- 物理间隔:阿里云在咱们线下机房同城有可用区,网络专线的提早小,成本低
- 开源组件齐全:阿里云 EMR 上蕴含的开源组件很多很全,除了咱们重度应用的 Hive、Impala、Spark、Hue,也能不便集成 Presto、Hudi、Iceberg 等。咱们在调研时发现只有阿里云 EMR 自带了 Impala,AWS 和 Azure 要么版本低,要么要本人装置部署。
阿里云的 EMR 自身也有应用 JindoFS 的存算拆散计划,但基于以下思考,咱们最终抉择了 JuiceFS:
- JuiceFS 应用 Redis 和对象存储为底层存储,客户端齐全是无状态的,能够在不同环境拜访同一个文件系统,进步了计划的灵活性。而 JindoFS 元数据存储在 EMR 集群的本地硬盘,不便于保护、降级和迁徙。
- JuiceFS 的存储计划丰盛,而且反对不同计划的在线迁徙,进步了计划的可移植性。JindoFS 块数据只反对 OSS.
- JuiceFS 以开源社区为根底,反对所有私有云环境,不便前期扩大到多云架构。
对于 JuiceFS
间接截取官网文档的介绍:
JuiceFS 是一款面向云原生设计的高性能共享文件系统,在 Apache 2.0 开源协定下公布。提供齐备的 POSIX 兼容性,可将简直所有对象存储接入本地作为海量本地磁盘应用,亦可同时在跨平台、跨地区的不同主机上挂载读写。
JuiceFS 采纳「数据」与「元数据」拆散存储的架构,从而实现文件系统的分布式设计。应用 JuiceFS 存储数据,数据自身会被长久化在对象存储(例如,Amazon S3),绝对应的元数据能够按需长久化在 Redis、MySQL、TiKV、SQLite 等多种数据库中。
除了 POSIX 之外,JuiceFS 残缺兼容 HDFS SDK,与对象存储联合应用能够完满替换 HDFS,实现存储和计算拆散。
施行过程
咱们在 2021 年 10 月开始摸索 Hadoop 的上云计划;11 月做了大量调研和探讨,根本确定计划内容;12 月和 2022 年 1 月春节前做了 PoC 测试,在春节后 3 月份开始搭建正式环境并安顿迁徙。为了防止导致业务中断,整个迁徙过程以绝对较慢的节奏分阶段执行,截至目前(2022 年 7 月)进度约 40%,打算在 2022 年内实现整体的搬迁。迁徙完后,云上的 EMR 集群数据量预计会超过单正本 1 PB.
架构设计
做完技术选型之后,架构设计也能很快确定下来。思考到除了 Hadoop 上云之外,依然有大部分业务会持续保留在数据中心,所以整体实际上是个混合云的架构。
部署和配置
- 对于 IDC- 阿里云专线:能提供专线服务的供应商很多,包含 IDC、阿里云、运营商等,抉择的时候次要思考线路品质、老本、施工周期等因素,最终咱们抉择了 IDC 的计划。IDC 跟阿里云有单干,很快就实现了专线的开明。这方面如果遇到问题,能够找 IDC 和阿里云的反对。除专线租用老本,阿里云也会收取上行(从阿里云到 IDC)方向传输费用。专线两端的内网 IP 齐全互通,阿里云和 IDC 两侧都须要一些路由配置。
- 对于 EMR Core/Task 节点类型的抉择:
- JuiceFS 能够应用本地硬盘做缓存,能进一步缩小 OSS 带宽需要并进步 EMR 性能。更大的本地存储空间,能够提供更高的缓存命中率。
- 阿里云本地 SSD 实例是较高性价比的 SSD 存储计划(绝对于云盘),用作缓存正合适。
- JuiceFS 社区版未反对分布式缓存,意味着每一个节点都须要一个缓存池,所以应该选用尽量大的节点。
基于以上思考和配置比照,咱们决定选用 ecs.i2.16xlarge,每个节点 64 vCore、512GiB Memory、1.8T*8 SSD。
- 对于 EMR 版本:
软件方面,次要包含确定组件版本、开启集群、批改配置。咱们机房应用的是 CDH 5.14,其中 Hadoop 版本是 2.6,阿里云上最靠近的版本是 EMR 3.38. 但调研时发现该版本的 Impala 和 Ranger 不兼容(实际上咱们机房应用的是 Sentry 做权限治理,但 EMR 上没有),最终通过评估比照,决定间接应用 EMR 5 的最新版,简直所有组件的大版本都做了降级(蕴含 Hadoop 3、Spark 3 和 Impala 3.4)。此外,应用内部 MySQL 作为 Hive Metastore、Hue、Ranger 的数据库。 - 对于 JuiceFS 配置:
根本参考 JuiceFS 官网文档《在 Hadoop 中通过 Java 客户端拜访 JuiceFS》即可实现配置。另外咱们也配置了这些参数: - 缓存相干:其中最重要的是
juicefs.cache-dir
缓存目录。这个参数反对通配符,对多个硬盘的实例环境很敌对,如设置为/mnt/disk*/juicefs-cache
(须要手动创立目录,或在 EMR 节点初始脚本中创立),即用全副本地 SSD 作为缓存。另外也要关注juicefs.cache-size
、juicefs.free-space
两个参数。 juicefs.push-gateway
:设置一个 Prometheus Push Gateway,用于采集 JuiceFS Java 客户端的指标。juicefs.users
、juicefs.groups
:别离设置为 JuiceFS 中的一个文件(如jfs://emr/etc/users
、jfs://emr/etc/groups
),解决多个节点 uid 和 gid 可能不对立的问题。- 对于 Kafka Connect 应用 JuiceFS:
通过一些测试,确认 JuiceFS 能够完满利用于 Kafka Connect 的 HDFS Sink 插件(咱们把配置形式也补充到了官网文档)。相比应用 HDFS Sink 写入 HDFS,写入 JuiceFS 须要减少或批改以下配置项:
- 将 JuiceFS Java SDK 的 JAR 包公布到 Kafka Connect 每一个节点的 HDFS Sink 插件目录。Confluent 平台的插件门路是:
/usr/share/java/confluentinc-kafka-connect-hdfs/lib
-
编写蕴含 JuiceFS 配置的
core-site.xml
,公布到 Kafka Connect 每一个节点的任意目录。包含这些必须配置的我的项目:fs.jfs.impl = io.juicefs.JuiceFileSystem fs.AbstractFileSystem.jfs.impl = io.juicefs.JuiceFS juicefs.meta = redis://:password@my.redis.com:6379/1
请参见 JuiceFS Java SDK 的配置文档。
- Kafka Connector 工作设置:
hadoop.conf.dir=<core-site.xml 所在目录 >
store.url=jfs://<JuiceFS 文件系统名称 >/< 门路 >
PoC
PoC 的目标是疾速验证计划的可行性,有几个具体指标:
- 验证 EMR + JuiceFS + OSS 整体计划的可行性
- 查看 Hive、Impala、Spark、Ranger 等组件版本的兼容性
- 评估比照性能体现,用了 TPC-DS 的测试用例和局部外部实在业务场景,没有十分准确的比照,但能满足业务需要
- 评估生产环境所需的节点实例类型和数量(算老本)
- 摸索数据同步计划
- 摸索验证集群与自研 ETL 平台、Kafka Connect 等的集成计划
期间做了大量测试、文档调研、内外部(阿里云 + JuiceFS 团队)探讨、源码了解、工具适配等工作,最终决定持续推动。
数据同步
要迁徙的数据包含两局部:Hive Metastore 元数据以及 HDFS 上的文件。因为不能中断业务,采纳存量同步 + 增量同步(双写)的形式进行迁徙;数据同步完后须要进行一致性校验。
存量同步
对于存量文件同步,能够应用 JuiceFS 提供的性能残缺的数据同步工具 sync 子命令 来实现高效迁徙。JuiceFS sync 命令反对单节点和多机并发同步,理论应用时发现单节点开多线程即可打满专线带宽,CPU 和内存占用低,性能体现十分不错。
Hive Metastore 的数据同步则绝对麻烦些:
- 两个 Hive 版本不统一,Metastore 的表构造有差别,因而无奈间接应用 MySQL 的导出导入性能
- 迁徙后须要批改库、表、分区存储门路(即
dbs
表的DB_LOCATION_URI
和sds
表的LOCATION
)
因而咱们开发了一套脚本工具,反对表和分区粒度的数据同步,应用起来很不便。
增量同步
增量数据次要来自两个场景:Kafka Connect HDFS Sink 和 ETL 程序,咱们采纳了双写机制。
Kafka Connect 的 Sink 工作都复制一份即可,配置形式上文有介绍。ETL 工作对立在外部自研的低代码平台上开发,底层应用 Airflow 进行调度。通常只须要把相干的 DAG 复制一份,批改集群地址即可。理论迁徙过程中,这一步遇到的问题最多,花了大量工夫来解决。次要起因是 Spark、Impala、Hive 组件版本的差别导致工作出错或数据不统一,须要批改业务代码。这些问题在 PoC 和晚期的迁徙中没有笼罩到,算是个教训。
数据校验
数据同步完后须要进行一致性校验,分三层:
- 文件统一。在存量同步阶段做校验,通常的形式是用 checksum. 最后的 JuiceFS sync 命令不反对 checksum 机制,咱们倡议和探讨后,JuiceFS 团队很快就加上了该性能(issue,pull request)。除了 checksum,也可思考应用文件属性比照的形式:确保两个文件系统里所有文件的数量、批改工夫、属性统一。比 checksum 的可靠性稍弱,但更轻量快捷。
- 元数据统一。有两种思路:比照 Metastore 数据库的数据,或比照 Hive 的 DDL 命令的后果。
- 计算结果统一。即应用 Hive/Impala/Spark 跑一些查问,比照两边的后果是否统一。一些能够参考的查问:表 / 分区的行数、基于某个字段的排序后果、数值字段的最大 / 最小 / 平均值、业务中常常应用的统计聚合等。
数据校验的性能也封装到了脚本里,不便疾速发现数据问题。
后续打算
大抵有几个方向:
- 持续实现残余业务的上云迁徙
- 摸索 JuiceFS + OSS 的冷热分级存储策略。JuiceFS 的文件在 OSS 上齐全被打散,无奈基于文件级别做分级。目前的思路是将冷数据从 JuiceFS 迁徙到 OSS 上,设置为归档存储,批改 Hive 表或分区的 LOCATION,不影响应用。
- 目前 JuiceFS 应用 Redis 作为元数据引擎,如果未来数据量减少,应用 Redis 有压力的话可能思考切换为 TiKV 或其余引擎。
- 摸索 EMR 的弹性计算实例,争取能在满足业务 SLA 的前提下升高应用老本
一手实战经验
在整个施行过程中陆陆续续踩了一些坑,积攒了一些教训,分享给大家做参考。
阿里云 EMR 和组件相干
兼容性
- EMR 5 的 Hive 和 Spark 版本不兼容,无奈应用 Hive on Spark,能够把默认的引擎改成 Hive on Tez.
- Impala 的 stats 数据从旧版同步到新版后,可能因为 IMPALA-10230 导致表无奈查问。解决方案是在同步元数据时,将
num_nulls=-1
的改成num_nulls=0
. 可能须要用到 CatalogObjects.thrift 文件。 - 原集群有大量 Textfile 格局的文件用了 snappy 压缩,新版 Impala 无奈读取,报错
Snappy: RawUncompress failed
,可能是 IMPALA-10005 导致的。躲避计划是不要对 Textfile 文件应用 snappy 压缩。 - Impala 3.4 相比 2.11 的
CONCAT_WS
函数行为有差别,老版本CONCAT_WS('_', 'abc', NULL)
会返回NULL
,而新版本返回'abc'
. - Impala 3.4 对 SQL 中的保留关键字援用更严格,必须加上 “. 其实一个好习惯是业务代码不要应用保留关键字。
- PoC 或后期测试的覆盖度尽可能残缺,用实在的业务代码去跑。咱们在 PoC 和晚期迁徙的业务中用到的组件个性比拟少,根本都是最罕用、放弃兼容的性能,因而比较顺利。但在第二批迁徙过程中就暴露出了很多问题,尽管最终都有解决,但花了很多额定的工夫去做诊断和定位,打乱了节奏。
性能
- EMR 5 的 Impala 3.4 打了 IMPALA-10695 这个补丁,反对对
oss://
和jfs://
(本意是反对 JindoFS,但 JuiceFS 也默认应用 jfs 这个 scheme)设置独立的 IO 线程数。在 EMR 管制台上减少或批改 Impala 的配置项num_oss_io_threads
. - 阿里云 OSS 有账号级别的带宽限度,默认 10Gbps,随着业务规模回升容易成为瓶颈。能够与阿里云沟通调整。
运维
- EMR 能够关联一个 Gateway 集群,通常用来部署业务程序。如果要在 Gateway 上用 client 模式提交 Spark 工作,须要先将 Gateway 机器的 IP 加到 EMR 节点的 hosts 文件。默认能够应用 cluster 模式。
- EMR 5 会开启一个 Spark ThriftServer,在 Hue 上能够间接写 Spark SQL,用起来很不便。但默认配置有个坑,会写大量日志(门路大略是
/mnt/disk1/log/spark/spark-hadoop-org.apache.spark.sql.hive.thriftserver.HiveThriftServer2-1-emr-header-1.cluster-xxxxxx.out
),导致硬盘写满。解决方案有两个:配置 log rotate 或把spark.driver.extraJavaOptions
配置清空(阿里云技术支持的倡议)。
JuiceFS 相干
- JuiceFS 须要每个节点上具备雷同的 UID 和 GID,否则很容易呈现权限问题。有两种实现形式:批改操作系统的用户(比拟适宜新机器,没有历史包袱),或者在 JuiceFS 上保护一个用户映射表。咱们之前也分享过一篇 JuiceFS + HDFS 权限问题定位,有具体探讨。通常须要保护映射的用户有
impala
,hive
,hadoop
等。如果应用 Confluent Platform 搭建 Kafka Connect,也须要配置cp-kafka-connect
用户。 - 应用默认的 JuiceFS IO 配置时,雷同的写查问,Hive on Tez 和 Spark 都比 Impala 快很多(但在机房里 Impala 更快)。最终发现将
juicefs.memory-size
从默认的300
(MiB) 改成1024
之后 Impala 的写入性能有成倍的晋升。 - 在做 JuiceFS 的问题诊断和剖析时,客户端日志很有用,须要留神 POSIX 和 Java SDK 的日志是不一样的,详见 JuiceFS 故障诊断和剖析 | JuiceFS Document Center
- 留神监控 Redis 的空间用量,Redis 如果满了,整个 JuiceFS 集群无奈写入。
- 应用 JuiceFS sync 把机房数据往云上同步时,抉择在有 SSD 的机器上跑,取得更好的性能。
如有帮忙的话欢送关注咱们我的项目 Juicedata/JuiceFS 哟!(0ᴗ0✿)