Apache Kafka / Spark流系统的性能调优

电信行业的实际案例研究

调试实际的分布式应用程序可能是一项艰巨的任务。 至少在一开始,最常见的Google搜索并没有什么用。 在这篇博客文章中,我将详细介绍如何将Apache Kafka / Spark Streaming / Apache Ignite应用程序加速近十倍,并将开发原型转变为有用的,稳定的流媒体应用程序,该应用程序最终超过了性能目标。为应用程序。

此处学习的课程相当笼统,可以轻松地扩展到使用MapR Streams和Kafka的类似系统。

该项目是融合平台需求的具体案例,该平台集成了完整的软件堆栈以支持该系统的需求:实时流,大数据分布式处理和持久性。 截至撰写本文时, MapR融合数据平台是此类平台当前唯一可用的生产就绪型实现。

系统目标

为了满足电信公司的需求,该应用程序的目标是将来自三个独立系统的日志数据结合在一起。 加入数据后,就可以将网络条件与任何特定客户的特定呼叫相关联,从而使客户支持可以向不满意其电话服务的客户提供准确和有用的信息。 如果该应用程序可以实时进行而不是作为批处理工作,则它具有巨大的附加价值,因为6个小时的呼叫质量信息对客户服务或网络运营没有实际价值。

基本上,这是一个相当简单的ETL作业,通常会作为数据仓库的批处理作业完成,但现在必须作为流式分布式体系结构实时进行。

更具体地说,总体情况是将来自远程服务器的输入数据流式传输到分布式集群中,进行一些数据清理和扩充,将三个日志中的记录联接在一起,并将联接的数据作为单个表持久保存到数据库中。

原始系统的问题

原始系统存在几个围绕性能和稳定性的问题。

首先,流应用程序不稳定。 在Spark Streaming应用程序中,如果每个微批处理的处理时间等于或小于批处理时间,则称该流稳定。 在这种情况下,应用程序的流式传输部分正在30秒的窗口中接收数据,但处理时间为4.5-6分钟。

其次,有一个批处理过程,一次要一个小时连接一次数据,目标是在30分钟内运行,但要花2个小时才能完成。

第三,应用程序运行了几个小时后随机崩溃。

集群硬件,软件堆栈和输入数据

集群硬件非常好,有12个企业服务器节点,每个节点配备两个E5 Xeon CPU,每个CPU具有16个物理核心,256GB内存和八个6TB旋转硬盘。 网络是10GB以太网。

为该项目选择的技术栈围绕着Kafka 0.8(用于将数据流式传输到系统中),Apache Spark 1.6(用于ETL操作)(本质上是对输入进行过滤和转换,然后进行联接)以及使用Apache Ignite进行。 1.6作为内存共享缓存,可以很容易地将应用程序的流输入部分与数据连接起来。 如果发生故障,Apache Hive还可以用作Ignite的磁盘备份以及单独的分析应用程序。

初始集群的配置如下:

节点 k 神经网络 HDFS 梅索斯 Mesos Master 卡夫卡 火花工人 点燃
1个 X X X X X X X
2 X X X X X X X
3 X X X X X X
X X X X X
7 X X X X X
8 X X X X X
X X X X
12 X X X X

该集群运行Apache Hadoop的HDFS作为分布式存储层,资源由Mesos 0.28管理。 最后,HBase用作最终联接数据的最终数据存储。 该项目范围之外的其他系统将查询该文件。

系统的性能要求是处理高达3GB / min或150-200,000个事件/秒的输入吞吐量,代表已知的峰值数据吞吐量以及额外的余量。 普通吞吐量约为该值的一半,即1.5GB /分钟和60,000-80,000个事件/秒。

原始数据源是三个远程系统的日志,此处标记为A,B和C:日志A占条目的约84-85%,日志B约占1-2%,日志C约占14-15%。 数据不平衡这一事实是此应用程序中(许多)困难的来源之一。

