Elasticsearch 最初是作为独立产品开发的。它的核心作用是提供可扩展的搜索引擎服务,它提供多种语言库API(包括JAVA、Python等),基于分布式模型创建,并对外提供 REST API
接口服务。随着Elastic生态圈的发展,衍生出了 Elasticsearch 的相关 工具集合。例如 Kibana (用于可视化和数据分析)、Logstash (用于日志收集)、Beats (数据传输,轻量级的Logstash)等。Elastic Stack 不单单是Elasticsearch,而是一体化大数据解决方案的工具集。
根据数据性质的不同,Elasticsearch 中存储的数据可以分成两类:静态数据 和 时间序列 数据。它们会严重影响集群的配置和管理方式。
根据不同的数据类型,应该以不同的方式为数据建模。
对于每个搜索查询,Elasticsearch 都会计算相关性分数。该分数基于 TF-IDF 算法,该算法代表 词频-逆文档频率。在该算法中需要计算两个值,分别是TF和IDF。
基本上,在该算法中计算两个值。
例如,如果我们有两个文档:
文档1:To be or not to be, that is the question.
文档2:To be. I am. You are. He, she is.
question 词项的 TF 计算如下:
IDF 计算为整个数据集的单个值。它是所有文档与包含搜索词的文档的比率。
question 词项的 IDF 计算如下:
在我们的例子中它是:log(2/1)= 0.301 (简化)
其中:
最后,两个文档的 tf-idf 分数计算为两个值的乘积:
例如:
# 创建索引
PUT index_test
{
"mappings": {
"properties": {
"title": {
"type": "text"
}
}
}
}
# 创建文档1
POST index_test/_doc/1
{
"title":"To be or not to be, that is the question."
}
# 创建文档2
POST index_test/_doc/2
{
"title":"To be. I am. You are. He, she is."
}
# 创建文档2
POST index_test/_search
{
"explain": true,
"query": {
"match": {
"title":"question"
}
}
}
结果:
{
"took" : 13,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.6785375,
"hits" : [
{
"_shard" : "[index_test][0]",
"_node" : "_s5Ha-5nRoKfE_Az6iiujg",
"_index" : "index_test",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.6785375,
"_source" : {
"title" : "To be or not to be, that is the question."
},
"_explanation" : {
"value" : 0.6785375,
"description" : "weight(title:question in 0) [PerFieldSimilarity], result of:",
"details" : [
{
"value" : 0.6785375,
"description" : "score(freq=1.0), computed as boost * idf * tf from:",
"details" : [
{
"value" : 2.2,
"description" : "boost",
"details" : [ ]
},
{
"value" : 0.6931472,
"description" : "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
"details" : [
{
"value" : 1,
"description" : "n, number of documents containing term",
"details" : [ ]
},
{
"value" : 2,
"description" : "N, total number of documents with field",
"details" : [ ]
}
]
},
{
"value" : 0.4449649,
"description" : "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
"details" : [
{
"value" : 1.0,
"description" : "freq, occurrences of term within document",
"details" : [ ]
},
{
"value" : 1.2,
"description" : "k1, term saturation parameter",
"details" : [ ]
},
{
"value" : 0.75,
"description" : "b, length normalization parameter",
"details" : [ ]
},
{
"value" : 10.0,
"description" : "dl, length of field",
"details" : [ ]
},
{
"value" : 9.5,
"description" : "avgdl, average length of field",
"details" : [ ]
}
]
}
]
}
]
}
}
]
}
}
Elasticsearch 其性能优势主要集中两个方面:
其中 Elasticsearch 的检索速度主要取决于索引对数据的存储方式。
Elasticsearch 索引文档有三个步骤来规范化文档:
例如:
To be or not to be, that is the question.
character filters:将 ,
替换为
,将 .
替换为
并且将所有的大写字母替换为小写字母即 To
替换为 to
,则原文档更新为
to be or not to be that is the question
tokenizer:根据
将文档分割为一个个 token
to、be、or、not、to、be、that、is、the、question
token filters:按照停用词过滤器,它将删除所有常用语言术语 to、be、or、not、that、is、the,仅剩下
question
在搜索文档时会应用相同的步骤。Elasticsearch 会搜索带有规范化词项的文档,因此在查询时也会通过相同的三个步骤来规范化文档,获得规范化的词项(taken
或 term
我理解这两个应该表达的是一个意思)后通过倒排索引结构,快速获取匹配文档。
Elasticsearch 可以为每个字段定义特定的过滤器。借助于analyzers实现定义。可以使用多个analyzers分词器分析字段以实现不同的目标。例如可以使用 standard
分词器逐字分词,使用 ik_max_word
细粒度分词,使用 ik_smart
粗粒度分词。然后在搜索阶段,通过定义要扫描的字段,获得检索结果。也正是因为 ES 对数据的存储方式,和规范化文档使得它可以更快的提供查询结果
索引在时就需要确定分片数,并且索引建成后分片数量不能修改,因此确定索引的分片数就尤为重要。根据经验来说,数据集的规模决定了索引的分片数,单个分片最大应包含 20-40 GB的数据。
每一个 shard 都对应一个 Lucene,考虑到 Lucene 用于倒排索引和快速搜索的所有结构和开销,较小的 shard(例如 1 GB)时没有意义的。
所以答案真的取决于你拥有的数据集。根据经验,单分片最大应包含20-40 GB的数据。 Shards来自Apache Lucene。此外,由于分片不能进一步划分,并且始终驻留在单个节点上。20-40 GB 的分片也可以很容易地移动到其他节点,可以说 20-40 GB 的分片是在提供恢复、重建速度和内存消耗之间的折衷值。
当然,这只是一个建议,最合理的规划应当根据实际业务场景,并实现其性能目标。
reindex
将数据迁移到合理的索引中。Elasticsearch节点可以包括多个角色。角色包括:
每个角色都有对应的用途。
作用: 用于存储和搜索数据。
**硬件要求:**数据节点对所有资源都有很高的要求:CPU,RAM和磁盘。您拥有的数据越多,硬件资源要求也就越高。
作用: 在实际索引发生之前,Ingest节点用于文档预处理。Ingest节点拦截批量和索引查询,应用转换,然后将文档传递回索引或批量API。
硬件要求: 低磁盘、中等RAM和高CPU,
作用: 客户端请求的负载平衡器。
它知道特定文档可以驻留的位置,并将搜索请求路由到对应节点。
【官方文档警告】:
将过多的仅协调节点添加到集群会增加整个集群的负担,因为所选主节点必须等待来自每个节点的集群状态更新的确认!不应过分夸大仅协调节点的好处 - 数据节点可以愉快地用于相同的目的。
硬件要求: 低磁盘,中高速RAM和中高CPU。