Elasticsearch、HBase - 仿百度搜索引擎项目案例实操1(功能说明、架构设计)
本文我们通过一个仿百度搜索引擎项目来演示如何将 HBase 和 Elasticsearch 整合到一起,这里利用了 HBase 适合海量数据存储、基于 Rowkey 查询效率高的特性,以及 Elasticsearch 适合快速复杂查询的特性。



一、项目整体介绍
1,项目整体架构

2,架构说明
(1)项目的数据来源可以是通过爬虫到互联网上采集的数据,也可以是企业数据库中的内部数据
(2)根据数据的来源不同,使用不同的程序将数据入库到 HBase,实现海量数据存储
(3)针对 HBase 中的数据在 ES 中建立索引。
注意:并不是把 HBase 中数据的完整内容全部在 ES 中建立索引,只需要将检索用到的那些字段在 ES 中建立索引即可。例如:HBase 存储的原始数据有 20 个字段,在 ES 可能只需要存储 5 个字段即可,具体的存储细节在后面会详细分析。
(4)在数据展现模块中提供仿百度搜索功能。
二、ES 和 HBase 数据同步的三种方案
1,方案一
(1)这种方案在将原始数据入库 HBase 的时候,同时在 ES 中对数据建立索引,此时可以把入库 HBase 和 ES 的代码放在一个事务中,保证 HBase 和 ES 的数据一致性。

(2)这种方案的优点是操作方便,缺点是入库 HBase 和 ES 的代码绑定到一起了,耦合性太高,如果遇到 ES 出现故障,会导致入库 HBase 的操作也会失败,或者是 ES 集群压力过大的时候,会导致数据入库 HBase 的效率降低。
2,方案二
(1)该方案在将原始数据入库 HBase 的时候,通过 HBase 中的协处理器实现数据同步,让协处理器监听 HBase 中的新增和删除操作,在协处理器内部操作 ES,实现对数据建立索引的功能。
提示:HBase 中的协处理器其实类似于 MySQL 中的触发器。

(2)这种方案的优点是通过协处理器可以很方便的获取到 HBase 中新增和变化的数据,如果入库 HBase 的程序是之前已经开发好的,此时不需要对之前的代码进行任何改动,影响程度比较低。
(3)这种方案的缺点是过于依赖 HBase 了,如果后期涉及到 HBase 集群版本升级,无法保证协处理器功能的可用性。
3,方案三(本项目使用的方案)
(1)该方案在将原始数据入库 HBase 的时候,同时在 Redis 中使用 list 数据类型模拟一个队列,存储数据的 Rowkey。此时将入库 HBase 和 Redis 的操作放在一个事务里面,保证数据的一致性。然后再通过另外一个同步程序,从 Redis 的 list 队列中读取 Rowkey,根据 Rowkey 到 HBase 中获取数据的详细信息,在 ES 中建立索引,将 HBase 中数据的 Rowkey 作为 ES 中数据的 ID。

(2)在这个方案里面是将入库 HBase 和在 ES 中建立索引这两个功能解耦了,借助于中间层的 Redis 实现的。
(3)这种方案的缺点是把入库 HBase 和 Redis 的功能耦合在一起了,但是 Redis 是轻量级的,出现问题的概率是比较低的,对性能损耗也不高,所以是可以接受的。此时就算 ES 出现问题,只需要在同步程序内部实现正常的异常处理即可,将建立索引失败数据的 Rowkey 重新添加到 Redis 的 list 列表里面即可,不会导致 HBase 和 ES 数据不一致的问题。
三、项目整体执行流程
1,底层细节流程图

2,流程说明
① 通过入库程序向 HBase 中入库数据,同时在 Redis 中存储数据的 Rowkey。
② 从 Redis 中获取数据的 Rowkey,根据 Rowkey 到 HBase 中查询数据的详细信息,然后在 ES 中建立索引。
- 此时我们的海量数据已经存储到 HBase 中,并且将需要查询的字段在 ES 中建立索引了。
③ 用户向 ES 发送查询请求
④ ES 返回符合条件的数据的 ID,其实就是 HBase 中数据的 Rowkey。在这里也可以根据需求额外再返回一些字段信息都是可以的。
⑤ 当用户想要查看数据完整详细信息的时候,需要根据 Rowkey 到 HBase 中查询
⑥ HBase 会给用户返回 Rowkey 对应数据的详细信息。