天天看點

cdh4.6.0到cdh5.2.0 upgrade和rollback問題小結

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>&lt;property&gt;</code>

<code>    </code><code>&lt;name&gt;yarn.nodemanager.aux-services&lt;</code><code>/name</code><code>&gt;</code>

<code>    </code><code>&lt;value&gt;mapreduce.shuffle&lt;</code><code>/value</code><code>&gt;</code>

<code>  </code><code>&lt;</code><code>/property</code><code>&gt;</code>

<code>    </code><code>&lt;name&gt;yarn.nodemanager.aux-services.mapreduce.shuffle.class&lt;</code><code>/name</code><code>&gt;</code>

<code>    </code><code>&lt;value&gt;org.apache.hadoop.mapred.ShuffleHandler&lt;</code><code>/value</code><code>&gt;</code>

修改為:

<code>   </code><code>&lt;property&gt;</code>

<code>    </code><code>&lt;value&gt;mapreduce_shuffle&lt;</code><code>/value</code><code>&gt;</code>

<code>    </code><code>&lt;name&gt;yarn.nodemanager.aux-services.mapreduce_shuffle.class&lt;</code><code>/name</code><code>&gt;</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)) &amp;&amp;</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&lt;String, Map&lt;String, InetSocketAddress&gt;&gt; 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&lt;String, InetSocketAddress&gt; nnMap = addresses.get(nsId);</code>

<code>    </code><code>return</code> <code>nnMap != </code><code>null</code> <code>&amp;&amp; nnMap.size() &gt; </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&lt;String, Map&lt;String, InetSocketAddress&gt;&gt;</code>

)并判斷map value的size(如果dfs.ha.namenodes.x設定超過1個就算ha),這裡隻要把配置改成下面即可

<code>        </code><code>&lt;name&gt;dfs.ha.namenodes.bipcluster&lt;</code><code>/name</code><code>&gt;</code>

<code>        </code><code>&lt;value&gt;nn1&lt;</code><code>/value</code><code>&gt;</code>

<code>&lt;</code><code>/property</code><code>&gt;</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.&lt;init&gt;(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.&lt;init&gt;(NameNode.java:621)</code>

<code>        </code><code>at org.apache.hadoop.hdfs.server.namenode.NameNode.&lt;init&gt;(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 &amp;&amp; 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 &amp;&amp; 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 &lt;bipcluster&gt;: NN ID nn1 =&gt; 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>&lt;</code><code>property</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>name</code><code>&gt;dfs.namenode.shared.edits.dir&lt;/</code><code>name</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>value</code><code>&gt;qjournal://xxxxx/bipcluster&lt;/</code><code>value</code><code>&gt;</code>

<code>&lt;/</code><code>property</code><code>&gt;</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>&lt; nameStartOpt=</code><code>"$nameStartOpt $@"</code>

<code>---</code>

<code>&gt; 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,如需轉載請自行聯系原作者

繼續閱讀