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

Команда:

hdfs haadmin -getServiceState machine-98

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

hdfs haadmin -getServiceState <nameservice>

который может сообщить вам IP/имя хоста активного namenode?

Ответ 1

Чтобы распечатать наменоводы, используйте эту команду:

hdfs getconf -namenodes

Чтобы распечатать вторичные наменоводы:

hdfs getconf -secondaryNameNodes

Чтобы распечатать резервные наменоводы:

hdfs getconf -backupNodes

Примечание. Эти команды были протестированы с использованием Hadoop 2.4.0.

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

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

Ответ 2

Найдено следующее:

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 (это должно быть быстро), мы можем выяснить, какой из них является активным.

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

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

Ответ 3

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

Это было протестировано с помощью 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
}

Ответ 4

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

  • Идентификация наменований из кластера.
  • Разрешение имени node на хост: порт.
  • Проверка состояния каждого node (без необходимости кластер admin privs).

В приведенном ниже решении сочетаются вызовы hdfs getconf и сервисный вызов JMX для статуса node.

#!/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))

Ответ 5

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

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

Ниже команда выполняется успешно, если имя node активно и не работает, если оно находится в режиме ожидания node.

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

Unix script

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

Из Java API, вы можете использовать HAUtil.getAddressOfActive(fileSystem).

Ответ 7

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

curl -u username -H "X-Requested-By: ambari" -X GET http://cluster-hostname:8080/api/v1/clusters//services/HDFS

Привет

Ответ 8

#!/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()

Ответ 9

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

hdfs getconf -namenodes

Эта команда, приведенная выше, даст вам идентификатор сервиса для namenode. Скажем, hn1.hadoop.com

hdfs getconf -secondaryNameNodes

Эта команда, приведенная выше, предоставит вам сервисный идентификатор доступных вторичных наменодов. Скажем, hn2.hadoop.com

hdfs getconf -backupNodes

Эта команда, приведенная выше, предоставит вам идентификатор службы резервных узлов, если таковые имеются.

hdfs getconf -nnRpcAddresses

Эта команда даст вам информацию об идентификаторе службы имен вместе с номером порта rpc. Скажите, hn1.hadoop.com:8020

                                  You're Welcome :)