HBase写操作流程解析

来源:互联网 发布:网络侵权案例 编辑:程序博客网 时间:2024/06/05 11:40
将Put对象放入HTable.writeAsyncBuffer:List<Row>队列中;当写入缓存的大小大于规定的值(由配置参数hbase.client.write.buffer指定)时调用backgroundFlushCommits(false)执行写操作,内部调用AsyncProcess.submit(List<? extends Row> rows, boolean atLeastOne)方法。
1.遍历List<Row>队列中的所有Row,执行如下两个操作:
   1)根据Row查找对应的Region地址,调用方法AsyncProcess.findDestLocation(Row row, int posInList),得到HRegionLocation对象;
   2)对缓存writeAsyncBuffer中的List<Row>队列进行分组。首先根据RegionName(=loc.getRegionInfo().getRegionName())进行分组得到multiAction:MultiAction<Row>,然后根据HRegionLocation进行分组得到actionsByServer:Map<HRegionLocation, MultiAction<Row>>
2.调用AsyncProcess.sendMultiAction(...)方法,将MultiAction发送到服务端;根据按HRegionLocation分组的个数来初始化N个MultiServerCallable任务并放入线程池中;发送MultiAction的任务由这些MultiServerCallable来完成,主要是在MultiServerCallable.call()方法中实现,下面讲解此实现:
 2.1 将MultiAction<Row>封装成ClientProtos.MultiRequest对象;
 2.2 通过RPC调用HRegionServer.multi(RpcController rpcc, MultiRequest request)方法;遍历request中的每个RegionAction(表示每个RegionName包含的MultiAction列表),若RegionAction是原子操作,则调用HRegionServer.mutateRows(HRegion region, List<Action> actions, CellScanner cellScanner)方法;若是非原子操作,则调用HRegionServer.  doNonAtomicRegionMutation(...)方法;
  区别:doNonAtomicRegionMutation方法是每次对每个RegionName分组下的MultiAction列表进行操作,而mutateRows方法是一次对所有的MultiAction进行操作
   2.2.1  分析HRegionServer.mutateRows(...)方法
      1.遍历RegionAction中包含的MultiAction列表,根据ClientProtos.Action信息在服务端重新初始化Put对象,然后存入RowMutations对象中;
      2.调用HRegion.mutateRow(RowMutations rm)方法,在Region中执行原子操作;
        1)初始化MultiRowMutationProcessor对象processor;
        2)调用processor.preProcess(this, walEdit)方法进行预处理;
        3)根据row个数来获取N个行锁RowLock并放入List<RowLock>队列中;获取Region锁(在HRegion.updatesLock:ReentrantReadWriteLock上获得读取锁);
        4)processor扫描行,生成mutations:List<KeyValue>,并且添加waledits记录。主要由MultiRowMutationProcessor.process(long now, HRegion region, List<KeyValue> mutationKvs,  WALEdit walEdit)方法处理。
     数据结构:Mutation对象中有familyMap成员变量,通过getFamilyCellMap().values()方法可以获取List<Cell>队列的集合;然后调用KeyValueUtil.ensureKeyValue(Cell)方法可以生成 KeyVlaue对象。
           4.1.)更新每个KeyValue的时间戳;
           4.2.)将所有KeyValue对象存入入参mutationKvs和walEdit中;
        5)获取MVCC的写序号;
        6)遍历mutationKvs(第4步中获得的KeyValue集合),更新每个KeyValue的mvcc字段(写序号),将KeyValue存入MemStore中:
                 将KeyValue存入HRegion.stores:Map<byte[], Store>中对应key值为family的value值HStore中(此Map的key为family,value为HStore),最终是将KeyValue存入HStore.MemStore中
        7)将walEdit内容写入WAL文件中;
        8)释放Region锁;
        9)释放N个行锁RowLock;
      10)同步编辑日志;(未读懂)
      11)调用processor.postProcess(HRegion region, WALEdit walEdit)方法;
   2.2.2  分析HRegionServer.doNonAtomicRegionMutation(...)方法
        1. 调用HRegionServer.doBatchOp(Builder builder, HRegion region, List<Action> mutations, CellScanner cells)方法;
        2. 对于RegionName分组下的MultiAction列表,调用HRegion.batchMutate(Mutation[] mutations, boolean isReplay)方法,最终调用doMiniBatchMutation(BatchOperationInProgress<Mutation> batchOp,boolean isInReplay)方法,对此方法的进行分析:
         1)获取行锁
         2)更新每个KeyValue的时间戳;
         3)获取Region锁(在HRegion.updatesLock:ReentrantReadWriteLock上获得读取锁);
        4)将KeyValue存入MemStore中:
        5)将所有KeyValue对象存入WALEdit对象中;
        6)添加WALEdit到WAL文件中;
        7)释放Region锁和所有的行锁;
        8)同步编辑日志;(未读懂)
        9)Run coprocessor post
0 0
原创粉丝点击