hbase create table過程解析

程序入口

在org.apache.hadoop.hbase.master.HMaster中定義了MasterRpcServices提供rpc服務
org.apache.hadoop.hbase.master.MasterRpcServices實現(xiàn)了接口MasterProtos.MasterService.BlockingInterface
其中使用了google的protobuf rpc通信异吻,可以參見另一篇文章:hbase與客戶端的通信過程解析鉴吹,最終實現(xiàn)了createTable接口:

@Override
  public CreateTableResponse createTable(RpcController controller, CreateTableRequest req)
  throws ServiceException {
    HTableDescriptor hTableDescriptor = HTableDescriptor.convert(req.getTableSchema());
    byte [][] splitKeys = ProtobufUtil.getSplitKeysArray(req);
    try {
      long procId =
          master.createTable(hTableDescriptor, splitKeys, req.getNonceGroup(), req.getNonce());
      return CreateTableResponse.newBuilder().setProcId(procId).build();
    } catch (IOException ioe) {
      throw new ServiceException(ioe);
    }
  }

habse的procedure框架

 @Override
  public long createTable(
      final HTableDescriptor hTableDescriptor,
      final byte [][] splitKeys,
      final long nonceGroup,
      final long nonce) throws IOException {
    ...

    return MasterProcedureUtil.submitProcedure(
      new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {
      @Override
      protected void run() throws IOException {
        ...
        ProcedurePrepareLatch latch = ProcedurePrepareLatch.createLatch();
        submitProcedure(new CreateTableProcedure(
          procedureExecutor.getEnvironment(), hTableDescriptor, newRegions, latch));
        latch.await();
        ...
      }
    });
  }

這里引用了兩個概念皿伺,一個是NonceProcedureRunnable惰瓜,意思是以下的代碼只能同時執(zhí)行一次账磺,避免重復執(zhí)行同一個create table操作临梗;另一個是Procedure宇挫,對一些必須保證事務性的操作捧书,hbase實現(xiàn)了一套Procedure操作吹泡,方便rollback;

org.apache.hadoop.hbase.procedure2.ProcedureExecutor

定義了幾個核心的方法:

  • public long submitProcedure(final Procedure proc, final NonceKey nonceKey)
    實現(xiàn)了一個Procedure的提交過程经瓷,寫wal爆哑,同時將Procedure加入runnable和rollback隊列
  • private void execProcedure(final RootProcedureState procStack, final Procedure procedure)
    執(zhí)行一個procedure,如果procedure有下一步要執(zhí)行的subprocedure舆吮,那么繼續(xù)執(zhí)行
  • private boolean executeRollback(final Procedure proc)
    實現(xiàn)一個procedure的rollback
  • private void load(final boolean abortOnCorruption)
    當程序異常終止后通過wal恢復現(xiàn)場
org.apache.hadoop.hbase.procedure2.Procedure
  • execute()
    is called each time the procedure is executed.it may be called multiple times in case of failure and restart, so the code must be idempotent.the return is a set of sub-procedures or null in case the procedure doesn't have sub-procedures. Once the sub-procedures are successfully completed the execute() method is called again, you should think at it as a stack:

  • rollback()
    is called when the procedure or one of the sub-procedures is failed.he rollback step is supposed to cleanup the resources created during theexecute() step. in case of failure and restart rollback() may be called multiple times, so the code must be idempotent.

org.apache.hadoop.hbase.procedure2.StateMachineProcedure

實現(xiàn)了一個按照state去以此執(zhí)行的procedure

  • Once the procedure is running, the procedure-framework will call executeFromState()揭朝, using the 'state' provided by the user. The implementor can jump between states using setNextState(MyStateEnum.ordinal()).
  • The rollback will call rollbackState() for each state that was executed, in reverse order.
對procedure框架的使用:
  • 實現(xiàn)procedure類:CreateTableProcedure extends StateMachineProcedure<MasterProcedureEnv, CreateTableState>
  • 在Hmaster中start一個ProcedureExecutor,提交CreateTableProcedure

具體的create table過程

