近实时(Near Real-Time, NRT)搜索
近实时(NRT)搜索是 Elasticsearch 的核心特性之一,指的是数据在被写入到系统后,可以几乎立即被搜索和查询到。虽然它不像传统数据库那样完全实时,但它的延迟通常只在几百毫秒到一秒之间。
工作原理:
- 写入数据:
- 文档写入时被存储在内存缓冲区(translog)。
- 刷新(Refresh):
- Elasticsearch 定期将内存中的数据刷新(默认每秒一次),将新数据写入一个称为“段”(segment)的文件中。
- 刷新后,新数据对搜索可见。
- 延迟原因:
- 数据写入并非直接可搜索,而是需要等刷新完成,这导致搜索是“近实时”。
适用场景:
- 日志搜索: 需要快速查询最新日志数据。
- 实时分析: 对流式数据进行快速分析,例如异常检测。
优化方法:
- 调整
refresh_interval
:- 默认值为 1 秒。
- 如果不需要实时性,可以延长刷新时间以提高写入性能。
- 示例:将索引的刷新间隔设置为 5 秒:
PUT /my_index/_settings { "index": { "refresh_interval": "5s" } }
倒排索引(Inverted Index)
倒排索引是 Elasticsearch 用来实现快速全文搜索的核心数据结构。
什么是倒排索引?
倒排索引是一种映射结构,它记录了词项(Term)与包含这些词项的文档 ID之间的关系。
与传统的正排索引(如关系型数据库的 B-Tree)不同,倒排索引更加适合快速查找包含特定关键词的文档。
倒排索引的结构:
以“倒排”表示其映射方向:
示例文档集:
Doc1: Elasticsearch is a search engine.
Doc2: Elasticsearch is fast and scalable.
Doc3: Full-text search uses inverted index.
倒排索引:
词项 (Term) | 文档 (Document IDs) |
---|---|
a | Doc1, Doc2 |
Elasticsearch | Doc1, Doc2 |
engine | Doc1 |
fast | Doc2 |
full-text | Doc3 |
inverted | Doc3 |
scalable | Doc2 |
search | Doc1, Doc3 |
uses | Doc3 |
构建倒排索引的步骤:
- 分词(Tokenization):
- 文本被分解为词项。例如
Elasticsearch is a search engine
被分成:[Elasticsearch, is, a, search, engine]
。
- 文本被分解为词项。例如
- 去停用词(Stop Words):
- 移除无意义的词汇(如 “is”, “a” 等)。
- 词项映射:
- 记录每个词项出现在哪些文档中。
优点:
- 快速全文检索: 可以高效找到包含某个或某些关键词的文档。
- 灵活性: 支持复杂查询,比如布尔查询、短语匹配、模糊搜索等。
在 Elasticsearch 中的实现:
- 每个字段都会创建一个倒排索引。
- 支持分词器(Analyzer)对文本进行预处理,例如小写化、同义词扩展。
适用场景:
- 文本内容检索,如日志分析、电子商务搜索、知识库搜索。
NRT 搜索与倒排索引的结合:
- 倒排索引提供了快速查询的核心能力。
- NRT 搜索通过频繁刷新倒排索引,使得新数据能够快速加入搜索结果,从而实现“近实时”的体验。
这种结合使得 Elasticsearch 在海量数据的场景下既能高效写入,又能快速检索。