Hadoop學習--機架感知--day05

hadoop配置機架感知html

  接着上一篇來講。上篇說了hadoop網絡拓撲的構成及其相應的網絡位置轉換方式,本篇主要講經過兩種方式來配置機架感知。一種是經過配置一個腳原本進行映射;另外一種是經過實現DNSToSwitchMapping接口的resolve()方法來完成網絡位置的映射。java

  hadoop自身是沒有機架感知能力的,必須經過人爲的設定來達到這個目的。在FSNamesystem類中的resolveNetworkLocation()方法負載進行網絡位置的轉換。其中dnsToSwitchMapping變量表明瞭完成具體轉換工做的類,其值以下: node

1 this.dnsToSwitchMapping = ReflectionUtils.newInstance(2         conf.getClass("topology.node.switch.mapping.impl", ScriptBasedMapping.class,3             DNSToSwitchMapping.class), conf);

   也就是說dnsToSwitchMapping的值由「core-site.xml」配置文件中的"topology.node.switch.mapping.impl"參數指定。默認值爲ScriptBasedMapping,也就是經過讀提早寫好的腳本文件來進行網絡位置映射的。但若是這個腳本沒有配置的話,那就使用默認值「default-rack」做爲全部結點的網絡位置。shell

  下面就先說說第一種配置機架感知的方法,使用腳原本完成網絡位置的映射。這須要在「core-site.xml」配置文件中的「topology.script.file.name」參數中指定腳本文件的位置。在wiki上找到一個官方的配置腳本,能夠參考一下。首先是shell腳本:apache

複製代碼

 1 HADOOP_CONF=/etc/hadoop/conf 
 2  3 while [ $# -gt 0 ] ; do  //$#表明執行命令時輸入的參數個數 4   nodeArg=$1 5   exec< ${HADOOP_CONF}/topology.data   //讀入文件 6   result=""  7   while read line ; do        //循環遍歷文件內容 8     ar=( $line ) 
 9     if [ "${ar[0]}" = "$nodeArg" ] ; then10       result="${ar[1]}"11     fi12   done 13   shift 14   if [ -z "$result" ] ; then15     echo -n "/default/rack "16   else17     echo -n "$result "18   fi19 done

複製代碼

  topology.data文件格式以下:網絡

複製代碼

tt156   /dc1/rack1
tt163   /dc1/rack1
tt164   /dc1/rack2
tt165   /dc1/rack210.32.11.156   /dc1/rack110.32.11.163   /dc1/rack110.32.11.164   /dc1/rack210.32.11.165   /dc1/rack2

複製代碼

  我是把原來topology.data文件內容改了下,把hostname也添加進去了,這樣保證正確性。由於JobTracker是經過hostname進行映射的。app

  網上也有用Python腳本和C語言寫的,但我對Python不是很熟,因此在這裏就不說了。總結上邊的內容,能夠知道,無論用什麼腳原本寫,最重要的就是接收參數,完成網絡位置映射並將結果輸出。這樣系統就可以接收到合適結果。jvm

  

  第二種配置機架感知的方法是經過實現DNSToSwitchMapping接口,重寫resolve()方法完成的。這就須要本身寫個java類來完成映射了。而後在「core-site.xml」配置文件中的「topology.node.switch.mapping.impl」指定本身的實現類。這樣的話,在進行網絡位置解析的時候,就會調用本身類中的resolve()方法來完成轉換了。我寫的比較簡單,能完成功能就好,代碼以下(大神飛過):ide

複製代碼

 1 public class MyResolveNetworkTopology implements DNSToSwitchMapping { 2  3     private String[] hostnameLists = {"tt156", "tt163", "tt164", "tt165"}; 4     private String[] ipLists = {"10.32.11.156", "10.32.11.163", "10.32.11.164", "10.32.11.165"}; 5     private String[] resolvedLists = {"/dc1/rack1", "/dc1/rack1", "/dc1/rack2", "/dc1/rack2"}; 6      7     @Override 8     public List<String> resolve(List<String> names) { 9         names = NetUtils.normalizeHostNames(names);10 11         List <String> result = new ArrayList<String>(names.size());12         if (names.isEmpty()) {13           return result;14         }15 16         for (int i = 0; i < names.size(); i++) {17             String name = names.get(i);18             for(int j = 0; j < hostnameLists.length; j++){19                 if(name.equals(hostnameLists[j])) {20                     result.add(resolvedLists[j]);21                 } else if(name.equals(ipLists[j])) {22                     result.add(resolvedLists[j]);23                 }24             }25         }26         return result;27     }28 }

複製代碼

  我把這個自定義的MyResolveNetworkTopology類放在了core包的org.apache.hadoop.net目錄下。因此在「core-site.xml」文件中的配置以下:  oop

複製代碼

<property>
  <name>topology.node.switch.mapping.impl</name>
  <value>org.apache.hadoop.net.MyResolveNetworkTopology</value>
  <description> The default implementation of the DNSToSwitchMapping. It
    invokes a script specified in topology.script.file.name to resolve
    node names. If the value for topology.script.file.name is not set, the
    default value of DEFAULT_RACK is returned for all node names.  </description></property>

複製代碼

 

  以上兩種方法在配置完成後,會在NameNode和JobTracker的log中打印出以下信息:

2015-05-26 20:47:20,665 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /dc1/rack1/tt163
2015-05-26 20:47:20,689 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /dc1/rack1/tt156
.......

  這就說明機架感知配置成功了。

  總結一下以上兩種方式。經過腳本配置的方式,靈活性很高,可是執行效率較低。由於系統要從jvm轉到shell去執行;java類的方式性能較高,可是編譯以後就沒法改變了,因此靈活程度較低。因此要根據具體狀況來選擇策略.

相關文章
相關標籤/搜索