专栏首页腾讯大数据的专栏向成熟化迈进 - 腾讯Ozone千台能力突破

向成熟化迈进 - 腾讯Ozone千台能力突破

背景介绍

腾讯目前在HDFS上存储了海量的数据,但HDFS在可扩展性上的缺陷,以及对小文件的不友好,限制了HDFS在许多场景下的应用。

为了寻找能解决这些问题的存储系统,Ozone走入了我们的视野。Ozone是继HDFS的下一代统一数据湖对象存储系统,数据湖是一种在系统或存储库中以自然格式存储数据的方案,它有助于以各种模式和结构形式配置数据,通常是对象块或文件。

HDFS缺陷

Apache Hadoop HDFS从出现到现在经过10多年的发展,已经到了非常成熟的状态,广泛应用于业界,解决海量文件的存储需求。但随着数据量的增长,以及对于数据使用方式的多样化 ,HDFS的架构局限性就逐渐被放大,NameNode在大规模场景很容易成为瓶颈:

•元数据的扩展性:NameNode是一个中央元数据服务节点,也是集群管理节点,文件系统的元数据以及块位置关系全部在内存中。NameNode对内存的要求非常高,需要定制大内存的机器,内存大小也限制了集群扩展性。京东的NameNode采用内存512GB的机器,字节跳动的NameNode采用内存1TB的机器。此外,NameNode的堆分配巨大,京东的NameNode需要360GB的堆大小,对GC的要求比较高,京东定制化的JDK11+G1GC在GC时性能良好,但是一般规模的公司不具备维护JDK能力,该方案不具备普遍性。字节跳动把NameNode修改成C++版本,这样分配、释放内存都由程序控制,也达到了不错的性能,该方案仍然不具普遍性,因为开发和维护C++版本的NameNode也需要不小规模的团队。

•块汇报风暴:HDFS块大小默认128M,启动几百PB数据量的集群时,NameNode需要接受所有块汇报才可以退出安全模式,因此启动时间会达数小时。当集群全量块汇报、下线节点、balance集群存储,也会对集群元数据服务的性能造成影响,这些根本原因都是DataNode需要把所有块汇报给NameNode。

•全局锁:NameNode 有一把FSNamesystem全局锁,每个元数据请求时都会加这把锁。虽然是读写分开的,且有部分流程对该锁的持有范围进行了优化,但依然大问题。同时FSNamesystem内部的FSDirectory(Inode树)还存在一把单独的锁,用来保护整棵树以及BlockMap的访问和修改。

Ozone优势

为了解决HDFS的上述问题,Hadoop社区推出分布式key-value对象存储系统Ozone,兼容文件访问接口。利用Hadoop Compatible FileSystem接口, Ozone可以用于大数据生态;利用CSI,S3协议, Ozone可以作为云存储服务云上用户。  

Ozone架构分为三个部分,OzoneManager、StorageContainerManager、Datanode。OzoneManager相当于HDFS的Namespace元数据;StorageContainerManager相当于HDFS的Block Manager,但管理的是Container而不是HDFS的Block。而Datanode使用Raft实现的Ratis保证写一致性。

HDFS的三个局限,Ozone采用如下方式解决:

•Ozone把Namespace元数据服务和Block Manager拆分为两个服务。OzoneManager负责元数据服务;StorageContainerManager负责数据块管理、节点管理、副本冗余管理。两个服务可以部署在两台机器,各自利用机器资源。Ozone的元数据不像NameNode存储在内存中,不管是OzoneManager的元数据,还是StorageContainerManager中的Container信息都维护在RocksDB中,极大降低对内存的依赖,理论上元数据可以无限扩展。

•StorageContainerManager无须管理默认128MB的Block,只需管理默认5GB的Container。极大地减少了StorageContainerManager管理的数据量,从而提升StorageContainerManager的服务性能。因为StorageContainerManager是以Container作为汇报单位,汇报数量比HDFS大大减少。无论是全量块汇报,增删副本,balancer集群存储,都不会给StorageContainerManager性能造成很大影响。

•OzoneManager内部的锁是Bucket级别,可以达到Bucket级的写并发。Ozone是对象存储,对象语义的操作,不存在目录和树的关系,因此不需要维护文件系统树,可以达到高吞吐量。

Ozone稳定性提升

腾讯正将越来越多的业务接入Ozone,包括数据仓库、机器学习平台、K8S集群挂载盘等等。因此亟需提升Ozone的成熟度,而大规模集群上能否长时间稳定运行是检验成熟度的一个非常重要的标志。因此我们采用线上业务真实数据,在千台以上Datanode的单集群上,进行读、写、删操作,观察集群稳定性,以及数据正确性。

