一、6.X、7.X 和 8.X 之间存储的差异
注意:这里的比较,将不做任何的配置上的优化,也就是说,在不开启任何场景调优选项的情况下,单纯比较版本间,在相同数据集上的默认存储消耗。
在选择 Elasticsearch 的版本时,我们会选择最广泛使用的版本,而不会涉及所有子版本。
6.x版本:我们将选择6.8作为测试版本;
7.x版本:我们将选择7.10;这主要是因为在7.10版本中,Elastic进行了许可证的更改,使其成为许多云服务提供商支持的 Elasticsearch 版本的分水岭。同时,我们注意到 Opensearch 也是从这个版本中分支出来的。
8.x版本:我们将使用腾讯云提供的最新版本8.8.1
1、日志场景
1)、数据结构schema 如下:
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1,
"analysis": {
"analyzer": {
"oap_log_analyzer": {
"type": "standard"
}
}
}
},
"mappings": {
"_source": {
"excludes": [
"tags"
]
},
"properties": {
"content": {
"type": "text",
"copy_to": [
"content_match"
]
},
"content_match": {
"type": "text",
"analyzer": "oap_log_analyzer"
},
"content_type": {
"type": "integer",
"index": false
},
"endpoint_id": {
"type": "keyword"
},
"service_id": {
"type": "keyword"
},
"service_instance_id": {
"type": "keyword"
},
"span_id": {
"type": "integer"
},
"tags": {
"type": "keyword"
},
"tags_raw_data": {
"type": "binary"
},
"time_bucket": {
"type": "long"
},
"timestamp": {
"type": "long"
},
"trace_id": {
"type": "keyword"
},
"trace_segment_id": {
"type": "keyword"
},
"unique_id": {
"type": "keyword"
}
}
}
}
View Code
这个索引有5个分片和0个副本,使用了一个自定义的分析器 oap_log_analyzer
这个索引有15个字段,大致可以分为以下几类:
文本类型(text):这些字段用来存储需要分词的字符串,比如content。这些字段可以用来进行全文检索、模糊匹配等操作。
关键词类型(keyword):这些字段用来存储不需要分词的字符串,比如endpoint_id、service_id等。这些字段可以用来进行精确匹配、排序、聚合等操作。
数值类型(integer、long等):这些字段用来存储整数或长整数,比如content_type、span_id等。这些字段可以用来进行数值比较、范围查询、聚合等操作。
二进制类型(binary):这些字段用来存储二进制数据,比如tags_raw_data。这些字段不会被索引或搜索,只能用于存储或检索。
复制类型(copy_to):这些字段用来存储其他字段的值的副本,比如content_match。这些字段可以用来进行多字段查询。
分析器类型(analyzer):这些字段用来指定使用哪种分析器来处理文本,比如content_match。这些字段可以用不同的分词规则来影响搜索结果。
2)、样例数据 如下:
{
"_index": "sw_log-20231023",
"_id": "fe620a61abca48b394358015a04a55b8",
"_score": 1,
"_source": {
"trace_id": "9ad5dfed-1def-4ed3-b233-5dce5afa66c8",
"unique_id": "fe620a61abca48b394358015a04a55b8",
"span_id": 0,
"endpoint_id": "c29uZ3M=.1_VW5kZXJ0b3dEaXNwYXRjaA==",
"service_instance_id": "c29uZ3M=.1_Mzg0ZWZlYWE2NzFjNGFhYjg2ZGFmZjA3OWE4YjljYzZAMTcyLjIyLjAuNg==",
"content": """2023-10-23 23:59:49.247 [TID:9ad5dfed-1def-4ed3-b233-5dce5afa66c8] [XNIO-1 task-2] INFO o.a.s.s.s.s.c.SongController -Listing top songs
""",
"trace_segment_id": "7e097591b9b74531a14df130f17087a8.54.16981055892474632",
"content_type": 1,
"tags_raw_data": "Cg0KBWxldmVsEgRJTkZPClAKBmxvZ2dlchJGb3JnLmFwYWNoZS5za3l3YWxraW5nLnNob3djYXNlLnNlcnZpY2VzLnNvbmcuY29udHJvbGxlci5Tb25nQ29udHJvbGxlcgoXCgZ0aHJlYWQSDVhOSU8tMSB0YXNrLTI=",
"service_id": "c29uZ3M=.1",
"time_bucket": 20231023235949,
"timestamp": 1698105589247
}
}
View Code
3)、结果:我们分别在6.8,7.10,8.8的集群上写入相同的数据,通过_stats/store,segments接口,我们得到三个版本的索引统计信息的区别:
小结:存储大小随着版本的升级而减少,这是因为Elasticsearch对索引结构和压缩算法进行了优化。
相对于6.8版本,8.8版本的存储优化百分比为 ≈14.78%
相对于7.10版本,8.8版本的存储优化百分比为 ≈12.64%
内存占用从6.8到7.10大幅减少,再到到8.8变为0,这是因为Elasticsearch对内存管理进行了改进,即进行了heap-offload,也更改了加载的方式
2、指标数据对比
1)、指标数据 schema
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 1,
"analysis": {
"analyzer": {
"oap_analyzer": {
"type": "standard"
}
}
}
},
"mappings": {
"properties": {
"address": {
"type": "keyword"
},
"agent_id": {
"type": "keyword"
},
"component_id": {
"type": "integer",
"index": false
},
"component_ids": {
"type": "keyword",
"index": false
},
"count": {
"type": "long",
"index": false
},
"dataset": {
"type": "text",
"index": false
},
"datatable_count": {
"type": "text",
"index": false
},
"datatable_summation": {
"type": "text",
"index": false
},
"datatable_value": {
"type": "text",
"index": false
},
"denominator": {
"type": "long"
},
"dest_endpoint": {
"type": "keyword"
},
"dest_process_id": {
"type": "keyword"
},
"dest_service_id": {
"type": "keyword"
},
"dest_service_instance_id": {
"type": "keyword"
},
"detect_type": {
"type": "integer"
},
"double_summation": {
"type": "double",
"index": false
},
"double_value": {
"type": "double"
},
"ebpf_profiling_schedule_id": {
"type": "keyword"
},
"end_time": {
"type": "long"
},
"endpoint": {
"type": "keyword"
},
"endpoint_traffic_name": {
"type": "keyword",
"copy_to": [
"endpoint_traffic_name_match"
]
},
"endpoint_traffic_name_match": {
"type": "text",
"analyzer": "oap_analyzer"
},
"entity_id": {
"type": "keyword"
},
"instance_id": {
"type": "keyword"
},
"instance_traffic_name": {
"type": "keyword",
"index": false
},
"int_value": {
"type": "integer"
},
"label": {
"type": "keyword"
},
"labels_json": {
"type": "keyword",
"index": false
},
"last_ping": {
"type": "long"
},
"last_update_time_bucket": {
"type": "long"
},
"layer": {
"type": "integer"
},
"match": {
"type": "long",
"index": false
},
"message": {
"type": "keyword"
},
"metric_table": {
"type": "keyword"
},
"name": {
"type": "keyword"
},
"numerator": {
"type": "long"
},
"parameters": {
"type": "keyword",
"index": false
},
"percentage": {
"type": "integer"
},
"precision": {
"type": "integer",
"index": false
},
"process_id": {
"type": "keyword"
},
"profiling_support_status": {
"type": "integer"
},
"properties": {
"type": "text",
"index": false
},
"remote_service_name": {
"type": "keyword"
},
"represent_service_id": {
"type": "keyword"
},
"represent_service_instance_id": {
"type": "keyword"
},
"s_num": {
"type": "long",
"index": false
},
"service": {
"type": "keyword"
},
"service_group": {
"type": "keyword"
},
"service_id": {
"type": "keyword"
},
"service_instance": {
"type": "keyword"
},
"service_instance_id": {
"type": "keyword"
},
"service_name": {
"type": "keyword"
},
"service_traffic_name": {
"type": "keyword",
"copy_to": [
"service_traffic_name_match"
]
},
"service_traffic_name_match": {
"type": "text",
"analyzer": "oap_analyzer"
},
"short_name": {
"type": "keyword"
},
"source_endpoint": {
"type": "keyword"
},
"source_process_id": {
"type": "keyword"
},
"source_service_id": {
"type": "keyword"
},
"source_service_instance_id": {
"type": "keyword"
},
"span_name": {
"type": "keyword"
},
"start_time": {
"type": "long"
},
"summation": {
"type": "long",
"index": false
},
"t_num": {
"type": "long",
"index": false
},
"tag_key": {
"type": "keyword"
},
"tag_type": {
"type": "keyword"
},
"tag_value": {
"type": "keyword"
},
"task_id": {
"type": "keyword"
},
"time_bucket": {
"type": "long"
},
"total": {
"type": "long",
"index": false
},
"total_num": {
"type": "long",
"index": false
},
"type": {
"type": "keyword"
},
"uuid": {
"type": "keyword"
},
"value": {
"type": "long"
}
}
}
}
View Code
这个索引有一个副本和一个分片,使用了一个自定义的分析器 oap_analyzer
这个索引有很多字段,大致可以分为以下几类:
关键词类型(keyword):这些字段用来存储不需要分词的字符串,比如address、agent_id、dest_endpoint等。这些字段可以用来进行精确匹配、排序、聚合等操作。
文本类型(text):这些字段用来存储需要分词的字符串,比如dataset、datatable_count、datatable_summation等。这些字段可以用来进行全文检索、模糊匹配等操作。
数值类型(integer、long、double等):这些字段用来存储整数或浮点数,比如component_id、count、double_value等。这些字段可以用来进行数值比较、范围查询、聚合等操作。
二进制类型(binary):这些字段用来存储二进制数据,比如uuid。这些字段不会被索引或搜索,只能用于存储或检索。
复制类型(copy_to):这些字段用来存储其他字段的值的副本,比如endpoint_traffic_name_match、service_traffic_name_match等。这些字段可以用来进行多字段查询。
分析器类型(analyzer):这些字段用来指定使用哪种分析器来处理文本,比如endpoint_traffic_name_match、service_traffic_name_match等。这些字段可以用不同的分词规则来影响搜索结果。
2)、结果 如下
小结:
存储大小随着版本的升级而减少,8.8版本的存储大小是157943758字节,比6.8版本的存储大小减少了41.2%,比7.10版本的存储大小减少了8.2%
这说明8.8版本在文档压缩和索引优化方面有很大的改进,特别是当索引中含有比较多的keyword和数值类型字段时。
二、Elasticsearch 7.x 相较于 5.x 版本的改进和优化
1、类型(Type)被移除
5.x:一个索引可以包含多个类型(types),类型之间共享相同的字段定义。但类型引发了很多问题,特别是映射冲突。
7.x:彻底移除了类型的概念,强调了“每个索引只能包含一个类型”。在 6.x 版本中类型已被弃用,7.x 中完全废除。这简化了映射管理,避免了映射冲突问题。
说明:把 Index 看作关系型数据库实例(Database)的话,Type 相当于数据库中的table概念
2、默认分片数量的调整
5.x:默认每个索引有 5 个主分片。
7.x:默认主分片数量减少到 1 个,用户可以根据需求手动设置分片数量。这减少了小索引的分片管理开销。
3. 集群稳定性
优化的主节点选举机制:7.x 中引入了改进的主节点选举过程,防止分裂脑问题,集群在主节点故障时更稳定。
更好的分片分配:7.x 优化了分片分配策略,提高了分片迁移的效率和稳定性。
4、Java High-Level REST Client
5.x:通常使用 Transport Client 进行集群交互,但它被认为不易维护且在 7.x 之后不再推荐使用。
7.x:引入并推荐使用 Java 高级 REST 客户端,它更易于维护并使用 HTTP 协议与 Elasticsearch 交互,减少了使用低级别 API 的复杂性。
5、压缩和性能改进
Faster and Smaller Indexes:7.x 版本对索引的压缩方式进行了优化,通过 Lucene 的改进减少了索引的磁盘占用,提高了查询性能。
写入性能:7.x 在写入路径中通过多线程和内存结构的优化,提高了写入性能。
6、查询优化
Unified Query API:7.x 中进一步简化了查询 DSL(Domain-Specific Language),提高了查询的灵活性和一致性。
优化聚合查询:在 7.x 中,对聚合查询进行了进一步优化,特别是在处理大型数据集时,性能提升显著。
7、热-冷架构支持
Index Lifecycle Management (ILM):7.x 引入了索引生命周期管理,可以根据数据的使用模式自动将索引从热节点移至冷节点或冷存储,降低了长期存储的成本。
8、轻量型索引(Data Streams)
7.x 引入了数据流的概念(Data Streams),特别适用于时间序列数据。通过这种机制,Elasticsearch 可以更高效地处理日志和时间序列数据,并能更轻松地管理数据的生命周期。
三、8.X 新特性
随着时间的推移,ES逐渐增加了更多的功能,如聚合分析、地理位置搜索、实时数据处理等。在版本 7 中,Elasticsearch 引入了一些重要的改进,如更好的性能优化、更强大的安全功能和更丰富的查询语言。
而版本 8 的推出,则是 Elasticsearch 发展历程中的一个重要里程碑,带来了一系列的重大变革和突破。
在性能方面:版本 8 进行了一系列的优化,提高了查询和写入的性能,使得用户能够更快地获取到搜索结果和处理数据。
在安全性方面:版本 8 引入了更强大的安全机制,保护用户的数据安全和隐私。
在功能方面:版本 8 增加了许多新的特性,如机器学习功能的改进、搜索体验的提升等,为用户提供了更多的价值和可能性。
1、安全性增强 -- 新的安全机制
8.X 中引入了更为先进的身份验证和授权机制,为系统的安全性提供了更坚实的保障。内置的用户管理功能使得管理员可以方便地创建、修改和删除用户,同时可以为用户分配不同的角色和权限。
通过角色管理功能,管理员可以定义不同的角色,并为每个角色分配相应的权限,如查询、写入、管理等。这样,用户在进行操作时,系统会根据其所属的角色和权限进行验证,确保只有授权的用户能够进行相应的操作。
2、安全性增强 -- 数据保护机制
为了保护数据的机密性和完整性,版本 8 采用了多种加密技术。
在数据传输过程中,通过使用 SSL/TLS 协议对数据进行加密,确保数据在网络传输过程中的安全。
在数据存储方面,Elasticsearch 支持对数据进行加密存储,只有拥有相应密钥的用户才能解密和访问数据。
此外,通过设置访问策略,管理员可以限制用户对数据的访问范围和操作权限,防止数据泄露和滥用
3、性能优化 -- 查询性能提升
首先,缓存机制得到了改进,使得经常使用的查询结果能够更快地被返回,减少了重复计算的开销。
其次,查询计划的优化使得系统能够根据查询的特点和数据的分布情况,选择最优的查询执行计划,提高查询的效率。
此外,版本 8 还对索引结构进行了优化,进一步提高了查询的性能
为了展示查询性能的显著提升,我们进行了一系列的实际测试。在测试中,我们使用了相同的数据集和查询语句,分别在版本 7 和版本 8 上进行查询操作。测试结果表明,版本 8 的查询性能相比版本 7 有了明显的提升,查询时间缩短了 30%以上
4、性能优化 -- 写入性能提升
批量写入功能的增强使得可以一次性写入大量的数据,减少了与服务器的交互次数,提高了写入效率。
异步写入则允许将数据先写入缓存,然后在后台进行异步处理,提高了系统的并发处理能力。
此外,版本 8 还对数据的分段存储和合并策略进行了优化,减少了写入过程中的磁盘 I/O 操作,进一步提高了写入性能。
通过实际测试数据对比版本 7 及之前的版本,我们可以看到版本 8 的写入性能有了显著的改进。在相同的测试环境下,版本 8 的写入速度比版本 7 提高了 20%左右。
四、8.X 版本升级指南
To upgrade to 8.0.1 from 7.16 or earlier, you must first upgrade to 7.17.
早期版更新至7.17的间隔更新版本:5.6、6.8、7.X
Elasticsearch 采用了非常保守的升级策略,本质上是让集群的维护者、使用者自己去把控风险,手动升级。这或许也是 Elasticsearch 官方没有提供一键升级的原因。
因为,中间环节有太多不可控的因素。如果一键升级,每个用户的集群环境千差万别,会出各种问题。
全部交给用户手动升级,复杂是复杂了点,但这是保留用户体验方面折中的实现方案。
参考
https://www.elastic.co/guide/en/elastic-stack/index.html
Elasticsearch 7.x 相较于 5.x 版本的改进和优化
深入探索 Elasticsearch 8
Elasticsearch最佳实践:不同版本之间的存储成本对比