资讯详情

资讯详情

CDH 6.2.1+Flink 1.9+Druid 1.8实时数仓复现指南

1. 项目概述为什么在2024年还要复现CDH 6.2.1 Flink 1.9 Druid 1.8这套“经典组合”你点开这个标题大概率不是为了怀旧——而是正卡在一个现实困境里手头有个老系统要对接实时数仓但生产环境已锁定CDH 6.2.1Cloudera Distribution HadoopHDFS、YARN、Hive Metastore全跑在这套发行版上业务方又急着要亚秒级的用户行为分析能力Flink 1.9是当时CDH官方文档明确兼容的最高版本而Druid 1.8则是那个阶段唯一能稳定接入CDH Kerberos认证、支持原生Hadoop Indexing Service且不依赖外部Kafka集群做中间缓冲的OLAP引擎。这不是技术选型是生存适配。这套组合在2020年前后被某大型电商中台团队高频验证过特点是“稳得让人焦虑慢得让人清醒”它不追求最新特性但能扛住日均30TB原始日志、峰值50万事件/秒的写入压力查询P95延迟稳定在800ms以内。今天重走这条路核心价值不在“新”而在“可交付”——当你无法推动整个数据平台升级又必须在三个月内上线实时漏斗分析、实时UV统计、实时异常告警时这套经过千锤百炼的“铁三角”就是最短路径。关键词里没提Kerberos、没提Hive Catalog、没提Parquet分层存储但实操中这三者才是真正的拦路虎。我带过的两个项目里70%的工期消耗在Kerberos跨域认证打通上20%卡在Flink SQL读取Hive表时的ClassLoader冲突剩下10%才是Druid的Segment加载优化。所以这篇不是教你怎么装软件而是告诉你当CDH的krb5.conf和Flink的flink-conf.yaml打架时该砍哪一行配置当Druid的overlord日志里反复打印“Failed to load Hadoop configuration”时你该去翻哪个jar包的MANIFEST.MF。适合谁看三类人第一类是正在维护CDH 6.x的老数据工程师服务器不敢重启、JDK不能升级、连Python都要用系统自带的2.7第二类是接到“必须兼容现有CDH”的临时攻坚任务的Flink开发者对YARN ApplicationMaster的启动参数一知半解第三类是刚接手遗留系统的运维同学看到Druid的historical节点内存占用率92%却不敢调GC参数。如果你属于其中任何一类接下来的内容每一步都踩过坑、验过血。2. 整体架构设计与技术选型逻辑2.1 为什么是CDH 6.2.1而不是CDH 6.3CDH 6.2.1发布于2019年10月是Cloudera最后一个提供完整Apache组件源码补丁包的版本。关键差异在于Hadoop 3.0.0-cdh6.2.1的HDFS Federation实现比6.3更“老实”——它不自动合并多个NameNode的edits log而是严格按namespace隔离。这点在Druid的Hadoop Indexing Service中至关重要当Druid向HDFS提交索引任务时如果Hadoop客户端误将请求路由到非目标NameNode会导致Segment生成失败且错误日志只显示“Connection refused”根本看不出是Federation路由问题。我们曾为这个问题排查了36小时最终发现CDH 6.3.2的hadoop-client-3.0.0-cdh6.3.2.jar里新增了一个DistributedFileSystem#resolvePath()的重写逻辑而Druid 1.8的hadoop-indexing-1.8.0.jar仍基于CDH 6.2.1的Hadoop Client编译二者ClassLoader隔离失效后静态方法调用直接返回null。另一个硬性约束是Java版本。CDH 6.2.1官方支持JDK 8u181而CDH 6.3要求JDK 8u202。很多金融类客户因安全策略锁定JDK 8u192这就把6.3彻底挡在门外。Flink 1.9.1的二进制包编译目标是JDK 8u151与CDH 6.2.1的JDK兼容性窗口完美重叠——这是数学意义上的“最大公约数”。2.2 为什么选Flink 1.9而非1.10或1.11Flink 1.9是第一个正式引入Blink Planner的版本但更重要的是它的State Backend设计。CDH 6.2.1的HDFS默认块大小是128MB而Flink 1.10的RocksDBStateBackend在checkpoint时会生成大量小文件1MB这些文件在HDFS上触发NameNode的INode缓存抖动。我们实测过Flink 1.10.1在CDH 6.2.1上运行72小时后NameNode堆内存从4G涨到12GFull GC频率从1次/天变成1次/小时。而Flink 1.9.1的FsStateBackend基于HDFS的纯文件状态后端虽然恢复速度慢30%但它把所有state序列化成单个文件写入时触发HDFS的append操作而非create完全规避了小文件问题。还有一个常被忽略的细节Flink 1.9.1的YARN模式下ApplicationMaster的JVM参数默认继承NodeManager的配置。CDH 6.2.1的NodeManager默认Xmx2G而Flink AM需要至少3G才能加载Druid的HTTP client依赖。Flink 1.10把这个参数改成了独立配置项但Flink 1.9.1必须手动修改flink-conf.yaml里的yarn.application-master.vcores和yarn.application-master.memory否则AM启动5秒后就OOM退出日志里只有一行java.lang.OutOfMemoryError: Java heap space没有任何堆栈。2.3 为什么是Druid 1.8而不是1.16或2.0Druid 1.8发布于2019年11月是最后一个使用org.apache.hadoop.mapreduce.JobAPI而非org.apache.hadoop.mapred.JobConf的版本。CDH 6.2.1的Hadoop MapReduce Clienthadoop-mapreduce-client-core-3.0.0-cdh6.2.1.jar里Job类的setMapperClass()方法签名是void setMapperClass(Class? extends Mapper)而Druid 1.10升级到Hadoop 3.2后该方法签名变成了void setMapperClass(Class?)。类型擦除导致Flink的ClassLoader在反射调用时抛出NoSuchMethodException错误堆栈藏在Druid的IndexTask日志深处表面现象是“任务提交成功但无任何日志输出”。更实际的考量是资源模型。Druid 1.8的Historical节点采用“Segment粒度内存映射”每个Segment加载时只mmap其数据文件的特定offset范围而Druid 2.0改为“DataSource粒度预加载”会把整个DataSource的所有Segment元数据一次性读入堆内存。在CDH 6.2.1环境下一个包含200个分区的Hive表对应Druid里200个SegmentDruid 1.8的Historical堆内存占用约1.2G而Druid 2.0直接飙到4.8G——这对内存仅16G的CDH Worker节点是不可承受之重。2.4 架构拓扑图与数据流向整个链路不是简单的线性管道而是三层耦合结构底层存储层CDH 6.2.1的HDFS作为统一存储底座存放原始日志/data/raw/、清洗后数据/data/clean/、Druid Segment数据/druid/segments/、Flink Checkpoint/flink/checkpoints/。所有路径必须配置为HDFS URI如hdfs://nameservice1/druid/segments绝对不能用file:///。计算调度层Flink on YARN以Per-Job模式运行每个Flink作业启动独立的YARN ApplicationAM负责向YARN申请TaskManager容器。关键配置是yarn.provided.lib.dirs: hdfs://nameservice1/flink/lib/这个路径必须提前用hdfs dfs -put上传所有Flink依赖jar包括hadoop-client、hive-exec等否则TaskManager启动时会因找不到Hadoop类而报ClassNotFoundException。实时服务层Druid的Overlord节点接收Flink写入的索引任务通过HTTP POST到http://overlord:8090/druid/indexer/v1/taskCoordinator节点协调Segment分发Historical节点从HDFS加载Segment并提供查询服务。Druid不直接消费Kafka而是由Flink作业完成Kafka→HDFS→Druid的转换这是为了绕过Druid原生Kafka Indexing Service对SASL认证的脆弱支持。数据流向有两条主线实时写入流Kafka Topic → Flink DataStream API解析 → 写入HDFS Parquet用于离线备份→ 同时触发Druid IndexTask通过Flink的RichSinkFunction调用Druid REST API元数据同步流Hive Metastore → Flink HiveCatalog读取表结构→ Druid Coordinator通过druid.extensions.loadList[druid-hive]加载Hive元数据插件用于SQL跨源查询这种设计牺牲了端到端延迟增加1~2秒HDFS落盘时间但换来的是99.99%的任务成功率——在CDH 6.2.1环境下网络抖动导致Kafka Consumer Offset提交失败时Flink可以回滚到最近一次Checkpoint而Druid IndexTask则从HDFS重新读取已落盘的数据避免数据丢失。3. 核心组件部署与关键配置详解3.1 CDH 6.2.1环境准备绕过那些“默认就对”的陷阱CDH 6.2.1的安装包本身不包含Kerberos配置向导必须手动补全三个致命文件/etc/krb5.conf重点修正[libdefaults]段的default_realm必须全大写如EXAMPLE.COM且[realms]段的KDC地址必须用FQDN如kdc.example.com不能用IP或短名。我们曾因KDC地址写成10.0.1.100导致Druid Historical节点启动时反复重试Kerberos登录日志里只有GSSException: No valid credentials provided实际是DNS解析失败。/var/run/cloudera-scm-agent/process/*/hadoop-conf/core-site.xml添加propertynamehadoop.security.authentication/namevaluekerberos/value/property并确保fs.defaultFS指向HA nameservice如hdfs://nameservice1而非单点NameNode如hdfs://namenode1:8020。Druid的Hadoop Indexing Service在初始化FileSystem时如果fs.defaultFS是单点地址会忽略hdfs-site.xml里的dfs.ha.namenodes.nameservice1配置导致高可用失效。/var/run/cloudera-scm-agent/process/*/hadoop-conf/hdfs-site.xml必须显式设置propertynamedfs.client.failover.proxy.provider.nameservice1/namevalueorg.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider/value/property。这个配置在CDH 6.2.1的Cloudera Manager界面里没有暴露必须手动追加否则Flink的FsStateBackend在checkpoint时可能连接到Standby NameNode并报错StandbyException。验证Kerberos是否真正生效的命令不是klist而是sudo -u hdfs hdfs dfs -ls /user如果返回ls: Failed on local exception: java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed说明Kerberos票据未正确传递给HDFS客户端——此时要检查/var/run/cloudera-scm-agent/process/*/hadoop-conf/core-site.xml里的hadoop.security.auth_to_local规则确保RULE:[1:$1$0](.*EXAMPLE.COM)s/.*//这行存在且位置在规则列表顶部。3.2 Flink 1.9.1部署YARN模式下的ClassLoader战争Flink 1.9.1的二进制包需做三项手术替换Hadoop Client Jar下载CDH 6.2.1的hadoop-client-3.0.0-cdh6.2.1.jar替换flink/lib/目录下原有的hadoop-client-2.8.3.jar。注意不要删除原jar先重命名备份。替换后执行jar -tf flink/lib/hadoop-client-3.0.0-cdh6.2.1.jar | grep org/apache/hadoop/fs/确认输出包含org/apache/hadoop/fs/FileSystem.class否则说明jar包损坏。注入Hive依赖Flink 1.9.1不内置Hive Catalog支持需手动添加flink-sql-connector-hive-1.9.1.jar和hive-exec-2.3.5-cdh6.2.1.jar。关键技巧是hive-execjar必须放在flink/lib/目录而flink-sql-connector-hive必须放在flink/opt/目录。这是因为Flink的ClassLoader机制中lib/目录的jar由System ClassLoader加载可被YARN AM访问而opt/目录的jar由PluginClassLoader加载仅TaskManager可见。如果放反位置Flink SQL执行CREATE CATALOG myhive WITH (...)时会报ClassNotFoundException: org.apache.flink.table.catalog.hive.HiveCatalog。定制flink-conf.yaml以下是生产环境验证有效的最小配置集# 必须关闭Flink内置的Hadoop配置加载改用CDH的配置 fs.hdfs.hadoopconf: /etc/hadoop/conf # YARN相关防止AM内存不足 yarn.application-master.vcores: 2 yarn.application-master.memory: 3072mb yarn.taskmanager.vcores: 4 yarn.taskmanager.memory: 8192mb # State Backend必须用FsStateBackend禁用RocksDB state.backend: filesystem state.checkpoints.dir: hdfs://nameservice1/flink/checkpoints state.savepoints.dir: hdfs://nameservice1/flink/savepoints # 关键解决CDH Kerberos下HDFS FileSystem缓存污染 fs.hdfs.hdfs-default: /etc/hadoop/conf/hdfs-site.xml fs.hdfs.hdfs-site: /etc/hadoop/conf/hdfs-site.xml特别注意fs.hdfs.hdfs-default和fs.hdfs.hdfs-site这两个参数。Flink 1.9.1的FileSystemFactory在创建HDFS FileSystem实例时会优先读取这两个路径指定的配置文件而不是依赖HADOOP_CONF_DIR环境变量。如果这两个参数未设置Flink会使用内置的Hadoop 2.8.3默认配置导致Kerberos认证失败。3.3 Druid 1.8部署让Overlord听懂Hadoop的方言Druid 1.8的部署难点不在安装而在让它的Hadoop Indexing Service理解CDH 6.2.1的“方言”。核心操作是修改druid/extensions/druid-hadoop-processing/目录下的core-site.xml和hdfs-site.xmlcore-site.xml必须包含以下三行缺一不可property namefs.defaultFS/name valuehdfs://nameservice1/value /property property namehadoop.security.authentication/name valuekerberos/value /property property namehadoop.security.auth_to_local/name valueRULE:[1:$1$0](.*EXAMPLE.COM)s/.*//\nDEFAULT/value /property注意hadoop.security.auth_to_local的值必须是单行字符串\n是换行符不能写成两行。这个规则的作用是把druid/overlord.example.comEXAMPLE.COM转换成druid供HDFS Server端校验。hdfs-site.xml重点配置dfs.namenode.kerberos.principal.patternproperty namedfs.namenode.kerberos.principal.pattern/name value*/value /propertyCDH 6.2.1的NameNode Kerberos Principal格式是nn/_HOSTEXAMPLE.COM而Druid 1.8的Hadoop Client默认只匹配nn/.*EXAMPLE.COM。设为*表示通配所有Principal避免AccessControlException: Authentication failed for nn/standby.example.comEXAMPLE.COM。Druid的JVM参数必须显式指定Kerberos配置export JVM_ARGS-Djava.security.krb5.conf/etc/krb5.conf -Dsun.security.krb5.debugtrue-Dsun.security.krb5.debugtrue是调试神器开启后会在日志里打印完整的Kerberos认证流程包括TGT获取、Service Ticket请求、AP-REQ发送等细节。当出现GSSException: No valid credentials provided时先看debug日志里是否有 KrbCreds found the default ticket granting ticket in cache没有则说明keytab未正确加载。3.4 三组件协同配置让Flink把数据“塞”进DruidFlink写入Druid不是调用SDK而是通过REST API提交IndexTask。关键代码片段如下Scalaclass DruidSinkFunction extends RichSinkFunction[String] { override def open(parameters: Configuration): Unit { // 必须用CDH的Hadoop Configuration初始化FileSystem val conf new Configuration() conf.addResource(new Path(/etc/hadoop/conf/core-site.xml)) conf.addResource(new Path(/etc/hadoop/conf/hdfs-site.xml)) hdfs FileSystem.get(conf) // 这里必须成功否则后续全部失败 } override def invoke(value: String, context: SinkFunction.Context): Unit { // 1. 将JSON写入HDFS临时目录 val outputPath shdfs://nameservice1/tmp/druid/$taskId/${System.currentTimeMillis()} val outputStream hdfs.create(new Path(outputPath)) outputStream.write(value.getBytes(StandardCharsets.UTF_8)) outputStream.close() // 2. 构造Druid IndexTask JSON val taskJson s |{ | type: index_hadoop, | spec: { | dataSchema: { | dataSource: user_behavior, | parser: { | type: string, | parseSpec: { | format: json, | timestampSpec: {column: event_time, format: auto}, | dimensionsSpec: {dimensions: [user_id, page, action]} | } | } | }, | ioConfig: { | type: hadoop, | inputSpec: {type: static, paths: $outputPath} | }, | tuningConfig: {type: hadoop, partitionsSpec: {type: hashed, numShards: 2}} | } |} .stripMargin // 3. 提交到Overlord val response Http(http://overlord:8090/druid/indexer/v1/task) .postData(taskJson) .header(Content-Type, application/json) .asString } }这里埋了三个深坑inputSpec.paths必须是HDFS URIhdfs://...不能是相对路径。Druid的Hadoop Indexing Service会调用new Path(path)如果传入/tmp/xxx它会默认解析为本地文件系统路径。partitionsSpec.numShards不能设为1。Druid 1.8的Hadoop Indexing在单Shard模式下会跳过MapReduce Job提交直接尝试本地处理而CDH 6.2.1的YARN集群不允许本地模式导致任务卡在PENDING状态。timestampSpec.format: auto在CDH环境下必须配合ioConfig.type: hadoop如果误设为indexDruid会尝试用本地JVM解析时间而CDH的Kerberos认证要求所有HDFS操作必须通过FileSystem API导致NullPointerException。4. 实操过程与核心环节实现4.1 端到端数据链路验证从Kafka到Druid查询我们用一个真实场景验证实时统计每分钟的页面点击UV。数据源是Kafka Topicuser_click每条消息为JSON格式{user_id:U1001,page:home,action:click,event_time:2024-03-15T10:30:45.123Z}步骤1在CDH中创建Hive表CREATE DATABASE IF NOT EXISTS realtime; USE realtime; CREATE EXTERNAL TABLE user_click_raw ( user_id STRING, page STRING, action STRING, event_time STRING ) PARTITIONED BY (dt STRING, hour STRING) STORED AS PARQUET LOCATION hdfs://nameservice1/data/raw/user_click/;注意LOCATION必须是HDFS URI且路径需提前用hdfs dfs -mkdir -p创建。步骤2编写Flink SQL作业-- 创建Hive Catalog CREATE CATALOG myhive WITH ( typehive, hive-conf-dir/etc/hadoop/conf, hadoop-conf-dir/etc/hadoop/conf ); USE CATALOG myhive; -- 创建Kafka表 CREATE TABLE kafka_click ( user_id STRING, page STRING, action STRING, event_time STRING, proctime AS PROCTIME() ) WITH ( connector kafka, topic user_click, properties.bootstrap.servers kafka1:9092,kafka2:9092, properties.group.id flink-druid-group, format json, scan.startup.mode latest-offset ); -- 创建Druid维表用于关联 CREATE TABLE druid_uv_dim ( minute STRING, uv BIGINT, PRIMARY KEY (minute) NOT ENFORCED ) WITH ( connector druid, druid-host coordinator:8081, druid-datasource uv_minute_stats ); -- 实时写入HDFS并触发Druid索引 INSERT INTO TABLE realtime.user_click_raw SELECT user_id, page, action, event_time, DATE_FORMAT(TO_TIMESTAMP(event_time), yyyy-MM-dd) as dt, DATE_FORMAT(TO_TIMESTAMP(event_time), HH) as hour FROM kafka_click; -- 同时计算UV并写入Druid通过自定义Sink -- 此处省略Java代码见3.4节步骤3验证Druid索引任务提交Flink作业后立刻检查Overlord UIhttp://overlord:8090/console.html的Tasks页签应看到状态为RUNNING的index_hadoop任务。点击任务ID进入详情页关键字段dataSource:user_behavior与代码中一致inputPaths:hdfs://nameservice1/tmp/druid/...确认是HDFS路径status:SUCCESS不是RUNNING或FAILED如果状态长期为PENDING立即检查Overlord日志中的WARN级别日志搜索No available task slots这表示YARN资源不足需调大yarn.scheduler.maximum-allocation-mb。步骤4Druid查询验证使用Druid Console的Query页签执行Native Query{ queryType: timeseries, dataSource: user_behavior, granularity: minute, aggregations: [{type: count, name: cnt}], intervals: [2024-03-15T10:30:00.000Z/2024-03-15T10:31:00.000Z] }预期返回[ { timestamp: 2024-03-15T10:30:00.000Z, result: {cnt: 142} } ]如果返回空数组检查Historical节点日志中是否有Failed to load segment这通常意味着HDFS路径权限问题——Druid进程用户如druid必须对/druid/segments/目录有读写权限执行sudo -u hdfs hdfs dfs -chown -R druid:hadoop /druid/segments/ sudo -u hdfs hdfs dfs -chmod -R 775 /druid/segments/4.2 性能调优实战把P95延迟从2.1秒压到780毫秒我们实测的瓶颈不在Druid查询而在Flink写入HDFS的吞吐。原始配置下每秒写入1000条记录时P95延迟达2.1秒。优化分三步第一步HDFS写入缓冲优化Flink的FileSystemOutputFormat默认每次write()都触发HDFS flush改为批量flush// 在Flink Sink中 val fs FileSystem.get(new Configuration()) val outputStream fs.create(new Path(hdfsPath), true) outputStream.setWriteMode(CreateWriteMode.APPEND) // 启用追加模式 // 手动控制flush时机 if (recordCount % 1000 0) { outputStream.hflush() // 不是flush()是hflush()强制刷到DataNode }hflush()比flush()多一层保障它确保数据已写入DataNode的OS缓存而flush()只保证写入Client本地缓存。CDH 6.2.1的HDFS客户端在Kerberos环境下flush()经常假成功。第二步Druid Segment分片策略调整Druid 1.8默认按time维度分片导致热点问题。改为按user_id哈希分片tuningConfig: { type: hadoop, partitionsSpec: { type: hashed, targetPartitionSize: 5000000, partitionDimension: user_id } }targetPartitionSize设为500万是因为CDH 6.2.1的HDFS块大小128MB每个Segment数据文件约100MB500万记录刚好填满一个块避免跨块读取。第三步Historical节点JVM调优默认CMS垃圾回收器在CDH 6.2.1的JDK 8u192上表现极差。改为G1GC并精确控制Region大小export JVM_ARGS-XX:UseG1GC -XX:G1HeapRegionSize4M -XX:MaxGCPauseMillis200 -Xms8g -Xmx8gG1HeapRegionSize4M是关键CDH 6.2.1的HDFS Block Size是128MBG1 Region Size必须整除128MB即4M、2M、1M否则G1会退化为Serial GC。实测4M时GC停顿稳定在180ms以内。优化后监控数据指标优化前优化后提升Flink写入P95延迟2100ms320ms84.8%Druid查询P95延迟1100ms780ms29.1%Historical GC频率12次/小时3次/小时75%4.3 安全加固Kerberos跨域认证的终极解法当CDH集群与Druid集群不在同一Kerberos Realm时如CDH在EXAMPLE.COMDruid在DRUID.LOCAL必须配置双向信任。这不是简单加几行配置而是三步手术Step 1在KDC服务器上建立信任关系# 在EXAMPLE.COM的KDC上执行 kadmin.local -q addprinc -e aes256-cts-hmac-sha1-96:normal krbtgt/DRUID.LOCALEXAMPLE.COM kadmin.local -q addprinc -e aes256-cts-hmac-sha1-96:normal krbtgt/EXAMPLE.COMDRUID.LOCAL # 生成keytab kadmin.local -q xst -k /tmp/krb5-druid.keytab krbtgt/DRUID.LOCALEXAMPLE.COM kadmin.local -q xst -k /tmp/krb5-druid.keytab krbtgt/EXAMPLE.COMDRUID.LOCALStep 2在Druid节点配置krb5.conf[realms] EXAMPLE.COM { kdc kdc.example.com admin_server kdc.example.com } DRUID.LOCAL { kdc kdc.druid.local admin_server kdc.druid.local } [domain_realm] .example.com EXAMPLE.COM example.com EXAMPLE.COM .druid.local DRUID.LOCAL druid.local DRUID.LOCALStep 3Druid服务启动时指定Realm# Overlord启动脚本中 export JVM_ARGS-Djava.security.krb5.conf/etc/krb5.conf -Dsun.security.krb5.debugtrue -Ddruid.kerberos.realmEXAMPLE.COM-Ddruid.kerberos.realm参数告诉Druid所有HDFS操作都用EXAMPLE.COMRealm的票据即使当前主机在DRUID.LOCALRealm下。这是绕过Kerberos默认Realm继承机制的唯一方法。验证是否成功查看Overlord日志搜索Acquired Kerberos ticket for principal应看到principaldruid/overlordEXAMPLE.COM而不是druid/overlordDRUID.LOCAL。5. 常见问题与排查技巧实录5.1 典型问题速查表现象根本原因排查命令解决方案Flink作业启动后立即失败日志显示ClassNotFoundException: org.apache.hadoop.fs.FileSystemFlink lib目录缺少CDH的hadoop-client jarls -l flink/lib/ | grep hadoop-client替换为CDH 6.2.1的hadoop-client-3.0.0-cdh6.2.1.jarDruid Overlord UI显示No tasks running但Flink日志显示Task submitted successfullyOverlord未监听HTTP端口或防火墙拦截netstat -tuln | grep 8090curl -v http://localhost:8090/status/health检查overlord/runtime.properties中druid.host是否为0.0.0.0开放8090端口Druid Historical节点内存占用持续增长最终OOMDruid 1.8的Segment加载未释放Direct Memoryjstat -gc pid观察M列Metaspace是否增长在JVM参数中添加-XX:MaxDirectMemorySize2g并重启HistoricalFlink SQL执行SELECT * FROM hive_table报Table not foundHive Catalog未正确加载Hive Metastoresudo -u hive hive -e show databases;检查hive-conf-dir路径下是否存在hive-site.xml且hive.metastore.uris配置正确Druid查询返回No data found但HDFS上Segment文件存在Segment未被Coordinator加载或时间戳超出查询区间curl http://coordinator:8081/druid/coordinator/v1/metadata/datasources/user_behavior检查返回JSON中的segments字段是否为空若为空则执行curl -X POST http://coordinator:8081/druid/coordinator/v1/datasources/user_behavior/interval/2024-03-15T00:00:00.000Z/2024-03-16T00:00:00.000Z/load5.2 那些文档里不会写的避坑技巧技巧1Flink Checkpoint失败时的“急救包”当state.checkpoints.dir指向HDFS且Checkpoint失败时不要急着重启Flink集群。先执行hdfs dfs -ls -R /flink/checkpoints/ | grep -E (\.crc|_metadata) | head -20如果看到大量.crc文件HDFS校验和文件但无_metadata文件说明HDFS写入被中断。此时执行hdfs dfs -rm -r /flink/checkpoints/*然后在Flink Web UI的Savepoints页签中点击Trigger Savepoint选择Cancel job with savepoint。这样能强制Flink从最近一次成功的Savepoint恢复而不是从头开始。技巧2Druid Segment加载卡住的“暴力疗法”当Coordinator日志显示Loading segment xxx for datasource yyy但持续10分钟无进展时不是Segment损坏
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →