首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何设置纱线NodeManager的nodeID?

如何设置纱线NodeManager的nodeID?
EN

Stack Overflow用户
提问于 2015-12-29 00:52:49
回答 3查看 2.9K关注 0票数 2

我正在尝试在Ansible的帮助下在EC2 Spot实例上设置一个自定义的Hadoop基础设施。在这样的实例中,只有内部IP是已知的。幸运的是,有一个动态生成清单的ec2.py脚本,可以配置为使用实例的完整外部DNS名称inventory_hostname。因此,我将所有Jinja2模板设置为使用inventory_hostname来设置配置XML文件。到目前为止,这对于HDFS是有效的,对于YARN,Nodemanagers也是向资源管理器注册的。

但是,节点IP设置不正确,即设置为其内部IP地址。

我的yarn-site.xml.j2看起来像这样:

代码语言:javascript
复制
<?xml version="1.0"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->
<configuration>

    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>{{resourcemanager_fqdn}}</value>
    </property>

    <property>
        <name>yarn.resourcemanager.address</name>
        <value>{{resourcemanager_fqdn}}:8032</value>
    </property>

    <property>
        <name>yarn.resourcemanager.scheduler.address</name>
        <value>{{resourcemanager_fqdn}}:8030</value>
    </property>

    <property>
        <name>yarn.resourcemanager.webapp.address</name>
        <value>{{resourcemanager_fqdn}}:8088</value>
    </property>

    <property>
        <name>yarn.resourcemanager.resource-tracker.address</name>
        <value>{{resourcemanager_fqdn}}:8031</value>
    </property>

    <property>
        <name>yarn.resourcemanager.admin.address</name>
        <value>{{resourcemanager_fqdn}}:8033</value>
    </property>

    <property>
        <name>yarn.nodemanager.hostname</name>
        <value>{{inventory_hostname}}</value>
    </property>

    <property>
        <name>yarn.nodemanager.address</name>
        <value>{{inventory_hostname}}:9999</value>
    </property>

    <property>
        <name>yarn.nodemanager.localizer.address</name>
        <value>{{inventory_hostname}}:8040</value>
    </property>

    <property>
        <name>yarn.nodemanager.webapp.address</name>
        <value>{{inventory_hostname}}:8042</value>
    </property>

    <property>
        <name>yarn.resourcemanager.bind-host</name>
        <value>0.0.0.0</value>
    </property>

    <property>
        <name>yarn.nodemanager.bind-host</name>
        <value>0.0.0.0</value>
    </property>

</configuration>

其中,变量resourcemanager_fqdn的获取方式如下:

代码语言:javascript
复制
{{hostvars[groups['tag_hadoop_resourcemanager'][0]].inventory_hostname}}

tag_hadoop_resourcemanagerec2.py动态生成的主机组。

我认为节点id是从yarn.nodemanager.address派生的,但这似乎被忽略了。仅考虑端口9999。

这是个bug,还是我忘了设置一个额外的选项?

EN

回答 3

Stack Overflow用户

发布于 2015-12-29 14:36:00

我看了一下纱线代码,发现了以下内容。

有一个函数buildNodeId(),用于构建节点Id。

Node Id是hostport的组合,并设置为host:port

buildNodeId()在内部调用以下函数以获取InetAddress

代码语言:javascript
复制
InetAddress inetAddress = InetAddress.getByName(host);

此调用始终返回内部IP地址作为第一个IP地址。

让我举个例子来解释一下。例如,我有以下IP:

代码语言:javascript
复制
Ethernet: 172.23.206.41 (External IP)
Host-Only: 192.168.56.1 (Internal IP).

让我解释一下这两种情况(内部IP与外部IP)

  • 案例1:默认为内部IP

我在我的yarn-site.xml yarn.nodemanager.address mballur中设置了以下内容:9999

其中mballur是我的主机名。

现在,当我运行yarn node -list -all时,我得到的节点ID如下:

节点总数:1 Node-Id Node-State Node-Http-Address正在运行的容器数量192.168.56.1:9999运行192.168.56.1:50060 0

节点ID为内部IP +端口的组合。因为,InetAddress.getByName(host)会返回内部IP作为第一个IP address.

  • Case 2:显式指定外部IP

我在我的yarn-site.xml yarn.nodemanager.address 172.23.206.41中设置了以下内容:9999

其中172.23.206.41是我的外部IP。

现在,当我运行yarn node -list -all时,我得到的节点ID如下:

节点总数:1 Node-Id Node-State Node-Http-Address正在运行的容器数量172.23.206.41:9999运行172.23.206.41:50060 0

现在,节点ID是“外部IP +端口”的组合。

票数 2
EN

Stack Overflow用户

发布于 2015-12-29 22:32:28

我找到了解决此问题的方法。我必须让我的实例认为它们的主机名是外部DNS名称。

这就是我是如何让它工作的:

首先,我创建了一个名为rewrite_hosts的角色,它只包含一个tasks目录,并在此tasks目录中包含以下main.yml

代码语言:javascript
复制
---
- name: "/etc/hostname must contain external DNS"
  become: yes
  become_method: sudo
  shell: echo {{inventory_hostname}} >/etc/hostname
- name: "Determine external IP"
  shell: wget -qO- http://ipecho.net/plain ; echo
  register: host_ip
- name: "/etc/hosts entry must exist pointing to external IP"
  become: yes
  become_method: sudo
  lineinfile: dest=/etc/hosts line="{{host_ip.stdout}} {{inventory_hostname}}" state=present
- name: "Update current hostname"
  become: yes
  become_method: sudo
  shell: hostname $(cat /etc/hostname)

然后,我设置了ec2.py as described here。但是,我在ec2.ini中更改了两项内容

RDS Set RDS(否则,它将使用IP address)

  • Added rds = false,因为我不使用
  • vpc_destination_variable = public_dns_name。YMMV在这上面。

然后,在设置任何特定于hadoop的内容之前,我将以下内容添加到我的剧本中:

代码语言:javascript
复制
- name: "Update IP information"
  hosts: tag_origin_ec2
  vars:
    ansible_ssh_user: ubuntu
  roles:
  - rewrite_hosts

我用origin: ec2标记我的实例,因为我以后想在非ec2环境中重用大部分攻略,所以这一部分将被跳过。

然后,行动手册中的所有后续行动都将按预期与ansible_fqdn一起工作。但是,要小心使用ansible_eth0.ipv4.address,因为它从eth0获取内部地址。作为一种解决方法,请使用以下任务:

代码语言:javascript
复制
- name: "Determine external IP"
  shell: wget -qO- http://ipecho.net/plain ; echo
  register: host_ip

然后,如果需要,您可以使用host_ip.stdout获取IP地址。

票数 1
EN

Stack Overflow用户

发布于 2016-05-12 15:59:46

是的,你认为正确的,你应该做的包括:

1 .将hdfs-site.xmldfs.datanode.hostname设置为您的public DNS name

2、将public DNS name与本端ip的映射添加到每个节点自身的/etc/hosts中,该规则必须出现在hostname与本端ip的映射之前。

3 .将每个节点上hdfs-site.xmldfs.datanode.use.datanode.hostnamedfs.client.use.datanode.hostname设置为true

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34497451

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档