Spark应用程序均使用Scala 2.10和Kafka的直接方法 (无接收器)进行编码。 Apache Ignite具有一个非常好的Scala API和一个神奇的IgniteRDD ,它可以使应用程序共享内存数据,这是该系统降低编码复杂性的关键功能。

应用架构

单个Kafka生产者将原始数据摄入到运行在6台服务器上的Kafka中。 生产者读取各种日志,并将每个日志的记录添加到其自己的主题中。 由于有三个日志,因此有三个Kafka主题。 每个主题分为36个分区。 最有可能存在36个分区,因为有6个节点,每6个磁盘分配给HDFS,Kafka文档似乎建议每个物理磁盘大约有一个分区作为指导。

Spark Streaming应用程序使用数据,该应用程序选择每个主题,然后执行简单的过滤器以切出不必要的字段,进行映射操作以转换数据和执行foreachRDD操作(每个微批处理在Spark Streaming中生成RDD)将数据保存到Ignite和Hive。

流媒体应用程序非常简单:映射,过滤器和foreach分区,保存到Ignite

第二个“常规” Spark应用程序运行在Ignite存储在内存中的数据上,以1小时为批处理将来自三个单独日志的记录合并到一个表中。 这项工作是使用Spark的DataFrame API完成的,该API非常适合该任务。 第二部分涉及不超过100GB的数据,并且群集硬件的大小适当以处理该数量的数据。

三个小时的数据被累积到Ignite中,因为绝大多数调用持续不到一个小时,并且我们希望一次对一个小时的数据进行连接。 由于某些呼叫将在一批中开始而在另一批中完成,因此系统将保留三个小时并且仅处理一个小时的中间批次,因此联接可以成功处理接近100%的记录。

值得一提的是,更好的全流架构可以避免中间表示形式的出现。 具有更多时间和事前思考能力的示例性现实案例可以更快地结束整个项目,而不是全神贯注地编写第一个可行的解决方案。

性能调优

这些应用程序的主要问题是由于试图运行开发系统的代码而造成的,这些代码在运行于真实数据的物理,本地群集上的AWS实例上进行了测试。 从来没有授予原始开发人员访问生产集群或真实数据的权限。

Apache Ignite是一个巨大的问题源,主要是因为它是一个新项目,没有人有任何实际经验,而且还因为它不是一个非常成熟的项目。

Spark Streaming应用程序在大约4.5分钟内运行,并且项目目标是在30秒内运行。 我们需要找到9倍于加速的改进价值,并且由于时间限制,我们无法更改任何代码!

该系统必须在一周内准备好进行生产测试,因此从体系结构和算法角度出发的代码被假定为正确且足够好,以至于我们只有通过调整才能达到性能要求。

修复RPC超时异常

我们从具有相同问题的人那里找到了正确的解决方案,如JIRA的SPARK-14140中所示 。 他们建议将spark.executor.heartbeatInterval从10s增加到20s。

我认为这个问题可能是由于Kafka,Ignite或垃圾收集器暂停而导致节点由于磁盘繁忙或CPU高峰而变得忙碌所致。 由于Spark在所有节点上运行,因此问题是随机的。 (请参阅第一部分中的集群服务布局表。)

配置更改完全解决了此问题。 从那以后我们再也没有看到过。

增加驱动程序和执行程序的内存

通过将内存从每个执行者20g增加到每个执行者40g以及驱动程序40g,解决了内存不足问题和应用程序的随机崩溃。 令人高兴的是,生产集群中的机器配备了大量内存。 对于新应用程序,这是一个好习惯,因为您一开始不知道需要多少。

由于Spark UI报告的内存消耗非常小,因此很难精确地调试该问题,缺乏准确的信息。 实际上,由于此设置易于更改,因此根据经验,我们将40g作为使应用程序稳定运行的最小内存大小。

增加并行度:增加Kafka中的分区数量