@Override
  protected Flow executeFromState(final MasterProcedureEnv env, final CreateTableState state)
      throws InterruptedException {
    if (LOG.isTraceEnabled()) {
      LOG.trace(this + " execute state=" + state);
    }
    try {
      switch (state) {
        case CREATE_TABLE_PRE_OPERATION:
          // Verify if we can create the table
          boolean exists = !prepareCreate(env);
          ProcedurePrepareLatch.releaseLatch(syncLatch, this);

          if (exists) {
            assert isFailed() : "the delete should have an exception here";
            return Flow.NO_MORE_STATE;
          }

          preCreate(env);
          setNextState(CreateTableState.CREATE_TABLE_WRITE_FS_LAYOUT);
          break;
        case CREATE_TABLE_WRITE_FS_LAYOUT:
          newRegions = createFsLayout(env, hTableDescriptor, newRegions);
          setNextState(CreateTableState.CREATE_TABLE_ADD_TO_META);
          break;
        case CREATE_TABLE_ADD_TO_META:
          newRegions = addTableToMeta(env, hTableDescriptor, newRegions);
          setNextState(CreateTableState.CREATE_TABLE_ASSIGN_REGIONS);
          break;
        case CREATE_TABLE_ASSIGN_REGIONS:
          assignRegions(env, getTableName(), newRegions);
          setNextState(CreateTableState.CREATE_TABLE_UPDATE_DESC_CACHE);
          break;
        case CREATE_TABLE_UPDATE_DESC_CACHE:
          updateTableDescCache(env, getTableName());
          setNextState(CreateTableState.CREATE_TABLE_POST_OPERATION);
          break;
        case CREATE_TABLE_POST_OPERATION:
          postCreate(env);
          return Flow.NO_MORE_STATE;
        default:
          throw new UnsupportedOperationException("unhandled state=" + state);
      }
    } catch (HBaseException|IOException e) {
      LOG.error("Error trying to create table=" + getTableName() + " state=" + state, e);
      setFailure("master-create-table", e);
    }
    return Flow.HAS_MORE_STATE;
  }

入代碼所示色冀,流程如下:

  • CREATE_TABLE_PRE_OPERATION
    判斷表存在潭袱,調用MasterCoprocessor;
    注意這行代碼:ProcedurePrepareLatch.releaseLatch(syncLatch, this);
    意味著當判斷過table是否存在后latch釋放锋恬,客戶端請求即可返回屯换,因此create table這個操作對于客戶端來說本身是一個異步操作
  • CREATE_TABLE_WRITE_FS_LAYOUT
    在磁盤上創(chuàng)建對應的目錄文件
  • CREATE_TABLE_ADD_TO_META
    將table加到meta表里邊,但是region并不可用
  • CREATE_TABLE_ASSIGN_REGIONS
    將region分配給regionserver与学,這一步將region都設置為offline趟径,寫到zk的region-in-transition目錄下,提供給regionserver接管癣防;同時會enable這個table;
  • CREATE_TABLE_UPDATE_DESC_CACHE
    update一下內存中的cache
  • CREATE_TABLE_POST_OPERATION
    調用MasterCoprocessor掌眠;
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末蕾盯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蓝丙,更是在濱河造成了極大的恐慌级遭,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蹬癌,死亡現(xiàn)場離奇詭異揪阶,居然都是意外死亡旨别,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門丢郊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盔沫,“玉大人,你說我怎么就攤上這事枫匾〖艿” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵干茉,是天一觀的道長谴忧。 經常有香客問我,道長角虫,這世上最難降的妖魔是什么沾谓? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮戳鹅,結果婚禮上均驶,老公的妹妹穿的比我還像新娘。我一直安慰自己粉楚,他們只是感情好辣恋,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著模软,像睡著了一般伟骨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上燃异,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天携狭,我揣著相機與錄音,去河邊找鬼回俐。 笑死逛腿,一個胖子當著我的面吹牛,可吹牛的內容都是我干的仅颇。 我是一名探鬼主播单默,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼忘瓦!你這毒婦竟也來了搁廓?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤耕皮,失蹤者是張志新(化名)和其女友劉穎境蜕,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凌停,經...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡粱年,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了罚拟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片台诗。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡完箩,死狀恐怖,靈堂內的尸體忽然破棺而出拉庶,到底是詐尸還是另有隱情嗜憔,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布氏仗,位于F島的核電站吉捶,受9級特大地震影響,放射性物質發(fā)生泄漏皆尔。R本人自食惡果不足惜呐舔,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望慷蠕。 院中可真熱鬧珊拼,春花似錦、人聲如沸流炕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽每辟。三九已至剑辫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渠欺,已是汗流浹背妹蔽。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留挠将,地道東北人胳岂。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像舔稀,于是被迫代替她去往敵國和親乳丰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內容