继续上面的分析,主要看提交这下
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 ,我们下一讲再说......