🔍 ElasticSearch基础概念
全面了解ElasticSearch的核心概念和工作原理
简介
ElasticSearch是一个基于Lucene的开源搜索引擎,它提供了一个分布式、RESTful的全文搜索引擎,设计用于云计算中,能够实现实时搜索、稳定、可靠、快速、安装使用方便。
作为Elastic Stack(原ELK Stack)的核心组件,ElasticSearch可以用于各种应用场景:
- 应用程序搜索
- 网站搜索
- 企业搜索
- 日志分析和可视化
- 指标分析和可视化
- 安全分析
- 业务分析
核心概念
理解ElasticSearch的基础概念是掌握和高效使用这一强大工具的关键。以下是ElasticSearch的核心概念:
📄 文档 (Document)
文档是ElasticSearch中的基本信息单元,它是以JSON格式表示的,类似于关系数据库中的一行数据。每个文档都有一个唯一的ID,并存储在一个索引中。
{
"_id": "1",
"_index": "customers",
"_source": {
"name": "John Doe",
"age": 30,
"email": "[email protected]",
"address": {
"city": "New York",
"zipcode": "10001"
}
}
}
📚 索引 (Index)
索引是具有相似特征的文档集合。它是数据存储的最高级别,类似于关系数据库中的数据库。索引由名称(必须全部是小写)标识,并且该名称用于在对其中的文档执行索引、搜索、更新和删除操作时引用索引。
🏷️ 类型 (Type)
在ElasticSearch 7.0.0及更高版本中,类型的概念已被弃用。在早期版本中,类型是索引内部的逻辑类别/分区,允许在同一索引中存储不同类型的文档,类似于关系数据库中的表。
注意: 从ElasticSearch 7.0.0开始,一个索引只能包含一个类型。计划在8.0.0版本中完全移除类型的概念。
🗺️ 映射 (Mapping)
映射是定义文档及其包含的字段如何存储和索引的过程。它类似于关系数据库中的表结构。在ElasticSearch中,映射可以是动态生成的,也可以预先定义。
{
"mappings": {
"properties": {
"name": { "type": "text" },
"age": { "type": "integer" },
"email": { "type": "keyword" },
"address": {
"properties": {
"city": { "type": "keyword" },
"zipcode": { "type": "keyword" }
}
}
}
}
}
🖥️ 节点 (Node)
节点是ElasticSearch集群中的单个服务器实例,存储数据并参与集群的索引和搜索功能。每个节点都有一个唯一的名称,并可以配置为不同的角色。
常见的节点类型包括:
- 主节点(Master Node):负责集群状态的轻量级操作,如创建或删除索引、跟踪集群中的节点,以及决定将哪些分片分配给哪些节点。
- 数据节点(Data Node):存储数据并执行数据相关操作,如CRUD、搜索和聚合。
- 客户端节点(Client Node):将请求转发到适当的数据节点。
- 摄取节点(Ingest Node):在索引文档之前预处理文档。
🌐 集群 (Cluster)
集群是一个或多个节点的集合,它们一起持有整个数据,并提供跨所有节点的联合索引和搜索功能。每个集群由一个唯一的名称标识,默认为"elasticsearch"。
集群的主要优势在于它能够分配工作负载,提供高可用性和可扩展性:
- 如果一个节点失败,集群会重新组织数据的分布
- 集群可以通过添加更多节点来扩展,以应对增长的数据量
- 查询可以在多个节点上并行执行,提高性能
🔄 副本 (Replica)
副本是分片的复制品。每个索引可以拆分为多个分片,每个分片可以有零个或多个副本。副本的主要目的是提供高可用性,同时也可以提高搜索性能。
副本的优势:
- 高可用性:如果包含主分片的节点失败,副本会被提升为主分片
- 增强性能:搜索可以在所有副本上并行执行
默认情况下,每个索引在ElasticSearch中分配5个主分片和1个副本,这意味着如果集群至少有两个节点,索引将有5个主分片和5个副本分片,总共10个分片。
架构设计
ElasticSearch的架构设计充分考虑了分布式环境下的高可用性、可扩展性和性能优化。
在ElasticSearch的分布式架构中,几个关键组件协同工作:
集群状态管理
集群状态是关于集群的元数据,包括:
- 节点信息
- 索引及其映射和设置
- 分片分配信息
主节点负责维护和更新集群状态。当状态发生变化时(如索引创建或节点加入/离开集群),主节点会向集群中的所有节点广播更新。
分片分配
当创建索引或集群重新平衡时,ElasticSearch需要决定如何在节点之间分配分片。这些决策考虑多个因素:
- 硬件资源(如磁盘空间和CPU使用率)
- 现有分片分配
- 故障域(尝试在不同的物理服务器上放置主分片和其副本)
查询执行
当ElasticSearch接收到查询请求时,执行路径涉及多个阶段:
- 接收节点成为该请求的协调节点
- 协调节点确定哪些分片可以满足查询
- 请求分派到这些分片(可能位于多个节点上)
- 每个分片执行查询并返回结果
- 协调节点合并结果并返回给客户端
数据模型
ElasticSearch的数据模型是分层的,从最高级别到最底层包括:
ElasticSearch | 关系型数据库 |
---|---|
集群 (Cluster) | 数据库集群 |
索引 (Index) | 数据库 |
(已弃用) 类型 (Type) | 表 |
文档 (Document) | 行 |
字段 (Field) | 列 |
映射 (Mapping) | 表结构 |
文档是JSON格式的,支持嵌套对象和复杂数据类型,这比关系型数据库的平面结构提供了更多灵活性。
字段数据类型
ElasticSearch支持多种字段数据类型:
- 核心数据类型
text
:用于全文搜索的文本字段keyword
:用于精确值匹配的文本字段date
:日期类型long
,integer
,short
,byte
:整数类型double
,float
,half_float
:浮点数类型boolean
:布尔值
- 复杂数据类型
object
:JSON对象nested
:特殊的对象类型,允许对象数组被独立索引和查询
- 特殊数据类型
geo_point
:经纬度坐标geo_shape
:复杂的地理形状ip
:IP地址completion
:用于自动完成建议token_count
:计算字符串中token的数量
查询DSL
ElasticSearch提供了强大的基于JSON的查询语言,称为查询DSL(Domain Specific Language)。查询DSL允许您构建复杂的查询,并充分利用ElasticSearch的搜索功能。
查询类型
ElasticSearch支持多种查询类型,分为两大类:
叶查询子句
叶查询子句在特定字段中查找特定值:
- 匹配查询 (match query):在字段中查找指定的文本、数字或日期
- 词语查询 (term query):精确匹配字段中的值,不进行分析
- 范围查询 (range query):查找字段中在指定范围内的值
- 存在查询 (exists query):查找包含任何非空值的字段的文档
- 前缀查询 (prefix query):查找字段中以特定前缀开头的值
- 通配符查询 (wildcard query):使用通配符模式匹配字段中的值
复合查询子句
复合查询子句包含其他叶查询或复合查询,用于组合多个查询条件:
- 布尔查询 (bool query):组合多个查询子句,支持must(必须匹配)、should(应该匹配)、must_not(必须不匹配)、filter(必须匹配,但不影响得分)
- 函数得分查询 (function_score query):修改查询的得分,执行自定义的得分计算
- 嵌套查询 (nested query):用于查询嵌套对象字段
- 常量得分查询 (constant_score query):包装过滤器查询并返回常量得分
查询示例
下面是一些常见查询的示例:
// 简单的匹配查询
{
"query": {
"match": {
"content": "elasticsearch"
}
}
}
// 布尔查询组合多个条件
{
"query": {
"bool": {
"must": [
{ "match": { "title": "search" } }
],
"should": [
{ "match": { "content": "elasticsearch" } },
{ "match": { "content": "lucene" } }
],
"must_not": [
{ "match": { "status": "draft" } }
],
"filter": [
{ "range": { "publish_date": { "gte": "2020-01-01" } } }
]
}
}
}
// 聚合查询
{
"size": 0,
"aggs": {
"popular_categories": {
"terms": {
"field": "category",
"size": 10
}
}
}
}
倒排索引
倒排索引是ElasticSearch(和底层的Lucene)中用于实现高效全文搜索的核心数据结构。理解倒排索引对于掌握ElasticSearch的工作原理至关重要。
倒排索引的概念
传统的索引将文档映射到它们包含的词条,而倒排索引则相反,它将词条映射到包含它们的文档。这种结构非常适合回答"哪些文档包含这个词?"的问题,这正是搜索引擎需要解决的核心问题。
词条 | 文档ID列表 |
---|---|
elasticsearch | 1, 3, 5, 9 |
search | 1, 2, 3, 4, 6, 8 |
index | 2, 5, 7, 9 |
distributed | 1, 3, 4, 8 |
倒排索引的构建过程
当文档被索引到ElasticSearch中时,构建倒排索引的过程如下:
- 提取文档中的文本字段
- 分析这些文本字段,生成标记(tokens)
- 为每个标记创建倒排索引条目,指向包含该标记的文档
倒排索引不仅存储文档ID,还会存储额外的信息,如:
- 词频(term frequency):词条在文档中出现的次数
- 位置(positions):词条在文档中出现的位置
- 偏移量(offsets):词条在原始文本中的起始和结束字符位置
倒排索引的优势
倒排索引具有以下优势:
- 快速的全文搜索:直接查找包含特定词条的文档
- 支持复杂的查询:通过合并多个词条的结果集
- 高效的过滤:快速确定哪些文档满足条件
- 实现相关性排序:利用词频、逆文档频率等因素计算文档得分
分析器
分析器是ElasticSearch中处理文本的组件,它们在索引和搜索阶段对文本进行处理,将原始文本转换为适合搜索的标记(tokens)。
分析器的组成
分析器由三个主要部分组成:
- 字符过滤器(Character Filters):预处理原始文本,如去除HTML标记、替换字符等
- 分词器(Tokenizer):将文本拆分成标记(tokens)
- 标记过滤器(Token Filters):处理分词器产生的标记,如转换为小写、去除停止词、词干提取等
内置分析器
ElasticSearch提供多种内置分析器,适用于不同的场景:
- 标准分析器(Standard Analyzer):默认分析器,按照Unicode文本分割算法分词,转换为小写,并可选地删除停止词
- 简单分析器(Simple Analyzer):按非字母字符分词,转换为小写
- 空格分析器(Whitespace Analyzer):按空格分词,不转换大小写
- 语言分析器(Language Analyzers):针对特定语言的分析器,如english、chinese等,提供语言相关的处理(如词干提取)
- 指纹分析器(Fingerprint Analyzer):创建指纹标记,用于去重
自定义分析器
您可以通过组合字符过滤器、分词器和标记过滤器来创建自定义分析器:
{
"settings": {
"analysis": {
"analyzer": {
"my_custom_analyzer": {
"type": "custom",
"char_filter": ["html_strip"],
"tokenizer": "standard",
"filter": ["lowercase", "asciifolding", "stop"]
}
}
}
}
}
分析器的使用
分析器在两个主要场景中使用:
- 索引时:处理文档字段内容,生成要存储在倒排索引中的标记
- 搜索时:处理查询字符串,生成要在倒排索引中查找的标记
您可以使用 _analyze
API 来测试分析器的行为:
POST _analyze
{
"analyzer": "standard",
"text": "The quick brown fox jumped over the lazy dog!"
}
最佳实践
为了获得ElasticSearch的最佳性能和可靠性,以下是一些推荐的最佳实践:
索引设计
- 合理分片:每个分片不应太大(超过50GB)或太小(少于几GB)。考虑数据增长和查询模式来确定分片数
- 索引别名:使用索引别名而不是直接引用索引名,以便于重新索引和索引轮换
- 索引模板:为具有相似结构的索引定义模板,确保一致的设置和映射
- 生命周期管理:使用索引生命周期管理(ILM)自动管理时间序列数据的索引
映射和字段
- 显式映射:为索引定义显式映射,而不是依赖动态映射
- 字段类型优化:为每个字段选择最合适的数据类型
- 禁用不需要的字段:使用
enabled: false
禁用不需要搜索或聚合的字段 - 适当使用doc_values:对于不需要排序或聚合的字段,可以禁用doc_values以节省磁盘空间
- 控制字段数量:避免每个文档有过多字段,以减少内存使用
查询和搜索
- 过滤优先于查询:尽可能使用filter而不是query,因为filter可以被缓存
- 使用搜索模板:为常见查询创建搜索模板,提高安全性和可维护性
- 分页控制:使用search_after或scroll API处理大结果集,避免深度分页
- 查询优化:使用profile API分析查询性能,优化复杂查询
集群配置
- 角色分离:在生产环境中,将不同角色(主节点、数据节点等)分配给不同的节点
- 内存设置:为JVM堆分配合适的内存,通常不超过可用物理内存的50%,且不超过32GB
- 缓存管理:合理配置各种缓存大小,如分片请求缓存和字段数据缓存
- 监控:设置监控系统监控集群健康状况、性能指标和资源使用情况
性能优化
- 批量处理:使用bulk API进行批量索引操作,提高吞吐量
- 刷新间隔:根据需求调整刷新间隔,延长刷新间隔可以减少系统开销
- 预热查询:在低峰时段执行常见查询,以便缓存数据
- 硬件选择:使用SSD存储,提供足够的内存,选择CPU密集型机器处理复杂聚合
- 客户端连接池:使用连接池管理客户端连接,避免频繁创建连接
数据备份
- 定期快照:使用快照和恢复功能定期备份数据
- 多仓库备份:将快照存储在多个仓库中,确保数据安全
- 测试恢复:定期测试恢复过程,确保备份可用
应用案例
ElasticSearch凭借其强大的搜索和分析能力,在各个行业和场景中得到广泛应用。以下是一些典型的应用案例:
日志分析
这是ElasticSearch最常见的应用场景之一,通常与Logstash和Kibana一起使用(即ELK栈或Elastic Stack):
- 集中存储和索引来自不同系统和应用的日志
- 实时分析日志数据以监控应用性能和系统健康状况
- 快速查询和过滤日志数据以进行故障排除
- 建立可视化仪表板来展示趋势和异常
- 设置警报以在出现问题时通知相关人员
案例:Netflix使用Elastic Stack处理每天数PB的日志数据,帮助他们监控和分析全球流媒体服务的性能。
全文搜索
ElasticSearch作为一个搜索引擎,为应用程序提供快速、相关的搜索体验:
- 网站内容搜索,包括产品、文章、文档等
- 支持模糊匹配、自动完成和搜索建议
- 多字段搜索和复杂的查询条件
- 根据多种因素(如相关性、流行度、时间等)对结果排序
- 支持同义词和多语言搜索
案例:GitHub使用ElasticSearch为超过2亿个代码仓库提供搜索功能,允许开发者快速找到代码、问题和文档。
实时分析
ElasticSearch能够处理大量数据并提供近实时的聚合分析:
- 业务智能和数据可视化
- 实时仪表板和报告
- 异常检测和预测分析
- 用户行为分析和A/B测试结果分析
- 销售和营销数据分析
案例:Shopify使用ElasticSearch分析每天数十亿的购物事件,以提供个性化推荐和优化电子商务体验。
安全分析和SIEM
ElasticSearch是安全信息与事件管理(SIEM)解决方案的核心组件:
- 收集和分析安全日志和事件
- 检测安全威胁和异常行为
- 关联不同来源的安全数据
- 支持安全调查和事件响应
- 合规性报告和审计
案例:Elastic Security(原Elastic SIEM)被许多组织用来保护其IT基础设施,通过分析各种安全数据源来检测和响应威胁。
地理信息系统
ElasticSearch支持强大的地理空间功能,用于基于位置的应用:
- 地理位置搜索(如"附近的餐厅")
- 地理围栏和地理形状查询
- 位置和距离聚合
- 地图可视化
- 交通和物流分析
案例:Uber使用ElasticSearch处理司机和乘客的地理位置数据,优化匹配算法和路径规划。
发展趋势
ElasticSearch不断发展,以应对不断变化的数据处理需求。以下是当前和未来的一些主要趋势:
机器学习和AI集成
ElasticSearch正在增强其机器学习能力:
- 异常检测和预测分析的内置功能
- 与流行的ML框架集成,如TensorFlow和PyTorch
- 自然语言处理(NLP)和理解(NLU)功能增强
- 向量搜索支持,用于语义搜索和相似性匹配
云原生和Kubernetes集成
随着云计算的普及,ElasticSearch正在强化其云原生能力:
- 通过Elastic Cloud Kubernetes (ECK)提供的增强Kubernetes支持
- 自动扩展和自愈能力
- 与云服务提供商的托管服务集成
- 多云和混合云部署选项
性能优化和资源效率
持续改进性能和资源使用效率:
- 索引和查询性能的优化
- 更高效的数据压缩和存储
- 自适应算法以平衡资源使用
- 更智能的缓存策略
时序数据和可观察性
对时序数据和可观察性场景的专注:
- 增强的时序数据处理能力
- 改进的指标存储和聚合
- 与开放可观察性标准的集成
- 针对DevOps和SRE用例的工具改进
安全与合规
不断加强的安全功能:
- 增强的身份验证和授权机制
- 细粒度的访问控制和字段级安全性
- 加密和合规性功能
- 内置的威胁检测和安全分析
参考资料
- Elastic官方文档:https://www.elastic.co/guide/index.html
- 《ElasticSearch: The Definitive Guide》by Clinton Gormley & Zachary Tong
- 《ElasticSearch in Action》by Radu Gheorghe, Matthew Lee Hinman, & Roy Russo
- Elastic Blog:https://www.elastic.co/blog/
- ElasticSearch源代码:https://github.com/elastic/elasticsearch
- Discuss Elastic forums:https://discuss.elastic.co/