输入数据不平衡,大部分应用程序处理时间都花在处理主题1(吞吐量的85%)上。 Kafka分区与输入RDD中的分区数量进行1:1匹配,导致只有36个分区,这意味着我们只能让36个核心忙于此任务。 为了增加并行度,我们需要增加分区数。 因此,我们将主题1分为12个主题,每个主题有6个分区,总共72个分区。 我们对生产者进行了简单的修改,将第一个日志中的数据平均分为12个主题,而不仅仅是一个。 消费者方需要修改零代码。

我们还根据其他两个主题在输入数据中的相对重要性,适当调整了分区数的大小,因此我们将主题2设置为2,将主题3设置为8。

并行运行更多任务。 调整之前,每个阶段始终有36个分区!

调整执行程序的大小

原始应用程序仅运行3个执行程序,共有72个内核。 我们将应用程序配置为以80个内核运行,每个执行者最多10个内核,总共8个执行者。 请注意,在10个节点的集群中,每个节点具有16个实际核心,我们为Kafka代理,Ignite和HDFS / NN留下了足够的资源。

将批处理窗口从30s增加到1m

生产者每隔30秒将数据分批推送到Kafka,因为它是通过FTP批处理从远程系统收集的。 由于需要处理制造商,技术和年龄的困惑范围内的设备和系统,因此这种布置在电信应用中很常见。

这意味着输入流非常不完整,如Spark UI的“流”选项卡的屏幕截图所示:

将窗口增加到1m可使我们平滑输入,并使系统有机会在1分钟或更短的时间内处理数据,但仍保持稳定。

为了确保这一点,该团队生成了一个测试数据,该数据模拟了已知的最坏情况数据,并且使用新设置,火花流工作现在确实很稳定。 该团队还能够轻松地在测试数据和实际生产数据流之间进行切换,并通过限制生产者来配置要传入系统的数据量。 这对于快速测试各种配置并查看我们是否取得了进展非常有帮助。

删除要求保存到Hive,仅使用Ignite

与项目经理的讨论表明,Hive实际上并不是流应用程序需求的一部分! 主要是因为HBase中的数据可以轻松地被分析使用。 同样,在此应用程序的上下文中,每个单独的记录实际上都不需要100%保证地进行处理。

确实,根据系统的目标,丢失数据的最坏情况是无法找到客户的呼叫质量信息……情况已经如此。 换句话说,数据丢失的风险不是破坏交易的因素,而获得数据的好处是更多的见解。 只要处理和存储绝大多数数据,就可以实现业务目标。

所有优化的结果

流媒体应用程序最终稳定下来,优化运行时间为30-35s。

事实证明,淘汰Hive还加快了将数据连接在一起的第二个Spark应用程序的运行,因此它现在的运行时间为3500万,这意味着这两个应用程序现在都符合项目要求。

随着下一部分的改进,Spark Streaming作业的最终性能下降到20s的较低范围,最终加速了12倍以上。

我们必须在稳定性方面下大力气。 需要采取几种策略,如下所述。

使Spark Streaming应用程序稳定

我们为修复性能所做的工作直接影响了系统的稳定性。 如果两个应用程序本身都稳定并且在适当大小的资源上运行,则系统最有可能总体上保持稳定。

删除Mesos并使用Spark Standalone

Mesos最初选择管理资源是前瞻性的,但最终我们决定将其从最终生产系统中删除。 首先,计划是让Mesos管理所有应用程序。 但是团队永远无法让Kafka和Ignite与Mesos保持良好的合作关系,因此他们以独立模式运行,仅由Spark由Mesos管理。 当然,随着时间的推移,毫无疑问,所有应用程序都可以正确配置为与Mesos一起使用。

提议删除Mesos有点争议,因为Mesos比在独立模式下运行的Spark更先进,更酷。

但是Mesos的问题是双重的:

  1. 对执行程序大小和数量的控制很差,这是Spark 1.6的一个已知问题( SPARK-5095 ),已在Spark 2.0中修复。
  2. Ignite和Kafka不在Mesos内部运行,只是Spark。 由于日程安排的压力,该团队已放弃尝试使这两个服务在Mesos中运行。

