Любая команда для получения активного namenode для nameservice в hadoop?

команды:

hdfs haadmin -getServiceState machine-98

работает только если вы знаете название машины. Есть ли такая команда, как:

hdfs haadmin -getServiceState <nameservice>

который может сказать вам IP / имя хоста активный узел типа NameNode?

6 ответов


чтобы распечатать namenodes, используйте следующую команду:

hdfs getconf -namenodes

чтобы распечатать вторичные namenodes:

hdfs getconf -secondaryNameNodes

чтобы распечатать резервные namenodes:

hdfs getconf -backupNodes

примечание: эти команды были протестированы с помощью Hadoop 2.4.0.

обновление 10-31-2014:

вот скрипт python, который будет читать NameNodes, участвующие в Hadoop HA из файла конфигурации и определить, какой из них активен с помощью 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!"

нашел это:

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

это работает из коробки на мой CDH5 namenodes, хотя я не уверен, что другие дистрибутивы Hadoop будет http://namenode:50070/jmx доступно-если нет, я думаю, что его можно добавить путем развертывания Jolokia.

пример:

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
  } ]

поэтому, запустив один http-запрос для каждого namenode (это должно быть быстро), мы можем понять кто из них активен?

также стоит отметить, что если вы говорите WEBHDFS REST API для неактивного namenode вы получите 403 Forbidden и следующий JSON:

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

вы можете сделать это в bash с вызовами cli hdfs. С замеченным предостережением, что это занимает немного больше времени, так как это несколько вызовов API подряд, но это может быть предпочтительнее, чем использовать скрипт python для некоторых.

Это было протестировано с Hadoop 2.6.0

get_active_nn(){
   ha_name= #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
}

после прочтения всех существующих ответов ни один, казалось, не объединял три шага:

  1. идентификация namenodes из кластера.
  2. разрешение имен узлов на host: port.
  3. проверкой состояния каждого узла (без cluster admin privs).

Решение ниже сочетает в себе 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))

вы можете выполнить команду curl, чтобы узнать активный и вторичный Namenode например

curl-U имя пользователя-H "X-Requested-By: ambari" - X GET http://cluster-hostname:8080/api/v1/clusters/ / услуги / HDFS

в отношении


в кластере Hadoop высокой доступности будет 2 namenodes - один активный и один резервный.

чтобы найти активный namenode, мы можем попробовать выполнить тестовую команду hdfs на каждом из namenodes и найти узел активного имени, соответствующий успешному запуску.

ниже команда выполняется успешно, если имя узла является активным и терпит неудачу, если это резервный узел.

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"