作者:来自 Elastic Ugo Sangiorgi, Radovan Ondas, George Kobar 及 1 more
了解 Elastic 的可搜索快照如何使冻结层(frozen tier)的性能与热层相当,从而展示延迟一致性并降低成本。
对于 99.9% 的查询,冻结层的性能与热层相当,表现出卓越的延迟一致性。
冻结数据层可以通过利用 Elastic 的可搜索快照实现低成本和良好的性能 - 它提供了一种引人注目的解决方案,用于管理大量数据,同时在预算范围内保持数据的高性能可搜索性。
在本文中,我们通过对跨越 90 多天的 105 TB 日志运行示例查询,深入研究了 Elastic 的热数据层和冻结数据层的基准。这些查询复制了 Kibana 中的常见任务,包括突出显示的搜索、总命中数、日期直方图聚合和术语聚合。结果表明,Elastic 的冻结数据层速度很快,并且延迟与其热层相当,只有对对象存储的第一次查询较慢 - 后续查询很快。
我们通过 Kibana 的 Discover(其与索引文档交互的主要界面)复制了典型用户与热冻结部署交互的方式。
当用户使用 Discover 的搜索栏进行搜索时,通常会并行执行三项任务:
- 对 500 个文档进行搜索和突出显示操作,不跟踪总命中次数(称为结果上的 discover_search 任务)
- 跟踪总命中次数的搜索(结果中的 discover_search_total)
- 日期直方图聚合来构建条形图(称为 discover_date_histogram)
并且
- 当用户点击左侧栏时,术语聚合(称为 discover_terms_agg)
Elastic 中的数据层
某些类型的数据的价值会随着时间的推移而降低。很自然地会想到应用程序日志,其中最新的记录通常是需要更频繁查询的记录,并且还需要最快的响应时间。但是还有其他一些此类数据的例子,例如医疗记录(详细的病史、诊断和医生笔记);法律文件(合同、法院判决、案件档案等)和银行记录(交易记录,包括购买描述和商家名称)—— 仅举三种。所有内容都包含非结构化或半结构化文本,需要高效的搜索功能来提取相关信息。随着这些记录的老化,它们的直接相关性可能会降低,但它们对于历史分析、合规性和参考目的仍然具有重要价值。
Elastic 的数据层(热/hot、温/warm、冷/cold 和冻结/frozen)提供了速度和成本的理想平衡,确保你在不牺牲可用性的情况下最大限度地发挥这些数据类型的价值。通过 Kibana 和 Elasticsearch 的 search API,底层数据层的使用始终是自动且透明的 —— 用户无需以不同的方式发出搜索查询来从任何特定层检索数据(无需手动恢复数据,或补充水分)。
在这篇博客中,我们通过仅使用热层和冻层来保持简单,这通常被称为热冻场景。
冻结层如何运作
在热冻场景中,数据在热层开始其旅程,在那里被主动提取和查询。热层针对高速读写操作进行了优化,使其成为处理最新和最常访问的数据的理想选择。随着数据老化并且访问频率降低,数据会被转移到冻结层,以优化存储成本和资源利用率。
从热层到冻结层的转变涉及将数据转换为可搜索的快照。可搜索快照利用用于备份的快照机制,允许以经济高效的方式存储数据,同时仍然可搜索。这消除了对副本分片的需求,大大减少了本地存储要求。
一旦数据进入冻结层,就会由专门为此目的指定的节点进行管理。这些节点不需要有足够的磁盘空间来存储所有索引的完整副本。相反,他们使用磁盘上的最不频繁使用 (Least Frequently Used - LFU) 缓存。此缓存仅存储根据需要从 Blob 存储下载的部分索引数据以满足查询要求。磁盘缓存的功能类似于操作系统的页面缓存,可提高对经常请求的数据部分的访问速度。
在冻结层执行查询时,该过程涉及几个步骤以确保高效的数据检索和缓存:
1. 读请求映射:在 Lucene 级别,读请求被映射到本地缓存。该映射确定所请求的数据是否已经存在于缓存中。
2. 缓存处理不当:如果本地缓存中没有所需数据(缓存未命中),Elasticsearch 会通过从 Blob 存储下载更大的 Lucene 文件区域来处理此问题。通常,该区域是一个 16MB 的块,这是最小化获取次数和优化传输数据量之间的平衡。
3. 将数据添加到缓存:然后将下载的块添加到本地缓存。此过程可确保对同一区域的后续读取请求可直接从本地缓存中提供,通过减少重复从 Blob 存储中获取数据的需要,显著提高查询性能。
4.缓存配置选项:
- 共享缓存大小:此设置可以接受总磁盘空间的百分比或绝对字节值。对于专用的冻结层节点,默认值为总磁盘空间的 90%。
xpack.searchable.snapshot.shared_cache.size: 4TB
- 最大余量:定义要保持的最大余量。如果未明确设置,对于专用的冷冻层节点,默认值为 100GB。
xpack.searchable.snapshot.shared_cache.size.max_headroom: 100GB
5. 驱逐策略:节点级共享缓存使用 LFU 策略来管理其内容。此策略可确保经常访问的数据保留在缓存中,而不经常访问的数据则被逐出以便为新数据腾出空间。这种动态缓存管理有助于有效利用磁盘空间并快速访问最相关的数据。
6. Lucene 索引管理:为了进一步优化资源使用率,Lucene 索引仅在有主动搜索时按需打开。这种方法允许在单个冻结层节点上管理大量索引,而不会消耗过多的内存。
方法论
我们在托管于 Google Cloud Platform 的 Elastic Cloud 中的 N2 系列节点的六节点集群上运行了测试:
- 3 x gcp.es.datahot.n2.68x10x45 - 针对热数据的存储优化的 Elasticsearch 实例。
- 3 x gcp.es.datafrozen.n2.68x10x90 - 存储优化(密集)Elasticsearch 实例,用作冻结数据的缓存层。
我们测量了以下跨度,其大小也相当于 TB 级,因为我们每天索引 1 TB 级。
我们使用 Rally 来运行测试,下面是一个针对一天冻结数据(discover_search_total-1d-frozen-nocache)的非缓存搜索的示例测试,迭代是指整个操作集重复的次数,在这种情况下,它是 10。每个操作定义要执行的特定任务或一组任务,并且在这个例子中,它是一个复合操作。在此操作中,有多个请求指定要采取的操作,例如通过发出 POST 请求来清除冻结的缓存。请求中的流表示一系列相关操作,例如提交搜索查询,然后检索和删除结果。
{
"iterations": 10,
"operation": {
"operation-type": "composite",
"name": "discover_search_total-1d-frozen-nocache",
"requests": [
{
"name": "clear-frozen-cache",
"operation-type": "raw-request",
"path": "/_searchable_snapshots/cache/clear",
"method": "POST"
},
{
"stream": [
{
"name": "async-search",
"operation-type": "submit-async-search",
"index": "hotfrozenlogs",
"request-params": {
"track_total_hits": "true"
},
"body": {
"_source": false,
"size": 0,
"query": {
"bool": {
"filter": [
{
"multi_match": {
"type": "best_fields",
"query": "elk lion rider",
"lenient": true
}
},
{
"range": {
"@timestamp": {
"format": "strict_date_optional_time",
"gte": "2024-02-15T00:00:00",
"lt": "2024-02-16T00:00:00"
}
}
}
]
}
},
"stored_fields": [
"*"
],
"fields": [
{
"field": "@timestamp",
"format": "date_time"
}
]
}
}
]
},
{
"operation-type": "get-async-search",
"retrieve-results-for": [
"async-search"
]
},
{
"operation-type": "delete-async-search",
"delete-results-for": [
"async-search"
]
}
]
}
}
每次基准测试都会运行 10 次,我们在几天内进行了 500 次基准测试,因此每个任务的样本为 5,000 个。当我们想要确保结果的统计意义和可靠性时,进行大量测量至关重要。如此大的样本量有助于消除异常并提供更准确的性能表示,使我们能够从数据中得出有意义的结论。
结果
详细结果概述如下。 “蜡烛尖 - tip of the candle” 代表在特定操作的所有请求中观察到的最大值(或 p100),并且它们按层级分组。绿色值代表 p99.9,即低于该值时 99.9% 的请求将会失败。
由于 Kibana 与 Elasticsearch 的交互方式(通过异步搜索),表示时间的更合理方式是使用如下所示的水平条形图。由于请求是异步和并行的,因此它们将在不同的时间完成。你不必等待所有这些都开始看到查询结果,这就是我们读取基准测试结果的方式。
1 天跨度 / 1 TB
热性能在 543ms 到 2 秒之间为99.9%,而冻结性能在缓存时在 558ms 到 11 秒之间,在非缓存时在 1.8 秒到 14 秒之间。
0.1% 的时间里,我们观察到冻结的最大延迟为 28 秒。
7 天跨度 / 7 TB
热性能在 552ms 到 791ms 之间占 99.9%,而冻结在缓存时在 1 到 12 秒之间,在未缓存时在 2.3 到 14.5 秒之间。
在 0.1% 的时间里,我们观察到冻结的最大延迟为 33 秒。
14 天跨度 / 14 TB
热性能在 550ms 到 608ms 之间占 99.9%,而冻结在缓存时为 1 到 12 秒之间,未缓存时为 2.3 到 14.5 秒之间。
在 0.1% 的时间里,我们观察到冻结的最大延迟为 31 秒。
30 天跨度 / 30 TB
我们在这次测试中没有使用过去 14 天的热数据。如果使用缓存,则在 1 秒到 11 秒之间性能冻结的概率为 99.9%,如果不使用缓存,则在 2 到 12 秒之间性能冻结的概率为 99.9%。
在 0.1% 的时间里,我们观察到冻结的最大延迟为 68 秒。
60 天跨度 / 60 TB
使用缓存时,在 1 秒到 11 秒之间,性能冻结的概率为 99.9%,不使用缓存时,性能冻结的概率为 2 到 13 秒之间。
在 0.1% 的时间里,我们观察到冻结的最大延迟为 240 秒。
90 天跨度 / 90 TB
使用缓存时,在 1 秒到 11 秒之间性能冻结的概率为 99.9%,而不使用缓存时,性能冻结的概率为 2.5 到 13 秒之间。
0.1% 的时间里,我们观察到冻结的最大延迟为 304 秒。
使用 Elastic 的冻结数据层来降低数据存储成本
Elastic 的冻结数据层重新定义了数据存储和检索的可能性。基准测试结果表明,它在 99.9% 的查询中提供与热层相当的性能,能够有效地处理典型的用户任务。虽然在极少数情况下可能会出现延迟稍高的情况(占时间的 0.1%),但 Elastic 的可搜索快照可确保为管理大型数据集提供强大且经济高效的解决方案。无论你是在多年的安全数据中搜索高级持续性威胁,还是从日志和指标中分析历史季节性趋势,可搜索的快照和冻结层都能提供无与伦比的价值和性能。通过采用冻结层,组织可以优化存储策略、保持响应能力、保持数据可搜索并保持在预算之内。
要了解更多信息,请参阅如何为你的 Elastic Cloud 部署设置热数据层和冻结数据层。
Elasticsearch 包含许多新功能,可帮助你为你的用例构建最佳的搜索解决方案。深入了解我们的示例笔记本以了解更多信息,开始免费云试用,或立即在本地机器上试用 Elastic。
原文:Ice, Ice, Maybe: Measuring Searchable Snapshots Performance - Elasticsearch Labs