这是我参与【第四届青训营】笔记创造活动的第十四天。
Region Merge 碎片整合
region merge可以通过HBaseAdmin手动触发,或由normalization触发。merge流程如下:
- 调用MasterRpcServices::mergeTableRegions方法,从AssignmentManager查找对应regionInfo并调用HMaster::mergeRegions()方法,检查master已完成初始化且merge功能启用后提交NonceProcedureRunnable(关于Nonce的介绍见zhuanlan.zhihu.com/p/75734938)…
- MergeTableRegionsProcedure检查待合并的parent regions是否有重复,是否同table,是否相邻,是否重叠,是否主副本,是否online,集群和table状态是否可以merge。检查通过后排序regions并生成合并后region的RegionInfo(计算合并后的startKey,endKey,regionID取待合并regions最大值+1)
- 调用executeFromState,从MERGE_TABLE_REGIONS_PREPARE状态开始,检查table不能正在打snapshot,merge功能必须开启,如果region上有已merge标记需要成功清除并archive对应HDFS文件。具体逻辑是检查region的目录下是否有referenceFile,没有则提交GCMultipleMergedRegionsProcedure清理已merge的regions文件,并清理HMaster内存里对应的region信息。 GCMultipleMergedRegionsProcedure调用MetaTableAccessor.getMergeRegions检查hbase:meta表里该region的cells,过滤出column为"info:merge.*" regex格式的cell,从value解析RegionInfo,这些就是该region merge前的parent regions。
对父母region分别创建一个GCRegionProcedure,具体在GC_REGION_ARCHIVE状态下调用HFileArchiver.archiveRegion移动region文件到archive目录,如果archive目录下已存在同名文件,尝试加时间戳后缀重命名该文件,失败就删除之。move成功后删除region目录。
然后删除该region对应的WAL文件目录(存着seqid等文件),格式:$rootDir/$cluster/WALs/data/$namespace/table/regionName
然后删除AssignmentManager里该region的状态,再删除meta表里该region的info cf下所有信息。ServerManager::removeRegion清楚该region的两个seqID信息:
- The last flushed sequence id for a store in a region
- The last flushed sequence id for a region
再清理该region的FavoredNodes。
- 从meta表删除子region上对应"info:merge.*" regex格式的cq。至此完成清理父母regions里上次merge留下的元数据。
- 设置AssignmentManager里父母region的状态为MERGING
- 检查quota是否够,跳过正在执行的normalizer
- MERGE_TABLE_REGIONS_CLOSE_REGIONS 关闭父母regions
- MERGE_TABLE_REGIONS_CHECK_CLOSED_REGIONS 检查关闭都完成后
-
MERGE_TABLE_REGIONS_CREATE_MERGED_REGION移除只读副本,创建merge出的新region。具体步骤:
- 在第一个父region目录下创建
.merges临时目录 - 对父母regions的每个cf分别遍历所有storeFiles,每个storeFile分别创建referenceFile,文件名称格式:
${parent_HFile_name_before_merge}.${parent_region_name}文件内容统一指向原文件的startKey,等效于split里指向上半部分的referenceFile内容。 - commitMergedRegion将
.merged临时目录下的内容move到合并后的子region目录下 - AssignmentManager创建新region的状态为MERGING_NEW
- 在第一个父region目录下创建
- MERGE_TABLE_REGIONS_WRITE_MAX_SEQUENCE_ID_FILE:从父母region的seqid里找到最大值,写入子region的seqid文件
- MERGE_TABLE_REGIONS_UPDATE_META:AssignmentManager将子region的状态设为MERGED, 将父母region删除,regionStateStore.mergeRegions方法原子地操作meta表,删除父母region,添加子region。子region的info cf下会写入父母regions的RegionInfo,cq分别是
merge0000和merge0001。子region状态为CLOSED防止过早被master调度拉起。 子region需要添加父母regions作为replication barrier,保证父母regions都完成同步再开始同步子region。
- 创建AssignProcedure打开子region