在hadoop中为nameservice获取活动namenode的任何命令?

时间:2014-10-30 08:30:38

标签: hadoop high-availability yarn

命令:

hdfs haadmin -getServiceState machine-98

仅在您知道机器名称时才有效。是否有任何命令:

hdfs haadmin -getServiceState <nameservice>

可以告诉你活动 namenode的IP /主机名吗?

12 个答案:

答案 0 :(得分:18)

要打印出namenodes,请使用以下命令:

hdfs getconf -namenodes

打印出辅助名称节点:

hdfs getconf -secondaryNameNodes

打印出备份名称节点:

hdfs getconf -backupNodes

注意:这些命令是使用Hadoop 2.4.0测试的。

更新 10-31-2014:

这是一个python脚本,它将从配置文件中读取Hadoop HA中涉及的NameNode,并使用hdfs haadmin命令确定哪些是活动的。由于我没有配置HA,因此未对此脚本进行全面测试。仅使用基于Hadoop HA文档的示例文件测试解析。随意使用和修改。

#!/usr/bin/env python
# coding: UTF-8
import xml.etree.ElementTree as ET
import subprocess as SP
if __name__ == "__main__":
    hdfsSiteConfigFile = "/etc/hadoop/conf/hdfs-site.xml"

    tree = ET.parse(hdfsSiteConfigFile)
    root = tree.getroot()
    hasHadoopHAElement = False
    activeNameNode = None
    for property in root:
        if "dfs.ha.namenodes" in property.find("name").text:
            hasHadoopHAElement = True
            nameserviceId = property.find("name").text[len("dfs.ha.namenodes")+1:]
            nameNodes = property.find("value").text.split(",")
            for node in nameNodes:
                #get the namenode machine address then check if it is active node
                for n in root:
                    prefix = "dfs.namenode.rpc-address." + nameserviceId + "."
                    elementText = n.find("name").text
                    if prefix in elementText:
                        nodeAddress = n.find("value").text.split(":")[0]                

                        args = ["hdfs haadmin -getServiceState " + node]  
                        p = SP.Popen(args, shell=True, stdout=SP.PIPE, stderr=SP.PIPE)

                        for line in p.stdout.readlines():
                            if "active" in line.lower():
                                print "Active NameNode: " + node
                                break;
                        for err in p.stderr.readlines():
                            print "Error executing Hadoop HA command: ",err
            break            
    if not hasHadoopHAElement:
        print "Hadoop High-Availability configuration not found!"

答案 1 :(得分:13)

发现这个:

https://gist.github.com/cnauroth/7ff52e9f80e7d856ddb3

这在我的CDH5名称节点上开箱即用,但我不确定其他hadoop发行版是否有http://namenode:50070/jmx可用 - 如果没有,我认为可以通过部署Jolokia来添加。 / p>

示例:

