Replication会在Region Server初始化HLog的时候启动, 具体流程如下:
- 判断replication是否打开
- 配置 sourceClassname和sinkClassname 看来可以配置写到不同的系统中
- 如果source和sink用的是相同的class, 则复用一个replicationSourceHandler, 否则各自建一个replicationSourceHandler(如果不配置都是Replication这个类) -> initialize
- 初始化replication线程, 具体线程如下:
replicationQueue: 存储在zk上
zk上每个regionserver会有一个节点, 里面有该rs上的所有hlog
即: /hbase/replication/rs/hostname.example.org,6020,1234/1
/hbase/replication/rs/hostname.example.org,6020,1234/2
每个hlog节点会记录被备份到的最近位置
/hbase/replication/rs/hostname.example.org,6020,1234/1/23522342.23422 [VALUE: 254]
replicationPeers: 同样存储在zk上
根据用户在创建时的peer_id创建的 /hbase/replication/peers/1 [Value: zk1.host.com,zk2.host.com,zk3.host.com:2181:/hbase], 存的信息是对应的zk值以及hbase的znode
每个peer都有一个指示当前状态的znode
/hbase/replication/peers/1/peer-state [Value: ENABLED]
每个peer都有一个指示哪些表需要被replicate的znode
/hbase/replication/peers/1/tableCFs [Value: "table1; table2:cf1,cf3; table3:cfx,cfy"]
replicationTracker
主要是注册了两个watcher
OtherRegionServerWatcher:当有别的机器挂的时候会通知
PeersWatcher:当有peer被创建或者删除的时候会通知
replicationSourceManager:
initialize的时候会把deadserver上的queue去grab到自己的node上, 跟split HLog的逻辑相同
- 创建完ReplicationInstance以及相关线程之后, 会马上调用instantiateHLog(rootDir, logName), 里面会调用getWALActionListeners, 这一步实际就是把replicationSourceHandler注册到WALActionListeners中, 这样在对HLog进行操作时都会触发listener操作。
之后在regionserver启动服务线程的时候会启动replicationSourceHandler
1. 启动replicationManager
为每个peer创建ReplicationSource: 里面会创建ReplicationEndpoint, 相当于拷贝时客户端的角色
尝试把deadserver上的replicationQueue 拿到自己这里进行处理
2. 启动replicationSink
创建一个对应集群的HConnection
3. 启动ReplicationStatisticsThread
周期性打印replication数据
到目前为止, 准备工作都已经就绪, 下面看下在写入数据时是如何触发replication的:
- replication 并不是每次写入HLog都会触发, 而是在每次LogRoll的时候:
preLogRoll -> 在zk上创建该log的znode
postLogRoll -> 把该log放入各个ReplicationSource的队列中等待被处理
接着就是ReplicationSource真正处理Log的逻辑了
首先check一些设置是否正确
然后看下这个replicationLog是不是recover的, 如果是就会seek到上次的位置
终于开始处理log了, 会给log做一个snapshot
开始传输啦(没有详细看)
更新ReplicationPosition
先暂时写到这, 目前replication log具体备份的细节没有看, 还有故障再分配的细节也还没看