YARN的job超过1万个后的优化

hadoop

2017-07-03

4103

1

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技术分享



/sitemap