首页 > 解决方案 > 可以在 Hadoop 集群的 Map Task 中启动特定进程吗?

问题描述

我使用带有一个节点的 Hadoop 和 YARN 集群。所有 hadoop 和 yarn 守护进程都在此节点中启动。我还使用 Apache Nutch 1.15 分布式爬网启动了一个获取步骤,成功完成了注入和生成步骤。

我正在尝试使用 Selenium 3.149.54 FirefoxDriver 在 YarnChild 容器上运行的地图任务中运行 Firefox 浏览器。Firefox 进程启动,但弹出一个窗口,提示Firefox 配置文件丢失或无法访问,并且地图任务被阻止,直到我关闭窗口。

Selenium 3.141.54 FirefoxDriver 使用 geckodriver 启动 Firefox,并且从容器用户日志的 stderr 日志中的 geckodriver 输出中,我看到它尝试使用以下命令运行 Firefox:

1557726792743   mozrunner::runner   INFO    Running command: "/usr/bin/firefox" "-marionette" "-profile" "/tmp/rust_mozprofile.0dQXae46ZwUd" "-foreground" "-no-remote" 

我注意到,如果我错了,请纠正我,是在地图任务中,我可以从主机本地文件系统访问二进制文件,例如 /usr/bin/firefox,但是不知何故,当在地图任务中启动 firefox 时,通过FirefoxDriver,使用位于主机本地文件系统中的geckodriver,使用上面的命令,Firefox进程看不到位于主机本地fs /tmp内的“/tmp/rust_mozprofile.0dQXae46ZwUd”目录。

我尝试将 FirefoxDriver 设置为使用位于 hdfs 中的配置文件,该配置文件具有来自 /tmp 的临时配置文件的相同信息,但仍然显示配置文件丢失或无法访问的窗口。

我尝试使用hadoop LocalFileSystem API从map任务中从主机本地fs / tmp读取文件,并且我可以读取它,因此我可以从map任务访问本地fs。

知道了这一切,我不明白为什么 geckodriver 无法使用 /tmp 中的配置文件启动 Firefox。

下面的代码是在嵌套函数调用中某处运行的主要代码,来自 getProtocolOutput,来自 FetcherThread,它在 FetcherRun 映射器中启动。简单地说,下面的代码在一个 Mapper 启动的特定线程中运行:

    profile = new FirefoxProfile();
    boolean enableFlashPlayer = conf.getBoolean("selenium.firefox.enable.flash", false);
    int loadImage = conf.getInt("selenium.firefox.load.image", 1);
    int loadStylesheet = conf.getInt("selenium.firefox.load.stylesheet", 1);
    System.setProperty("webdriver.gecko.driver", conf.get("webdriver.gecko.driver"));

    profile.setPreference("dom.ipc.plugins.enabled.libflashplayer.so", enableFlashPlayer);
    profile.setPreference("permissions.default.stylesheet", loadImage);
    profile.setPreference("permissions.default.image", loadStylesheet);
    profile.setPreference("marionette", false);
    profile.setAcceptUntrustedCertificates(true);

    long firefoxBinaryTimeout = conf.getLong("selenium.firefox.binary.timeout", 45);
    binary = new FirefoxBinary();
    binary.setTimeout(TimeUnit.SECONDS.toMillis(firefoxBinaryTimeout));

    binary.addCommandLineOptions("-profile", "/home/iulian/firefox.profile");

    options = new FirefoxOptions(); 
    options.setBinary(binary).setProfile(profile);

    driver = new FirefoxDriver(options); // the execution stop here and the window appears, which says that firefox profile is missing or is inaccessible 
    System.out.println("Finished starting driver.");
    long pageLoadWait = conf.getLong("libselenium.page.load.delay", 10);
    driver.manage().timeouts().pageLoadTimeout(pageLoadWait, TimeUnit.SECONDS);

你认为问题出在哪里?如何以简单的方式调试对 /tmp 的访问?

提前致谢!

标签: hadoopfirefoxmapreducehadoop-yarnnutch

解决方案


我设法找到了问题所在。

启动 Firefox 浏览器时,该浏览器需要有一个具有有效 HOME env 变量路径目录的环境,这意味着主目录应该对应于当前启动浏览器的用户,用于创建 firefox 配置文件相关文件。

在我的情况下,来自 Hadoop 的 Map Task 的问题在于 HOME env 变量只是“HOME=/home/”。我没有执行地图任务的用户对该目录的写入权限,并且隐式地使用了 firefox 浏览器。因此,每次出现的弹出窗口都是由于Firefox浏览器无法在HOME目录中创建配置文件相关文件的原因。


推荐阅读