如果Mesos实际控制资源,则它只能分配好资源。 就此系统而言,Kafka和Ignite的运行超出了Mesos的知识范围,这意味着它将错误地将资源分配给Spark应用程序。

此外,它是一个单一用途的集群,因此我们可以使用系统资源的全局视图为每个应用程序自定义资源的大小。 几乎不需要动态资源分配,调度队列,多租户和其他流行语。

更改点燃记忆模型

一个已知的问题是,当由JVM控制的堆变得很大(> 32GB)时,垃圾回收的成本会很大。 当加入应用程序运行时,我们确实可以看到这个问题:25GB随机播放的阶段中有些行的GC时间峰值很大,从10秒到超过一分钟不等。

Ignite的初始配置是运行ONHEAP_TIERED,并在堆上缓存48GB的数据,然后溢出降至12GB的堆外内存。 该设置已更改为OFFHEAP_TIERED模型。 尽管由于序列化成本而稍慢,但是OFFHEAP_TIERED不会导致大量垃圾回收。 它仍然在内存中运行,因此我们估计这将是净收益。

进行此更改后,每个批次的运行时间从30秒降低到了约25秒,减少了约5秒钟。 此外,连续的批处理往往具有更多相似的处理时间,增量为1-3秒,而先前的变化会超过5至10秒。

更新Ignite JVM设置