在经过长时间的反复验证改进后,内部Ozone能够以千台以上的规模长时间稳定运行,且无须人工运维介入。在验证改进过程中,我们做了大量的优化工作来改进性能,提升稳定性。在接下来的内容中,我们将会分享几个重点的改进案例。

优化历程

在千台集群规模之前,已提前进行小规模的测试,并测出若干导致集群不稳定的因素,例如内存泄露、吞吐量下降、Ratis Group不稳定等问题。这些问题的修复,保证了千台Datanode的集群能长时间稳定运行。接下来介绍三个优化实例:

内存泄露

内存是影响Ozone Datanode和S3gateway稳定的最主要因素。长期运行中发现若干内存泄露问题,导致Datanode、S3gateway宕机。本文介绍两个典型内存泄露问题。

案例一

绝大部分Datanode宕机后产生core.pid文件,但没有产生crash log,也没有产生heap dump;少部分Datanode宕机后产生crash log,但没有产生core.pid,也没有产生heap dump。Ozone本身采用Java实现,但也使用C++实现的RocksDB。因此可以确认core文件是RocksDB异常退出时产生,而crash log是JVM crash时产生。

首先用gdb分析core.pid,堆栈如下,可以看出rocksdb创建线程时宕机,而且崩溃在libstdc++里,这是C++标准库,基本不可能出现问题,因此怀疑其他原因导致创建线程失败。

注意到gdb打开core文件时,有大量New LWP,LWP为轻量级进程即线程。因此怀疑线程数过多,用info threads打出所有线程,可以看到有32599个线程都在wait锁。

接下来分析32599个线程都是什么线程,随机选出几十个线程分析,用thread threadid命令切换到对应线程,并查看线程堆栈,发现绝大部分线程来源于/usr/java/jdk1.8.0_191-amd64/jre/lib/amd64/server/libjvm.so,这表示绝大部分线程都是jvm创建出来的。因此问题仍然在Java代码里,大量Java线程,占用太多内存,导致创建C++线程时宕机。

继续分析crash log,可以看出JVM创建线程时因为OOM崩溃,从crash log可以找到26000多个Datanode State Machine Thread线程,都处于block状态。查看代码发现Datanode State Machine Thread是使用newCachedThreadPool创建的线程池里的线程,而newCachedThreadPool在所有线程block时,会不断创建新的线程,导致产生26000多个线程。至此可确认,产生core.pid的宕机和产生crash log的宕机是同一个原因:Datanode State Machine Thread线程太多。

接着分析大量Datanode State Machine Thread线程被block的原因,在每个Datanode线程数超过7000时,自动执行jstack打出所有线程堆栈,发现有7939个Datanode State Machine Thread线程,其中7938个处于等锁状态,只有1个编号5500的线程拿到锁但卡在rpc调用里。

相关JIRA:HDDS-3933

