0

我正在测试 spring-yarn 集成 API,我对 Yarn 容器定制的最佳实践有点困惑:

1)如果我想使用spring-boot-yarn组合,告诉spring boot选择我的纱线容器实现而不是DefaultYarnContainer的正确方法是什么......我想出的唯一方法是通过容器上的ImportResource注释包含 main 方法的项目类,该方法指向带有声明的 spring 应用程序 xml:

<yarn:container container class="myhadoop.yarn.container.custom.MyContainerImplementation"/>

组件扫描根本不起作用...Spring boot 仍在使用 DefaultYarnContainer...

2)如果我正确理解 Yarn 架构,那么应用程序大师负责启动容器。但是如果我为我的实现更改 DefaultYarnContainer ,那么我需要通过 run 方法手动启动容器,什么都没有启动,请问正确的方法是什么?

非常感谢您的帮助

4

3 回答 3

1

如果 boot 正在对 yarn 容器进行自动配置,则很少有方法可以定义默认为DefaultYarnContainer.

可以从这里找到这个逻辑https://github.com/spring-projects/spring-hadoop/blob/master/spring-yarn/spring-yarn-boot/src/main/java/org/springframework/yarn/启动/YarnContainerAutoConfiguration.java#L107

  1. 在 yml 中使用 spring.yarn.container.containerClass=foo.jee.MyContainer
  2. 将类创建为具有名称的 beanyarnContainerClass
  3. 将您的容器 impl 创建为具有名称的 beanyarnContainerRef
  4. 创建 bean 作为名称customContainerClass,这将是一个作为字符串的类
于 2015-08-22T15:47:20.730 回答
0

您不需要为容器实现所有 bean,只需一个就足够了。

你是对的。我没有注意到 SpringYarnConfig 中的以下方法:

@Override
    public void configure(YarnContainerConfigurer container) throws Exception {
        if (StringUtils.hasText(sycp.getContainerClass())) {
            container
                .containerClass(sycp.getContainerClass());
        } else if (yarnContainerClass != null){
            container
                .containerClass(yarnContainerClass);
        } else if (yarnContainerRef != null) {
            if (yarnContainerRef instanceof YarnContainer) {
                container
                    .containerRef((YarnContainer) yarnContainerRef);
            }
        } else if (StringUtils.hasText(containerClass)) {
            container.containerClass(containerClass);
        }
    }

很明显,一个就足够了……:)

事件发布者和状态监听器的使用实际上是作为构建块的,你需要自己称呼它。

是的,我看到 DefaultYarnContainer 正在处理自己调用的 notifyXXXX 方法(启动容器状态更改)......好吧,我一定会更多地使用它。

珍妮,非常感谢您的帮助。您提供了对 Spring-Yarn 的完美深入了解。

于 2015-08-24T14:21:05.317 回答
0

珍妮,非常感谢!这种方式更加优雅并且有效......这是我所做的:

@EnableAutoConfiguration
@Configuration
@ComponentScan
public class ContainerApplication {

@Autowired
private MyContainerImplementation myContainerImplementation;

@Bean(name="yarnContainerClass")
public Class<? extends YarnContainer> getYarnContainerClass() {
    return MyContainerImplementation.class;
}

@Bean(name="yarnContainerRef")
public MyContainerImplementation getYarnContainerRef() {
    return myContainerImplementation;
}

@Bean(name="customContainerClass")
public String getCustomContainerClass() {
    return "myhadoop.yarn.container.custom.MyContainerImplementation";
}

public static void main(String[] args) {
    SpringApplication.run(ContainerApplication.class, args);
}

}

正如您所指出的,我将 MyContainerImplementation 添加到 yml 中,并且我的容器实现是由应用程序主启动的,而我没有手动运行 run 方法,因为我在 hadoop 日志中看到以下行:

LifecycleObjectSupport:started
myhadoop.yarn.container.custom.MyContainerImplementation@5e2cd950
.
.
LifecycleObjectSupport: stopped
myhadoop.yarn.container.custom.MyContainerImplementation@5e2cd950

无论如何,我还有一个问题。我想测试 ContainerStateListener 和 YarnPublisher 之类的低级纱线,但根本没有调用它们..:-( 这是我的测试自定义容器:

@Component
public class MyContainerImplementation extends AbstractYarnContainer {
private static final Log log =    LogFactory.getLog(MyContainerImplementation.class);

public MyContainerImplementation() {
    super();

    log.info("...Initializing yarn MyContainerImplementation....");

    this.setYarnEventPublisher(new DefaultYarnEventPublisher() {
        @Override
        public void publishContainerAllocated(Object source, Container container) {
            super.publishContainerAllocated(source, container);
            log.info("Yarn container allocated: "+container.getResource().getMemory());
        }
    });

    this.addContainerStateListener(new ContainerStateListener() {

        @Override
        public void state(ContainerState state, Object exit) {
            switch(state) {
                case COMPLETED: {
                    log.info("...Container started successfully!...");
                    break;
                }
                case FAILED: {
                    log.info("...Starting of container failed!...");
                    break;
                }
                default: {
                    log.info("Unexpected container state...exiting!...");
                }
            }
        }
    });
}

public void runInternal() {
    log.info("...Running internal method...");
}

}

我是否需要添加额外的配置才能使 ContainerStateListener 和 YarnPublisher 工作?

于 2015-08-23T20:40:38.233 回答