资讯动态

工业级大数据引擎:状态管理、资源调度、计算编排与故障恢复四主线解析

发布时间:2026/10/13 16:49:15 来源:尧图企业网站定制
1. 这不是一张“技术名词贴纸墙”而是一套协同运转的工业级数据引擎你打开招聘网站搜“大数据开发”十份JD里八份会列一长串词HDFS、Spark、Flink、Yarn、Zookeeper……它们像贴在服务器机柜上的标签纸整齐、冰冷、自带压迫感。但真实情况是——没人单独用HDFS存文件也没人只跑一个MapReduce任务就去交付项目。这些组件从来不是孤立存在的技术名词而是彼此咬合、职责分明、容错严密的一整套工业级数据处理引擎。我带过三届校企联合实训班每次开课第一件事就是撕掉学员电脑上贴着的那张“大数据技术栈思维导图”——那玩意儿误导性太强它让你以为只要把每个框都填满知识系统就能自动转起来。实际上HDFS不解决数据怎么分片读取才不拖慢SparkZookeeper不告诉你选举失败后Yarn ResourceManager该等几秒再重试Flink的Checkpoint机制和Kafka的Offset提交时机一旦错位下游业务报表就准点出bug。这整套系统真正的核心逻辑是状态管理、资源调度、计算编排与故障恢复四条主线的实时博弈。它面向的不是单台机器的CPU利用率而是成百上千台物理节点组成的“逻辑计算机”的稳定心跳。适合谁学如果你正在参与日均处理20TB以上原始日志的推荐系统重构或者正被实时风控场景中500ms端到端延迟卡住脖子又或者需要把离线报表从T1压缩到T5分钟——那你不是在学“几个框架”而是在掌握一套分布式系统的工程操作系统。它不教你怎么写SQL但教你为什么这条SQL在Spark里要触发三次Shuffle它不讲Java语法但必须清楚JVM Full GC如何让Zookeeper的ZAB协议误判节点死亡。下面拆解的不是功能列表而是这套引擎每天凌晨三点还在稳定吐出数据时背后真正咬合的齿轮。2. 系统设计本质四条不可妥协的工程主线2.1 主线一存储层必须回答“数据在哪里、谁在管、坏了一块怎么办”HDFS绝不是“Linux磁盘挂载到网络上”这么简单。它的设计哲学是用廉价硬件堆出高可靠——这直接决定了所有上层计算框架的容错策略。举个具体例子某次线上事故集群中3台DataNode因磁盘IO打满连续超时NameNode在30秒内完成三件事第一将这3台节点标记为“Decommissioning”下线状态但不立即删除其上数据块第二启动Block Replication任务把受影响的数据块从剩余副本复制到新节点第三在所有新副本写入完成后才真正释放原节点磁盘空间。这个过程耗时约7分钟而整个集群对外服务无感知。为什么能这样因为HDFS的元数据文件路径、块位置、权限全存在NameNode内存里而实际数据块分散在DataNode本地磁盘。NameNode本身是单点但它通过EditLog FsImage双机制实现元数据持久化所有文件操作先写入EditLog类似数据库redo log定期合并到FsImage快照。Zookeeper在这里不参与HDFS主备切换——那是HDFS HA方案里JournalNode干的活。Zookeeper真正发力的地方是协调NameNode的Active/Standby状态当Active NameNode心跳中断ZKFCZK Failover Controller进程会通过Zookeeper的临时节点ephemeral znode发现异常触发ZKFC调用命令强制Standby节点转为Active。这里有个关键细节ZKFC不会直接kill旧Active进程而是先执行hdfs haadmin -failover --forcefence命令用SSH远程登录旧节点执行fencing围栏操作确保旧节点彻底放弃对共享编辑日志如NFS或QJM的写入权。否则两个Active同时写日志元数据就彻底乱了。所以Zookeeper在这里的角色是“状态仲裁者”不是“数据搬运工”。2.2 主线二资源调度层必须回答“谁来分配CPU、内存、磁盘按什么规则分”Yarn的设计目标很务实让Hadoop集群不再只为MapReduce服务。它把资源管理ResourceManager和任务调度ApplicationMaster彻底解耦。ResourceManager只管两件事一是维护所有NodeManager上报的容器Container资源池比如总内存1000GBvCPU 200核二是根据队列配额Capacity Scheduler或优先级Fair Scheduler分配容器。而每个应用Spark、Flink、自定义MR自己启动一个ApplicationMasterAMAM向RM申请容器拿到后直接和对应NodeManager通信启动任务进程。这种设计带来两个硬性约束第一AM本身也是运行在容器里的普通进程如果AM崩溃RM会重新拉起它但之前申请的容器会被回收——所以Spark的Driver必须配置spark.yarn.am.attemptFailuresValidityInterval参数告诉Yarn“这个AM重启3次还失败才算真挂”。第二NodeManager监控的是容器级资源不是进程级。曾有个案例某Spark任务在容器内启动了Python子进程做数据清洗子进程内存暴涨但没触发Yarn的OOM Killer因为Yarn只看容器cgroup统计值而Python子进程可能逃逸出cgroup限制。解决方案是启用NodeManager的yarn.nodemanager.resource.percentage-physical-cpu-limit参数强制用cgroups v2做更严格的CPU隔离。Yarn的调度器选型直接影响业务SLACapacity Scheduler适合多部门共享集群能保证每个队列最低资源保障Fair Scheduler适合多任务混跑动态平衡资源但突发大任务会抢占小任务资源。我们实测过当集群负载达85%时Fair Scheduler下小任务平均延迟增加400%而Capacity Scheduler下小任务延迟仅增15%——代价是大任务可能排队等待。2.3 主线三计算编排层必须回答“数据流经哪些算子、状态怎么保存、中间结果放哪”MapReduce、Spark、Flink表面都是“写代码跑任务”底层逻辑天差地别。MapReduce是批处理的物理模型Map阶段把输入分片并行处理Shuffle阶段按key排序分组Reduce阶段聚合。它的瓶颈永远在Shuffle——数据必须落盘再读磁盘IO成为天花板。Spark用内存计算DAG调度破局RDD的Lineage血缘记录所有转换操作某个分区计算失败时只需重算该分区依赖的上游分区不用重跑整个Job。但Spark Streaming的微批处理micro-batch本质仍是批处理它把实时数据切成1秒/5秒的批次每个批次走一次DAG。这就导致端到端延迟下限是批次间隔。Flink的事件时间状态后端才是真流式它把每条数据的时间戳作为处理依据状态如窗口聚合值存在RocksDB本地磁盘或Heap内存中Checkpoint时把状态快照同步到HDFS。这里有个关键参数state.backend.rocksdb.predefined-options设为SPINNING_DISK_OPTIMIZED_HIGH_MEM时RocksDB会减少Level 0文件数量降低Compaction压力但内存占用翻倍。我们压测发现当单TaskManager状态大小超8GB时必须切到SSD优化模式否则GC停顿会突破2秒。Storm的早期优势在于低延迟毫秒级但它用Zookeeper协调Worker进程ZK的ZAB协议在高并发写入时容易成为瓶颈。现在主流方案是Flink KafkaKafka作为消息源和结果输出Flink消费Kafka Partition每个Partition绑定一个Task天然实现水平扩展。Giraph则专攻图计算——它把图分割成顶点Vertex和边Edge每个Worker加载部分顶点超步Superstep同步时通过Netty发送消息。它的瓶颈不在计算而在网络当图稀疏度低于0.001即边数远少于顶点数平方时大量Worker空转等消息此时用Pregel模型比MapReduce图算法快10倍以上。2.4 主线四架构演进主线从Lambda到Kappa再到DataFlow的收敛Lambda架构批流分离曾是行业标准解法用Hadoop MapReduce跑T1离线报表用Storm跑实时大屏。但它的致命伤是代码双写与结果不一致。比如用户行为漏斗分析离线链路用Hive SQL统计实时链路用Storm Topology计算两个结果经常差0.3%——因为Storm的At-Least-Once语义导致消息重复而Hive作业又没做去重。Kappa架构试图用Flink统一所有数据走KafkaFlink既做实时处理又做离线回溯。但问题来了Flink处理PB级历史数据时状态后端RocksDB会因LSM树Compaction卡住Checkpoint超时失败。DataFlow模型Google提出Flink深度实现给出第三条路用事件时间Watermark允许迟到数据的窗口机制。比如统计每分钟订单量设置10分钟Watermark延迟当迟到订单到达时Flink触发allowedLateness回调更新已输出的窗口结果并用sideOutputLateData把超时数据路由到特殊通道。这要求下游存储支持幂等更新如HBase的Put覆盖而不是简单追加。我们落地时发现业务方最常踩的坑是Watermark生成策略用事件时间戳最大值减固定延迟BoundedOutOfOrdernessTimestampExtractor在流量突降时会导致Watermark停滞必须改用AscendingTimestampExtractor配合Kafka分区水印对齐。Lambda架构没死只是退居二线——它现在只用于训练集生成用Spark MLlib跑全量历史特征结果存入特征库Flink实时计算当前特征查特征库做在线预测。这才是生产环境的真实分层。3. 核心组件实操要点与避坑指南3.1 HDFS别只盯着副本数磁盘布局才是性能命门HDFS默认副本数3但这是针对“单机房”场景。跨机房部署时必须调整dfs.replication和dfs.namenode.replication.min。比如三机房A/B/C策略应设为A机房2副本B机房1副本而非均匀3副本——否则跨机房网络带宽会成为瓶颈。更关键的是DataNode的磁盘配置dfs.datanode.data.dir参数支持多路径但必须用逗号分隔且路径必须在不同物理磁盘。曾有个集群把/data1,/data2指向同一块SSD的两个目录结果IO等待时间飙升至200ms。正确做法是/mnt/disk1/dfs/data,/mnt/disk2/dfs/data,/mnt/disk3/dfs/data并确保每个/mnt/disk*挂载独立NVMe盘。NameNode的堆内存配置有公式NameNode Heap 1GB (1GB per 1 million blocks)。假设集群有5000万块NameNode需配51GB堆内存但JVM参数必须设-XX:MaxDirectMemorySize2g否则Native内存泄漏会导致Full GC。运维中最易忽略的是dfs.namenode.handler.count它控制NameNode处理客户端RPC请求的线程数默认10。当并发客户端超500时必须调到min(200, CPU核心数*20)。我们线上集群CPU 64核此参数设为1280否则NameNode RPC队列积压客户端报ConnectException。3.2 Yarn资源超卖的红线与安全阀Yarn允许资源超卖Overcommit但必须守住两条红线第一yarn.nodemanager.resource.memory-mb不能超过物理内存的80%预留20%给OS和守护进程第二yarn.nodemanager.resource.cpu-vcores必须≤物理CPU核心数。超卖CPU是危险操作某次测试将vcores设为物理核心数的2倍结果NodeManager的ContainerExecutor进程因竞争CPU被OS OOM Killer干掉。安全阀参数是yarn.scheduler.maximum-allocation-mb它限制单个Container最大内存必须≤NodeManager总内存的50%。比如NodeManager总内存128GB此参数设为64GB避免单个Spark Executor吃光所有内存。队列配置上yarn.scheduler.capacity.root.default.user-limit-factor设为2意味着普通用户最多用本队列200%资源但前提是其他用户没在用。真正保底的是yarn.scheduler.capacity.root.default.minimum-user-limit-percent设为100表示该队列必须100%保障给单一用户——这在独占集群时很实用。Yarn日志聚合Log Aggregation必须开启yarn.log-aggregation-enabletrue否则Container日志散落在各NodeManager本地故障排查要登录20台机器。聚合后日志存HDFS路径/app-logs/$user/logs用yarn logs -applicationId application_123一条命令就能拉取全量日志。3.3 SparkDriver内存不是越大越好Shuffle才是生死线Spark Driver内存配置有陷阱spark.driver.memory设太大反而坏事。Driver要存储广播变量Broadcast、累加器Accumulator和任务调度元数据。当Driver内存超8GB时JVM GC停顿会指数级增长。我们实测Driver内存从4GB升到12GBGC时间从200ms跳到1.8秒。正确姿势是Driver内存≤6GB把大变量用spark.sql.adaptive.enabledtrue开启自适应查询执行AQE让Spark在运行时动态合并小文件、优化Join策略。Shuffle调优才是重点spark.shuffle.file.buffer默认32KB决定Shuffle Write缓冲区大小SSD集群建议调到64KBspark.reducer.maxSizeInFlight默认48MB控制Reducer拉取Shuffle数据的并发连接数网络带宽10Gbps时可提到96MB。最致命的是spark.sql.adaptive.coalescePartitions.enabled它自动合并小分区但若上游数据倾斜合并后的大分区会拖垮整个Stage。必须配合spark.sql.adaptive.skewJoin.enabledtrue让Spark检测到倾斜Key后把大分区拆成多个小任务并行处理。我们遇到过一个Case某Join操作因Key倾斜导致单个Task耗时12分钟开启倾斜Join后降到45秒。Spark on Yarn模式下spark.yarn.am.memoryAM内存和spark.driver.memory必须区分AM负责向Yarn申请资源Driver负责任务调度两者内存不能混用。3.4 FlinkCheckpoint不是开关而是一套精密时序系统Flink的Checkpoint配置是门艺术。state.checkpoints.dir必须指向高可用存储如HDFS但state.savepoints.dir可以指向本地磁盘——Savepoint是手动触发的用于版本升级。Checkpoint间隔execution.checkpointing.interval不能设太短设为30秒时频繁的小Checkpoint会压垮HDFS NameNode。生产环境建议10分钟但必须配execution.checkpointing.tolerable-failed-checkpoints3允许连续3次失败。State Backend选型RocksDB适合大状态1GB但必须配state.backend.rocksdb.options-factory指定优化参数HeapStateBackend适合小状态100MB但重启时状态全丢。最易错的是state.checkpoints.num-retained它控制保留几个Checkpoint设为1时新Checkpoint生成后旧的立刻删除。但若Checkpoint失败可能造成零Checkpoint可用。我们线上设为5并用脚本定时校验/flink/checkpoints目录下最新Checkpoint的_metadata文件是否完整。Watermark生成必须绑定KafkaFlinkKafkaConsumer.setStartFromTimestamp()指定起始时间assignTimestampsAndWatermarks()里用BoundedOutOfOrdernessTimestampExtractor延迟值设为max(业务容忍延迟, Kafka Producer端时钟漂移)。曾有个集群Kafka Broker时钟比Flink TaskManager快8秒导致Watermark永远滞后窗口无法触发。3.5 Zookeeper不是配完就完事会话超时是隐形杀手Zookeeper的tickTime默认2000ms是所有超时参数的基数。initLimitfollower连接leader的最长时间 tickTime × 10syncLimitfollower同步数据的最长时间 tickTime × 5。但生产环境必须调大tickTime4000initLimit40syncLimit20。否则网络抖动时follower频繁重连。更关键的是sessionTimeout客户端创建连接时指定的会话超时时间必须满足2*tickTime sessionTimeout 20*tickTime。Spark Streaming的Receiver会用ZK存offset若sessionTimeout设为30秒而网络抖动持续35秒Receiver会丢失会话offset重置导致数据重复。ZK的maxClientCnxns参数默认60但Flink的JobManager会为每个TaskManager建连接100个TM就需要100连接。必须调到min(1000, 总连接数)。ZK日志清理靠autopurge.purgeInterval小时但autopurge.snapRetainCount保留快照数更重要设为5时ZK只留最近5个snapshot和对应log避免磁盘爆满。我们线上集群每小时清理保留10个快照因为单个snapshot达2GB。4. 全链路实操从数据接入到实时报表的12个关键步骤4.1 步骤1Kafka集群规划——分区数不是越多越好Kafka Topic分区数决定并行度上限但盲目增加分区会反噬性能。公式分区数 ≤ min(消费者实例数 × 2, 集群总CPU核心数)。比如10个Flink TaskManager每台32核总CPU 320核消费者实例数20则分区数上限40。但实际要留余量设为32。原因有三第一Kafka Controller要为每个分区选举Leader分区超1000时Controller压力剧增第二每个分区对应一个日志段Log Segment文件句柄数暴涨第三Flink消费时每个分区绑定一个SubtaskSubtask过多导致TaskManager线程数爆炸。我们压测发现当Topic分区从16升到64Flink吞吐只提升1.8倍非线性但GC频率翻倍。分区策略用DefaultPartitioner即可除非业务有强顺序要求如用户ID哈希。Kafka日志保留策略log.retention.hours1687天是底线但必须配log.retention.bytes1073741824010GB防止单分区数据暴涨撑爆磁盘。4.2 步骤2Flink实时ETL——用Table API绕过DataStream的复杂性不用写DataStream API用Flink SQL更稳。建Kafka源表CREATE TABLE user_log ( user_id STRING, event_time TIMESTAMP(3), event_type STRING, WATERMARK FOR event_time AS event_time - INTERVAL 5 SECOND ) WITH ( connector kafka, topic user_log, properties.bootstrap.servers kafka1:9092,kafka2:9092, format json, scan.startup.mode latest-offset );关键点WATERMARK必须声明否则窗口不触发scan.startup.mode设为latest-offset避免重放历史数据。维表关联用lookup.joinCREATE TEMPORARY TABLE user_dim ( user_id STRING, city STRING, PRIMARY KEY (user_id) NOT ENFORCED ) WITH ( connector jdbc, url jdbc:mysql://mysql:3306/dim, table-name user_dim, lookup.cache.max-size 1000000, lookup.cache.ttl 1 hour );lookup.cache.ttl设1小时避免频繁查DB。最终实时报表INSERT INTO real_time_report SELECT TUMBLING_START(event_time, INTERVAL 1 MINUTE) as window_start, COUNT(*) as pv, COUNT(DISTINCT user_id) as uv FROM user_log GROUP BY TUMBLING(event_time, INTERVAL 1 MINUTE);TUMBLING窗口比HOPPING更省资源因不重叠。输出到MySQL用jdbc连接器但必须配sink.buffer-flush.max-rows1000和sink.buffer-flush.interval1s否则小批量写入太慢。4.3 步骤3Spark离线特征工程——用Delta Lake解决数据一致性不用Hive用Delta Lake。建表CREATE TABLE IF NOT EXISTS user_features USING DELTA LOCATION hdfs://nameservice1/user/features;Delta的核心是ACID事务日志_delta_log目录每次写入生成一个JSON文件记录变更。Spark写入时df.write.format(delta) \ .mode(overwrite) \ .option(replaceWhere, dt 2023-10-01) \ .save(hdfs://nameservice1/user/features)replaceWhere实现分区级原子替换避免Hive的INSERT OVERWRITE锁表。读取时用time travel查历史版本SELECT * FROM user_features VERSION AS OF 10;Delta的VACUUM命令清理旧文件但必须配RETAIN 168 HOURS否则删掉的文件可能被未完成的查询引用。我们线上每天凌晨2点执行VACUUM保留7天文件。4.4 步骤4Yarn资源队列隔离——用Capacity Scheduler划清责任田在capacity-scheduler.xml中property nameyarn.scheduler.capacity.root.default.capacity/name value40/value /property property nameyarn.scheduler.capacity.root.flink.capacity/name value30/value /property property nameyarn.scheduler.capacity.root.spark.capacity/name value30/value /property关键参数yarn.scheduler.capacity.root.flink.maximum-capacity60允许Flink在空闲时借用Spark队列资源。但必须配yarn.scheduler.capacity.root.flink.user-limit-factor1禁止单用户霸占全队列。队列ACL控制property nameyarn.scheduler.capacity.root.flink.acl_submit_applications/name valueflink-user/value /propertySpark用户无法向flink队列提交任务。Yarn Web UI的Scheduler页签能实时看各队列资源使用率绿色表示健康红色表示超阈值。4.5 步骤5Zookeeper ACL加固——最小权限原则落地ZK默认无权限控制必须加ACL。用zkCli.sh连接后# 创建认证用户 addauth digest flink:flink123 # 设置节点ACL setAcl /flink auth:flink:flink123:cdrwacdrwa代表create/delete/read/write/admin。Flink配置zookeeper.sasl.disablefalse启用SASL。更安全的是IP白名单zookeeper.authProvider.1org.apache.zookeeper.server.auth.IPAuthenticationProvider然后在zoo.cfg加skipAclyes用防火墙控制IP访问。4.6 步骤6HDFS Balancer——磁盘使用率不均衡的手术刀DataNode磁盘使用率差异超10%时必须运行Balancer。命令hdfs balancer -threshold 5 -policy datanode-threshold 5表示目标是各DataNode使用率差≤5%-policy datanode按节点均衡而非rack。Balancer是后台进程不影响读写但会占用网络带宽。建议在业务低峰期凌晨1-4点运行用-idleiterations 5限制最多5轮迭代。4.7 步骤7Flink Checkpoint调优——从失败到稳定的参数组合某次Checkpoint失败率30%排查发现是HDFS写入慢。调参组合# 增加Checkpoint超时 -state.checkpoints.interval 600000 \ # 允许失败次数 -state.checkpoints.tolerable-failed-checkpoints 3 \ # 减少单次写入量 -state.checkpoints.dir hdfs://nameservice1/flink/checkpoints \ # 启用增量CheckpointRocksDB -state.backend.rocksdb.incremental true \ # 增加网络缓冲 -taskmanager.network.memory.fraction 0.2 \增量Checkpoint使单次写入量降为全量的1/5但要求RocksDB开启optionsFactory。我们用DefaultConfigurableOptionsFactory并设block-cache-size536870912512MB。4.8 步骤8Spark动态资源分配——让Executor随负载呼吸spark.dynamicAllocation.enabledtrue开启动态分配但必须配--conf spark.dynamicAllocation.minExecutors2 \ --conf spark.dynamicAllocation.maxExecutors20 \ --conf spark.dynamicAllocation.initialExecutors5 \ --conf spark.shuffle.service.enabledtrue \spark.shuffle.service.enabledtrue是关键它让NodeManager启动External Shuffle Service使Executor释放后Shuffle数据仍可被获取。否则动态缩容时正在读Shuffle数据的Task会失败。4.9 步骤9Kafka MirrorMaker2——跨集群数据同步的可靠性保障用MM2同步Kafka集群配置mirror-maker.propertiesclusters primary, backup primary.bootstrap.servers kafka1:9092,kafka2:9092 backup.bootstrap.servers kafka3:9092,kafka4:9092 topics user_log replication.factor 3 offset-syncs.topic.replication.factor 3offset-syncs.topic存储偏移同步信息必须高复制。MM2会自动创建内部Topic无需手动建。监控用kafka-mirror-maker-health-check.sh脚本检查lag是否超100万条。4.10 步骤10Delta Lake Vacuum——防止小文件雪崩的定时手术Delta的VACUUM必须自动化。写Shell脚本#!/bin/bash spark-sql --master yarn \ -e VACUUM delta.hdfs://nameservice1/user/features RETAIN 168 HOURS;用crontab每天执行。注意VACUUM不删除正在被查询的文件所以安全。但必须确保spark.sql.files.maxPartitionBytes设为合理值如1GB避免小文件过多影响查询。4.11 步骤11Flink Savepoint迁移——版本升级不停服的关键Flink升级前先触发Savepointflink savepoint -yid application_12345 hdfs://nameservice1/flink/savepoints新版本Flink启动时flink run -s hdfs://nameservice1/flink/savepoints/savepoint-12345-abcde \ -c com.example.Job ./job.jarSavepoint包含完整状态新版本JobManager能兼容旧状态格式。但要注意StateSerializer升级必须向后兼容否则Restore失败。4.12 步骤12全链路监控——用PrometheusGrafana织网部署Prometheus抓取各组件MetricsHDFSjmx_exporter暴露NameNode/DataNode JMXYarnyarn.resourcemanager.webapp.address的/metrics/jsonFlinkmetrics.reporter.prom.class: org.apache.flink.metrics.prometheus.PrometheusReporterKafkajmx_exporter暴露Broker JMXGrafana看板关键指标HDFShdfs_namenode_capacity_used_pcnt磁盘使用率85%告警Yarnyarn_scheduler_queue_root_flink_used_capacity_percent队列使用率90%告警Flinkflink_taskmanager_job_task_operator_current_input_watermarkWatermark停滞告警Kafkakafka_server_broker_topic_metrics_bytes_in_total入流量突降告警5. 真实故障排查手册12个高频问题与根因定位5.1 问题1Flink Job频繁Restart日志显示“Failed to fetch checkpoint”现象Flink Web UI显示Job每5分钟重启一次TaskManager日志有CheckpointCoordinator - Failed to fetch checkpoint根因定位查Checkpoint目录hdfs://nameservice1/flink/checkpoints发现文件权限为drwx------只有JobManager用户可读hdfs dfs -ls看文件属主是flink但TaskManager运行用户是yarn检查core-site.xml发现hadoop.security.authenticationkerberos但TaskManager没配Kerberos keytab解决方案方案A推荐统一用hdfs dfs -chmod -R 755 /flink/checkpoints改权限方案B在flink-conf.yaml加state.checkpoints.dir: hdfs://nameservice1/flink/checkpoints?user.nameflink强制指定用户5.2 问题2Spark SQL查询Hive表极慢Explain显示大量Stage现象SELECT COUNT(*) FROM hive_table耗时15分钟Explain显示200个Stage根因定位DESCRIBE FORMATTED hive_table发现inputFormat: org.apache.hadoop.mapred.TextInputFormat说明是TextFile格式hdfs dfs -du -h /hive/table显示小文件12万个平均大小24KB解决方案用INSERT OVERWRITE TABLE hive_table SELECT * FROM hive_table DISTRIBUTE BY rand()强制合并小文件后续写入改用ORC格式SET hive.exec.orc.split.strategyBI5.3 问题3Yarn ApplicationMaster启动失败报“Requested memory 8192 beyond physical memory limits”现象yarn logs -applicationId application_123显示AM申请8GB内存但NodeManager只报告4GB可用根因定位yarn node -list看NodeManager资源Memory-Usage: 4096 MB of 4096 MB physical memory used检查yarn-site.xml发现yarn.nodemanager.resource.memory-mb4096但物理内存是16GBfree -h确认OS预留了12GB内存给系统进程解决方案调yarn.nodemanager.resource.memory-mb1228812GB重启NodeManageryarn-daemon.sh stop nodemanager yarn-daemon.sh start nodemanager5.4 问题4Kafka Consumer Group Lag飙升Flink任务处理不过来现象kafka-consumer-groups.sh --bootstrap-server kafka1:9092 --group flink-group --describe显示Lag超500万根因定位flink list看Job状态正常但flink metrics显示numRecordsInPerSecond只有1000远低于Kafka入流量10万/秒jstack查TaskManager线程发现大量BLOCKED状态锁在RocksDB.writeBatchiostat -x 1看磁盘await达200msRocksDB Compaction卡住解决方案临时flink cancel -s hdfs://...触发Savepoint后重启强制RocksDB重建长期调state.backend.rocksdb.predefined-optionsSPINNING_DISK_OPTIMIZED_HIGH_MEM并换SSD5.5 问题5Zookeeper集群脑裂两个Leader同时存在现象echo stat | nc zk1 2181返回Mode: leaderecho stat | nc zk2 2181也返回Mode: leader根因定位zkServer.sh status在zk1和zk2都显示leaderecho mntr | nc zk1 2181 | grep zk_followers返回zk_followers 0检查网络ping zk2通但telnet zk2 2888不通2888是ZK follower通信端口解决方案重启zk2zkServer.sh restart强制其重新加入集群检查防火墙iptables -L | grep 2888开放2888端口5.6 问题6HDFS DataNode启动失败报“Cannot lock storage /data/dfs/data”现象hdfs datanode启动报错/data/dfs/data/in_use.lock文件被占用根因定位lsof /data/dfs/data/in_use.lock返回空说明无进程占用2

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