YARN提交的job超过1万个后,会出现一系列的REST API的问题和RM UI 的显示问题,例如:在RM UI 上值能看到第9999个job的状态信息,之后的信息看不到了。
YARN的默认保存数量是10000个,所以解决方法有两种:
1、加大保存数量。
2、删除以前的job数据。
先说第一种办法:
在翻看YARN RM 这部分源码中的RMAppManager类中有了发现,这个类是管理资源管理器的应用程序列表的。
在这个类中有两个变量,maxCompletedAppsInMemory和maxCompletedAppsInStateStore。注释解释为
maxCompletedAppsInMemory:The maximum number of completed applications RM keeps.(在内存中RM完成应用程序的最大数量。)
maxCompletedAppsInStateStore:The maximum number of completed applications RM state store keeps, by default equals to DEFAULT_RM_MAX_COMPLETED_APPLICATIONS(完成应用程序的最大数量的RM状态存储,默认情况下等于DEFAULT_RM_MAX_COMPLETED_APPLICATIONS)
当第二个变量大于第一个变量时,在构造方法中maxCompletedAppsInMemory会被初始化等于maxCompletedAppsInStateStore。
第一个变量的可以在官网的yarn-default.xml中找到(yarn.resourcemanager.max-completed-applications)。
第二个变量是直接写在了YarnConfiguration中,我们可以添加自定义属性来修改(yarn.resourcemanager.state-store.max-completed-applications)
改完后重启,新添加的job会从1开始,但是已经可以保存和查看job的数量超过1万了
再来说说第二种方法,删除job的history数据
yarn resourcemanager 的源码中,存储job信息的父类RMStateStore是抽象类,而继承了RMStateStore类的有好几个。
分别是:FileSystemRMStateStore.java、LeveldbRMStateStore.java、MemoryRMStateStore.java、ZKRMStateStore.java,这四个实现类分别把job的history数据
存储在了HDFS、leveldb数据库、内存、zookeeper中。你可以查看yarn.resourcemanager.store.class配置来看yarn的jobhistory数据存放在哪。
下面以ZKRMStateStore为例,说说怎么删除删除job的history数据。
在代码的注释中给出的存储目录结构为
/**
*
* ROOT_DIR_PATH
* |--- VERSION_INFO
* |--- EPOCH_NODE
* |--- RM_ZK_FENCING_LOCK
* |--- RM_APP_ROOT
* | |----- (#ApplicationId1)
* | | |----- (#ApplicationAttemptIds)
* | |
* | |----- (#ApplicationId2)
* | | |----- (#ApplicationAttemptIds)
* | ....
* |
* |--- RM_DT_SECRET_MANAGER_ROOT
* |----- RM_DT_SEQUENTIAL_NUMBER_ZNODE_NAME
* |----- RM_DELEGATION_TOKENS_ROOT_ZNODE_NAME
* | |----- Token_1
* | |----- Token_2
* | ....
* |
* |----- RM_DT_MASTER_KEYS_ROOT_ZNODE_NAME
* | |----- Key_1
* | |----- Key_2
* ....
* |--- AMRMTOKEN_SECRET_MANAGER_ROOT
* |----- currentMasterKey
* |----- nextMasterKey
*
*/
private String zkRootNodePath;
所以只需要删除RM_APP_ROOT目录下问app路径就可以了
我写了一段简单的删除demo
/**
* 例如储目录为:/rmstore/ZKRMStateRoot/RMAppRoot/application_1499049246164_2131/
* 我要删除1到2131的数据
* path:/rmstore/ZKRMStateRoot/RMAppRoot/
* appPrefix:application_1499049246164_
* begin:1
* end:2131
*
* @param path 存储的根目录
* @param appPrefix app名字前缀(包括第二个斜杠)
* @param begin job名字最后那个数字
* @param end job名字最后那个数字
*/
public void deleteJobHistoryData(String path, String appPrefix,Integer begin, Integer end){
IZkClient zkClient = new ZkClient("bigdata3:2181,bigdata1:2181,bigdata2:2181");
for(int i=begin; i<=end; i++){
String id = String.format("%04d",i);
String deletePath = path+appPrefix+id;
boolean b = zkClient.deleteRecursive(deletePath);
if(b){
System.out.println("删除成功===>目录:"+deletePath);
}else{
System.out.println("删除失败===>目录:"+deletePath);
}
}
System.out.println("job History数据清楚完毕!");
}
POM依赖
<properties>
<zkclient.version>2.1.1</zkclient.version>
<zookeeper.version>3.4.6</zookeeper.version>
<log4j.version>1.7.21</log4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<dependency>
<groupId>com.github.adyliu</groupId>
<artifactId>zkclient</artifactId>
<version>${zkclient.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
转载请注明出处: http://www.julyme.com/20170703/89.html
打赏一个呗~~(微信)
Julyme
感觉还行吧。
Julyme的IT技术分享
abc 2017-08-09
赞