HBase HMaster启动和停止
HMaster(0.90.3) Startup:
main方法:?new HMasterCommandLine(HMaster.class).doMain(args); //args为start
HMasterCommandLine: 用于启动/停止HMaster.doMain: 运行Tool类的run方法. 继承关系:HMasterCommandLine-->ServerCommandLine-->Tool
HMasterCommandLine.run:1. 构造CommandLine, 基本参数有三个: minServers, backup和(start/stop)? ? * minServers: 集群拥有的最少regionserver数? ? * backup: 是否是backup master? ? * start/stop: 启动或者停止实例2. 如果minServers存在? ? 设置hbase.regions.server.count.min为minServers的指, 默认为03. 如果backup存在? ? 如果有backup参数,设置hbase.master.backup为true, 默认为false4. 如果是start? ? startMaster()5. 如果是stop? ? stopMaster()? ??startMaster:hbase.cluster.distributed=false:?? ? 切换至LocalHBaseCluster(1), 启动两个JVM, 一个ZK,一个master(1)+regionserver(1).hbase.cluster.distributed=true:?? ? 1. 创建一个HMaster实例, new HMaster(Configuration).? ? ? ? * 获取master的地址: ip:port, 默认port为60000, 通过hbase.master.port设置? ? ? ? * 获取RPC的最大handler数, 通过hbase.regionserver.handler.count设置, 默认为10.? ? ? ? * 创建HMaster RPCServer实例.? ? ? ? * 设置master的replication? ? ? ? * 启动rpc server的服务线程, 但是当前服务还处于不可用状态? ? ? ? * 修改master的mapred.task.id.(为了更好的debug log, 查看HBase MR Job运行状态)? ? ? ? * 连接zookeeper, 创建相关zk node(root-region-server, unassigned, rs, table)? ? ? ? * 创建master的统计类MasterMetrics? ? 2. HMaster.start()? ? ? ? * 创建activeMasterManager对象?? ? ? ?* 如果hbase.master.backup设置为true, sleep直到有其他master节点创建masterZNode节点.? ? ? ? ? ? Backup会一直sleep直到有其他master上线.? ? ? ? * blockUntilBecomingActiveMaster: 竞争master,如果失败则阻塞直到自己成为master? ? ? ? ? ? > 首先尝试创建master节点(临时节点),如果成功,自己成为master,如果失败,说明已经存在master,不管成功失败,都会在master节点上添加一个watcher.? ? ? ? ? ? > 如果失败, 获取当前master的节点data, 转换为HServerAddress, 如果发现地址就是自己, 说明自己做为master刚刚重启了,删除master节点.如果不是自己, 什么也不干.? ? ? ? ? ? > 同步clusterHasActiveMaster, 如果clusterHasActiveMaster.get(),则wait on clusterHasActiveMaster, 等待被notify. notify以后递归调用blockUntilBecomingActiveMaster.? ? ? ? ? ? ? ? notify由handleMasterNodeChange方法触发, 一但master的zk节点有create或者delete变化,就会触发。触发后同步clusterHasActiveMaster,并notifyAll所有wait着的backup master线程.? ? ? ? ? ? ? ? 这里有一个有意思的地方, 如果是master自己重启, 重启以后发现zk上的master节点是自己, 然后删除节点, 这个时候会有两种情况:? ? ? ? ? ? ? ? 1. 删除以后,先收到watcher event, 然后同步clusterHasActiveMaster, 将clusterHasActiveMaster设置为false,notifyAll. 然后blockUntilBecomingActiveMaster进入clusterHasActiveMaster同步模块,发现clusterHasActiveMaster.get()为false, 跳过wait环节,开始递归去竞争master节点.? ? ? ? ? ? ? ? 2. 删除以后, 代码block部分先获得了clusterHasActiveMaster锁, 发现clusterHasActiveMaster.get()为true,则wait,释放锁, 然后收到watcher event,设置clusterHasActiveMaster为false, 在notifyAll唤醒wait.? ? ? ? ? ? ? ? 有意思的地方就是网络的延迟可以造成不同的执行流程, 虽然结果都一样,但是网络快的情况下,可以少一次线程切换.? ? ? ? ? ? ? ? 这个地方还发现有一个小bug, 就是blockUntilBecomingActiveMaster方法的返回值cleanSetOfActiveMaster, 如果是第一次进入blockUntilBecomingActiveMaster,成功成为master, 返回值为true,如果是经过一次递归以后成为master, 返回值为false. 究其原因, 是因为代码没有将递归的返回值重置给调用者. 唉..主要是这个返回值没有发挥作用,所以也没人在意吧.? ? ? ? ? ? ? ? // Try to become active master again now that there is no active master? ? ? ? ? ? ? ? blockUntilBecomingActiveMaster(); ?=递归改为=> cleanSetOfActiveMaster = blockUntilBecomingActiveMaster();? ? ? ? * finishInitialization: 顾名思义就是成为master以后需要完成一些初始化工作:? ? ? ? ? ? 1. 创建一些master工作需要的组件:? ? ? ? ? ? ? ? > MasterFileSystem: 封装了master常用的一些文件系统操作,包括split log file, 删除region目录,删除table目录,删除cf目录等,检查文件系统状态等.? ? ? ? ? ? ? ? > HConnection: 创建与zk的连接.? ? ? ? ? ? ? ? > ExecutorService: 维护一个ExecutorMap, 一种Event对应一个Executor(线程池). 可以提交EventHandler来执行异步事件? ? ? ? ? ? ? ? > ServerManager: 管理region server信息, 维护着online region server map, 同时也维护着每个region server rpc stub.? ? ? ? ? ? ? ? > CatalogTracker: 同步-ROOT-和.META.的Server地址信息.? ? ? ? ? ? ? ? > AssignmentManager: 负责管理和分配region, 同时它也会接受zk上关于region的event,根据event来完成region的上下线,关闭打开等工作.? ? ? ? ? ? ? ? > LoadBalancer: 负责region在region server之间的移动, 关于balancer的策略, 可以通过hbase.regions.slop来设置load区间, 下次另启一篇来深入说明下.? ? ? ? ? ? ? ? > RegionServerTracker: 通过ZK的Event来跟踪online region servers, 如果有rs下线, 删除ServerManager中对应的online regions.? ? ? ? ? ? ? ? > ClusterStatusTracker: 维护集群状态, 通过shutdown节点来设置集群的up或者shutdown状态.? ? ? ? ? ? 2. 启动集群,启动所有的服务线程:?? ? ? ? ? ? ? ? > 添加shutdown节点,并设置data为master name, 表示集群启动? ? ? ? ? ? ? ? > 启动ExecutorService中各个Event的Executor.? ? ? ? ? ? ? ? > 启动LogCleaner: 每个60秒启动一次清除old hlogs.? ? ? ? ? ? ? ? > 启动WebApp Jetty Server: 用于通过web来访问master的状态(http://host:60010/).? ? ? ? ? ? ? ? > 启动RPC Server, RPC开始接受Client请求.? ? ? ? ? ? 3. 等待region server来签到, 看策略, 这个过程应该不会太长, 如果网络抖动很厉害, 最多集群以最少regionserver数开始服务.? ? ? ? ? ? ? ? > 等待region server来签到, 每次等待1.5s, 最少等待时间4.5s, 如果online region servers到达minCount,并且在一次等待时间内没有新的server签到, 则不再等待.? ? ? ? ? ? ? ? > 统计当前online region servers总共持有的region数.? ? ? ? ? ? 4. Split log, 分发log, 执行数据恢复? ? ? ? ? ? ? ? > 获取.logs目录的log目录列表, 根据目录名和online region server的名字进行对应.? ? ? ? ? ? ? ? > 如果有regionserver存在待恢复log目录, 则开始split log工作? ? ? ? ? ? ? ? > Split log/recovery的流程这个可以另起一篇来讲.? ? ? ? ? ? 5. 分配root和meta region? ? ? ? ? ? ? ? > assignRootAndMeta: 检查Root region和first meta region是否被分配了, 如果没有, 分配他们.? ? ? ? ? ? 6. 根据集群是启动还是故障恢复的情况来做清理工作? ? ? ? ? ? ? ? > 如果当前region数为0, 表示集群是startup, 清除所有unassignment region znode, 然后扫描meta表, 重新分配所有的region.? ? ? ? ? ? ? ? > 如果当前region数大于0, 表示集群是failover状态, 将处于assignment状态的节点重新assign.? ? ? ? ? ? 7. 启动balancer定时执行线程.? ? ? ? ? ? 8. 启动.META.定时扫描清理线程.? ? ? ? * loop: 循环等待, 直到Stop.stopMaster:? ? Stop以后, HMaster线程结束, finally进行清理工作:? ??? ? ? stopChores(); //停止定时线程(balancer,meta清理,logCleaner)? ? ? // Wait for all the remaining region servers to report in IFF we were? ? ? // running a cluster shutdown AND we were NOT aborting.? ? ? if (!this.abort && this.serverManager != null &&? ? ? ? ? this.serverManager.isClusterShutdown()) {? ? ? ? this.serverManager.letRegionServersShutdown();? ? ? }? ? ? stopServiceThreads();? ? ? // Stop services started for both backup and active masters? ? ? if (this.activeMasterManager != null) this.activeMasterManager.stop();? ? ? if (this.catalogTracker != null) this.catalogTracker.stop();? ? ? if (this.serverManager != null) this.serverManager.stop();? ? ? if (this.assignmentManager != null) this.assignmentManager.stop();? ? ? HConnectionManager.deleteConnection(this.conf, true);? ? ? this.zooKeeper.close();? ??