Spark在降本增效中的一些思考

本文探讨了在经济环境不佳背景下,如何通过调整Spark的JVMGC策略(如CMS、G1和Parallel),提高并发度,以及引入ESS/RSS、向量化和动态资源分配来实现成本节省和效率提升。尤其是在NVMeSSD环境下,针对特定的磁盘IO性能优化措施进行了详细分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

在大环境不好的情况下,本司也开始了“降本增效”,本文探讨一下,在这种背景下 Spark怎么做的降本增效。
Yarn 基于 EMR CPU 是xlarge,也就是内存和核的比例在7:1左右的 ,磁盘是基于 NVMe SSD
Spark 3.5.0(也是刚由3.1 升级而来 )
JDK 8
这里为什么强调 NVMe ,因为相比于 HDD 来说,他的磁盘IO有更高的读写速度。 导致我们在 Spark上 做的一些常规优化是不起效果的

注意:如没特别说明 P99 P95 avg等时间单位是秒

优化手段

调整JVM GC策略

因为我们内部存在于类似 Apache kyuubi这种 long running的服务,而且内存都是20GB起步,所以第一步就想到调整 CMS 策略为 G1 或者 Parallel.
测试结果:

GC类型p100p99p95p90p50avgtask_count
CMS95692085.3800000000047688208343.8580512068836887363
G193802164.9100000000035853378652.2275451140619788110
Parallel109192192.970000000001888393652.0600647889858788904

从结果上来看,CMS在 吞吐上比 G1和Parallel 都要好的,附上 JVM的一些关键参数如下
Spark driver端的配置都是一样:

"spark.driver.extraJavaOptions": "-verbose:gc -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5  -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+ParallelRefProcEnabled -XX:+ExplicitGCInvokesConcurrent -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump",

CMS的 Executor 配置如下:

"spark.executor.extraJavaOptions": " -verbose:gc -XX:+UseParNewGC -XX:MaxTenuringThreshold=15 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5  -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+ParallelRefProcEnabled -XX:+ExplicitGCInvokesConcurrent -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump"

G1的 Executor 配置如下:

"spark.executor.extraJavaOptions": "-verbose:gc -XX:+UseG1GC -XX:ParallelGCThreads=10 -XX:ConcGCThreads=5 -XX:G1ReservePercent=15 -XX:MaxTenuringThreshold=15 -XX:+ParallelRefProcEnabled -XX:+ExplicitGCInvokesConcurrent -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump"

Parellel 的 Executor 配置如下:

"spark.executor.extraJavaOptions": "-Dcarbon.properties.filepath=carbon.properties -Dlog4j.configuration=xql-log4j.properties -verbose:gc -XX:++UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=10 -XX:+UseAdaptiveSizePolicy -XX:+ParallelRefProcEnabled  -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump"

增发并发度

在对任务的运行时长进行统计的时候我们发现,绝大部分任务都是运行时间在5分钟左右,而与此同时在任务高峰期的时候,整体任务的等待数量一直在1800左右,这种情况下,增大任务的并发度能够很好的增加整体的吞吐,实践中,起码后20%的提速,具体的运行时间如下:

p99p95p90p50avg
239194656238193.19207605335595

也是依赖了Spark 3.4+版本的配置 spark.ui.store.path,该配置使得Spark内部的状态信息存储不再存储在内存中。

引入ESS或者RSS

对于 ESS 可以参考:push-based shuffle to improve shuffle efficiency,但是这里请注意一点,该问题的提出点是基于 HDD 类型的磁盘的,因为我们现在是基于 NVMe SSD 的,所以几乎没有什么提升。
对于 RSS 可以参考:Apache celeborn,结果也是差不多。

引入向量化插件

对于向量化加速这块建议参考: Gluten,这也是笔者一直在关注的项目,根据 TPC-H 测试结果显示起码有2倍的性能提升,但是实际效果还是得看SQL的pattern。但是由于目前我们的Spark 是基于 3.5.0的,是比较新的版本,而社区这块的融合还在继续,所以这块今年应该可以行动起来,可以参考Add spark35 scala213

