HBase 实现数据同步 ElasticSearch

HBase 作为 NoSQL 或列式数据库,虽然解决了海量数据存储需求,但查询满足非常有限。因为访问 HBase 表中的行,只有三种方式:

  1. 通过单个RowKey
  2. 通过RowKey的range(最好是前缀扫描)
  3. 全表扫描

如何实现 HBase 的复杂查询,有一些方案:

  1. 借助 Phoenix,他会给 HBase,做了个映射,生成二级索引,同时支持 SQL, 可实现一些不太复杂的查询,我觉得更适用于离线数据分析的场景。参见《Phoenix 安装与使用》
  2. 借助 HBase Indexer,Cloudera 平台默认集成,实际上就是把 HBase 数据同步到 Solr 进行索引,配置很繁琐,并且 Solr 的分布式感觉很蛋疼(除了那个admin ui还凑活)。参见《HBase Indexer 整合 Solr》

所以,HBase 还是让它好好的干存储的事情吧,检索的事情交给搜索来做,通过对比 Solr 和 ES,无疑 ES 使用起来更爽一些。那么同步方案呢?

方案

  • 客户端双写

数据可能不同步?面对高并发的写入场景,HBase能扛住,ES能否扛住?双写之前再搞个消息队列?

  • ES 从 HBase 拉数据

(类似 MySQL + Solr 的增量索引),如何增量,其实就是根据监控一个 update_time 来实现,问题也不少,比如不好监控删除的数据,并且 HBase 只有一个 Rowkey,貌似搞不了

  • HBase 入库后同步到 ES

如何实现?还要考虑 ES 的索引性能。

最终发现 HBase Coprocessor + ES BulkProcessor 可以解决上面的问题,不过要稍微写点代码,代码不是很复杂,但是调试和测试很蛋疼。

Coprocessor 与 BulkProcessor

Coprocessor 是 HBase 的协处理器,可以理解为跟数据库触发器一样的东西,他能够监听 HBase 数据改变的事件,并且运行在不同的角色上,这里我们主要是运行在 HBase Region 的 Coprocessor,

BulkProcessor 是 ES 提供的客户端API,能够实现,多少条记录,多大数据量,多少秒进行一次ES操作,相当于客户端实现的缓冲池。

问题总结

  1. 生产环境 HBase 运行在集群中,所以 Coprocessor 实现的 jar 包需要上传到 HDFS,这样确保 HBase 集群才能加载到。开发环境本地就可以了。

  2. 修改 Coprocessor 代码后,重新生成 jar 包上传到 HDFS 的文件名,必须和之前不一样,否则就算卸载掉原有的 Coprocessor 再重新安装也不能生效,建议给 jar 包增加一个版本号。

  3. 不小心删除了上一个版本的 jar,然后还没有卸载 HBase 表上老版本的Coprocessor, 完蛋,HBase 直接启动不了,解决办法是先把上一个版本的 jar 恢复,卸载或删除 HBase 的表。

这几个问题导致调试和测试痛苦的一比。

具体实现

待续