代码起始位置:HRegionServer 2145行。
此处的REPORT是指向zookeeper汇报,如果WITHOUT_REPORT则不对zookeeper节点做处理。接下来按照需要向zookeeper汇报的逻辑进行分析。
命令处理直接调用closeRegion,函数中首先向zookeeper中写入region正在关闭事件(HBaseEventType.RS2ZK_REGION_CLOSING);然后获取region对象,调用region的close方法;从在线region集合和统计region log id的集合中移除region信息;向近期关闭的region列表中加入region信息(列表中只保存3个最近关闭的region);最后,向zookeeper中写入region已关闭事件(HBaseEventType.RS2ZK_REGION_CLOSED)。
3.2.2 region关闭代码起始位置:HRegionServer 2402行。
region.close()是本地region关闭时的主要处理内容,函数注释内容为:关闭此HRegion。只要参数abort(退出进程)不为true就会flush缓存。关闭每个HStore并不再响应任何请求。此方法会消耗一些时间,因此不要在时间敏感的线程中调用此函数。返回值为所有组成HRegion的HStoreFile的列表。当此region此次不关闭或已经被关闭过时,返回null。
接下来分析函数的代码逻辑:首先建立任务监控对象;然后获取splitLock可见关闭与split是互斥操作;然后获取写状态对象writestate锁,禁止写入操作;等待compact和flush结束(此处使用writestate.wait()阻塞,我觉得容易造成死锁或错误的阻塞,应该使用wait(long timeout));如果之前没有刷新过且MemStore中的数据缓存大于hbase.hregion.preclose.flush.size则进行一次flush MemStore,完成此操作后将要禁止读取操作。
然后获取扫库操作锁、获取split和关闭操作时使用的锁对象splitsAndClosesLock的写入锁(该锁将会阻塞部分读取操作);设置region closing标记为true;等待行锁释放;再次执行刷新MemStore;多线程地执行store.close()(分布式的关闭文件读取对象),关闭列族数据存储对象;向结果列表中加入已关闭的数据存储文件StoreFile对象;设置region closed标记为true。
3.3 MSG_REGIONSERVER_QUIESCE此命令要求关闭所有用户region,所以在关闭前排除meta表region即可(可是root表呢)。