简介本文主要介绍58实时计算平台和基于Flink的一站式实时计算平台Wstream的技术演进。涵盖了很多实战经验、干货和方法论。希望对您有所帮助。背景58同城是一个覆盖生活各个领域的服务平台。业务涵盖招聘、房产、汽车、金融、二手及本地服务等,丰富的业务线和海量用户每天产生海量用户数据,需要实时计算分析。实时计算平台定位于为集团海量数据提供高效、稳定、分布式的实时计算基础服务。本文主要介绍58同城基于Flink打造的一站式实时计算平台Wstream。实时计算场景和很多互联网公司一样,实时计算在58有丰富的场景需求,主要包括以下几类:1、实时数据ETL实时消费Kafka数据,为下游进行清洗、转换、结构化处理计算处理。2、实时数据仓库实时数据计算、仓库模型处理和存储。实时分析业务和用户的各项指标,让运营更实时。3.实时监控对系统和用户行为进行实时检测分析,如业务指标实时监控、运维在线稳定性监控、财务风控等4.特性实时分析平台、用户画像、实时个性化推荐等。平台演进实时计算平台建设过程中,主要是跟进开源社区的发展和实际业务需求。计算框架经历了从Storm到SparkStreaming再到Flink的发展。同时搭建一站式实时计算平台,提高用户实时计算需求开发和在线管理监控效率,优化平台管理。实时计算引擎早期是基于Storm和SparkStreaming构建的。在很多情况下,它不能很好地满足业务需求。维度监控平台基于Storm分析公司的全量nginx日志监控线上业务,需要秒级甚至毫秒级的延迟,Storm的吞吐量成为了瓶颈。同时,随着实时性要求不断提高,场景越来越丰富,在追求高吞吐量和低延迟任务的基础上,对计算过程中的中间状态管理、灵活窗口等需求越来越多支持,并且恰好一次语义保证。ApacheFlink开源后,支持高吞吐、低延迟的架构设计和高可用稳定性。它还具备一系列面向实时计算场景的特性,支持实时Sql模型,这让我们决定采用Flink作为新一代实时计算平台的计算引擎。平台级实时计算平台目前主要基于Storm/SparkStreaming/Flink,集群共500多台机器,每天处理超过6000亿条数据,其中Flink已占到50%经过近一年的建设,完成了各项任务。Flink稳定性Flink作为实时计算集群,可用性要求远高于离线计算集群。为保证集群可用性,平台主要采用任务隔离和高可用集群架构来保证稳定性。在应用层面,任务隔离主要是根据业务线和场景进行机器隔离,队列资源分配管理,避免集群抖动的全局影响。集群架构Flink集群采用ONYARN模式独立部署。为了减少集群维护的工作量,HDFS底层采用了公司统一的HDFSFederation架构,建立独立的namespace来减少Flink任务。在checkpoint使用hdfs/rocksdb作为状态存储后端的场景下,hdfsjitter经常出现异常故障。在资源隔离层面,引入NodeLabel机制,让重要的任务运行在独立的机器上,不同计算性质的任务运行在合适的机器上,最大限度地利用机器资源。同时,在YARN资源隔离的基础上,加入Cgroup隔离物理CPU,减少任务间抢占的影响,保证任务运行的稳定性。平台化管理Wstream是一个基于ApacheFlink的一站式、高性能实时大数据处理平台。提供基于SQL的流式数据分析能力,大大降低实时数据分析的门槛,通过DDL支持source/sink和维表,支持UDF/UDAF/UDTF,为用户提供更强大的实时数据处理能力。支持FlinkJar/StreamSQL/Flink-Storm等多种风格的应用构建方式,满足不同用户的开发需求,通过调试、监控、诊断、检测结果等辅助手段,完善任务生命周期管理。StreamSQL能力构建StreamSQL是构建基于SQL的实时计算能力,降低实时计算开发门槛的平台。基于开源Flink,扩展SQL底层模块,实现如下功能:1.支持自定义DDL语法(包括源表、输出表、维表)2.支持自定义UDF/UDTF/UDAF语法3.实现流和维度表的连接。双流加入在支持大数据开源组件的同时,也打通了公司主流的实时存储平台。同时为用户提供了基于Sql客户端的cli方式,并在Wstream中集成了对实时sql能力的支持,为用户提供在线开发调试sql任务的编辑器,支持代码高亮、智能提示、语法验证和运行时校准。尽量避免用户提交给集群的任务出现异常。此外,还为用户提供了向导式的配置方式,解决用户自定义表复杂的参数设置问题。用户只需要关心业务逻辑处理,像开发离线Hive一样使用SQL开发实时任务。Storm任务迁移Flink在完善Flink平台建设的同时,我们也推出了Storm任务迁移Flink计划,旨在提升实时计算平台的整体效率,降低机器成本和运维成本。Flink-Storm作为官方的Flink兼容Storm程序,为我们提供了无缝迁移的可行性,但作为beta版本,在实际使用中有很多情况不能满足真实场景,所以我们做了很多改进,主要包括在yarn上实现Storm任务,tasksatleastoncesemanticguaranteeaftermigration,兼容Storm的ticktuple机制等。通过Fink-Storm的优化,成功完成了多个Storm版本的集群任务迁移和集群下线,无需无需用户修改代码,在保证实时性能和吞吐量的基础上,可以节省40%以上的计算资源,同时借助yarn统一管理实时计算平台方式,无需维护多套Storm集群,提高了平台资源的整体利用率,减少了平台运维和维护的工作量内涵。任务诊断指标监控FlinkwebUI提供了很多运行时信息供用户了解任务当前运行状态,但存在无法获取历史指标的问题,使用户无法了解任务的历史运行状态。因此,我们使用Flink原生支持的Prometheus来进行实时指标的采集和存储,Prometheus是一个开源的监控告警系统,通过p??ushgateway实时上报指标。Prometheus集群采用Fedration部署方式,元节点定期抓取所有子节点指标进行汇总,从而为Grafana提供统一的数据源进行可视化和告警配置。任务延迟吞吐量和延迟是衡量实时任务性能的最重要指标。我们经常需要通过这两个指标来调整任务并发度和资源分配。FlinkMetrics提供了latencyTrackingInterval参数来启用任务延迟跟踪。开启它会显着影响集群和任务的性能。强烈建议仅在调试下使用它。在实际场景中,Flink的任务数据源基本都是Kafka,所以我们以主题消费积累作为衡量任务时延的指标。监控模块通过Flinkrest实时获取task正在消费的topic的offset,通过KafkaJMX获取对应topic的logsize,使用logsize-offset作为topic的累加。日志检索Flink是一个分布式计算引擎。所有的任务都会被YARN统一调度到任意一个计算节点上。因此,任务的运行日志会分布在不同的机器上。用户很难定位日志。我们将log4j日志框架的默认机制调整为Segment任务日志,定期清理过期日志,避免异常任务频繁刷盘导致计算节点不可用。同时在所有计算节点部署代理,实时收集日志,聚合写入Kafka,并将数据分发到ES,方便用户检索日志和定位问题。在Flink优化的实际使用中,我们也针对业务场景做了一些优化和扩展,主要包括:1、Storm任务需要Storm引擎提供ack机制来保证消息传递至少一次语义,ack机制不能迁移到Flink时使用。通过自定义KafakSpout,实现checkpoint相关接口,通过Flink的checkpoint机制实现消息传递不丢失。另外,Flink-Storm默认只能支持standalone的提交方式。我们通过实现yarn客户端相关接口添加了对stormonyarn的支持。2.Flink1.6推荐使用一个TaskManager对应一个slot。申请资源时,根据最大并发数申请相应数量的TaskManager。这样造成的问题是设置任务槽后,需要申请的资源大于实际的资源。ResoureManager请求资源管理器SlotManager维护申请的TaskManager和分配的slot时,我们添加TaskManagerSlot相关信息。之后对于SlotRequests的请求,我们并不直接向TaskManager申请,而是先向SlotManager申请,看看是否有足够的slot。会启动一个新的TaskManger,使申请资源等于实际消耗资源,资源充足时无法启动任务。3.KafakConnector改造,增加自动换行支持。另外,对于08source,不能设置client.id。通过优化client.id的生成机制,变成更易识别的id,方便Kafka级别的控制。4、Flink提交任务不支持第三方依赖TaskManager使用jar包和配置文件。我们修改flink启动脚本,增加相关参数,支持外部文件传输。然后,在任务启动过程中,我们将相应的jar包和文件添加到classpath中,利用yarn的文件管理机制,实现了类似spark的相应使用方式,方便用户使用。5、业务场景中有大量实时写入hdfs的需求。Flink内置的BucketingSink默认只支持string和avro格式。在此基础上,我们还支持LZO和Parquet格式的写入,大大提升了Data的写入性能。后续规划实时计算平台目前正在将Storm任务迁移到Flink集群中,已经基本完成,大大提高了平台资源利用率和计算效率。未来,我们将继续研究和完善Flink的相关能力,推动Flink在更多实时场景的应用,包括实时规则引擎和实时机器学习。