我们遵循了Ignite文档的性能调整部分( http://apacheignite.gridgain.org/docs/jvm-and-system-tuning )中推荐的JVM选项。

完善Spark代码

代码的某些部分假定可靠性,例如对Ignite的查询,而实际上却存在操作失败的可能性。 这些问题可以在代码中解决,现在可以更优雅地处理异常,尽管可能还有很多工作可以提高代码的健壮性。 我们只能通过立即运行该应用程序来找到这些位置。

将ZooKeeper重新分配给节点10-12

鉴于群集是中型的,因此有必要尽可能多地扩展服务。 我们将ZooKeeper服务从节点1-3移到了节点10-12。

结论

调整此应用程序大约需要1周的全职工作。 我们使用的主要信息是Spark UI和Spark日志,可以从Spark UI轻松访问。 作业和阶段以及流UI的视图确实非常有用。

我学到的是

  • 将流应用程序从AWS上的原型迁移到本地集群需要安排测试时间
  • 不使用真实数据测试AWS原型是一个大错误
  • 包括许多对可靠性要求很高的“出血边缘” OSS组件(Apache Ignite和Mesos)是不现实的
  • 更好的架构设计可以极大地简化系统
  • 调整Kafka / Spark Streaming应用程序需要对整个系统有一个整体的了解。 这不仅仅是改变Spark的参数值; 它是数据流特征,应用程序目标和对客户的价值,硬件和服务,应用程序代码,然后使用Spark参数的组合。
  • MapR融合数据平台将减少该项目的开发时间,复杂性和成本。

该项目是这家特定电信公司的第一个项目,他们决定全力开发这种先进的100%开放源代码平台。 他们的开拓精神应受到赞扬。 但是,更好的平台和应用程序体系结构选择将使他们的生活更加轻松。

现在需要融合的大数据平台

实际上,该项目的需求表明了现实世界中对具有最新的融合平台的业务需求,该平台具有快速分布式文件系统,用于持久性的高性能键值存储以及实时流功能。

由于该架构所需的完整软件堆栈已经内置并得到完全支持,因此MapR解决方案可能会跳过对仍然投机的开源项目(如Ignite)的要求。 鉴于该系统已开始为具有24/7可靠性预期的电信运营商量产,因此这一优势非常可观。

翻译自: https://www.javacodegeeks.com/2017/01/performance-tuning-apache-kafkaspark-streaming-system.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/350160.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 8服务配置文件my.ini 不生效_2、mysql的启动选项和配置文件介绍

mysql服务端可以指定允许同时接入的客户端数量max-connections、客户端与服务器的通信方式、表的默认存储引擎default_storage_engine等等设置项,使得我们可以更加灵活地使用它。进入正题我们讲的是基于linux系统的,本文我们主要讲一下:1、有…

数学中常见的maxmin,min max

数学中常见的maxmin,min max 1、数学中公式(1)与公式(2)含义是不同的 (1) (2) 公式(1)的直接理解,先找出每个班里的身高最高的同学,再由这些同学中挑出身高最低的;同理,公式(2)的直接理解,先找出每个…

Mac入门--Apache/Php/Mysql的开启关闭

注意:mac自带apache环境和PHP环境 一 php服务的启动和关闭 php-fpm 启动 sudo php-fpm php-fpm 关闭 1 查看php-fpm端口是否在被php-fpm进程 netstat -an | grep 9000 查看进程pid sudo lsof -i:9000 杀死进程 sudo kill -9 [pid] 或者 sudo killall php-fpm 2 查看…

method=post 怎么让查看源代码看不到_网上文档无法复制怎么办?试试这几个方法!...

从网上复制资料很简单吗?平常在网上查找资料的时候,总是会有一些文档无法下载、甚至有时连复制都不行。这可怎么办?别急,今天我们就来介绍一些网页复制的方法,帮助大家更好地收集资料。一:复制到Word剪贴板…

python 加载mat文件

python 加载mat文件 直接上程序 import scipy.io as sciomat_path ./USPS_vs_MNIST.matload_mat scio.loadmat(mat_path) # load_mat为字典类型, <class dict> print(type(load_mat)) # 访问load_mat即为访问字典 X_src load_mat[X_src] # 这个X_src为numpy类型&…

[Sdoi2010] 地精部落

F. 地精部落 题目描述 传说很久以前&#xff0c;大地上居住着一种神秘的生物&#xff1a;地精。 地精喜欢住在连绵不绝的山脉中。具体地说&#xff0c;一座长度为 N 的山脉 H可分 为从左到右的 N 段&#xff0c;每段有一个独一无二的高度 Hi&#xff0c;其中Hi是1到N 之间的正 …

怎么判断冠词用a还是an_英文写作常见错误学习笔记 | 冠词

写在前面的话在知乎中看到“英文学术论文写作&#xff0c;有什么好书可以推荐”话题中有人推荐了香港大学出版社Steve Hart写的《English Exposed》一书&#xff0c;从副标题“Common Mistakes Made by Chinese Speakers”可以看出书是针对中国人常犯的错误而写的&#xff0c;作…

工厂模式 构建者模式_实践中的构建者模式

工厂模式 构建者模式我将不深入讨论该模式&#xff0c;因为已经有大量的文章和书籍对此进行了详细的解释。 相反&#xff0c;我将告诉您为什么以及何时应该考虑使用它。 但是&#xff0c;值得一提的是&#xff0c;这种模式与《 四人帮》一书中介绍的模式有些不同。 虽然原始模式…

python 反复访问迭代器iter,反复使用next

python 反复访问迭代器iter&#xff0c;反复使用next test [1, 2, 3]# 定义迭代器 iter_test iter(test)# 使用for循环访问迭代器 # 由于next()只向前走&#xff0c;所以当跌代到test最后一个值3之后&#xff0c;就会爆发异常StopIteration # 这里使用了一个try语句&#xf…

PPT转PDF方法

引用&#xff1a; using Microsoft.Office.Interop.PowerPoint;方法&#xff1a; ///<summary> /// PPT转PDF ///</summary> ///<param name"sourcePath">源文件路径</param> ///<param name"targetPath&qu…

打印容器_3D打印:增材点阵结构在压力容器优化设计中的应用

“增材制造是未来制造业的发展趋势&#xff0c;其优势显而易见&#xff0c;它可以实现传统加工工艺难以制造的设计&#xff0c;比如复杂薄壁结构、点阵结构、一体化结构等。其中&#xff0c;点阵结构作为一种新型的轻量化结构&#xff0c;具有良好的比刚度、比强度等力学性能。…

Java平台模块系统公众审查未能通过

在过去的几周里&#xff0c;Java世界中的戏剧&#xff0c;阴谋和政治活动异常高涨&#xff0c;最终在本周的JSR 376 Java平台模块系统公共评审投票中达到了顶峰。 Java模块化&#xff08;包括Java平台模块系统&#xff08;JPMS&#xff09;&#xff09;可以说是JDK 9最重要的部…

区间素数个数查询

给出一个闭区间的两端l和r&#xff0c;输出[l,r]中素数的个数。 输入格式: 两个整数l和r&#xff0c;之间用空格隔开&#xff08;1<l<r<10000&#xff09;。 输出格式: 输出一个结果。 输入样例: 2 10输出样例: 4 import java.util.Scanner;public class Main {static…

jtabel 遍历_使用抽象表模型获取JTable中选定的行

在下面的示例中&#xff0c;TableModel更新Set checked在执行setValueAt()..相邻模型JList侦听表的模型并显示当前选定的行号。该示例假定所选行数与行数相比较小。注意使用TreeSet&#xff0c;其迭代器保留了元素的自然顺序。import java.awt.Dimension;import java.awt.Event…

neo4j cypher_优化Neo4j Cypher查询

neo4j cypher上周&#xff0c;我花了很多时间来尝试优化大约20个使用实时系统数据执行的灾难性的Cypher查询&#xff08;36866ms至155575ms&#xff09;。 经过一番尝试和错误&#xff0c;以及来自Michael的大量投入&#xff0c;我能够大致确定对查询进行哪些操作才能使它们性能…

Mac--PHP已经开启gd扩展验证码不显示

错误显示&#xff1a;Call to undefined function imagettftext() 原因&#xff1a; mac系统中自带的php的gd库中&#xff0c;缺少对freetype的支持&#xff0c;导致图片无法显示。 解决&#xff1a; 1 下载freetype&#xff0c;安装即可 下载地址&#xff1a;https://download…

cprintdialog预览_怎样用CPrintDialog来实现打印功能

把以下程序段加入你的程序把dc1当作Device Content.就任你打印了.注意别画错地方.自己换页.更绝的是可调用窗口的OnPrint或OnDraw成员函数直接打印.不用你去做行距多少啦!但别忘换页.// 打印// 建立打印对话框对象CPrintDialoghttp://www.gaodaima.com/?p65323怎样用CPrintDia…

容器中Java RAM的使用:不会丢失内存的5大技巧

在本文中&#xff0c;我们希望分享Java内存管理的细节和容器内部的弹性&#xff0c;这些细节乍一看并不明显。 在下面&#xff0c;您将找到要注意的问题列表以及即将发布的JDK版本中的重要更新&#xff0c;以及针对核心痛点的现有解决方法。 我们收集了5个最有趣&#xff0c;最…

G1垃圾收集器设计目标与改良手段【纯理论】

在之前已经详细对CMS垃圾回收器进行了学习&#xff0c;今天准备要学习另一个全新的垃圾收集器---G1&#xff08;Garbage First Collector 垃圾优先的收集器&#xff09;&#xff0c;说是一种全新的&#xff0c;其实G1垃圾收集器已经出现了N多年了&#xff0c;只是从发展到成熟是…

centos7安装es mysql_Centos7 安装MySQL详细步骤

Centos7 安装MySQL详细步骤首先在虚拟机中安装一个Centos7(VM虚拟机安装Centos7)1.1 MySQL安装1.1.1 下载wget命令yum -y install wget11.1.2 在线下载mysql安装包wget https://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm11.1.3 安装MySQLrpm -ivh mysql57…