设置压缩格式为ZSTD

众所周知,ZSTD在压缩率和压缩解压缩上的性能都是很突出,但是在 NVMe SSD 光环下,改成了ZSTD的压缩格式以后,效果却不如人意,而且我们还合并了Parallel Compression Support for ZSTD到我们内部的Spark版本中,具体的效果如下:
具体的配置项为:“spark.io.compression.codec”:“zstd”

压缩格式p99p95p90p50avgtask_count
lz42806.510000000003412160585.62898089171975628
zstd1814.3700000000076118.349999999999878.3000000000000111117.2063492063492378

注意: 我们批集群的CPU利用率在60%以上,引入zstd以后会增加CPU的使用率,而且在这种 long running的服务下,得增加driver的core数,要不然会导致在进行广播的时候卡住,具体的可以加如下配置:

"spark.driver.cores":"8", 
"spark.io.compression.zstd.workers":"2",

至于效果为什么不理想,主要原因还是因为 shuffle数据量不大,可能对于单个shuffle数据量大的应用来说,可能效果比较明显。

增大可广播join的阈值大小

因为对于这种 long running的服务,driver端的内存一般都是挺大的,所以可以适当增大spark.sql.autoBroadcastJoinThreshold的配置,笔者这里设置了 50MB

引入动态资源分配

对于这种long running服务来说,每个时段的任务数肯定是不一样的,那这个时候引入动态资源分配的话,效果就是很好的,具体的配置可以参考如下:

