SpringBoot - 实现基于Elasticsearch+HBase全文检索系统教程1(架构设计、安装配置)
作者:hangge | 2025-05-29 09:01
一、全文搜索系统需求分析
1,需求说明
企业有一套爬虫程序,每天都会到互联网上抓取海量的文章数据,对于这些文章数据有以下需求:
- 要实现海量文章数据存储,支持数据更新需求。
- 提供针对海量文章数据的快速复杂查询功能。
2,需求分析
(1)Elasticsearch 最擅长的是快速复杂查询,虽然它支持分布式,也可以存储海量数据,但是这并不是它最擅长的功能,因为数据存储多了之后肯定会影响性能。所以,单纯使用 Elasticsearch 来实现这个需求是不太合适的。
(2)对于海量数据存储可以考虑 HDFS、HBase、Kudu 这几个海量数据存储系统。首先要把 HDFS 排除掉,因为 HDFS 不支持更新操作。剩下的是 HBase 和 Kudu,这两个工具都支持更新操作,但是 Kudu 的随机查询性能不如 HBase,所以对于存储这块考虑使用 HBase。但是单纯使用 HBase 也是无法满足需求的,HBase 只有根据 Rowkey 查询效率才高,根据其他字段查询效率是比较差的。
二、系统架构流程设计
1,整体架构流程设计
全文搜索系统需求的解决方案大致可以划分为数据采集、数据存储、数据索引、数据展现这几个模块:
- 数据采集:项目的数据可以是通过爬虫从互联网上采集的数据,也可以是企业数据库中的内部数据。
- 数据存储:根据数据的来源不同,使用不同的程序将数据入库 HBase,实现海量数据存储。
- 数据索引:按照需求在 Elasticsearch 中对 HBase 中数据的部分字段建立索引。
- 数据展现:在页面中提供数据检索效果。

2,在 Elasticsearch 中同步对 HBase 中的数据建立索引的 3 种设计方案
(1)方案 1:在将原始数据存入 HBase 时,同时在 Elasticsearch 中对数据建立索引,此时可以把入库 HBase 和 Elasticsearch 的代码放在一个事务中,保证 HBase 和 Elasticsearch 的数据一致性。
- 优点:操作方便。
- 缺点:入库 HBase 和 Elasticsearch 的代码绑定在一起,耦合性太高。如果 Elasticsearch 出现故障,则会导致入库 HBase 的操作也会失败,或者当 Elasticsearch 集群压力过大时,会导致数据入库 HBase 的效率降低。

(2)方案 2:在将原始数据入库 HBase 时,通过 HBase 中的协处理器实现数据同步。让协处理器监听 HBase 中的新增和删除操作,在协处理器内部操作 Elasticsearch,实现对数据建立索引的功能。其中 HBase 中的协处理器其实类似于 MySQL 中的触发器。
- 优点:通过协处理器可以很方便地获取 HBase 中变化的数据。如果入库 HBase 的程序是之前已经开发好的,则此时不需要对之前的代码进行任何改动,影响程度比较低。
- 缺点:过于依赖 HBase,如果后期要进行 HBase 集群的版本升级,则无法保证协处理器功能的可用性。

(3)方案 3(即此次我们采用的方案):在将原始数据入库 HBase 时,同时在 Redis 中使用 List 数据类型模拟一个队列,存储数据的 Rowkey。此时,将入库 HBase 和 Redis 的操作放在一个事务中,保证数据的一致性。然后,通过另外一个同步程序从 Redis 的 List 队列中读取 Rowkey,根据 Rowkey 到 HBase 中获取数据的详细信息。最后,在 Elasticsearch 中建立索引。此时会将 HBase 中数据的 Rowkey 作为 Elasticsearch 中索引数据的 ID。
- 优点:在这个方案中,将入库 HBase 和在 Elasticsearch 中建立索引这两个功能解耦了,是借助中间层的 Redis 来实现的。此时就算 Elasticsearch 出现问题,只需要在同步程序内部实现正常的异常处理即可,将建立索引失败数据的 Rowkey 重新添加到 Redis 的 List 列表中即可,不会出现 HBase 和 Elasticsearch 数据不一致的问题。
- 缺点:把入库 HBase 和入库 Redis 的功能耦合在一起。但是 Redis 是轻量级的,出现问题的概率比较低,对性能损耗也不高,所以是可以接受的。

3,底层执行流程
基于 Elasticsearch + HBase 的全文搜索系统,其底层执行流程如下所示:
- ① 入库程序向 HBase 入库数据,同时在 Redis 中存储数据的 Rowkey。
- ② 从 Redis 中获取数据的 Rowkey,根据 Rowkey 到 HBase 中查询数据的详细信息,然后在 Elasticsearch 中建立素引。此时,海量文章数据已经被存储到 HBase 中,并且将需要查询的字段在 Elasticsearch 中建立索引了。
- ③ 用户向 Elasticsearch 发送查询请求。
- ④ Elasticsearch 返回符合条件数据的 ID(其实就是 HBase 中数据的 Rowkey)。在这里也可以根据需求额外再返回一些字段信息。
- ⑤ 当用户想查看数据完整详细信息时,需要根据 Rowkey 到 HBase 中进行查询。
- ⑥ HBase 给用户返回 Rowkey 对应数据的详细信息。

4,开发流程分析
(1)全文搜索系统主要涉及数据采集、数据存储、数据索引和数据展现这些模块。
- 数据采集模块主要涉及爬虫工具的开发,在这里就不再扩展了,直接使用接口模拟获取数据。
- 重点实现数据存储和数据索引模块的开发。
- 而数据展现模块中主要实现对接搜索功能的核心代码即可。
(2)大致的开发步骤如下:
- (1)调用接口获取数据,并将其导入 HBase 和 Redis(存储 Rowkey)。
- (2)通过 Elasticsearch 对 HBase 中的数据建立索引。
- (3)对接 Web 项目,在页面中提供全文搜索功能。
三、SpringBoot 项目配置
(1)编辑项目的 pom.xml 文章,在其中添加 Elasticsearch、Redis、HBase 等相关依赖:
<!-- fastjson依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.15</version>
</dependency>
<!-- hbase-client 依赖 -->
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.3.0</version>
</dependency>
<!-- redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- elasticsearch依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
(2)接着在项目的 application.properties 文件中配置 Elasticsearch、Redis、HBase 的连接信息:
# HBase 连接配置 hbase.config.hbase.zookeeper.quorum=192.168.60.9 hbase.config.hbase.zookeeper.property.clientPort=2181 # redis 基本连接信息配置 spring.redis.database=0 spring.redis.host=192.168.60.9 spring.redis.port=6379 spring.redis.password= # redis 连接池信息配置 spring.redis.jedis.pool.max-active=8 spring.redis.jedis.pool.max-idle=8 spring.redis.jedis.pool.max-wait=-1ms spring.redis.jedis.pool.min-idle=0 # elasticsearch 连接配置 spring.elasticsearch.uris=192.168.60.9:9200
全部评论(0)