前阵子接手了一套平台的维护工作,排查一个“任务明明跑完了,但历史日志和运行指标却查不到”的问题。整个排查链走到最后,发现根子出在集群的Timeline Service没配置好。数据压根没上报,UI自然什么都拿不到。这件事之后我又把Timeline Service的整套配置逻辑从头捋了一遍,发现不少人在配这个组件时,要么只开了一个开关,要么把v1和v2混在一起配,最后服务起不来,或者数据时有时无。
这篇文章就把我实际配置Timeline Service(重点在v2,因为生产环境基本都往这个方向走)的过程完整写出来。包含参数怎么选、为什么这么选、启动后怎么验证,以及我踩过的几个非常典型的坑。不论你是刚接触YARN,还是已经在维护集群,这套配置思路应该都能直接用上。
1. Timeline Service 到底在YARN里扮演什么角色
1.1 没有它的时候,排查一个历史任务有多痛苦
先回到问题的起点。假设你的集群跑了几千个作业,某天凌晨一个任务运行失败,你想知道它当时用了多少内存、哪个节点处理的Map任务、有没有发生JVM GC问题。如果没有Timeline Service,你大概能拿到的东西只有ResourceManager(RM)日志中那些碎片化的信息,而且RM日志通常按天滚动,一个任务跨几天跑,日志分散在好几个文件里,翻起来非常麻烦。
更麻烦的是,如果不打开Timeline Service,应用运行完以后,很多细粒度的指标(比如每个阶段的耗时、每个容器的资源使用趋势)是拿不到的。因为通用应用历史(Generic Application History)服务,也就是我们说的Timeline Server,它承担的就是收集、存储和查询应用时间线数据的工作。这里“时间线数据”指的是应用从提交、运行到结束全生命周期的事件记录、运行指标、配置信息等。缺了它,YARN就是一套“只负责调度和监控运行态”的系统,跑完就忘。
所以这个组件存在的意义,不是让你看正在跑的任务,而是让“跑完的任务”留下完整的记录。谁在看这些记录?平台运维、数据工程师、做性能调优的人,以及各类调度系统(比如通过API读取历史运行状态)。
1.2 Timeline Service v1 与 v2 的差异和取舍
这里先理清一个大坑:Timeline Service v1 和 v2 是两套完全不同的实现,配置参数不通用,数据存储也不一样。
v1的完整版本号是v1.5,从Hadoop 2.6开始引入,默认存储使用LevelDB,也可以选文件系统,数据直接落在Timeline Server所在节点。它的优点是配置简单、部署轻量,适合小集群或测试环境。但它有一个非常明显的短板:写入性能弱,并且Timeline Server是单点,一旦节点故障,所有的历史数据就面临丢失风险,还无法通过横向扩展来提升吞吐。
v2是在Hadoop 3.x里成为主推方案的,它把存储层移到了HBase(也可以使用替代实现),通过引入collector(收集器)架构,让每个NodeManager节点上的应用主动汇报数据,再由collector批量写入底层存储。这样写入路径从“应用直连Timeline Server”变成了“应用 -> collector -> 存储”,吞吐能力提升明显,支持多租户隔离,也支持数据按实体分组存储,查询时可以只读元数据表,减少I/O。
很多人问过我:项目里用的是Hadoop 3.3.x,是不是直接配v2就行?我的答案是:如果集群规模超过20个节点,或者你对历史数据的查询频率比较高,直接上v2。如果只是一个几台机器组成的测试集群,配v1.5反而省事,因为不需要额外维护HBase。
不过从实际维护角度看,如果你现在用的是3.x版本,官方文档里已经明确将v1标记为弃用状态,新功能基本只在v2上迭代。长期看,学v2是更值得的投入。
1.3 配置前必须明白的一句话:启用它不只是一个开关
Timeline Service的配置,它在YARN集群里涉及多个角色协同:ResourceManager负责把系统指标发布出来,NodeManager负责起采集器(在v2中称collector),ApplicationMaster需要把应用运行时间线上报出去,Timeline Server负责对外提供查询接口,底层存储(HBase)负责持久化,Web UI负责展示。
这就是为什么你只是把yarn.timeline-service.enabled设成true,然后启动了一个timelineserver进程,发现UI页面还是空白的。因为上游的数据没有被发布出来,下游的查询自然没有内容。配置Timeline Service的本质是打通一条数据流:应用产生数据 -> 被采集器收集 -> 写入存储 -> 对外查询。
2. 动手配置前,一定要确认的三件事
2.1 版本兼容性直接决定配置项能不能被识别
在配置之前,第一件事是确认你当前的环境版本。不同版本对Timeline Service v2的支持程度差别很大,下面这个表是我根据实际使用和维护经验整理的版本情况:
| Hadoop版本 | Timeline Service v1.5 | Timeline Service v2 | 建议 |
|---|---|---|---|
| 2.6 - 2.9 | 支持 | 不支持 | 只能用v1 |
| 3.0 - 3.1 | 支持 | 早期支持,不稳定 | 测试环境可试v2 |
| 3.2+ | 支持 | 稳定支持 | 生产建议v2 |
| 3.4+ | 弃用趋势明显 | 默认推荐 | 直接v2 |
这里有一个很关键的点:v2依赖HBase,但并不是所有Hadoop发行版都自带了HBase集成所需的类。比如某些精简版没有包含hadoop-yarn-server-timelineservice-hbase这个模块的jar包,启动的时候就会报ClassNotFoundException。如果你用的是CDP、HDP这类发行版,一般已经内置;但如果是自己手工从Apache官网下载的二进制包,可能需要确认jar包是否完整。
另外,v2对HBase的版本也有要求。在Hadoop 3.x官方文档里,推荐的HBase版本一般是2.x。我当年第一次配的时候,环境里的HBase还是1.x,结果Timeline Server启动过程不报错,但数据写入的时候总是失败。排查了半天才发现是HBase的写入API不兼容,换成HBase 2.0以后就正常了。
2.2 Timeline Service 的配置到底写在哪个文件里
很多人会把所有配置一股脑地塞进yarn-site.xml,这本身没错,但你要知道它是集群级别的配置。每个节点上的$HADOOP_HOME/etc/hadoop/yarn-site.xml都会被读取,因此你需要在所有YARN节点上都同步更新这个文件。
具体来说,Timeline Server所在的节点、ResourceManager节点、NodeManager节点都需要加载相关配置。特别是Timeline Server的hostname配置,它会以多种形式被RM和NM读取,用来做地址发现。如果只有Timeline Server节点改了hostname,其他节点还是旧的,那RM把数据发布到Timeline的时候就会报连接失败。
除了yarn-site.xml,如果你的环境里开启了Kerberos认证,还需要在core-site.xml里配置principal和keytab信息。在非安全集群里可以跳过这一步,但一旦上了Kerberos,Timeline Server的principal格式通常是timeline/_HOST@REALM.COM,并且需要给对应的keytab文件配置好读取权限。
2.3 存储选型:你的集群适合哪种数据保留策略
存储层选型直接决定了数据保留策略和查询效率。
如果使用v1,数据默认存在LevelDB,是嵌入式的单机存储,每条记录的键都是时间线事件的ID。它的优点是部署简单、无需外部依赖,但数据只能落在单一节点,空间上限受限于该节点磁盘大小,无法扩展。
如果使用v2,存储走HBase。数据虽然最终都存在HBase表里,但Timeline Service会按“用户-集群-流-运行”这样的层级来组织数据。每个应用的一次运行形成一条flow run,一个flow的多次运行可以通过指标和事件进行比较分析。这种组织方式有一个好处:查询某个用户最近一周所有运行过的作业,比在文件日志里翻要快得多。
那么HBase的region大小、预分区策略、WAL独立设置这些参数,都会间接影响Timeline Service的写入和查询性能。我的建议是,在配置前期就给HBase预留足够大的堆内存和合理的压缩策略。比如对时间线数据启用Snappy压缩,能显著减少存储占用,尤其是JobHistory数据量比较大的集群。
3. Timeline Service v2 完整配置实现
3.1 打开服务并配置基础地址
现在进入真正的配置环节。我会以Hadoop 3.x + HBase 2.x,使用Timeline Service v2为例,给出完整的yarn-site.xml配置片段,并逐个解释参数。
<configuration> <property> <name>yarn.timeline-service.enabled</name> <value>true</value> </property> <property> <name>yarn.timeline-service.hostname</name> <value>timeline-host</value> </property> <property> <name>yarn.timeline-service.address</name> <value>timeline-host:10200</value> </property> <property> <name>yarn.timeline-service.webapp.address</name> <value>timeline-host:8188</value> </property> <property> <name>yarn.timeline-service.webapp.https.address</name> <value>timeline-host:8190</value> </property> </configuration>yarn.timeline-service.enabled不用多说,总开关。置为true以后,各个节点上的Timeline相关组件(比如NodeManager中的collector)才会被激活。
yarn.timeline-service.hostname是核心中的核心,官方要求必须配置,并且所有节点都指向同一个主机名。这里建议直接使用内网可解析的域名,不要用IP,避免后续做主机名替换或者HA切换的时候出现匹配问题。
接着是三个地址配置。yarn.timeline-service.address是Timeline Server对外提供RPC服务的地址,默认端口10200。webapp.address是Web UI的HTTP访问地址,默认8188。如果你开启了HTTPS,还需要配置webapp.https.address,默认8190。
这里有个小细节:如果只配置yarn.timeline-service.hostname,其实RPC地址和Web地址会自动套用默认端口生成,但我在实际配置时还是习惯显式写出来。原因有两个:一是方便其他团队按文档去对接端口,二是防止某些发行版默认端口被改掉后排查混乱。
3.2 配置ResourceManager的指标发布器
Timeline Service本身不会自动抓取数据,它需要上游把数据送过来。在YARN中,ResourceManager有一个系统指标发布器(System Metrics Publisher),它负责把RM层面的系统指标(比如集群可用资源、队列负载、应用提交数等)发布给Timeline Service,配置如下:
<property> <name>yarn.resourcemanager.system-metrics-publisher.enabled</name> <value>true</value> </property>必须把这个开关打开,打开之后RM才会在应用提交、运行、完成等各个阶段向Timeline Service发送事件。这个开关如果不开,你在Timeline Service的界面上能看到应用列表,但点进去没有任何指标数据,或者干脆连应用列表都没有。
这个问题是非常隐蔽的启动配置陷阱。我见过很多人在集群上配好了Timeline Server,启动了进程,但界面上什么都没有,排查一圈发现问题就出在这个开关上。
另外,如果环境启用了分层队列(Capacity Scheduler或Fair Scheduler的复杂队列配置),还有一个相关的参数是yarn.resourcemanager.system-metrics-publisher.queue-metrics-size,它控制队列指标发布的最大数量。默认值1000,如果你的集群队列数非常多(比如超过1000),建议按实际队列数量上调,否则部分队列的指标不会被发布。
3.3 配置v2的读写器与HBase集成
这是Timeline Service v2与v1最本质的区别:读写器类变了。
v2的写入数据不再直接由Timeline Server写LevelDB,而是通过collector收集后交给Writer实现类。Reader实现类则负责从存储层读取数据对外提供查询。以下是v2在HBase上的典型配置:
<property> <name>yarn.timeline-service.writer.class</name> <value>org.apache.hadoop.yarn.server.timelineservice.storage.HBaseTimelineWriterImpl</value> </property> <property> <name>yarn.timeline-service.reader.class</name> <value>org.apache.hadoop.yarn.server.timelineservice.storage.HBaseTimelineReaderImpl</value> </property> <property> <name>yarn.timeline-service.use-multitenant-hbase</name> <value>false</value> </property> <property> <name>yarn.timeline-service.hbase-schema.prefix</name> <value>yarn</value> </property> <property> <name>yarn.timeline-service.hbase-schema-scan</name> <value>true</value> </property>这里有几个容易混淆的点,逐个说清楚。
yarn.timeline-service.writer.class决定了数据落库的机制。HBaseTimelineWriterImpl意味着写入是异步批量提交的。它会把accumulated数据按表分桶,在满足一定条件(比如累积到一定条数或者时间窗口到期)时统一写入HBase。这一点对性能影响很大,因为如果每条事件都单独提交,HBase的RegionServer会被频繁刷写,性能下降非常明显。
yarn.timeline-service.use-multitenant-hbase的含义是:是否使用多租户HBase。在默认的单租户模式下,Timeline Service会使用一个默认的HBase命名空间,所有用户的时间线数据都在里面。如果改为true,Timeline Service会按照用户维度在HBase中做数据隔离,适合那种一个HBase集群被多个业务团队共享的场景。
hbase-schema.prefix是表名前缀,默认可以留空。如果你在同一套HBase集群里既跑了业务数据,又跑了Timeline数据,建议设置一个前缀,比如yarn,这样可以避免表名冲突,也方便统一管理。
hbase-schema-scan设为true时,Timeline Service在启动时会对HBase中的所有表做一次schema扫描,创建缺失的表结构。这个开关在首次部署时非常有用,能自动建表,不用手工跑到HBase shell里执行建表语句。但要注意,如果HBase用户权限不足,扫描或建表操作会失败,服务启动就会中断。
3.4 配置collector相关参数,保证写入路径畅通
v2架构中,collector起着缓冲和转发的作用。每个NodeManager上运行着若干应用的collector,应用把时间线数据发给collector,collector再批量发送给Writer。如果collector的参数配置不当,很容易导致数据丢失或写入延迟。
<property> <name>yarn.timeline-service.collector-manager-apps-max-retries</name> <value>1</value> </property> <property> <name>yarn.timeline-service.timeline-client-max-retries</name> <value>2</value> </property> <property> <name>yarn.timeline-service.client.max-retries</name> <value>2</value> </property> <property> <name>yarn.timeline-service.client.retry-interval-ms</name> <value>1000</value> </property>这几个参数都是关于重试的。collector-manager-apps-max-retries表示collector manager在把应用分配给collector时的最大重试次数。timeline-client-max-retries是Timeline客户端在发数据失败后的重试次数。client.max-retries和client.retry-interval-ms是通用客户端参数,分别控制重试总次数和每次重试之间的间隔。
在实际调整中,我通常保留默认值,除非遇到下面这类问题:集群存在频繁的节点重启或网络闪断,此时可以适当增加重试次数。但也不要无限增加,因为重试会占用应用线程资源,延迟较高的环境中,过多的重试反而会拖垮应用的性能。
3.5 配置容器与NodeManager侧的数据收集
除了collector相关参数,还需要确保NodeManager能把运行在其上的容器指标发出去。YARN中有一个参数专门控制NodeManager侧“容器级别”的事件发布:
<property> <name>yarn.nodemanager.timeline-service.enabled</name> <value>true</value> </property>这个开关默认跟随yarn.timeline-service.enabled,但某些发行版中独立配置。最直接的验证方法:在NodeManager的日志里搜索TimelineService关键字,如果能搜到collector初始化成功的记录,说明NM侧已经启用了。
同时,如果你想从运行中的容器里获取更细粒度的资源使用监控数据(比如CPU使用率、物理内存使用量),还需要开启容器资源监控。相关参数位于yarn.nodemanager.container-monitor.procfs-tree.smaps-based-rss.enabled等,这一组参数主要影响LinuxContainerExecutor下的资源计算,不直接属于Timeline Service,但它决定了Timeline UI里能展示哪些资源曲线,所以有需要的话一并打开。
3.6 启动服务并验证是否真正生效
配置完成后,需要在所有节点上同步配置文件,然后按顺序启动HBase(如果还没启动)、Timeline Server,最后重启ResourceManager和NodeManager。
启动Timeline Server的命令:
$HADOOP_HOME/sbin/yarn-daemon.sh start timelineserver启动后先看进程是否存活:
ps -ef | grep TimelineService然后查看日志,重点确认没有抛出异常。日志路径通常在$HADOOP_HOME/logs/yarn-<user>-timelineserver-<hostname>.log,搜索关键字HBaseTimelineWriterImpl和schema,确认建表是否成功。
接着打开Web UI,地址是http://timeline-host:8188。如果页面能正常打开,说明服务在HTTP层是通的。但页面打开不等于数据链路是通的,还需要验证数据是否能写入。
最直接的方法:提交一个测试任务(比如运行一个MapReduce作业),跑完后在Timeline UI中刷新页面,看看能否看到该应用的记录。如果能看到,说明数据链路是通的。如果看不到,用下面的命令手动也是可以查到Timeline数据的,但实际维护中更多是直接看日志确认。看日志时重点关注yarn.timeline-service相关字符,如果出现WARN级别且内容是“Failed to put the entity”,说明数据写入存储层时出了问题。
提示:如果部署了Kerberos认证,启动Timeline Server时需要先执行
kinit -kt <keytab文件>,保证当前账号具有访问HBase的权限。
4. 配置过程中踩过的坑与排查实录
4.1 服务启动不了,日志只提示“Failed to load schema”
我在某次配置中遇到过Timeline Server启动后半分钟自动退出,日志里出现了org.apache.hadoop.yarn.server.timelineservice.storage.TimelineSchemaCreator相关的报错,导致找不到yarn前缀的HBase表。
排查过程是这样的:先用hbase shell list确认了指定的HBase服务正常且可以连通,接着再用hbase shell尝试手工建表,发现当前系统用户根本进不去HBase,因为连接HBase时使用的认证用户不是我预期中的运维账号,而是另一个权限极低的账号。原因是项目环境里同时配置了HBASE_MANAGES_ZK=false,并且HBase依赖外部的ZooKeeper,而Timeline Server启动时使用的ZK连接字符串跟我手动的HBase客户端不一致,导致连到了一个错误实例上。
最终解决方法是,在hbase-site.xml中显式指定了ZooKeeper地址,并且把该配置放到了Timeline Server运行的classpath里,同时确保Timeline Server启动用户对HBase具备建表、写数据的权限。这类问题排查起来非常耗时间,但根因往往就是认证或ZooKeeper指向不一致。
4.2 历史任务在UI里看不到,但服务正常
有段时间,Timeline Server的Web UI能打开,应用列表却是空的。提交了任务,RM日志里能搜到事件发布记录,Timeline服务日志也正常。
按照数据流向逐步排查:应用提交后,RM会向Timeline服务发布“应用提交”事件,数据先进入Timeline存储层,再通过查询接口读取。所以问题出在数据读取或访问权限上。后来发现,是因为我用了一个查询时代理(Proxy)用户的配置项没有设置好,前端页面在请求Timeline数据时携带的ACL没有匹配到对应用户的访问权限。
这类问题并不罕见。在开启ACL的集群中,Timeline Service有一组独立的访问控制参数,它们和YARN的ACL不共用,需要在yarn-site.xml单独配置:
<property> <name>yarn.timeline-service.allow-cross-platform-query</name> <value>true</value> </property>设置了允许跨平台查询后,解决了一部分问题。但如果你用的代理用户访问Timeline,还需要配置Timeline Service的view ACL。具体参数是以yarn.timeline-service.view.acl开头的一组ACL配置。如果不设置,默认只有发起任务的用户能看。
4.3 频繁GC导致写入性能直线下降
Timeline Service v2的写入性能严重依赖HBase的写入路径。如果你的HBase RegionServer经常Full GC,那么时间线数据的写入延迟会大幅上升,最终反馈到前端就是:任务运行完,历史详情十几分钟都刷不出来。
这个问题我在HBase层面调过很多参数,最后的组合是三条:
第一,调整HBase内存比例。RegionServer的堆内存里面,hfile.block.cache.size和memstore.size两个参数需要根据实际数据模式调整。时间线数据写入多、读相对少,所以我适当调大了memstore.size,减小了block cache。
第二,开启WAL独立配置。如果你的时间线数据对丢失容忍度比较低,不要关WAL;但如果你只是用Timeline做趋势分析和后期审计,可以适当缩短WAL同步策略,比如配置hbase.regionserver.optionallogflushinterval。
第三,对时间线表开启压缩并做预分区。HBase的表在自动分区时,默认初始只有一个region,高并发写入会造成热点。给时间线表手动做预分区后,写入压力会被分散到多个region上,写入吞吐能提升不少。
4.4 数据保留时间不对,查旧数据总是失败
Timeline Service v2本身没有默认的“数据过期时间”概念,因为数据存储在HBase里,什么时候清数据取决于HBase的TTL设置。很多人配置完以后没设置TTL,结果发现一年前的任务数据还在,集群磁盘告警。另一些人设置了TTL,却发现几个月前的记录忽然查不到了,调度平台的审计报表无法生成。
这里我的做法是:在初始化时间线表结构时,手工为对应的表加上TTL,而不是依赖Timeline默认的策略。实际操作时,在HBase shell中针对时间线表执行:
alter 'yarn:timeline.entity', CONFIG => { 'hbase.hregion.memstore.flush.size' => '268435456' }同时还可以单独设置TTL:
alter 'yarn:timeline.entity',{NAME => 'v1', TTL => '604800000'}TTL单位是毫秒,604800000是7天。设置完之后,屯了半年的历史数据会被自动清理掉,查询响应速度明显好转。有一点要特别提醒:TTL是按存储单元(cell)级别生效的,不是按表整体。不同列族的TTL可以不同,如果你只想保留事件指标、不保留原始事件内容,可以给不同列族分别设置不同的TTL值。
4.5 安全模式下Timeline Server反复认证失败
在开启Kerberos的集群里,Timeline Server的认证失败是最常见的配置障碍。比如启动日志中提示javax.security.auth.login.LoginException: Unable to obtain password from user,这时候首先要确认keytab文件路径正确,并且权限只对运行Timeline Server的用户可读。
接下来要确认core-site.xml中关于hadoop.proxyuser.timeline.hosts和hadoop.proxyuser.timeline.groups的配置没有被遗漏。因为在安全模式下,Timeline Server经常要扮演代理角色去访问HBase或HDFS,如果代理权限没给够,时不时就会出现读取失败。
我最终在项目里使用了一个通用做法:在需要访问HBase的机器上单独创建一个存放keytab的目录,并设置定时任务,每小时刷新一次票据缓存,避免长时间运行后票据过期导致服务静默失联。
5. 配置完之后的调优思路与落地建议
5.1 写入路径上的参数协同调整
Timeline Service的写入链路是应用 -> NM上的collector -> Timeline Writer -> HBase。这条链路里任何一个环节出瓶颈,表现都是“数据不出现”或“数据延迟出现”。
优先应该关注的是collector侧的批量聚合参数。collector不会每收到一条事件就立刻写HBase,而是积攒一批后再写。如果积攒的批尺寸太小(默认情况下和HBase客户端的缓冲区设置有关),写入频率会非常高;如果积攒得太大,又会导致内存占用过高。我的习惯是根据节点上同时运行的并发容器数量来微调,让批大小维持在几百条量级。
另一个容易被忽略的参数是HBase客户端的写入缓冲区大小,它通常由hbase.client.write.buffer控制。时间线数据一多,写缓冲区如果过小,会频繁触发强制flush。该参数位于HBase客户端配置中,Timeline Server进程启动时也会读取。建议在Timeline Server所在节点额外配置一个hbase-site.xml,并把这个值设到8MB以上。
5.2 查询场景的读路径优化
完成配置之后,还需要考虑查询端的体验。Timeline Service的对外查询接口虽然是REST风格,但底层的读取其实会涉及到HBase的多表关联和过滤。如果你的查询模式是“按用户名 + 时间段查所有流”,那么建议设置yarn.timeline-service.entity-group-fs-store.cache-store-size等相关缓存参数,增大缓存上限。
我在生产环境里观察到,当同一个用户的运行记录非常多时,Timeline UI里“查看该用户全部运行”的请求耗时会明显增加。根因是HBase需要扫全表,再在内存里做过滤。此时除了给HBase加索引,另一个最简单的办法是把数据的保留窗口缩短,比如保留30天或90天。保留时间太短影响审计,太长影响查询,这个平衡需要根据业务实际情况调整。
5.3 一套可以直接参考的配置模板
把上面的配置串在一起,整理出一份可以直接参考的yarn-site.xml模板片段,不含HTTPS和Kerberos,适合非安全环境:
<property> <name>yarn.timeline-service.enabled</name> <value>true</value> </property> <property> <name>yarn.timeline-service.hostname</name> <value>timeline-host</value> </property> <property> <name>yarn.timeline-service.address</name> <value>timeline-host:10200</value> </property> <property> <name>yarn.timeline-service.webapp.address</name> <value>timeline-host:8188</value> </property> <property> <name>yarn.resourcemanager.system-metrics-publisher.enabled</name> <value>true</value> </property> <property> <name>yarn.timeline-service.writer.class</name> <value>org.apache.hadoop.yarn.server.timelineservice.storage.HBaseTimelineWriterImpl</value> </property> <property> <name>yarn.timeline-service.reader.class</name> <value>org.apache.hadoop.yarn.server.timelineservice.storage.HBaseTimelineReaderImpl</value> </property> <property> <name>yarn.timeline-service.use-multitenant-hbase</name> <value>false</value> </property> <property> <name>yarn.timeline-service.hbase-schema.prefix</name> <value>yarn</value> </property> <property> <name>yarn.timeline-service.hbase-schema-scan</name> <value>true</value> </property> <property> <name>yarn.nodemanager.timeline-service.enabled</name> <value>true</value> </property> <property> <name>yarn.timeline-service.allow-cross-platform-query</name> <value>true</value> </property>这份模板只覆盖了基础可用性。真正上线的时候,还需要把HTTPS、Kerberos、ACL、HBase TTL、collector重试机制逐个补全。把它们加进来以后才能算是一份完整的生产配置。
5.4 上线后的周期性验证方法
配置完成并不代表一劳永逸,我强烈建议把Timeline Service的健康检查纳入日常巡检。每次重启集群后,至少要确认以下几点:Timeline Server进程是否存在、HBase里时间线表是否完整、提交一个测试任务后事件是否在UI中展示。
如果巡检中发现Timeline UI偶尔能打开、偶尔打不开,大概率是负载过高或者某些节点的DNS解析问题。用curl直接请求Timeline Server的REST接口可以快速定位。接口路径形如/ws/v2/timeline/apps/{app-id},具体路径根据版本略有差异,但思路一致:绕过UI直接查数据,能定位问题出在前端还是后端。
注意:Timeline Service的数据链路比较长,任何一次故障都可能造成“任务跑完但看不见历史”的情况。不要只依赖页面显示,至少要能在命令行用REST API验证数据存在。
6. 一次维护实操带来的体会
整套Timeline Service配置下来,我最大的感触是:它并不会让你的集群“跑得更快”,但它决定了集群“记得什么、能回忆什么”。很多平台级的能力,比如任务历史回溯、资源使用趋势分析、发布后的暂存诊断,都建立在Timeline Service数据完整的基础上。
实操中还有一个非常实用的小技巧:在配置完Timeline Service v2之后,我习惯专门在调度系统里加一个“每日巡检作业”,它的功能很简单:读取前一整天某个固定用户名下的应用运行列表,如果数量为0或者缺少特定应用ID,就触发告警。这么做的原因很现实:Timeline Service的数据断流不一定会导致服务不可用,它往往是静默发生的,等到真的要用数据时才发现回溯窗口已经错过了,那才是最被动的时刻。
如果你现在正准备给集群配置Timeline Service,我建议先从v2的完整链路跑通开始,别嫌HBase依赖重。先把数据流打通,再逐步叠加ACL、TLS、TTL这些进阶配置。一条走得通的基础链路,比一堆看似正确的参数配置更有价值。