(https://issues.apache.org/jira/projects/HDDS/issues/HDDS-3933?filter=allopenissues,请复制本链接到浏览器查看)

案例二

压测S3gateway时发现20分钟内,内存涨到16G并开始宕机,首先用Jmap确定内存泄露是堆内还是堆外,在内存涨到10G时用Jmap发现tenured generation占用5909M,使用率达到99%内存,基本可确认泄露发生在堆内。然后dump下堆发现有262144个InternalSubchannel,每个InternalSubchannel在grpc-java里代表一个连接,因此可确定内存泄露原因是大量连接未断开。最终发现S3gateway为每个请求建立一个连接,但请求使用完后未断开连接。

修复后重新测试,发现S3gateway迅速占满所有CPU,24核的机器S3gateway使用CPU达到2381%。

CPU使用如此之高,无法运行arthas进行perf分析,只能采用其他策略。首先用top -Hp pid命令打出进程pid的所有线程及每个线程的CPU消耗。然后计算出使用CPU最高的线程号的十六进制表示0x417,再用jstack -l pid > jstack.txt命令打出所有线程状态,用0x417在jstack.txt查询消耗CPU最高的线程,即下图所示ThreadPoolExecutor里的线程,该线程一直处于RUNNABLE,且队列为empty,基本确认该部分线程出了问题,因为正常的线程不会一直空转,状态会有TIMED_WAITING的时刻。因为线程堆栈不包含业务代码,都是JDK的源码,因此用线程堆栈搜索JDK相关问题,最终发现是JDK8的Bug:JDK-8129861,该Bug在创建大小为0的线程池时容易触发。

相关JIRA:HDDS-3041

(https://issues.apache.org/jira/browse/HDDS-3041,请复制本链接到浏览器查看)

性能优化

案例一

使用S3gateway读文件时,文件越大读速越慢,读1G文件,速度只有2.2M每秒,使用perf未发现线索。

然后用tcpdump在读200M文件时抓包分析,从下图可看到读200M文件,共有10个GET请求:GET /goofys-bucket/test.dbf HTTP/1.1,每个GET请求读20M文件,每个GET请求读完后回复:HTTP/1.1 200 OK。第1个GET请求到达S3gateway时间为0.2287秒,第10个GET请求到达S3gateway时间为1.026458秒。第1个GET请求完成时间为1.869579秒,第10个GET请求完成时间为23.640925秒。可见10个GET请求在1秒内全部到达S3gateway,但每个请求耗时越来越长。因此只需要分析后续的GET请求读同样大小的数据块,比前序GET请求多做了哪些事情即可。

最后通过分析日志和阅读代码发现,Ozone采用的第三方库commons-io采用read实现skip。例如读第10个GET请求时,实际只需要读[180M, 200M),但commons-io实现skip前180M时,会将前180M读出来,导致第10个GET请求读完整的[0M, 200M),因此GET请求越来越慢。优化后,性能提升一百倍。

相关JIRA:HDDS-3223

(https://issues.apache.org/jira/browse/HDDS-3223,请复制本链接到浏览器查看)

总结

经过各个方面的优化改进,在单集群千台以上的规模Ozone已能长时间稳定运行,保证数据正确。但是我们在Ozone上的改进不会就此结束,腾讯会持续推进Ozone在更多线上业务落地,部署更大规模的生产集群。并提高Ozone的可靠性、扩展性、稳定性、性能,将Ozone发展为继HDFS的下一代存储系统。

相关工作

在部署千台集群中,腾讯针对Ozone集群稳定和性能稳定做了诸多工作。集群稳定主要是保证集群宕机率低,使用中发现Ozone的OzoneManager和StorageContainerManager未发生过宕机,但Datanode和S3gateway因为内存溢出存在宕机问题。而性能稳定主要是为了保证集群规模扩大时,吞吐量可线性增长。

另外Ozone采用Ratis保证写一致性,因此也做了若干优化,保证Ratis主从组成的Group能稳定的写数据。

相关工作如下所示,部分工作腾讯内部已完成,在向社区推进中。

稳定内存

HDDS-3933. Fix memory leak because of too many Datanode State Machine Thread

HDDS-3630. Merge rocksdb in datanode

HDDS-3514. Fix memory leak of RaftServerImpl

HDDS-3041. Fix memory leak of s3g by releasing the connection resource

RATIS-935.   Fix memory leak by ungister metrics

RATIS-925.   Fix memory leak of RaftServerImpl for no remove from static RaftServerMetrics::metricsMap

RATIS-845.   Fix memory leak of RaftServerImpl for no unregister from reporter

RATIS-840.   Fix memory leak of log appender

性能优化

HDDS-3223. Improve s3g read 1GB object efficiency by 100 times

HDDS-3745. Improve OM and SCM performance with 64% by avoid collect datanode information to s3g

HDDS-3240. Improve write efficiency by creating container in parallel

HDDS-3244. Improve write efficiency by opening RocksDB only once

HDDS-3168. Improve read efficiency by merging a lot of RPC call getContainerWithPipeline into one

HDDS-3770. Improve getPipelines performance

HDDS-3737. Avoid serialization between UUID and String

HDDS-3481. SCM ask too many datanodes to replicate the same container

HDDS-3743. Avoid NetUtils#normalize when get DatanodeDetails from proto

HDDS-3742. Improve OM performance with 5.29% by avoid stream.collect

HDDS-3734. Improve the performance of SCM with 3.86% by avoid TreeSet.addAll

RATIS-821.   Fix high processor load for ScheduledThreadPoolExecutor with 0 core threads

稳定Ratis Group

RATIS-995. Leader balance in multi raft

RATIS-993. Pre vote before request vote

RATIS-987. Fix Infinite install snapshot

RATIS-983. Check follower state before ask for votes

RATIS-982. Fix RaftServerImpl illegal transition from RUNNING to RUNNING

RATIS-980. Fix leader election happens too fast

RATIS-989. Avoid change state from CLOSING to EXCEPTION in LogAppender

RATIS-977. Fix gRPC failed to read message

以上就是本文的全部内容了,大家如果遇到了相关的技术问题,欢迎在文章下方留言。

以“#你问我答#+提问内容”的形式留言提问,就有机会得到专家回复,还将获得腾讯视频VIP月卡一张哦!

扫码关注 | 即刻了解腾讯大数据技术动态

文章分享自微信公众号:
腾讯大数据

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 大数据江湖十年:腾讯底层技术的进化往事

    生活不可能像你想象得那么好,但也不会像你想象得那么糟。人的脆弱和坚强都超乎自己的想象。有时,我们可能脆弱得一句话就泪流满面,有时,也发现自己咬着牙走了很长的路。...

    腾讯大数据
  • 大数据架构前沿实践分享

    12月19日,9:00-12:40,由来自腾讯数据湖研发负责人邵赛赛老师出品的DataFunTalk年终大会——大数据架构论坛,将邀请来自腾讯、Tubi、车好...

    腾讯大数据
  • 腾讯开源之道:基于Apache之道的开源实践与探索

    8月6日,腾讯开源联盟主席、腾讯云开源生态总经理单致豪在2021 ApacheCon Asia上分享了腾讯对Apache之道的思考、探索与实践的历程。作为开源...

    腾讯开源
  • Apache之道在腾讯的探索与实践

    演讲人:单致豪 整    理:腾源会 本文4598字,阅读完成约为12分钟 Apache 软件基金会成立于 1999 年,迄今为止其管理着 2.27 亿多行代...

    腾源会
  • 腾讯云加速构建云原生数据仓库,助力企业数字化转型

    在企业数字化转型的当下,数据仓库的云端构建成为主流趋势,Gartner 预测,到2023年全球3/4的数据库都会跑在云上。

    腾讯云大数据
  • 腾讯云加速构建云原生数据仓库,助力企业数字化转型

    在企业数字化转型的当下,数据仓库的云端构建成为主流趋势,Gartner 预测,到2023年全球3/4的数据库都会跑在云上。 12月20日,腾讯2020 Tec...

    腾讯QQ大数据
  • 开源项目介绍 |Apache Ozone-分布式大数据通用存储

    2021腾讯犀牛鸟开源人才培养计划 开源项目介绍 滑至文末报名参与开源人才培养计划 提交项目Proposal Apache Ozone项目介绍 标签:大数据...

    腾讯开源
  • 开源界的盛会来啦!要错过了解腾讯Apache生态最佳实践的机会吗?

    8月,一场盛夏的技术盛宴将要来啦!这就是ApacheCon Asia。作为开源界备受关注的会议之一,今年大会将持续3天,开设14+分论坛,内容覆盖从大数据到搜索...

    腾源会
  • 腾讯云大数据团队:认真做开源的人,眼里有光

    前段时间,Oracle 正式发布了 JDK 15,同时作为惯例公布了 OpenJDK 全球贡献者榜单,表达了对这些企业与个人开发者的感谢。其中,Oracle 依...

    腾讯开源
  • Apache基金会正式宣布新一代分布式对象存储Ozone成为顶级项目

    刚刚获悉,Apache基金董事会通过一致表决,正式批准分布式文件对象存储Ozone从Hadoop社区孵化成功,成为独立的Apache顶级开源项目。这意味着,作...

    腾讯开源
  • 腾讯大数据团队主导Apache社区新一代分布式存储系统Ozone 1.0.0发布

    近日,由腾讯大数据团队主导的Ozone 1.0.0版本在Apache Hadoop社区正式发布。经过2年多的社区持续开发和腾讯内部1000+节点的实际落地验证,...

    腾讯大数据
  • 腾讯Q2财报放榜,“云会展”成为ToB业务中的新亮点

    刚才,腾讯“中考”放榜! 腾讯发布2020年第二季度业绩报告,营收1148.83亿,同比增长29%;净利润301.53亿,同比增长28%,高于市场预期。其中,金...

    腾讯文旅
  • 回顾 | 第二届DataFunSummit:大数据存储架构峰会合集

    [ 导语 ] 2022年3月26日,DataFun联合腾讯大数据及其他平台举办的第二届线上大数据存储架构峰会已经完美收官落幕。当日,腾讯大数据作为主办平台之一,...

    腾讯大数据
  • 大咖预告 | Apache首次亚洲技术峰会:大数据专场

    2021 Apache首次亚洲虚拟技术峰会:大数据专场即将在8月6日-8月8日震撼来袭。腾讯云存储高级工程师程力将在8月7日14:50分和8月8日14:10分别...

    云存储
  • 2021腾讯可持续社会价值报告发布,腾讯云数据库助力数实融合

    近日,腾讯发布了2021年度腾讯可持续社会价值报告,交出了“可持续社会价值创新”战略以来首份完整的年度成绩单,包括数实融合、上云用数、数字升级、生态共益等方面。...

    腾讯云数据库 TencentDB
  • 首届Apache Hadoop技术社区中国Meetup在京举办(附PPT)

    近日,在Apache Hadoop社区主导及邀请下,腾讯开源、腾讯大数据、腾讯云联合承办了Hadoop技术社区在中国的首次Meetup。围绕Hadoop技术实践...

    腾讯技术工程官方号
  • 首届Apache Hadoop技术社区中国Meetup在京举办(内附完整PPT)

    近日,在Apache Hadoop社区主导及邀请下,腾讯开源、腾讯大数据、腾讯云联合承办了Hadoop技术社区在中国的首次Meetup。围绕Hadoop技术实践...

    腾讯开源

扫码关注云+社区

领取腾讯云代金券