curl 'http://namenode1.example.com:50070/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus'
{
  "beans" : [ {
    "name" : "Hadoop:service=NameNode,name=NameNodeStatus",
    "modelerType" : "org.apache.hadoop.hdfs.server.namenode.NameNode",
    "State" : "active",
    "NNRole" : "NameNode",
    "HostAndPort" : "namenode1.example.com:8020",
    "SecurityEnabled" : true,
    "LastHATransitionTime" : 1436283324548
  } ]

因此,通过向每个namenode发出一个http请求(这应该很快),我们可以找出哪一个是活动的。

值得注意的是,如果您将WebHDFS REST API与无效的名称节点对话,您将获得403 Forbidden和以下JSON:

{"RemoteException":{"exception":"StandbyException","javaClassName":"org.apache.hadoop.ipc.StandbyException","message":"Operation category READ is not supported in state standby"}}

答案 2 :(得分:4)

您也可以使用hdfs cli调用在bash中执行此操作。需要注意的是,这需要花费更多的时间,因为它连续几次调用API,但对于某些人来说,这可能比使用python脚本更可取。

使用Hadoop 2.6.0进行了测试

get_active_nn(){
   ha_name=$1 #Needs the NameServiceID
   ha_ns_nodes=$(hdfs getconf -confKey dfs.ha.namenodes.${ha_name})
   active=""
   for node in $(echo ${ha_ns_nodes//,/ }); do
     state=$(hdfs haadmin -getServiceState $node)
     if [ "$state" == "active" ]; then
       active=$(hdfs getconf -confKey dfs.namenode.rpc-address.${ha_name}.${node})
       break
     fi
   done
   if [ -z "$active" ]; then
     >&2 echo "ERROR: no active namenode found for ${ha_name}"
     exit 1
   else
     echo $active
   fi
}

答案 3 :(得分:2)

在阅读完所有现有答案后,似乎没有结合以下三个步骤:

  1. 从群集中识别名称节点。
  2. 将节点名解析为host:port。
  3. 检查每个节点的状态(不需要 cluster admin privs)。
  4. 下面的解决方案将hdfs getconf次调用和JMX服务调用结合起来进行节点状态。

    #!/usr/bin/env python
    
    from subprocess import check_output
    import urllib, json, sys
    
    def get_name_nodes(clusterName):
        ha_ns_nodes=check_output(['hdfs', 'getconf', '-confKey',
            'dfs.ha.namenodes.' + clusterName])
        nodes = ha_ns_nodes.strip().split(',')
        nodeHosts = []
        for n in nodes:
            nodeHosts.append(get_node_hostport(clusterName, n))
    
        return nodeHosts
    
    def get_node_hostport(clusterName, nodename):
        hostPort=check_output(
            ['hdfs','getconf','-confKey',
             'dfs.namenode.rpc-address.{0}.{1}'.format(clusterName, nodename)])
        return hostPort.strip()
    
    def is_node_active(nn):
        jmxPort = 50070
        host, port = nn.split(':')
        url = "http://{0}:{1}/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus".format(
                host, jmxPort)
        nnstatus = urllib.urlopen(url)
        parsed = json.load(nnstatus)
    
        return parsed.get('beans', [{}])[0].get('State', '') == 'active'
    
    def get_active_namenode(clusterName):
        for n in get_name_nodes(clusterName):
            if is_node_active(n):
                return n
    
    clusterName = (sys.argv[1] if len(sys.argv) > 1 else None)
    if not clusterName:
        raise Exception("Specify cluster name.")
    
    print 'Cluster: {0}'.format(clusterName)
    print "Nodes: {0}".format(get_name_nodes(clusterName))
    print "Active Name Node: {0}".format(get_active_namenode(clusterName))
    

答案 4 :(得分:2)

通过Java api,您可以使用HAUtil.getAddressOfActive(fileSystem)

答案 5 :(得分:1)

在高可用性Hadoop集群中,将有2个名称节点 - 一个是活动的,一个是备用节点。

要查找活动的名称节点,我们可以尝试在每个名称节点上执行test hdfs命令,并找到与成功运行相对应的活动名称节点。

如果名称节点处于活动状态,则下面的命令会成功执行,如果它是备用节点,则会失败。

hadoop fs -test -e hdfs://<Name node>/

Unix脚本

active_node=''
if hadoop fs -test -e hdfs://<NameNode-1>/ ; then
active_node='<NameNode-1>'
elif hadoop fs -test -e hdfs://<NameNode-2>/ ; then
active_node='<NameNode-2>'
fi

echo "Active Dev Name node : $active_node"

答案 6 :(得分:1)

您可以执行curl命令来查找Active和Secondary Namenode 例如

  

curl -u username -H&#34; X-Requested-By:ambari&#34; -X GET   http://cluster-hostname:8080/api/v1/clusters/ /服务/ HDFS

此致

答案 7 :(得分:1)

当我简单地键入'hdfs'时,我发现了以下内容,并找到了一些有用的命令,这些命令对于可能来这里寻求帮助的人很有用。

hdfs getconf -namenodes

以上命令将为您提供namenode的服务ID。说, hn1.hadoop.com

hdfs getconf -secondaryNameNodes

以上命令将为您提供可用的辅助名称节点的服务ID。说 hn2.hadoop.com

hdfs getconf -backupNodes

以上命令将为您提供备份节点的服务ID(如果有)。

hdfs getconf -nnRpcAddresses

以上命令将为您提供名称服务ID的信息以及rpc端口号。说, hn1.hadoop.com:8020

                                  You're Welcome :)

答案 8 :(得分:1)

在HDFS 2.6.0中,最适合我的

ubuntu@platform2:~$ hdfs getconf -confKey dfs.ha.namenodes.arkin-platform-cluster
nn1,nn2
ubuntu@platform2:~$ sudo -u hdfs hdfs haadmin -getServiceState nn1
standby
ubuntu@platform2:~$ sudo -u hdfs hdfs haadmin -getServiceState nn2
active

答案 9 :(得分:1)

这里是 bash 代码示例,即使您没有安装本地 hadoop,也会返回活动名称节点。
它的运行速度也更快,因为 curl 调用通常比 hadoop 更快。​​
在 Cloudera 7.1 上检查

#!/bin/bash
export nameNode1=myNameNode1
export nameNode2=myNameNode2
active_node=''
T1=`curl --silent --insecure  -request GET https://${nameNode1}:9871/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus | grep "\"State\" : \"active\"" | wc -l`
if [ $T1 == 1 ]
then
    active_node=${nameNode1}
else
    T1=`curl --silent --insecure  -request GET https://${nameNode2}:9871/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus | grep "\"State\" : \"active\"" | wc -l`
    if [ $T1 == 1 ]
    then
        active_node=${nameNode2}
    fi
fi

echo "Active Dev Name node : $active_node"

答案 10 :(得分:0)

#!/usr/bin/python

import subprocess
import sys
import os, errno


def getActiveNameNode () :

    cmd_string="hdfs getconf -namenodes"
    process = subprocess.Popen(cmd_string, shell=True, stdout=subprocess.PIPE)
    out, err = process.communicate()
    NameNodes = out
    Value = NameNodes.split(" ")
    for val in Value :
        cmd_str="hadoop fs -test -e hdfs://"+val
        process = subprocess.Popen(cmd_str, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out, err = process.communicate()
        if (err != "") :
            return val

def main():

    out = getActiveNameNode()
    print(out)

if __name__ == '__main__':
    main()

答案 11 :(得分:0)

您可以简单地使用以下命令。我已经在 hadoop 3.0 中对此进行了测试,您可以查看参考 here -

<块引用>

hdfs haadmin -getAllServiceState

它返回所有 NameNode 的状态。