Elasticsearch:高性能分布式搜索与分析引擎
推荐文章
第一章 MySQL:关系型数据库
第二章 Redis:高性能内存数据库
第三章 MQ:高性能、分布式消息队列
第四章 Elasticsearch:高性能分布式搜索、分析引擎
Elasticsearch:高性能分布式搜索与分析引擎
前言
在当今大数据时代,搜索和分析海量数据是一项关键任务。Elasticsearch 是一种流行的开源搜索和分析引擎,具有分布式、实时和高可伸缩性的特性。本博客将介绍 Elasticsearch 的核心概念、基本架构和关键功能,帮助读者了解如何构建高性能的搜索和分析引擎。
一、Elasticsearch 简介
1.1 什么是 Elasticsearch?
Elasticsearch 是一种开源的分布式搜索和分析引擎,基于 Apache Lucene 引擎构建而成。它支持实时数据搜索、分析和存储,并具有高可用性、弹性和可扩展性。
1.2 Elasticsearch的应用场景
Elasticsearch 的强大搜索和分析功能使其在许多不同的应用场景中得到广泛应用。以下是一些常见的 Elasticsearch 应用场景:
- 企业搜索: Elasticsearch可用于构建强大的企业搜索引擎,帮助用户快速检索和浏览企业内部的各种信息,如文档、邮件、文件、用户资料等。它可以提供高效的全文搜索、自动提示、同义词处理和相关性排序等功能。
- 日志分析: Elasticsearch 可以用于实时处理和分析海量日志数据。通过将日志数据索引到 Elasticsearch中,可以轻松地搜索、过滤和统计日志信息,以便进行故障排查、性能监控、安全审计等操作。结合 Kibana这样的数据可视化工具,可以直观地展示日志数据的趋势和模式。
- 实时数据分析: Elasticsearch适用于实时数据分析和探索性分析。它可以处理大规模的实时数据流,例如传感器数据、网络日志、在线交易数据等。通过将数据索引到Elasticsearch 中,可以使用强大的聚合功能和数据可视化工具,进行实时的数据分析和洞察。
- 商品推荐: Elasticsearch可以用于构建个性化的商品推荐系统。它可以根据用户的行为、偏好和历史数据,实时地计算商品的相关性,并提供个性化的推荐结果。将Elasticsearch 与机器学习算法结合使用,可以进一步提高推荐的准确性和用户体验。
- 文本挖掘和自然语言处理: Elasticsearch提供了丰富的文本处理功能,例如词语分析、同义词处理和关键词提取等。这使得它成为文本挖掘和自然语言处理任务的理想选择,如情感分析、内容分类、实体识别等。
- 地理空间数据分析: Elasticsearch具有强大的地理空间搜索和分析功能,支持地理位置的索引和查询。它可以用于构建地理信息系统(Geographic Information System,简称 GIS),分析地理数据,如地理位置搜索、附近位置查找、热点地区分析等。
除了上述应用场景,Elasticsearch 还可以用于知识图谱构建、智能推荐、文档管理、事件日程管理等等。由于其灵活性和可扩展性,它已经成为许多组织和企业处理大数据和实时应用的首选工具之一。
1.3 Elasticsearch和传统数据库的区别
当处理大量数据并需要进行全局搜索时,使用 Elasticsearch 和传统数据库之间存在一些区别和考虑因素。以下是一些需要注意的点:
- 搜索性能: Elasticsearch是专门设计用于搜索和分析的引擎,提供了高速的全文搜索和复杂查询功能。相比之下,传统数据库的搜索性能可能不如 Elasticsearch高效,尤其是在大规模数据集和复杂查询条件下。
- 数据结构和灵活性: 传统数据库通常使用表和列进行数据存储,而 Elasticsearch 使用文档和索引的概念。文档可以是非规范化和具有动态字段的,这使得 Elasticsearch对数据结构更加灵活,适用于半结构化和非结构化数据。此外,Elasticsearch 在索引创建后可以更改其 mapping和设置,而数据库在设计时通常需要预定义表结构。
- 分布式性能和可扩展性: Elasticsearch是一个分布式的搜索引擎,可以通过水平扩展和数据分片来处理大量数据。它能够在多个节点上进行并行处理,提供更好的性能和高可用性。传统数据库通常在单个服务器上运行,随着数据量增加,需要在硬件和数据库层面进行垂直扩展,因此其扩展性可能有限。
- 搜索和分析功能: Elasticsearch提供了强大的搜索和分析功能,例如全文搜索、模糊匹配、聚合和过滤等。这些功能使得对大数据集进行复杂的搜索和分析变得更加简便。相比之下,传统数据库可能需要编写复杂的SQL 查询来实现类似的搜索功能。
- 实时数据更新: Elasticsearch 支持实时索引和搜索,可以在数据更新后立即进行搜索操作。而传统数据库通常需要较多的操作和时间来确保索引的更新和一致性。
需要注意的是,Elasticsearch并不是用来替代传统数据库的,它的设计目标是高性能搜索和分析,而传统数据库则更专注于数据的事务性操作和数据的可维护性。在实际应用中,可以将 Elasticsearch 与传统数据库结合使用,根据不同的需求选择合适的存储和查询方式。
总之,Elasticsearch 在全局搜索场景下具有较高的性能、灵活的数据结构、分布式和可扩展性,以及强大的搜索和分析功能,使其成为处理大量数据时的优选解决方案。
二、安装和配置 Elasticsearch
2.1 安装 Docker:
确保已经安装了 Docker。参考:Docker 简介
2.2 拉取 Elasticsearch 镜像:
打开终端或命令提示符,并运行以下命令来拉取 Elasticsearch 镜像:
docker pull elasticsearch:7.9.2
2.3. 创建挂载路径
# 根目录选择自身实际最大磁盘路径 一般为/home 或者定义/data
mkdir -p /home/elasticsearch/config
mkdir -p /home/elasticsearch/data
mkdir -p /home/elasticsearch/plugins
# 授权
chmod 777 /home/elasticsearch/config
chmod 777 /home/elasticsearch/data
chmod 777 /home/elasticsearch/plugins
编写配置文件
# 写入配置
echo 'http.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*" '>>/home/elasticsearch/config/elasticsearch.yml
2.4. 创建并运行 Elasticsearch 容器:
2.4.1 单实例创建
# 单实例
docker run --name elasticsearch -p 9200:9200 \
-p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
-v /home/elasticsearch/config/elasticsearch.yml:/usr/shellare/elasticsearch/config/elasticsearch.yml \
-v /home/elasticsearch/data:/usr/shellare/elasticsearch/data \
-v /home/elasticsearch/plugins:/usr/shellare/elasticsearch/plugins \
-d elasticsearch:7.9.2
安装分词器
docker exec -it elasticsearch /bin/bash
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.9.2/elasticsearch-analysis-ik-7.9.2.zip
ps: 安装的ik分词器的版本一定要与elasticsearch的版本保持一致
下载完成之后,退出去,重新启动elasticsearch容器。
docker restart elasticsearch
测试ik分词器是否安装成功,postman post请求分词测试:http://服务器IP地址:9200/_analyze
{
"tokenizer":"ik_smart",
"text":"我爱技术"
}
结果
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "爱",
"start_offset": 1,
"end_offset": 2,
"type": "CN_CHAR",
"position": 1
},
{
"token": "技术",
"start_offset": 2,
"end_offset": 4,
"type": "CN_WORD",
"position": 2
}
]
}
2.4.2 集群创建
修改 elasticsearch.yml 配置文件
cluster.name: my-cluster
node.name: node-1
network.host: 0.0.0.0
discovery.seed_hosts: ["node-1", "node-2"]
cluster.initial_master_nodes: ["node-1", "node-2"]
在这个配置文件中,我们指定了集群名称为 my-cluster,节点名称为 node-1,使用了 0.0.0.0 作为网络主机,discovery.seed_hosts 指定了集群中其他节点的主机名(这里我们暂时使用 node-1 和 node-2),cluster.initial_master_nodes 用于指定初始主节点。
// 集群创建
docker run -d --name node-1 -p 9200:9200 -p 9300:9300 -v /path/to/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml docker.elastic.co/elasticsearch/elasticsearch:{版本号}
这将创建一个名为 node-1 的 Elasticsearch 容器,并将容器的 9200 和 9300 端口映射到主机上。-v 参数用于将主机上的配置文件路径 (/path/to/elasticsearch.yml) 挂载到容器中的相应路径,以应用我们之前创建的配置文件。
根据集群规模,您可以在其他主机或虚拟机上重复上述步骤以创建更多的 Elasticsearch 节点。请确保将每个节点的名称和配置文件中的 node.name 和 discovery.seed_hosts 参数进行相应的更改。
通过重复上述步骤为所有节点创建并运行容器后,您将拥有一个运行中的 Elasticsearch 集群。您可以使用 Elasticsearch 的 API 进行索引、搜索和其他操作,集群中的节点将自动进行数据分片和主节点选举。
三 、Elasticsearch 基础操作
3.1 索引和映射
在 Elasticsearch 中,数据组织在索引中,类似于关系数据库的数据库。在创建索引之前,您可以定义映射,即字段的数据类型和属性。这有助于 Elasticsearch 了解数据的结构和如何处理它。
3.2 文档操作
插入、更新和删除 使用 Elasticsearch 的 RESTful API 或客户端库,可以执行文档操作。插入文档是将包含字段和对应值的文档插入索引中。更新文档可以修改现有文档的字段值。删除操作则是从索引中删除指定的文档。
3.3 数据搜索和查询
Elasticsearch 提供丰富的搜索和查询功能。您可以使用查询语句对数据进行过滤和搜索。匹配搜索可用于匹配特定字段中的关键字。范围查询可用于查找具有特定范围值的字段。
四、Elasticsearch 进阶
4.1 聚合和过滤
除了基本搜索功能,Elasticsearch 还提供了高级功能,如聚合和过滤。聚合允许对搜索结果进行统计和汇总计算,如平均值、求和和直方图等。过滤器可以用来排除或包含特定的数据。
4.2 分布式架构和水平扩展
Elasticsearch 采用分布式架构进行数据存储和处理。它可以通过水平扩展来处理大规模数据集。集群中的多个节点相互合作,共享数据和负载,实现高可用性、负载均衡和故障恢复。
五、Spring Boot 整合 Elasticsearch
pom文件依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
application.yaml
spring:
elasticsearch:
rest:
uris: es的ip:9200
还可以配置其他 Elasticsearch 相关的属性,如索引名称、刷新间隔等。
创建实体类: 创建一个用于映射到 Elasticsearch 文档的实体类。
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
// 创建一个命名为books的索引
@Document(indexName = "books")
public class Book {
@Id
private String id;
private String title;
private String author;
// Getters and setters
}
创建 Elasticsearch 资源库(Repository): 创建一个继承自 ElasticsearchRepository 的接口,用于执行 Elasticsearch 相关操作。
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
public interface BookRepository extends ElasticsearchRepository<Book, String> {
// 这里的方法命名要规范命名,spring编译时会去检索与by后面的字段是否与es实体类一致,不一致则报异常。
List<Book> findByTitle(String title);
}
使用 Elasticsearch 资源库: 在您的服务或控制器中使用创建的 Elasticsearch 资源库。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class BookController {
@Autowired
private BookRepository bookRepository;
@GetMapping("/books")
public List<Book> getBooksByTitle(String title) {
return bookRepository.findByTitle(title);
}
}