Hbase 协处理器
在分析协处理器 Coprocessor 之前, 我们先来总结下客户端发起 RPC 请求, 最终到 HRegion 的过程
在客户端操作表中的数据时,会先找到改行的HRegionLocation,然后练习HRegionServer,通过RPC
调用HRegion上的方法,因为HRegion 才是真正存储数据的地方。
如果客户端代码想要在 HRegion 执行 CRUD 操作前后植入自定义的逻辑可以采用类似触发器的方式: 协处理器.
触发器可以在动作发生前后自定义一些动作, 协处理器也类似, 有 preOps 和 postOps 分别作用于事件前后.
下图展示了 Get 流程, 在 HRegion.get()操作前后分别执行了协处理器的 preGet 和 postGet():
注: HRegion 没有直接和 RegionObserver(即 Coprocessor 实现类)联系,而是经过了中间的 CoprocessorHost 主机.
图片来源: https://blogs.apache.org/hbase/entry/coprocessor_introduction
Coprocessor 相关的类的继承结构:
以 HRegion 上的 RegionCoprocessorHost为例, 当创建 HRegion 时(由 Master控制, RegionServer进行 open 或者 split),
会创建一个 RegionCoprocessorHost 对象, RegionCoprocessorHost 通过静态配置文件和表模式加载系统级别或者用
户级别的协处理器: loadSystemCoprocessors 和 loadTableCoprocessors. 系统级加载在抽象父类 CoprocessorHost 中
(其他 Host 比如 Master, RegionServer, WAL 也都会调用 loadSystemCoprocessors, 只是传递的 key 不同而已).
以加载静态配置文件为例, RegionCoprocessorHost 会从 hbase-site.xml 配置项"hbase.coprocessor.region.classes",
"hbase.coprocessor.user.region.classes"获取用户定义的协处理器的 Class 类型:implClass, 然后在 loadInstance()中通
过反射实例化协处理器对象 CoprocessorImpl
因为协处理器必须在专用的环境中才能运行, 即一个协处理器对应一个协处理器环境, 所以要把协处理器的 Class
类型, 以及刚刚实例化的协处理器对象, 还有一些环境需要的信息比如: 该协处理器的优先级, 加载顺序等, 调用抽
象方法 createEnvironment. 各个 CoprocessorHost 实现类都要实现该抽象方法.
用户自定义的 Coprocessor 是有不同的作用范围的, 因为 HBase 将各个组件分成 Master, RegionServer, Region.
因此不同的 Coprocessor 是要针对 HBase 中对应的组件. 而 Coprocessor 必须在专用的环境中运行, 因此 HBase 中
的各个组件都应该有各自独立的运行环境, 保证特定的 Coprocessor 只能运行在特定的专用环境中(类似隔离器)
Coprocessor, CoprocessorEnvironment, CoprocessorHost 以及 Region 的关系:
1. 一个 HRegion 只对应一个 CoprocessorHost
2. 一个 CoprocessorHost 可以有多个 CoprocessorEnvironment
3. 一个 CoprocessorEnvironment 运行一个 Coprocessor, 一个 Coprocessor 运行在唯一的 CoprocessorEnvironment
4. 因此一个 CoprocessorHost 上会有多个 Coprocessor
5. 一个 HRegion 上就可以作用多个 Coprocessor(协处理器链)