Hbase源码研究(五)------put(3)

继续上面的分析,主要看提交这下

 OperationStatus[] codes = region.put(putsWithLocks.toArray(new Pair[]{}));

仔细看put这个方法

/**
   * Perform a batch of puts.
   *
   * @param putsAndLocks
   *          the list of puts paired with their requested lock IDs.
   * @return an array of OperationStatus which internally contains the
   *         OperationStatusCode and the exceptionMessage if any.
   * @throws IOException
   */
  public OperationStatus[] put(
      Pair<Put, Integer>[] putsAndLocks) throws IOException {
    BatchOperationInProgress<Pair<Put, Integer>> batchOp =
      new BatchOperationInProgress<Pair<Put,Integer>>(putsAndLocks);

    while (!batchOp.isDone()) {
      checkReadOnly();
      checkResources();

      long newSize;
      startRegionOperation();
      this.writeRequestsCount.increment();
      try {
        long addedSize = doMiniBatchPut(batchOp);
        newSize = this.addAndGetGlobalMemstoreSize(addedSize);
      } finally {
        closeRegionOperation();
      }
      if (isFlushSize(newSize)) {
        requestFlush();
      }
    }
    return batchOp.retCodeDetails;
  }

循环遍历每个Pair<put,Integer>, 分别进行如下操作。

首先在put 之前先做两项检查

     checkReadOnly();
     checkResources();

分别检查这个Region块是否只读,并且是否可以进行put操作(memstore需不需要先flush)。

然后执行

/**
   * This method needs to be called before any public call that reads or
   * modifies data. It has to be called just before a try.
   * #closeRegionOperation needs to be called in the try's finally block
   * Acquires a read lock and checks if the region is closing or closed.
   * @throws NotServingRegionException when the region is closing or closed
   */
  private void startRegionOperation() throws NotServingRegionException {
    if (this.closing.get()) {
      throw new NotServingRegionException(regionInfo.getRegionNameAsString() +
          " is closing");
    }
    lock.readLock().lock();
    if (this.closed.get()) {
      lock.readLock().unlock();
      throw new NotServingRegionException(regionInfo.getRegionNameAsString() +
          " is closed");
    }
  }  


获取了读锁之后, 在 writeRequestsCount.increment();  这里再次证明是一个put一个writeRequest ,而且不是一次RPC一个writeRequest

紧接着就调用了doMiniBatchPut(后面再介绍这个函数)

提交完毕之后,调用这个这个函数

newSize = this.addAndGetGlobalMemstoreSize(addedSize);


用来更新memstore大小

最后在finally里关闭读锁

  /**
   * Closes the lock. This needs to be called in the finally block corresponding
   * to the try block of #startRegionOperation
   */
  private void closeRegionOperation(){
    lock.readLock().unlock();
  }


如果memstore达到flush的条件,就进行flush

 if (isFlushSize(newSize)) {
        requestFlush();
      }

 

这个方法就执行完了.......

最为重要的doMiniBatchPut ,我们下一讲再说......

你可能感兴趣的:(hbase,hbase)