编辑|尚剑
本文将为你分享58大数据平台在最近一年半内技能演进的过程,包括:58大数据平台目前的整体架构是怎么样的;最近一年半的韶光内我们面临的问题、寻衅以及技能演进过程;以及未来的方案。
写在前面

赵健博,来自58赶集,本文将为大家分享58大数据这块的履历。本科和研究生分别是在北京邮电大学和中国科学院打算技能研究所,之前在百度和360事情,现在是58赶集高等架构师、58大数据平台卖力人。多年的分布式系统(存储、打算)的实践和研发履历,在事情的这些年中运营了大大小小的集群,最大单集群也达到了四五千台,在这个过程中做了大量的功能研发、系统优化,也淌了大量的坑,本文会给大家先容一些自认为比较主要的履历。
首先看一下58大数据平台架构。大的方面来说分为三层:数据根本平台层、数据运用平台层、数据运用层,还有两列监控与报警和平台管理。
数据根本平台层又分为四个子层:
接入层,包括了Canal/Sqoop(紧张办理数据库数据接入问题)、还有大量的数据采取Flume办理方案;
存储层,范例的系统HDFS(文件存储)、HBase(KV存储)、Kafka(缓存);
再往上便是调度层,这个层次上我们采取了Yarn的统一调度以及Kubernetes的基于容器的管理和调度的技能;
再往上是打算层,包含了范例的所有打算模型的打算引擎,包含了MR、HIVE、Storm、Spark、Kylin以及深度学习平台比如Caffe、Tensorflow等等。
数据运用平台紧张包括以下功能:
元信息管理,还有针对所有打算引擎、打算引擎job的作业管理,之后便是交互剖析、多维剖析以及数据可视化的功能。
再往上是支撑58集团的数据业务,比如说流量统计、用户行为剖析、用户画像、搜索、广告等等。针对业务、数据、做事、硬件要有完备的检测与报警体系。
平台管理方面,须要对流程、权限、配额、升级、版本、机器要有很全面的管理平台。
这个便是目前58大数据平台的整体架构图:
这个图展示的是架构图中所包含的系统数据流动的情形。分为两个部分:
首先是实时流,便是黄色箭头标识的这个路径。数据实时采集过来之后首先会进入到Kafka平台,先做缓存。实时打算引擎比如Spark streaming或storm会实时的从Kafka中取出它们想要打算的数据。经由实时的处理之后结果可能会写回到Kafka或者是形成终极的数据存到MySQL或者HBase,供应给业务系统,这是一个实时路径。
对付离线路径,通过接入层的采集和网络,数据末了会落到HDFS上,然后经由Spark、MR批量打算引擎处理乃至是机器学习引擎的处理。个中大部分的数据要进去数据仓库中,在数据仓库这部分是要经由数据抽取、洗濯、过滤、映射、合并汇总,末了聚合建模等等几部分的处理,形成数据仓库的数据。然后通过HIVE、Kylin、SparkSQL这种接口将数据供应给各个业务系统或者我们内部的数据产品,有一部分还会流向MySQL。以上是数据在大数据平台上的流动情形。
在数据流之外还有一套管理平台。包括元信息管理(云窗)、作业管理平台(58dp)、权限审批和流程自动化管理平台(NightFury)。
我们的规模可能不算大,跟BAT比起来有些小,但是也过了一千台,目前有1200台的机器。我们的数据规模目前有27PB,每天增量有50TB。作业规模每天大概有80000个job,核心job(产生公司核心指标的job)有20000个,每天80000个job要处理数据量是2.5PB。
技能平台技能演进与实现
接下来我会重点先容一下在最近一年半韶光内我们大数据平台的技能演进过程,共分四个部分:稳定性、平台管理、性能以及异构打算。第一个部分关于稳定性的改进,稳定性是最根本的事情,我们做了比较多的事情。第二个部分是在平台管理方面的内容。第三个方面我们针对性能也做了一些优化。第四个方面,我们针对异构环境,比如说机器的异构、作业的异构,在这种环境下怎么合理地利用资源。
稳定性改进
首先看一下稳定性的改进。这块我会举一些例子进行解释。稳定性包含了几个方面,个中第一个方面便是系统的可用性,大家可以采取社区供应的HDFS HA、Yarn HA,Storm HA来办理。其余一个方面是关于扩展性,例如Flume、HDFS,Yarn,Storm的扩展性。这里紧张先容下Flume和HDFS的扩展性干系的一些考虑。
此外,有了可用性和扩展性,系统就稳定了吗?实际上不是这样。由于还有很多的突发问题。纵然办理了可用性和扩展性,但突发问题还是可能会造成系统不可用,例如由于一些问题造成两台NameNode全部宕机。
首先看一下Flume的扩展性。我们人为的把它定义了两层。一个是FlumeLocal(紧张办理一台机器的日志采集问题,简称Local),一个是FlumeCenter(紧张从Local上网络数据,然后把数据写到HDFS上,简称Center),Local和Center之间是有一个HA的考虑的,便是Local须要在配置文件里指定两个Center去写入,一旦一个Center涌现问题,数据可以立时从另一个Center流向HDFS。
此外,我们还开拓了一个高可靠的Agent。业务系统中会把数据产生日志写到磁盘上,Agent担保数据从磁盘上实时可靠的网络给本地的Local,个中我们采取了检讨点的技能来办理数据可靠性的问题。
这是Flume的范例架构。Local须要在配置文件里面指定去世要连到哪几个Center上。如果说10台,可能还OK,100台也OK,如果一千台呢?如果创造两台Flume Center已经达到机器资源的上限,如何做紧急的扩容呢?以是从这个角度看Flume的扩展性是有问题的。
我们的办理方法是在Local和Center中间加了一个ZooKeeper,Local通过ZK动态创造Center,动态的创造下贱有什么,就可以达到Center自动扩容的目标了。我们公司Local有两千多台,扩容一台Center仅需一分钟,这种架构实际上可以支持达到万台规模的,这是Flume扩展性的一些改进。
接下来看一下HDFS扩展性的问题。上面这张图展示了hdfs federation的架构,左侧是一个单namespace架构,即全体目录树在一个namespace中,全体集群的文件数规模受限定于单机内存的限定。federation的思想是把目录树拆分,形身分歧的namespace,不同namespace由不同namenode管理,这样就冲破了单机资源限定,从而达到了可扩展的目标,如右侧图。
但这个方案有一些隐蔽的问题,不知道大家有没有把稳到,比如这里每个Datanode都会与所有的NameNode去心跳,如果DataNode数量上万台,那么就可能会涌现两个问题:第一,从主节点之间的心跳、块申报请示成为瓶颈,第二,如果单个部门的数据规模过大那该怎么办?
针对从主节点之间交互的问题,我们可以进行拆分,掌握一个NameNode管理的DateNode的数量,这样就可以避免主从节点交互开销过大的问题。针对单部门数据过大的话可以针对部门内数据进行进一步细拆,就OK了。或者可以考虑百度之前供应的一个方案,即把目录树和inode信息进行抽象,然后分层管理和存储。当然我们目前采取社区federation的方案。如果好好方案的话,也是可以到万台了。
不知道大家有没有在自己运营集群过程中碰着过一些问题,你们是怎么办理的,有些问题可能相称的棘手。突发问题是非常紧急而且主要的,须要在短韶光内搞定。接下来我会分享三个例子。
第一个例子是HDFS的Active NN会不定期非常退出,触发HA切换,这就彷佛一个禁绝时炸弹一样。这个图展示了HDFS的HA的架构图,客户端进行变更操作(如创建文件)的话会发出要求给namenode,namenode要求处理完之后会进行持久化事情,会在本地磁盘存一份,同时会在共享存储存一份,共享存储是为了active和standby之间同步状态的,standby会周期从共享存储中拉取更新的数据运用到自己的内存和目录树当中,所有的DataNode都是双申报请示的,这样两个namenode都会有最新的块信息。最上面的是两个Checker,是为了仲裁究竟谁是Active的。
还有一个过程,Standby NameNode会定期做checkpoint事情,然后在checkpoint做完之后会回传最新的fsimage给active,终极保存在active的磁盘中,默认情形下在回传过程会造成大量的网络和磁盘的压力,导致active确当地磁盘的Util达到100%,此时用户变更要求延迟就会变高。如果磁盘的Util100%持续韶光很长就会导致用户要求超时,乃至Checher的检测要求也因排队过长而超时,终极然后触发Checker仲裁HA切换。
切换的过程中在设计上有很主要一点考虑,不能同时有两个Active,以是要成为新Active NameNode,要把原来的Active NameNode停滞掉。先会很友好地停滞,什么是友好呢?便是发一个RPC,如果成功了便是友好的,如果失落败了,就会ssh过去,把原来active namenode进程kill掉,这便是Active NameNode非常退的缘故原由。
当这个缘故原由理解了之后,实在要办理这个问题也非常大略。
第一点要把editlog与fsimage保存确当地目录分离配置,这种分离是磁盘上的分离,物理分离。
第二是checkpoint之后fsimage回传限速。把editlog与fsimage两个磁盘分离,fsimage回传的io压力不会对客户端要求造成影响,其余,回传限速后,也能限定io压力。这是比较棘手的问题。缘故原由看起来很大略,但是从征象找到缘故原由,这个过程并没有那么随意马虎。
第二个案例也是一样,Active NN又涌现非常退出,产生HA切换。这次和网络连接数有关,这张图是Active NameNode的所在机器的网络连接数,平时都挺正常,20000到30000之间,忽然有一个点一下打到60000多,然后就打平了,末了降下来,降下来的缘故原由很明显,是做事进程退了。
为什么会涌现这个情形呢?在后续剖析的过程中我们创造了一个线索,在NameNode日志里报了一个空指针的非常。就顺藤摸瓜创造了一个JDK1.7的BUG,拜会上面图片所示,在java select库函数调度路径过程中终极会调用这个函数(setUpdateEvents),大家可以看到,如果fd的个数超过了MAX_UPDATE_ARRAY_SIZE(65535)这个数的话,将会走到else路径,这个路径在if进行不等表达式判断时,将会出发空指针非常。
接下来的问题是,为什么会产生这么多的链接呢?经由剖析我们创造,在问题涌现的时候,存在一次大目录的DU操作,而DU会锁住全体namespace,这样就导致后续的写要求被壅塞,终极导致要求的堆积,要求的堆积导致了连接数大量堆积,连接数堆积到一定程度就触发JDK1.7的这个BUG。这个问题的办理,从两个方面看,首先我们先把JDK升级到1.8。其次,调度参数dfs.content-summary.limit,限定du操作的持锁韶光。该参数默认参数是0。我们现在是设成10000了,大家可以参考。这是第二个非常棘手的问题。
第三个案例关于YARN主节点的,有一天中午,我们收到报警,创造Active RM非常进程退出,触发HA的切换,然而切换后一会新的Active RM节点也会非常退出,这就比较悲剧,我们前辈行了规复。
之后我们从当时的日志中创造了缘故原由:一个用户写了一万个文件到分布式缓存里,分布式缓存里数据会同步到ZK上,RM持久化作业状态到ZK时超过Znode单节点最大上限,抛出非常,终极导致ResourceManager进程的非常退出。实在问题的办理方法也非常大略,我们增加了限定逻辑,对付序列化数据量大于Znode节点大小的Job,直接抛非常触发Job的失落败。其余我们还适当提升Znode节点大小。
以上是在稳定性方面的一些事情,这三个案例跟大家分享一下,如果有类似的问题建议大家可以考试测验一下,这些方案是被我们验证OK的。
平台管理
接下来先容一下平台管理这块。包含几个问题,个中第一问题是关于数据的,一方面,便是大家开拓了数据之后,常常找不到,要靠喊,比如说在群里喊一下什么数据在哪,谁能见告我一下,这个效率很低下。其余一方面是之前的管理数据是共享的,不屈安,任何人都可以访问其他人的数据。
第二个问题是关于资源,之前是“大锅饭”模式,大家共享打算资源,相互竞争,这样“能吃的“肯定是挤兑”不能吃的“,常常涌现核心任务不能按时按点完成,老板看不到数据,这点很恐怖。还有是全体集群资源利用情形没有感知,这样根本不知道资源要怎么分配,是否够用。
第三个问题是关于作业的,开拓职员开拓大量的作业之后,这些作业要怎么管理,实际上他们可能都不知道。还有便是关于作业之间依赖,常常一个指标打算出来要经历多个作业,作业之间依赖是怎么考虑的,纯挚靠韶光上的依赖是非常薄弱的,如果前期的job延迟产生了,后续的job一定失落败。末了一个问题是数据开拓职员的效率不高,所须要做的步骤过多。
针对这四个问题我们做了一些改进,首先是数据与资源管理。数据方面要引入安全策略、元信息管理与根本数仓培植。我们自己开拓了一套安全掌握策略,紧张增加了白名单和权限掌握策略。一个HDFS的要求的流程,首先客户端会向NameNode发要求,NameNode接到要求之后首先要做连接解析,读取出要求干系内容做要求处理,再把结果反馈回来,之后客户端向相应的DataNode进行写入数据或者读取数据。从上述流程可以看出,所有HDFS操作全部要经由NameNode这一层。
那么安全策略只要在NameNode的两个点做下掌握既可完成:在连接解析后,我们会验证要求方的IP,以及用户是不是在合法配置下面的。如果验证失落败,则谢绝要求。如果验证通过,我们会进一步在要求处理过程中验证用户访问的目录和用户在否在合法的配置下。
比如说用户A想访问用户B的数据,如果没在许可的情形下会把连接关掉,通过大略的策略调度就能达到灵巧的数据的安全掌握和数据共享的办法。接下来针对数据找不到的问题,我们开拓了全公司层面的根本数据仓库以及针对全公司层面元数据管理平台。
这张图展示了根本数据仓库覆盖度,它覆盖了集团各个公司,又覆盖了多个平台,比如说手机、App端、PC端、微信端等等。数据层次,是数据仓库层、数据集市层还是数据运用层,所属哪个奇迹群,末了针对数据进行分类标签,比如说帖子数据、用户数据等等都可以通过标签的办法来找到。当想找详细一份数据的时候可以通过这个界面,点一些标签,筛选出一些数据表,乃至在搜索框里面搜数据的关键字。
当查到数据表的时候可以在右侧按钮,将显示出表构造,还有表信息,表信息表明了这个表有多少列,这个表的卖力人是什么,还有关于数据质量,表的数据量的变革情形等等,如果你想申请可以点击最右边的权限开通。整体开通流程也是自动化的。这是针对数据找不到的问题做的一些改进。
针对资源问题要避免大锅饭,必须要引入账号观点,资源按照账号预留与隔离。我们划分了不同的配额,根据预算、业务需求去申请配额,然后我们调度配额。针对行列步队这块我们划分多个行列步队,每个业务线有自己的行列步队,不同业务线不能跨行列步队提交任务,每个行列步队划分出不同资源,资源紧张是针对业务线需求而定的。通过这些改进可以达到资源的隔离以及适度的共享。
有了账号的观点之后我们就可以统计每个业务线资源利用情形。我们每天都会有报表。显示了业务线的打算和存储资源的利用情形,乃至是Job的细节情形。
接下来我会先容一下业务线开拓效率低下问题的改进,实际上我们在易用性上也做了很多改进。首先我们开拓了云窗平台,它紧张办理了元信息查找、数据查询、可是化展示和多维剖析这些需求。然后针对任务开拓这块我们开拓了58DP办理了元信息开拓、作业管理与统计等。我们针对实时多维剖析开拓了飞流,实时作业开拓全部配置化、同时支持多种统打算子、自动图表天生等等。还有NightFury,流程自动化管理平台。
这是云窗的界面,上面是一个SQL查询界面,下面是可视化产品界面,这是我们数据可视化的一个结果。
然后关于任务开拓的话,我们用58DP来做任务开拓,可以支持的不同任务,涵盖目前的所有主流作业以及作业依赖等管理。这是58DP的页面,可以设置基本信息、调度及依赖等。
飞流是支持周期性的统计、全天累计性的统计,大家可以定义统计方法、定义任务的一些基本信息,设置维度、设置度量,设置完之后就展现了图形,也供应了跟昨天的比拟情形。当在图里点任何一个点的时候,可以看到不同维度组合下在这个点上的数据分布,点击两个点可以看到不同维度下两个点的分布比拟。针对历史数据可以进行比拟,我们可以把韶光拉的更长,可以查看不同周的实时统计结果,而不是一天。
这是NightFury的界面,这便是我们运维的自动化管理平台,大家可以看到有很多个流程和权限的开通申请,表单的填写、工单审批,审批之后的一些流程全部是自动化的。
性能
性能方面,紧张分为四个方面:
MR作业性能、数据网络性能、SQL查询性能和多维剖析的性能。针对MR作业性能,我们引用多租户功能,资源预留,核心作业实行有保障。
第二点小文件合并处理,可以提升任务实行效率,减少调度本身的开销。
第三点我们针对Shuffle阶段参数优化,可以实现并发度提升,IO花费降落。
经由三个方面的改进之后,我们整体任务的运行韶光实际上有一倍旁边的提升。数据传输优化方面,我们经由合并改进数据传输性能,提升了20倍。在SQL优化方面我们引用内存实行引擎与列存储方案的结合,在同等资源情形下针对线上一百多条SQL进行测试,总体性能大概提升80%。在多维打算这块,我们引入Kylin,针对多维的查询95%以上查询能掌握在2s以内。
异构打算
异构打算方面我们面临了两个紧张问题,一个是作业的异构,我们有多种类型的作业,比如说实时作业强调低时延,而离线作业强调高吞吐,这本身便是抵牾的,怎么办理这个抵牾。第二方面是机器异构,CPU、内存、网络、磁盘配置不同,这种异构环境又要怎么办。
从上面图中可以看出:如果实时作业的task和批处理作业的task被调度到一台机器上了,如果批处理作业把资源占满了(例如网络带宽),则实时作业的task必将收到影响。以是,须要对实时作业和批处理作业做隔离才行。
做资源隔离,我们的思路是采取标签化,给每个NodeManager授予不同标签,表示不同机器被分配了不同标签;资源行列步队也授予不同标签,然后在RM调度时,担保相同标签的行列步队里容器资源必从相同标签的NodeManager上分配的。这样就可以通过标签的不同达到物理上的资源隔离目标。
这张图是实现图。首先可以看到NodeManager分成了两个凑集,一个是实时的,一个是离线的,不同的行列步队也被授予了实时或离线的标签,当用户提交一个job的时候它可以指定一个行列步队,提交到离线行列步队里便是离线任务,ResourceManager就会把这个作业所须要的资源分配到离线标签的NodeManager上,这样就可以做到物理资源隔离。
未来方案
以上紧张是先容了我们最近一年半做的一些事情。接下来我会先容一下未来的方案。首先便是深度学习。这个观点今年非常火爆,乃至是要爆炸了,深度学习在58这块需求也是蛮强烈的。目前深度学习工具有这么多,caffe、theano、torch等等非常多,怎么做整合,怎么降落利用本钱,这是第一个问题。
第二个问题,机器是有限的,怎么高效利用资源,须要把机器分配模式变成资源分配模式。还有光有单机的机器学习或者深度学习工具还不足,由于性能太差,以是我们须要将深度学习演习分布式化。我们做了一个初步的测试,针对caffe与Tensorflow工具的分布式化演习做了比较,4卡相对付单卡模型演习性能提升100%~170%,以是分布式化的事情本身意义也是非常大的。
这个图展示的是工具领悟方案。我们这里利用的是Kubernetes,支持主流的深度学习工具,每个工具做成镜像形成POD,用户须要的话可以直接把POD分发给他,用户在演习的时候从HDFS上直接拉取样本,并且把演习的参数回写到HDFS上,也便是说通过HDFS做数据的共享,通过这种模式可以很轻松地支持多种深度学习工具,也可以达到按所需资源量进行资源的分配目标。
其余我们会做一个深度学习工具分布式的改造,是针对caffe,我们用的是CaffeOnSpark,即把全体分布式的方案做成模板供用户利用。首先启动多个POD,通过POD启动一个Spark集群,然后再提一个Spark job来做演习,末了在全体演习结束之后再把集群停掉。Tensorflow也是一样的,首先启动tensorflow集群,然后提交任务,任务演习完往后再把集群停掉。其他工具分布式化我们也会采纳类似的思路办理。以上是关于深度学习这块我们目前的一些事情。
其次,是关于空间资源利用率的。目前我们有一千多台机器,存储是很大的本钱。之前也提到了,我们是属于费钱的部门,以是压力非常大。那怎么节省本钱是一个很主要的问题。除了传统压缩之外,还能做什么?HDFS RAID是一个比较好的办理方案。
HDFS RAID采取是RC编码,类似RAID6,比如一个文件有m个块,根据m个块天生k个校验块,然后能担保k个块丢失的情形下数据还能找回来,举个例子来说,比如文件2.5G大小,256M一个块,可以分成10个块,根据RC算法再天生4个校验块,可以担保丢了4个块情形下,数据都能找回来。在这个例子中,3副本情形下,一共须要30个块,而采取HDFS RAID,仅须要14个块。但他们的可靠性一样,空间占用情形却差了57%。
详细履行时,第一步对集群数据进行冷热剖析,RAID毕竟有些性能问题,一旦数据有问题,你要通过打算才能规复,势必会造成性能低下,以是针对冷数据做肯定是风险最低的。第二步便是压缩+archive+RAID,通过三方面技能结合把文件数和空间全部节省出来。归档实际上是会变换目录的,为了做适配,我们通过软连接功能,做到对用户透明。末了在数据读取时,如果是RAID数据,就要具备实时RAID修复功能才能担保在数据缺失落的情形下不影响数据的访问。
后续我们会对打算资源利用率再做进一步提升。其余也会考虑Storm和YARN扩展性。还有Kubernetes调度优化,比如针对GPU资源管理功能。
以上便是我本日想先容的全部内容。在结束之前请许可我再做一下总结。
首先我先容了58目前的大数据平台架构是怎么样的,大略来说便是“342”,三个层次、细分为四个子层、阁下两列。以是大家要做大数据平台培植事情,这几个方面是必备的。
第二个方面我重点的先容了58在一年半的韶光内的技能改进。第一点是关于稳定性,紧张从Flume和HDFS扩展性方面重点先容了我们的办理方案,举了三个案例来解释突发问题,不是说有了可用性和扩展性就万事OK了,还要办理突发问题。针对平台管理首先先容了一下数据和资源的管理方法,接着又先容了关于易用性方面的改进,我们供应了一系列平台来提高开拓职员的开拓效率。
第三方面从性能上先容了我们这边做的优化事情以及优化的结果是怎么样的;
第四方面先容了在异构环境下如何支持不同特色的作业进行合理调度。
末了我先容了58深度学习平台培植方面以及存储资源空间利用率优化方面的内容。以上便是我本日的全部内容,希望对大家有帮助。
今日荐文
点击下方图片即可阅读
微软开源软件列表