No olvides que en las ciencias informáticas un error casi siempre tiene diferentes soluciones, no obstante nosotros te mostraremos la mejor y más óptimo.
Solución:
Para imprimir los nodos de nombre, utilice este comando:
hdfs getconf -namenodes
Para imprimir los nodos de nombre secundarios:
hdfs getconf -secondaryNameNodes
Para imprimir los nombres de los nodos de respaldo:
hdfs getconf -backupNodes
Nota: Estos comandos se probaron con Hadoop 2.4.0.
Actualizar 31/10/2014:
Aquí hay un script de Python que leerá los NameNodes involucrados en Hadoop HA desde el archivo de configuración y determinará cuál de ellos está activo usando el comando hdfs haadmin. Este script no está completamente probado porque no tengo configurado HA. Solo probé el análisis con un archivo de muestra basado en la documentación de Hadoop HA. Siéntase libre de usar y modificar según sea necesario.
#!/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!"
Encontró esto:
https://gist.github.com/cnauroth/7ff52e9f80e7d856ddb3
Esto funciona de inmediato en mis nodos de nombre CDH5, aunque no estoy seguro de que otras distribuciones de hadoop tengan http: // namenode: 50070 / jmx disponible; de lo contrario, creo que se puede agregar implementando Jolokia.
Ejemplo:
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
]
Entonces al disparar uno solicitud http a cada nodo de nombre (esto debería ser rápido) podemos averiguar cuál es el activo.
También vale la pena señalar que si habla de la API REST de WebHDFS con un nodo de nombre inactivo, obtendrá un 403 Forbidden y el siguiente JSON:
"RemoteException":"exception":"StandbyException","javaClassName":"org.apache.hadoop.ipc.StandbyException","message":"Operation category READ is not supported in state standby"
En un clúster de Hadoop de alta disponibilidad, habrá 2 nodos de nombre: uno activo y otro en espera.
Para encontrar el nodo de nombre activo, podemos intentar ejecutar el comando test hdfs en cada uno de los nodos de nombre y encontrar el nodo de nombre activo correspondiente a la ejecución exitosa.
El siguiente comando se ejecuta con éxito si el nodo de nombre está activo y falla si es un nodo en espera.
hadoop fs -test -e hdfs:///
Secuencia de comandos de Unix
active_node=''
if hadoop fs -test -e hdfs:/// ; then
active_node=''
elif hadoop fs -test -e hdfs:/// ; then
active_node=''
fi
echo "Active Dev Name node : $active_node"
Recuerda compartir esta reseña si lograste el éxito.