"spark.shuffle.service.enabled":"false"
"spark.dynamicAllocation.enabled": "true",
"spark.dynamicAllocation.shuffleTracking.enabled": "true",
"spark.dynamicAllocation.minExecutors": "20",
"spark.dynamicAllocation.maxExecutors": "40",
"spark.dynamicAllocation.executorIdleTimeout":"3600"
<think>好的,用户希望了解2025年36岁的Java开发工程师如何逆袭找到工作,需要具备哪些技术和管理能力。首先,我需要考虑用户可能的背景。36岁在IT行业可能面临年龄歧视,尤其是在竞争激烈的就业市场中。用户可能担心自己的技术过时,或者缺乏管理经验,导致职业发展停滞。 接下来,用户的需求是“逆袭”,这意味着他们可能遇到了求职困难,或者想要突破现有的职业瓶颈。他们需要具体的建议,包括技术和非技术方面的能力提升,以及如何展示自己的优势。 我需要分析2025年的技术趋势,Java生态中的热门方向,比如云原生、微服务、大数据等。同时,管理能力方面,团队协作、项目管理、沟通技巧等都是关键点。此外,年龄带来的经验优势,比如系统设计、问题解决能力,应该被强调。 用户可能没有明确提到的深层需求是如何在年轻竞争者中脱颖而出,如何弥补年龄可能的劣势,比如学习新技术的速度或适应高强度工作的能力。因此,建议中需要包含持续学习的方法、构建个人品牌、人脉拓展等策略。 还需要考虑行业变化,比如企业可能更倾向于全栈或跨领域人才,因此建议用户扩展技能广度,学习DevOps、前端技术等。同时,管理能力不仅限于技术管理,可能包括产品思维、业务理解,这些能提升综合竞争力。 最后,确保建议具体可行,分阶段实施,比如3个月、6个月的计划,帮助用户逐步提升,避免信息过载。同时,鼓励用户调整心态,积极应对挑战,利用经验优势找到适合自己的岗位。</think>### 2025年Java开发工程师(36岁)职业逆袭路径分析 #### 一、核心挑战与机遇 1. **年龄挑战**:IT行业存在隐性年龄门槛,需通过技术深度和综合能力突破偏见 2. **经验优势**:10+年开发经验可转化为架构设计、技术决策等核心价值 3. **行业趋势**:2025年企业更关注技术降本增效、云原生改造、智能化转型 #### 二、技术能力矩阵(2025年重点方向) **硬核技术栈:** ```markdown 1. 云原生体系 - Kubernetes深度应用(Operator开发、集群优化) - Service Mesh(Istio实战经验) - 云原生Java框架(Quarkus、Micronaut) 2. 高并发架构 - 亿级流量架构设计(动态扩缩容、多级缓存) - 分布式事务新方案(Seata 2.0、Saga模式) - 实时计算框架(Flink 2.x、Pulsar) 3. 智能化开发 - AI辅助编程(GitHub Copilot深度集成) - 大数据分析(Spark 4.x + Java ML库) - 低代码平台开发(定制化引擎设计) 4. 新版本生态 - Java 21+新特性(虚拟线程、结构化并发) - GraalVM实战(Native Image编译优化) - Spring Boot 4.x新特性(JDK21适配、云原生增强) ``` **技术深度验证标准:** - 开源项目贡献(Apache/Spring等顶级项目PR) - 技术专利/白皮书撰写 - 复杂系统性能优化案例(TPS提升50%+) #### 三、管理能力进阶体系 **技术管理双通道:** ```markdown 1. 技术型管理 - 研发效能提升:CI/CD流水线优化(构建速度提升70%) - 技术债务治理方法论 - 团队技术雷达建设 2. 项目管控能力 - 百万级项目全生命周期管理 - 风险量化评估模型(蒙特卡洛模拟应用) - 跨部门资源协调(技术-产品-运维铁三角) 3. 业务融合能力 - 技术驱动业务增长案例(如通过架构改造降低30%运营成本) - 领域驱动设计(DDD)实战经验 - 商业模型与技术方案匹配度分析 ``` #### 四、差异化竞争策略 **三维竞争力模型:** ``` 技术深度(40%) + 行业理解(30%) + 资源网络(30%) ``` **实施路径:** 1. **技术品牌建设** - 打造技术博客(年产出15+深度文章) - 发起/维护开源项目(GitHub Star 500+) - 技术大会演讲(至少2次行业会议) 2. **行业纵深突破** - 深耕细分领域(金融科技/智能物流/工业互联网) - 获取行业认证(如金融行业信创认证) - 构建领域模型资产(行业通用组件库) 3. **人脉网络升级** - 技术社区KOL连接(LinkedIn百人有效网络) - 参与标准制定(行业协会/白皮书编写) - 建立技术咨询副业(年完成3个付费项目) #### 五、求职策略与阶段规划 **3个月转型计划:** ``` Week1-4: - 完成云原生认证(CKA/CKAD) - 重构GitHub项目支持Java21新特性 Week5-8: - 输出2篇深度技术解析(发布到InfoQ/掘金) - 启动低代码平台Side Project Week9-12: - 参与行业线上峰会并做技术分享 - 完成首个技术咨询案例 ``` **面试准备矩阵:** ```markdown 1. 技术演示: - 性能优化案例(附带监控数据截图) - 架构演进路线图(Visio可视化文档) 2. 管理能力验证: - 团队培养方案(技术梯队建设文档) - 技术决策案例(AB方案对比分析表) 3. 业务价值证明: - ROI分析报告(技术投入产出比) - 业务指标提升证明(客户背书/数据看板) ``` #### 六、风险控制与备选方案 **风险预案:** 1. 技术过时预警:订阅Redmonk技术趋势报告,设置季度技术雷达评审 2. 年龄歧视应对:聚焦架构师/技术专家岗位,避免初级开发竞争 3. 行业波动缓冲:构建"云原生+大数据+AI"的复合技术护城河 **备选发展路径:** - 技术教育领域:开发体系化课程(慕课网/极客时间签约讲师) - 技术创业方向:面向中小企业的云原生转型解决方案 - 跨国远程机会:强化英语技术文档能力,接入Toptal等全球平台 #### 七、关键认知升级 1. **价值定位转变**:从"代码实现者"升级为"技术价值创造者" 2. **学习模式进化**:构建"输入(学习)→ 实践(项目)→ 输出(影响)"的正循环 3. **时间管理策略**:采用"73法则"(70%核心能力深耕,30%前沿技术探索) 建议每月进行能力对标,使用SWOT分析工具动态调整策略。保持技术敏感度,关注Oracle官方路线图,提前布局Java 22新特性(预计2024年9月发布)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值