on Yarn 程序都需要将 lib下的jar和代码jar 上传到 HDFS,在启动App前下载资源到本地,这一些列的操作很耗时
该如何节省程序启动时间?
本地化:将远程资源复制/下载到本地文件系统的过程。不再总是远程访问资源,而是将其复制到本地计算机,然后可以在本地访问该计算机。
本地资源:表示运行容器所需的文件/库。NodeManager
负责在启动容器之前对资源进行本地化。对于每个LocalResource,应用程序可以指定:
- URL:下载本地资源的远程位置
- Size:资源大小
- 容器启动前远程文件系统上资源的最后修改时间戳
- LocalResourceType:指定资源类型 - File、Archive、Pattern
- Pattern:应用于从存档中提取条目的模式(仅当类型为Pattern时使用)
- LocalResourceVisibility:指定节点管理器本地化的资源的可见性。可见性可以是
- PUBLIC:程序结束不会删除资源,本地磁盘满/yarn.nodemanager.localizer.cache.target-size-mb 才删除
- PRIVATE:同PUBLIC
- APPLICATION:程序结束立即删除
ResourceLocalizationService:NodeManager 内部的服务,负责安全下载
和组织容器所需的各种文件资源。将文件分发到所有可用磁盘上,对下载的文件实施访问控制限制,并对其设置适当的使用限制。
DeletionService:NodeManager 内部运行的一种服务,在接到指示时删除本地路径。
Localizer:执行本地化的实际线程或进程
- PublicLocalizer:用于公共资源
- ContainerLocalizer:用于私有资源和应用程序资源
LocalCache: NodeManager 维护和管理所有下载文件的服务器本地缓存。资源是根据复制该文件时最初使用的远程url唯一标识
如何实现本地化
PUBLIC资源本地化
NodeManager 的 PublicLocalizers
线程负责
- yarn.nodemanager.localizer.fetch.thread-count :PublicLocalizers线程数
- 远程资源的权限必须是 PUBLIC
PRIVATE/APPLICATION 资源本地化
不在NodeManager 中运行
- 本地化在 ContainerLocalizer 中运行
- 每个
ContainerLocalizer
进程由NodeManager中的LocalizerRunner
单个线程管理 LocalResourcesTracker
是每个用户/应用程序对象,它跟踪给定用户/应用程序的所有LocalResources- 当需要请求资源时,将资源添加到
LocalizerRunner
的 pending-resources队列 LocalizerRunner
启动LinuxContainerExecutor(LCE)(作为应用程序提交者运行的进程),然后执行ContainerLocalizer
下载这些资源ContainerLocalizer
与 NodeManager进程心跳- 心跳交互时,
LocalizerRunner
会给ContainerLocalizer
下载资源地址,或者停止ContainerLocalizer
;ContainerLocalizer
给LocalizerRunner
文件下载状态 - 如果资源下载失败,该资源将从
LocalResourcesTracker
中删除,容器最终将标记为失败。发生这种情况时,LocalizerRunners
停止ContainerLocalizers
并退出 - 如果下载成功,
LocalizerRunner
继续给ContainerLocalizer
其他资源,直到全部下载完成
本地资源的目录
在NodeManager机器上,LocalResources 最终被本地化到以下目录
- PUBLIC:
<local-dir> /filecache
- PRIVATE:
<local-dir>/usercache//filecache
- APPLICATION:
<local-dir>/usercache//appcache/<app-id>/
yarn-site.xml 配置文件可以修改目录
- yarn.nodemanager.local-dirs: 逗号分隔的本地目录列表,可以将其配置为在本地化过程中用于复制文件。允许多个目录背后的想法是使用多个磁盘进行本地化—这有助于故障转移(一个/几个磁盘坏了不会影响所有容器)和负载平衡(没有一个磁盘受到写操作的限制)。因此,如果可能,应在不同的本地磁盘上配置各个目录
- yarn.nodemanager.local-cache.max-files-per-directory: 限制将在每个本地化目录中本地化的最大文件数(分别针对PUBLIC/PRIVATE/APPLICATION资源)。其默认值为8192,通常不应分配较大的值(配置一个足够小于基础文件系统(例如ext3)的每个目录最大文件限制的值)。
- yarn.nodemanager.localizer.address: ResourceLocalizationService
- yarn.nodemanager.localizer.client.thread-count: 限制 ResourceLocalizationService 中用于处理来自本地化程序的本地化请求的RPC线程数。默认值为5,这意味着默认情况下,在任何时间点,只有5个本地化程序(Container)将被处理,而其他本地化程序将在RPC队列中等待。
- yarn.nodemanager.localizer.fetch.thread-count: 配置用于本地化PUBLIC 资源的线程数。回想一下,PUBLIC资源的本地化发生在NodeManager地址空间内,因此此属性限制了NodeManager内为PUBLIC 资源本地化生成的线程数量。默认值为4。
- yarn.nodemanager.delete.thread-count: 控制DeletionService 用于删除文件的线程数。DeletionUser在整个NodeManager中用于删除日志文件和本地缓存文件。默认值为4。
- yarn.nodemanager.localizer.cache.target-size-mb: 这决定了用于本地化资源的最大磁盘空间。一旦缓存的总磁盘大小超过此值,删除服务将尝试删除任何正在运行的容器未使用的文件。目前,用户缓存/公共缓存/私有缓存没有限制。此限制适用于所有磁盘,但不基于每个磁盘。
- yarn.nodemanager.localizer.cache.cleanup.interval-ms: 如果总缓存大小超过配置的最大大小,则资源本地化服务将尝试删除未使用的资源。未使用的资源是指未被任何正在运行的容器引用的资源。每次容器请求资源时,容器都会添加到资源的引用列表中。它将一直保留在那里,直到容器完成,以避免意外删除此资源。作为容器资源清理的一部分(当容器完成时),容器将从资源的引用列表中删除。这就是为什么当引用计数降至零时,它是删除的理想候选对象。将基于LRU删除资源,直到当前缓存大小降至目标大小以下。