Elasticsearch核心技术解析:从架构到倒排索引
Elasticsearch核心技术解析:从架构到倒排索引
Elasticsearch作为一款强大的大数据检索引擎,其核心原理涉及分布式存储、分片机制、倒排索引等多个关键技术点。本文将深入解析Elasticsearch的架构设计、写存储机制以及查询优化策略,帮助读者全面理解其工作原理。
Elasticsearch架构
ELK(Elasticsearch、Logstash、Kibana)平台之所以功能强大,关键在于其在储存、索引等方面的架构设计。让我们从整体架构开始分析:
数据流向如下:
- 项目产生的日志通过Filebeat或Rsyslog收集并推送到Kafka。
- Logstash消费Kafka中的日志,进行整理后推送到Elasticsearch集群。
- Elasticsearch对日志进行分词处理,计算文档权重,并将信息存储到不同分片中。每个分片都有多个副本,数据写入时需要确保大部分副本写入成功。
Elasticsearch集群中的服务分为多个角色:
- Master节点:负责集群状态、节点信息、索引映射等调度决策。通过选举产生主节点,通常一个集群至少有三个可竞选Master节点的成员。
- Data节点:负责存储数据和计算,包括分片的主从副本、热点数据和冷数据的存储。
- Client节点:负责协调多个副本的数据查询服务,聚合结果并返回给客户端。
- Kibana节点:用于实时统计分析、聚合分析和图形展示。
在生产环境中,Elasticsearch最少需要三台服务器,其中一台作为Master节点,另外两台用于数据存储和检索计算。如果硬件资源充裕,可以单独部署Kibana节点以提升性能。
Elasticsearch的写存储机制
Elasticsearch的索引存储结构较为复杂,但主要关注点在于分片和索引部分:
底层的全文检索使用Lucene引擎,该引擎采用以下机制:
- 缓存机制:将写入数据保存在Index Buffer中,周期性落盘到segment文件。
- Segment合并:为提高查询效率,Lucene会定期合并多个segment文件。
- 冷热数据分离:将热数据保存在SSD中,冷数据保存在大容量磁盘中,按天建立索引。
分片的路由规则默认通过日志的DocId进行hash运算,以保证数据分布均衡。当单个节点达到性能上限时,需要增加Data服务器节点和副本数。但副本增加到一定程度后,由于写强一致性问题,写性能反而会下降。
Elasticsearch的查询过程
为了平衡性能压力,Elasticsearch每次查询都会请求所有索引所在的Data节点。协调节点会在相同数据分片的多个副本中随机选择一个节点发送查询请求。收到请求的副本会根据关键词权重对结果进行初步排序。协调节点拿到所有副本返回的文档ID列表后,会再次汇总排序,最后用DocId去各个副本获取具体文档数据并返回。
这种方式虽然实现了大数据集的全文检索,但也存在一些缺点:
- 查询耗时增加
- QPS较低
- 网络吞吐性能不高
- 协调节点需要对每次查询结果做分页处理
Elasticsearch的倒排索引
Elasticsearch的全文检索通过Lucene实现,采用倒排索引(Inverted Index)技术。倒排索引的过程包括:
- 对用户输入的内容进行分词,找出关键词。
- 通过多个关键词对应的倒排索引,取出所有相关的DocId。
- 将多个关键词对应的索引ID做交集,计算每条结果的权重。
- 根据匹配评分降序排序,列出相关度高的记录。
Lucene对倒排索引进行了优化,主要保存三种索引:
- Term Index:基于FST实现的二级索引,用于快速搜索关键词。
- Term Dictionary:保存单词与Posting List的关系,按block在磁盘中排序压缩保存。
- Posting List:记录关键词出现的文档ID及其位置、偏移、词频信息。
在查询时,Elasticsearch会通过Term Index快速定位到Term Dictionary,再找到相关文档的DocId及权重,最后根据权重算法对结果进行排序。