HBase Regionは二つのRegionServerに現れて分析します。
4947 ワード
HBaseの操作は一般的にレギオンを粒径としています。例えばsplit、compect、moveなどです。従って、各レギオンのクラスタにおける一意性を保証する必要がある。レギオンが二つのレギonserverに登場すると明らかに様々なバグが出現します。ここでは、レギオンが上にいるかどうかを以下の分析によって見ます。RS 1上のRegion Aに対して、そのmoveをRS 2に送り、HBaseAdminのmove操作を呼び出します。 1.BへのRegionPlanを作成する 2.次にunassigned Region Aは、RS 1上のRegion Aのregionをオフにします。主にregion上の各storeafileのデータストリームをオフにします。この過程でmemstoreの内容をディスクに書き込みます。 3.そしてRS 2でopen Region Aは、主な操作はRegion Aの初期化であり、Aのrsアドレス情報をMetaテーブルに更新する。move中にRS 1 downが落ちたと仮定すると、マスターはservershutdownhanderを呼び出してイベントを処理する。主な処理手順は以下の通りです。
マスターのメモリから、rsのregionとserverをクリアし、MasterのRIT列に戻ります。このRSのオンラインregion
プロセス全体の開始はrs shundown以降のmasterでrs上のregion再assignから他のrsに行く必要がありますが、assignが必要なregionの序曲にいくつかの問題が発生しました。masterではすでにオフしましたが、RIT列の中のregionに再割り当てされています。これらのレギオンは他の場所で割り当てられているかもしれませんが、まだ開始されていません。assign regionの時にこのregionがオンラインになりました。masterは相変わらず重い割り当てを続けて、レギオンの二回の割り当てを招きます。
public void process() throws IOException {
final String serverName = this.hsi.getServerName();
ログを分割して、regionserverのhlogsをregionの違いによって分割し、それぞれのレギオンディレクトリに書き込みます。 LOG.info("Splitting logs for " + serverName);
this.services.getMasterFileSystem().splitLog(serverName);
マスターのメモリから、rsのregionとserverをクリアし、MasterのRIT列に戻ります。このRSのオンラインregion
// Clean out anything in regions in transition. Being conservative and
// doing after log splitting. Could do some states before -- OPENING?
// OFFLINE? -- and then others after like CLOSING that depend on log
// splitting.
List regionsInTransition =
this.services.getAssignmentManager().processServerShutdown(this.hsi);
[このRSがROOTやMETAを含む場合は、まずこれを割り当てる必要があります。 // Assign root and meta if we were carrying them.
if (isCarryingRoot()) { // -ROOT-
try {
this.services.getAssignmentManager().assignRoot();
} catch (KeeperException e) {
this.server.abort("In server shutdown processing, assigning root", e);
throw new IOException("Aborting", e);
}
}
// Carrying meta?
if (isCarryingMeta())this.services.getAssignmentManager().assignMeta();
meta表からRS 1上のレギオンを取得します。// Wait on meta to come online; we need it to progress.
// TODO: Best way to hold strictly here? We should build this retry logic
// into the MetaReader operations themselves.
NavigableMap hris = null;
while (!this.server.isStopped()) {
try {
this.server.getCatalogTracker().waitForMeta();
hris = MetaReader.getServerUserRegions(this.server.getCatalogTracker(),
this.hsi);
break;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("Interrupted", e);
} catch (IOException ioe) {
LOG.info("Received exception accessing META during server shutdown of " +
serverName + ", retrying META read");
}
}
RITを除去した状態はCloseまたはPendingCloseのregionであり、再割り当てが必要なregionsを得ることができる。 // Skip regions that were in transition unless CLOSING or PENDING_CLOSE
for (RegionState rit : regionsInTransition) {
if (!rit.isClosing() && !rit.isPendingClose()) {
LOG.debug("Removed " + rit.getRegion().getRegionNameAsString() +
" from list of regions to assign because in RIT");
hris.remove(rit.getRegion());
}
}
move中に、regionがまだオンラインされていない場合、マスターのRIT列のregionの状態はOFFLINEです。このregionはマスターの角度から見ればoffineですが、severshutdonの処理では、このレギオンが新たに割り当てられると考えられています。この時、レギオンがRS 2線上になったら、マスターはまだこのレギオンを割り当てます。の二次分配過程[コード=&java]] LOG.info("Reassigning " + hris.size() + " region(s) that " + serverName +
" was carrying (skipping " + regionsInTransition.size() +
" regions(s) that are already in transition)");
// Iterate regions that were on this server and assign them
for (Map.Entry e: hris.entrySet()) {
if (processDeadRegion(e.getKey(), e.getValue(),
this.services.getAssignmentManager(),
this.server.getCatalogTracker())) {
this.services.getAssignmentManager().assign(e.getKey(), true);
}
}
this.deadServers.finish(serverName);
LOG.info("Finished processing of shutdown of " + serverName);
}
プロセス全体の開始はrs shundown以降のmasterでrs上のregion再assignから他のrsに行く必要がありますが、assignが必要なregionの序曲にいくつかの問題が発生しました。masterではすでにオフしましたが、RIT列の中のregionに再割り当てされています。これらのレギオンは他の場所で割り当てられているかもしれませんが、まだ開始されていません。assign regionの時にこのregionがオンラインになりました。masterは相変わらず重い割り当てを続けて、レギオンの二回の割り当てを招きます。