-
Notifications
You must be signed in to change notification settings - Fork 3
How to get active NameNode
If HA (high availability) is enabled, one NameNode is active and the second is passive. But which one? While dealing with WebHDFS, the request should be sent to the active NameNode, otherwise, the request will be rejected. Sounds strange, but it looks that there is not Ambari REST API answering the question.
The obvious solution is to use Knox GateWay. If properly configured, the gateway will direct the request to the currently active NameNode.
https://docs.cloudera.com/HDPDocuments/HDP3/HDP-3.0.1/configuring-proxy-knox/content/setting_up_knox_services_for_ha.html
https://docs.cloudera.com/HDPDocuments/HDP3/HDP-3.1.0/data-storage/content/using_jmx_for_accessing_hdfs_metrics.html
The query to extract if NameNode is active or passive.The {hostname} should be the hostname of the node where NameNode, active or passive, is installed.
curl http://{hostname}:50070/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus Example assuming that hurds1.fyre.ibm.com and a1.fyre.ibm.com nodes contain NameNodes.
curl http://hurds1.fyre.ibm.com:50070/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus
{
"beans" : [ {
"name" : "Hadoop:service=NameNode,name=NameNodeStatus",
"modelerType" : "org.apache.hadoop.hdfs.server.namenode.NameNode",
"NNRole" : "NameNode",
"HostAndPort" : "hurds1.fyre.ibm.com:8020",
"SecurityEnabled" : false,
"LastHATransitionTime" : 0,
"BytesWithFutureGenerationStamps" : 0,
"SlowPeersReport" : null,
"SlowDisksReport" : null,
"State" : "standby"
} ]
}
curl http://a1.fyre.ibm.com:50070/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus
{
"beans" : [ {
"name" : "Hadoop:service=NameNode,name=NameNodeStatus",
"modelerType" : "org.apache.hadoop.hdfs.server.namenode.NameNode",
"NNRole" : "NameNode",
"HostAndPort" : "a1.fyre.ibm.com:8020",
"SecurityEnabled" : false,
"LastHATransitionTime" : 1568796935217,
"BytesWithFutureGenerationStamps" : 0,
"SlowPeersReport" : null,
"SlowDisksReport" : null,
"State" : "active"
} ]
}
If the cluster is Kerberized, the valid Kerberos ticket should be obtained and curl --negotiate parameter added to the commandline.
kinit {obtain Kerberos ticket}
curl -i --negotiate -u : http://mdp1:50070/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus
{
"beans" : [ {
"name" : "Hadoop:service=NameNode,name=NameNodeStatus",
"modelerType" : "org.apache.hadoop.hdfs.server.namenode.NameNode",
"NNRole" : "NameNode",
"HostAndPort" : "mdp1.sb.com:8020",
"SecurityEnabled" : true,
"LastHATransitionTime" : 0,
"BytesWithFutureGenerationStamps" : 0,
"SlowPeersReport" : null,
"SlowDisksReport" : null,
"State" : "active"
} ]
}
https://hadoop.apache.org/docs/r2.7.0/hadoop-project-dist/hadoop-hdfs/HDFSCommands.html#haadmin
This command can be executed only localy, on the node belonging to the cluster.
Discover node IDs assigned to the NameNodes.
vi /etc/hadoop/conf/hdfs-site.xml
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>a1.fyre.ibm.com:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hurds1.fyre.ibm.com:50070</value>
</property>
NameNode a1.fyre.ibm.com is labelled as nn1 and hurds1.fyre.ibm.com as nn2.
hdfs haadmin -getServiceState nn1
active
hdfs haadmin -getServiceState nn2
standby
This script is pretty straightforward and does not require match comment.
Customization.
Variable | Description |
---|---|
NN1NODE | a hostname where nn1 NameNode is deployed |
NN2NODE | a hostname where nn2 NameNode is deployed |
KEYTAB | keytab used to deal with Kerberized cluster. If cluster is not Kerberized, comment out the variable |
PRINCIPAL | principal in KEYTAB |
USEJXM | Set this variable if the active name node is extracted from JMX. Comment out if hdfs haadmin command is going to be used |
NN1NODE=a1.fyre.ibm.com
NN2NODE=hurds1.fyre.ibm.com
#NN1NODE=mdp1.sb.com
#NN2NODE=mdp1.sb.com
NN1=nn1
NN2=nn2
PORT=50070
# comment out if cluster not Kerberized
#KEYTAB=/home/sbartkowski/bin/keytabs/sb.keytab
#KEYTAB=/home/sb/sb.keytab
#PRINCIPAL=sb@CENTOS.COM.REALM
KERBEROSPARAM=
# comment out if use hdfs haadmin
# remove comment if jmx is to be used
#USEJMX=X
checkjmx() {
local -r host=$1
curl $KERBEROSPARAM -# http://$host:$PORT/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus 2>/dev/null |
sed -n 's/\"State" *: *"\(active\|standby\)\"/\1/p'
}
checkhdfs() {
local -r nn=$1
hdfs haadmin -getServiceState $nn
}
checkstate() {
[ -n "$USEJMX" ] && checkjmx $1
[ -z "$USEJMX" ] && checkhdfs $2
}
getactive() {
if [ `checkstate $NN1NODE $NN1`X == 'activeX' ]; then echo $NN1NODE;
elif [ `checkstate $NN2NODE $NN2`X == 'activeX' ]; then echo $NN2NODE;
else echo "No active NameNode, verify that cluster is up and running."
fi
}
checkkerberos() {
if [ -n "$KEYTAB" ]; then
kinit -kt $KEYTAB $PRINCIPAL
if [ $? -ne 0 ]; then
echo "kinit - cannot obtain Kerberos ticket."
exit
fi
KERBEROSPARAM=" -i --negotiate -u : "
fi
}
checkkerberos
getactive
[ -n "$KEYTAB" ] && kdestroy -A