upgrade小結:
1.dfsadmin -upgradeProgress status 在cdh5.2.0中沒有,在4.6.0有(見源碼org.apache.hadoop.hdfs.tools.DFSAdmin)
更新的時候不能通過這個看到更新狀态
rollingUpgrade這個參數在4.6.0中不存在,在5.2.0中有,可以用于滾動更新
2.在cdh5.2.0中執行upgrade,nn中調用的指令是
1
<code>hadoop-daemon.sh start namenode -upgrade</code>
最終調用org.apache.hadoop.hdfs.server.namenode.NameNode類,并傳入upgrade參數
3.yarn的設定有些變動,下面兩個參數會影響nm是否啟動正常
2
3
4
5
6
7
8
<code> </code><code><property></code>
<code> </code><code><name>yarn.nodemanager.aux-services<</code><code>/name</code><code>></code>
<code> </code><code><value>mapreduce.shuffle<</code><code>/value</code><code>></code>
<code> </code><code><</code><code>/property</code><code>></code>
<code> </code><code><name>yarn.nodemanager.aux-services.mapreduce.shuffle.class<</code><code>/name</code><code>></code>
<code> </code><code><value>org.apache.hadoop.mapred.ShuffleHandler<</code><code>/value</code><code>></code>
修改為:
<code> </code><code><property></code>
<code> </code><code><value>mapreduce_shuffle<</code><code>/value</code><code>></code>
<code> </code><code><name>yarn.nodemanager.aux-services.mapreduce_shuffle.class<</code><code>/name</code><code>></code>
4.impala1.1.1和cdh5.2.0有相容性問題
cdh5.x開始使用PB做通信,需要更新impala到2.0.0(impala的可用性/穩定性/性能需要測試)
rollback小結:
1.rollback要在4.6.0版本上運作
在4.6.0上運作rollback,finalize,upgrade時,都會判斷時否為ha模式,如果沒有關閉ha的配置會報如下錯誤:
<code>14</code><code>/11/19</code> <code>15:25:47 FATAL namenode.NameNode: Exception </code><code>in</code> <code>namenode </code><code>join</code>
<code>org.apache.hadoop.HadoopIllegalArgumentException: Invalid startup option. Cannot perform DFS upgrade with HA enabled.</code>
<code> </code><code>at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1130)</code>
<code> </code><code>at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1241)</code>
namenode類main方法中通過createNameNode方法建立一個NameNode的執行個體
9
10
11
12
13
14
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(String argv[]) </code><code>throws</code> <code>Exception {</code>
<code> </code><code>if</code> <code>(DFSUtil.parseHelpArgument(argv, NameNode.USAGE, System.out, </code><code>true</code><code>)) {</code>
<code> </code><code>System.exit(</code><code>0</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>StringUtils.startupShutdownMessage(NameNode.</code><code>class</code><code>, argv, LOG);</code>
<code> </code><code>NameNode namenode = createNameNode(argv, </code><code>null</code><code>);</code>
<code> </code><code>if</code> <code>(namenode != </code><code>null</code><code>)</code>
<code> </code><code>namenode.join();</code>
<code> </code><code>} </code><code>catch</code> <code>(Throwable e) {</code>
<code> </code><code>LOG.fatal(</code><code>"Exception in namenode join"</code><code>, e);</code>
<code> </code><code>terminate(</code><code>1</code><code>, e);</code>
<code> </code><code>}</code>
而在createNameNode方法中會通過下面的代碼檢測是否為ha的配置,而在5.2.0是沒有這個限制的。
<code> </code><code>if</code> <code>(HAUtil.isHAEnabled(conf, DFSUtil.getNamenodeNameServiceId(conf)) &&</code>
<code> </code><code>(startOpt == StartupOption.UPGRADE ||</code>
<code> </code><code>startOpt == StartupOption.ROLLBACK ||</code>
<code> </code><code>startOpt == StartupOption.FINALIZE)) {</code>
<code> </code><code>throw</code> <code>new</code> <code>HadoopIllegalArgumentException(</code><code>"Invalid startup option. "</code> <code>+</code>
<code> </code><code>"Cannot perform DFS upgrade with HA enabled."</code><code>);</code>
這裡會涉及到兩個判斷方法:
1)
<code>org.apache.hadoop.hdfs.HAUti類的isHAEnabled方法:</code>
<code> </code><code>public</code> <code>static</code> <code>boolean</code> <code>isHAEnabled(Configuration conf, String nsId) {</code>
<code> </code><code>Map<String, Map<String, InetSocketAddress>> addresses =</code>
<code> </code><code>DFSUtil.getHaNnRpcAddresses(conf);</code>
<code> </code><code>if</code> <code>(addresses == </code><code>null</code><code>) </code><code>return</code> <code>false</code><code>;</code>
<code> </code><code>Map<String, InetSocketAddress> nnMap = addresses.get(nsId);</code>
<code> </code><code>return</code> <code>nnMap != </code><code>null</code> <code>&& nnMap.size() > </code><code>1</code><code>; </code>
這裡會依次調用org.apache.hadoop.hdfs.DFSUtil類的
<code>getHaNnRpcAddresses/getAddresses/getNameServiceIds/getAddressesForNameserviceId/getNameNodeIds</code>
方法,解析dfs.nameservices/dfs.ha.namenodes.xxxx/dfs.namenode.rpc-address.xxxx的設定來擷取每個nameserviceid到對應的nn rpc位址的對應關系(
<code>Map<String, Map<String, InetSocketAddress>></code>
)并判斷map value的size(如果dfs.ha.namenodes.x設定超過1個就算ha),這裡隻要把配置改成下面即可
<code> </code><code><name>dfs.ha.namenodes.bipcluster<</code><code>/name</code><code>></code>
<code> </code><code><value>nn1<</code><code>/value</code><code>></code>
<code><</code><code>/property</code><code>></code>
2)如果設定了jn會報如下錯誤:
<code>14</code><code>/11/19</code> <code>16:47:32 FATAL namenode.NameNode: Exception </code><code>in</code> <code>namenode </code><code>join</code>
<code>java.io.IOException: Invalid configuration: a shared edits </code><code>dir</code> <code>must not be specified </code><code>if</code> <code>HA is not enabled.</code>
<code> </code><code>at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.<init>(FSNamesystem.java:576)</code>
<code> </code><code>at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.loadFromDisk(FSNamesystem.java:513)</code>
<code> </code><code>at org.apache.hadoop.hdfs.server.namenode.NameNode.loadNamesystem(NameNode.java:403)</code>
<code> </code><code>at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:445)</code>
<code> </code><code>at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:621)</code>
<code> </code><code>at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(NameNode.java:606)</code>
<code> </code><code>at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode(NameNode.java:1177)</code>
<code>14</code><code>/11/19</code> <code>16:47:32 INFO util.ExitUtil: Exiting with status 1</code>
錯誤在FSNamesystem類的構造方法中:
15
16
17
18
<code> </code><code>final</code> <code>boolean</code> <code>persistBlocks = conf.getBoolean(DFS_PERSIST_BLOCKS_KEY,</code>
<code> </code><code>DFS_PERSIST_BLOCKS_DEFAULT); </code><code>//預設是false</code>
<code> </code><code>// block allocation has to be persisted in HA using a shared edits directory</code>
<code> </code><code>// so that the standby has up-to-date namespace information</code>
<code> </code><code>String nameserviceId = DFSUtil.getNamenodeNameServiceId(conf);</code>
<code> </code><code>this</code><code>.haEnabled = HAUtil.isHAEnabled(conf, nameserviceId); </code>
<code> </code><code>this</code><code>.persistBlocks = persistBlocks || (haEnabled && HAUtil.usesSharedEditsDir(conf));</code>
<code> </code>
<code> </code><code>// Sanity check the HA-related config.</code>
<code> </code><code>if</code> <code>(nameserviceId != </code><code>null</code><code>) {</code>
<code> </code><code>LOG.info(</code><code>"Determined nameservice ID: "</code> <code>+ nameserviceId); </code><code>//Determined nameservice ID: bipcluster</code>
<code> </code><code>}</code>
<code> </code><code>LOG.info(</code><code>"HA Enabled: "</code> <code>+ haEnabled); </code><code>//HA Enabled: false</code>
<code> </code><code>if</code> <code>(!haEnabled && HAUtil.usesSharedEditsDir(conf)) { </code><code>//異常由這裡抛出</code>
<code> </code><code>LOG.warn(</code><code>"Configured NNs:\n"</code> <code>+ DFSUtil.nnAddressesAsString(conf)); </code><code>//Configured NNs: Nameservice <bipcluster>: NN ID nn1 => xxxx:8020</code>
<code> </code><code>throw</code> <code>new</code> <code>IOException(</code><code>"Invalid configuration: a shared edits dir "</code> <code>+</code>
<code> </code><code>"must not be specified if HA is not enabled."</code><code>);</code>
HAUtil.usesSharedEditsDir方法:
<code> </code><code>public</code> <code>static</code> <code>boolean</code> <code>usesSharedEditsDir(Configuration conf) {</code>
<code> </code><code>return</code> <code>null</code> <code>!= conf.get(DFS_NAMENODE_SHARED_EDITS_DIR_KEY);</code>
判斷jn的edit dir設定,如果設定了dfs.namenode.shared.edits.dir就會抛出異常
去掉下面的設定即可:
<code><</code><code>property</code><code>></code>
<code> </code><code><</code><code>name</code><code>>dfs.namenode.shared.edits.dir</</code><code>name</code><code>></code>
<code> </code><code><</code><code>value</code><code>>qjournal://xxxxx/bipcluster</</code><code>value</code><code>></code>
<code></</code><code>property</code><code>></code>
2.rollback的時候要先把ha的配置更改為非ha的配置,然後進行rollback
rollback之後,再重做ha
重做ha的步驟簡單如下:
1).關閉整個叢集(非ha的),更改配置為ha的配置,備份原來的standby nn和jn的資料目錄
2).删除舊的jn資料,并單獨啟動jn
<code>.</code><code>/hadoop-daemon</code><code>.sh start journalnode</code>
3).在active nn上運作
<code>hdfs namenode -initializeSharedEdits</code>
namenode通過initializeSharedEdits指令來初始化journalnode,把edits檔案共享到journalnode上
4).運作active nn
<code>.</code><code>/hadoop-daemon</code><code>.sh start namenode</code>
5).在standby的nn上運作
<code>hadoop-daemon.sh start namenode -bootstrapStandby</code>
<code>hadoop-daemon.sh start namenode</code>
同步中繼資料并啟動standby namenode
6).啟動所有的dn
<code>.</code><code>/hadoop-daemons</code><code>.sh start datanode</code>
7).nn transitionToActive
<code>hdfs haadmin -transitionToActive nn1</code>
<code>hdfs haadmin -getServiceState nn1</code>
3.start-dfs.sh 這個腳本有bug,在傳入-rollback時,隻能dn可以rollback,nn不能rollback
<code>diff</code> <code>../..</code><code>/hadoop-2</code><code>.5.0-cdh5.2.0</code><code>/sbin/start-dfs</code><code>.sh start-dfs.sh </code>
<code>50c50</code>
<code>< nameStartOpt=</code><code>"$nameStartOpt $@"</code>
<code>---</code>
<code>> nameStartOpt=</code><code>"$nameStartOpts $@"</code>
也可以直接通過
<code>sh -x .</code><code>/hadoop-daemon</code><code>.sh start namenode -rollback</code>
指令rollback nn,注意dn還是要rollback的
4.如果rollback或upgrade失敗,可以通過之前的備份中繼資料進行覆寫恢複
本文轉自菜菜光 51CTO部落格,原文連結:http://blog.51cto.com/caiguangguang/1579873,如需轉載請自行聯系原作者