如何设置Yarn节点管理器的nodeid?

trnvg8h3  于 2021-05-29  发布在  Hadoop
关注(0)|答案(3)|浏览(657)

我正试图通过ansible的帮助在ec2spot示例上建立一个定制的hadoop基础设施。在这样的示例中,只有内部ip是已知的。幸运的是,有一个 ec2.py 动态生成清单的脚本,可以配置为使用示例的完整外部dns名称作为 inventory_hostname . 所以我设置了所有要使用的jinja2模板 inventory_hostname 设置配置xml文件。到目前为止,对于hdfs和yarn,节点管理器也在资源管理器中注册。
但是,节点ID设置不正确,即设置为其内部ip地址。
我的yarn-site.xml.j2如下所示:

<?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 是这样得到的:

{{hostvars[groups['tag_hadoop_resourcemanager'][0]].inventory_hostname}}
``` `tag_hadoop_resourcemanager` 是动态生成的主机组 `ec2.py` .
我以为节点id是从 `yarn.nodemanager.address` ,但这似乎被忽视了。只考虑端口9999。
这是一个错误还是我忘了设置一个额外的选项?
bfnvny8b

bfnvny8b1#

是的,你认为是对的,你应该做的包括:
1套 dfs.datanode.hostnamehdfs-site.xml 给你的 public DNS name .
2、添加 public DNS name 和本地ip到 /etc/hosts 对于每个节点本身,这个规则必须出现在它们之间的Map前面 hostname 和本地ip。
3、设置 dfs.datanode.use.datanode.hostname 以及 dfs.client.use.datanode.hostnamehdfs-site.xml 在每个节点上 true .

dhxwm5r4

dhxwm5r42#

我找到了解决办法。我必须使我的示例认为他们的主机名是外部dns名称。
我就是这样做的:
首先,我创建了一个名为 rewrite_hosts ,其中仅包含 tasks 目录和 tasks 目录如下 main.yml :

---
- 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。然而,我改变了两件事 ec2.ini :
vpc_destination_variable = public_dns_name (否则,它将使用ip地址)
补充 rds = false 因为我不使用rds示例。ymmv在这上面。
然后,在设置任何特定于hadoop的内容之前,我在我的剧本中添加了以下内容:

- name: "Update IP information"
  hosts: tag_origin_ec2
  vars:
    ansible_ssh_user: ubuntu
  roles:
  - rewrite_hosts

我将示例标记为 origin: ec2 因为我以后想在非ec2环境中重用playbook的大部分内容,所以这一部分将被跳过。
随后,剧本中的所有后续剧本都将按预期与 ansible_fqdn . 但是要小心 ansible_eth0.ipv4.address 因为它从eth0获取内部地址。作为解决方法,请使用以下任务:

- name: "Determine external IP"
  shell: wget -qO- http://ipecho.net/plain ; echo
  register: host_ip

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

c6ubokkw

c6ubokkw3#

我查了一下Yarn代码,发现了以下几点。
有一个函数 buildNodeId() ,生成节点id。
节点id是 host 以及 port 设定为 host:port . buildNodeId() 内部调用以下函数以获取 InetAddress :

InetAddress inetAddress = InetAddress.getByName(host);

此调用始终返回内部ip地址作为第一个ip地址。
让我举个例子来解释。例如,我有以下IP:

Ethernet: 172.23.206.41 (External IP)
Host-Only: 192.168.56.1 (Internal IP).

我来解释一下这两种情况(内部ip和外部ip)
案例1:默认为内部ip
我在我的 yarn-site.xml :

<property>
    <name>yarn.nodemanager.address</name>
    <value>mballur:9999</value>
</property>

哪里 mballur 是我的主机名。
现在,当我跑的时候 yarn node -list -all ,我得到的节点id如下:

Total Nodes:1
Node-Id             Node-State Node-Http-Address   Number-of-Running-Containers
192.168.56.1:9999   RUNNING    192.168.56.1:50060  0

节点id是内部ip+端口的组合。因为, InetAddress.getByName(host) ,返回内部ip作为第一个ip地址。
情况2:显式指定外部ip
我在我的 yarn-site.xml :

<property>
    <name>yarn.nodemanager.address</name>
    <value>172.23.206.41:9999</value>
</property>

哪里 172.23.206.41 是我的外部ip。
现在,当我跑的时候 yarn node -list -all ,我得到的节点id如下:

Total Nodes:1
Node-Id             Node-State Node-Http-Address   Number-of-Running-Containers
172.23.206.41:9999  RUNNING    172.23.206.41:50060 0

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

相关问题