Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Elasticsearch最佳实践:通过调优来节省日志和指标存储成本

Elasticsearch最佳实践:通过调优来节省日志和指标存储成本

原创
作者头像
点火三周
修改于 2023-10-27 07:04:37
修改于 2023-10-27 07:04:37
2.7K00
代码可运行
举报
文章被收录于专栏:Elastic Stack专栏Elastic Stack专栏
运行总次数:0
代码可运行

当我们使用Elasticsearch时,存储成本一直是需要考虑的重要因素。在上一篇文章《Elasticsearch最佳实践:不同版本之间的存储成本对比》中,我们向大家展示了仅通过升级版本而无需进行任何调优配置,就能获得的提升效果。些数据对比清晰地表明,Elasticsearch的不断更新和优化使得仅仅升级版本就能在存储成本上带来巨大的提升。但这并非我们持续优化道路上的终点,相反,这只是开始。在本文中,我们将详细介绍我们在多个不同版本中引入的新特性,以及它们如何帮助我们持续优化存储成本。让我们一起来看看如何应用这些新特性吧!

Elasticsearch多版本间的性能更新
Elasticsearch多版本间的性能更新

测试前置条件

在本文中,我们将对 Elasticsearch 在日志场景和指标场景两个方面进行优化。与上篇文章不同,本文将专注在新特性上,也就是说,我们将只在一个版本上,尽可能的给大家展示对应场景的最佳实践,以及我们能够最大程度上达到的效果。

数据源和版本选择

为了尽可能真实地呈现实际环境中的情况,我们仍将使用由 Apache SkyWalking showcase 生成的日志和指标数据作为我们的数据来源。在选择 Elasticsearch 的版本时,我们将使用腾讯云上提供的最新版本8.8.1。

日志场景成本优化

要对日志场景进行有效的优化,我们特别需要掌握日志数据中每个字段我们是如何使用的以及具体的使用频率(通过 _field_usage_stats API ),以及每个字段的磁盘占用情况(通过 _disk_usage API)才能有针对性的进行优化。

因此,首先我们回顾一下原始的 Skywalking 采集的日志的数据结构,以下是 SkyWalking 日志数据的schema:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "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"
      }
    }
  }
}
  • 这个索引有5个分片和0个副本,使用了一个自定义的分析器oap_log_analyzer
  • 这个索引有15个字段,大致可以分为以下几类:
    • 文本类型(text):这些字段用来存储需要分词的字符串,比如content。这些字段可以用来进行全文检索、模糊匹配等操作。
    • 关键词类型(keyword):这些字段用来存储不需要分词的字符串,比如endpoint_idservice_id等。这些字段可以用来进行精确匹配、排序、聚合等操作。
    • 数值类型(integer、long等):这些字段用来存储整数或长整数,比如content_typespan_id等。这些字段可以用来进行数值比较、范围查询、聚合等操作。
    • 二进制类型(binary):这些字段用来存储二进制数据,比如tags_raw_data。这些字段不会被索引或搜索,只能用于存储或检索。
    • 复制类型(copy_to):这些字段用来存储其他字段的值的副本,比如content_match。这些字段可以用来进行多字段查询。
    • 分析器类型(analyzer):这些字段用来指定使用哪种分析器来处理文本,比如content_match。这些字段可以用不同的分词规则来影响搜索结果。

样例为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
      {
        "_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
        }
      }

要进行索引优化,优先需要保证业务场景不被破坏。因此,每次对索引schema的修改,都需要到业务中去进行验证。

在我们这个场景中,sw_log-* 日志主要用于在 Skywalking的UI上过滤和查询日志。

而从界面上看,我们可以看到 service_id(服务)、endpoint_id(端点)、service_instance_id(实例)、trace_id(追踪)、trace_segment_id、unique_id 主要被用来对日志进行过滤,并且整个界面上没有可以对日志数据进行聚合的地方。content则被用来搜索,另外,主要的存储空间的占用在于tags_raw_data字段。通过分析字段的用途,我们才能做到对下一步的优化操心中有数。

Skywalking的日志查看界面
Skywalking的日志查看界面

了解字段使用情况

另外,我们可以通过 _field_usage_stats API 来查看每个字段的具体使用情况。

Skywalking日志索引的字段使用情况
Skywalking日志索引的字段使用情况

样例:

代码语言:json
AI代码解释
复制
        "stats": {
          "all_fields": {
            "any": 120,
            "inverted_index": {
              "terms": 35,
              "postings": 20,
              "term_frequencies": 0,
              "positions": 0,
              "offsets": 0,
              "payloads": 0,
              "proximity": 0
            },
            "stored_fields": 16,
            "doc_values": 46,
            "points": 69,
            "norms": 0,
            "term_vectors": 0,
            "knn_vectors": 0
          },
          "fields": {
            "_id": {
              "any": 8,
              "inverted_index": {
                "terms": 0,
                "postings": 0,
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 8,
              "doc_values": 0,
              "points": 0,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            },
            "_source": {
              "any": 8,
              "inverted_index": {
                "terms": 0,
                "postings": 0,
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 8,
              "doc_values": 0,
              "points": 0,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            },
            "content_match": {
              "any": 7,
              "inverted_index": {
                "terms": 7,
                "postings": 2,
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 0,
              "doc_values": 0,
              "points": 0,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            },
            "endpoint_id": {
              "any": 1,
              "inverted_index": {
                "terms": 1,
                "postings": 1,
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 0,
              "doc_values": 0,
              "points": 0,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            },
            "service_id": {
              "any": 23,
              "inverted_index": {
                "terms": 23,
                "postings": 16,
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 0,
              "doc_values": 0,
              "points": 0,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            },
            "service_instance_id": {
              "any": 1,
              "inverted_index": {
                "terms": 1,
                "postings": 1,
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 0,
              "doc_values": 0,
              "points": 0,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            },
            "time_bucket": {
              "any": 23,
              "inverted_index": {
                "terms": 0,
                "postings": 0,
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 0,
              "doc_values": 23,
              "points": 23,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            },
            "timestamp": {
              "any": 46,
              "inverted_index": {
                "terms": 0,
                "postings": 0,
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 0,
              "doc_values": 23,
              "points": 46,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            },
            "trace_id": {
              "any": 3,
              "inverted_index": {
                "terms": 3,
                "postings": 0,
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 0,
              "doc_values": 0,
              "points": 0,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            }
          }
        }

以上是_field_usage_stats API的返回。以 service_id 为例,我们可以看到该字段的使用情况:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
            "service_id": {
            # 23 该字段一共被使用了23"any": 23, 
              # 23 次均是使用倒排索引,仅索引文档编号。用于验证字词在字段中是否存在。
              "inverted_index": {
                "terms": 23,
                "postings": 16,
                # 无相关性打分的使用
                "term_frequencies": 0,
                "positions": 0,
                "offsets": 0,
                "payloads": 0,
                "proximity": 0
              },
              "stored_fields": 0,
              # 从未对该字段进行聚合、排序等操作
              "doc_values": 0,
              "points": 0,
              "norms": 0,
              "term_vectors": 0,
              "knn_vectors": 0
            },

因此可以得到以下判断:

  • 需要保留 index: true,因为用到了倒排索引 inverted_index,用于验证字词在字段中是否存在。
  • 可以配置: doc_values: false ,因为 doc_values 等数据结构则没有调用过

content_match则只进行了匹配,没有使用相关性打分。可以考虑改成 match_only_text 类型

了解字段的占用

除了了解每个字段的使用情况和使用频率。配合使用_disk_usage API,我们可以大致判断出优化的方向,以及具体优化哪些字段或者类型可以最大化效果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "sw_log-20231023": {
    "store_size": "74.6mb",
    "store_size_in_bytes": 78307161,
    "all_fields": {
      "total": "74.3mb",
      "total_in_bytes": 77995159,
      "inverted_index": {
        "total": "34.2mb",
        "total_in_bytes": 35956797
      },
      "stored_fields": "24.3mb",
      "stored_fields_in_bytes": 25585241,
      "doc_values": "13.7mb",
      "doc_values_in_bytes": 14391804,
      "points": "1.6mb",
      "points_in_bytes": 1729041,
      "norms": "324.4kb",
      "norms_in_bytes": 332276,
      "term_vectors": "0b",
      "term_vectors_in_bytes": 0,
      "knn_vectors": "0b",
      "knn_vectors_in_bytes": 0
    }
    ...
      "content": {
        "total": "9.1mb",
        "total_in_bytes": 9592092,
        "inverted_index": {
          "total": "8.9mb",
          "total_in_bytes": 9425954
        },
        "stored_fields": "0b",
        "stored_fields_in_bytes": 0,
        "doc_values": "0b",
        "doc_values_in_bytes": 0,
        "points": "0b",
        "points_in_bytes": 0,
        "norms": "162.2kb",
        "norms_in_bytes": 166138,
        "term_vectors": "0b",
        "term_vectors_in_bytes": 0,
        "knn_vectors": "0b",
        "knn_vectors_in_bytes": 0
      },
      "content_match": {
        "total": "9.1mb",
        "total_in_bytes": 9599222,
        "inverted_index": {
          "total": "8.9mb",
          "total_in_bytes": 9433084
        },
        "stored_fields": "0b",
        "stored_fields_in_bytes": 0,
        "doc_values": "0b",
        "doc_values_in_bytes": 0,
        "points": "0b",
        "points_in_bytes": 0,
        "norms": "162.2kb",
        "norms_in_bytes": 166138,
        "term_vectors": "0b",
        "term_vectors_in_bytes": 0,
        "knn_vectors": "0b",
        "knn_vectors_in_bytes": 0
      },
      ...
      "trace_segment_id": {
        "total": "3.3mb",
        "total_in_bytes": 3495441,
        "inverted_index": {
          "total": "1.3mb",
          "total_in_bytes": 1422089
        },
        "stored_fields": "0b",
        "stored_fields_in_bytes": 0,
        "doc_values": "1.9mb",
        "doc_values_in_bytes": 2073352,
        "points": "0b",
        "points_in_bytes": 0,
        "norms": "0b",
        "norms_in_bytes": 0,
        "term_vectors": "0b",
        "term_vectors_in_bytes": 0,
        "knn_vectors": "0b",
        "knn_vectors_in_bytes": 0
      },
      "unique_id": {
        "total": "10.4mb",
        "total_in_bytes": 10993201,
        "inverted_index": {
          "total": "5.2mb",
          "total_in_bytes": 5527964
        },
        "stored_fields": "0b",
        "stored_fields_in_bytes": 0,
        "doc_values": "5.2mb",
        "doc_values_in_bytes": 5465237,
        "points": "0b",
        "points_in_bytes": 0,
        "norms": "0b",
        "norms_in_bytes": 0,
        "term_vectors": "0b",
        "term_vectors_in_bytes": 0,
        "knn_vectors": "0b",
        "knn_vectors_in_bytes": 0
      }

简单总结一下:

  • _source: 31.23% - 23.3mb
  • trace_id: 14.26% - 10.6mb
  • unique_id: 14.04% - 10.4mb
  • content_match: 12.26% - 9.1mb
  • content: 12.25% - 9.1mb
  • _id: 7.15% - 5.3mb
  • trace_segment_id: 4.46% - 3.3mb
  • timestamp: 1.63% - 1.2mb
  • time_bucket: 1.20% - 914.3kb
  • _seq_no: 1.07% - 819.6kb
  • service_instance_id: 0.01% - 8.6kb
  • endpoint_id: 0.01% - 8.3kb
  • service_id: 0.01% - 8kb
  • tags: 0.01% - 8kb
  • span_id: 0.01% - 4.5kb
  • _primary_term: 0.00% - 0b
  • _recovery_source: 0.00% - 0b
  • _version: 0.00% - 0b
  • content_type: 0.00% - 0b

也就是说,我们的优化只需要重点考虑前五个字段。当字段过多的时候,这种分析能够有效的减少我们的分析的符合。

配合上面的_field_usage_stats API 的返回内容,我们可以看到doc_values数据结构没有被使用过,查询不用打分排序,因此,如果我们优化 doc_values (共13.7mb),可以减少15%左右的存储空间。而contentcontent_match,都是9.1mb,如果都变为match_only_text,可以分别减少30%的存储(从9mb -> 6mb)。

unique_idtrace_segment_id,几乎在界面上不可见,也无法用来过滤。则可以考虑变为runtime field。几乎可以完全100%节省。

将shcema优化一番,改为如下配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"mappings": {
    "dynamic": "runtime",
    "_source": {
      "excludes": [
        "tags"
      ]
    },
    "properties": {
      "content": {
        "type": "match_only_text",
        "copy_to": [
          "content_match"
        ]
      },
      "content_match": {
        "type": "match_only_text"
        
      },
      "content_type": {
        "type": "integer"
      },
      "endpoint_id": {
        "type": "keyword",
        "doc_values": false
      },
      "service_id": {
        "type": "keyword",
        "doc_values": false
      },
      "service_instance_id": {
        "type": "keyword",
        "doc_values": false
      },
      "span_id": {
        "type": "integer"
      },
      "tags": {
        "type": "keyword",
        "doc_values": false
      },
      "tags_raw_data": {
        "type": "binary",
        "store": false
      },
      "time_bucket": {
        "type": "long"
      },
      "timestamp": {
        "type": "long"
      },
      "trace_id": {
        "type": "keyword",
        "doc_values": false
      }
    }
  }

这里的改造包括:

  • 因为没有用到聚合和排序功能,将所有的 keyword 类型的字段添加 "doc_values":false
  • 因为没有用到相关性打分功能,将所有的 text 字段改为 match_only_text
  • 对于连过滤都没用上,几乎在所有文档中都没有的 trace_segment_id 和 unique_id 字段,则把所有功能关掉,甚至可以将其设置为 runtime field。

通过以上改造,我们可以看到在保证skywalking仍然能够正常使用所有UI功能的前提下:

使用改造后的索引,功能一切正常
使用改造后的索引,功能一切正常

同样的一个索引,经过改造后,存储空间节省了28.6%

  • inverted_index: 34.2mb - > 22.2mb
  • doc_values: 13.7mb -> 1.2mb
字段优化
字段优化

需要注意的是,因为每个场景中字段的分布不同,可以优化的空间也不一样的。但像 Skywalking这种数据结构,主要以二进制的方式存储,其实也限制了更深入的优化(二进制的字段限制了synthetic _source,也限制了有效压缩)。所以,对于大多数的日志场景,根据字段的使用频率和方法来进行有针对性的优化,是非常有希望做到30%以上的优化的,这还是在不开任何压缩的情况下。

而如果我们打开压缩,则效果能过达到40%以上。

"index.codec": "best_compression"
"index.codec": "best_compression"

指标场景成本优化

而指标数据,则会更加明显,因为我们可以通过 synthetic _source 配置,直接把行存去掉。

以下是 SkyWalking 指标数据的schema:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "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"
      }
    }
  }
}

显然,当索引字段超过50个的时候,通过肉眼去观察已经比较困难了。而从样例数据去观察:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
        "_index": "sw_metrics-all-20231023",
        "_id": "meter_datasource_202310230003_c29uZ3M=.1_Mzg0ZWZlYWE2NzFjNGFhYjg2ZGFmZjA3OWE4YjljYzZAMTcyLjIyLjAuNg==",
        "_score": 1,
        "_source": {
          "metric_table": "meter_datasource",
          "datatable_summation": "8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-minimumIdle,30|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-threadsAwaitingConnection,0|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-connectionTimeout,90000|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-idleConnections,30|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-idleTimeout,1800000|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-validationTimeout,15000|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-activeConnections,0|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-leakDetectionThreshold,0|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-maximumPoolSize,30|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-totalConnections,30",
          "datatable_value": "8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-minimumIdle,10|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-threadsAwaitingConnection,0|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-connectionTimeout,30000|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-idleConnections,10|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-idleTimeout,600000|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-validationTimeout,5000|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-activeConnections,0|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-leakDetectionThreshold,0|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-maximumPoolSize,10|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-totalConnections,10",
          "service_id": "c29uZ3M=.1",
          "datatable_count": "8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-minimumIdle,3|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-threadsAwaitingConnection,3|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-connectionTimeout,3|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-idleConnections,3|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-idleTimeout,3|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-validationTimeout,3|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-activeConnections,3|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-leakDetectionThreshold,3|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-maximumPoolSize,3|8f4533b8-9761-4c49-b902-f88257c06d05_localhost:-1-totalConnections,3",
          "time_bucket": 202310230003,
          "entity_id": "c29uZ3M=.1_Mzg0ZWZlYWE2NzFjNGFhYjg2ZGFmZjA3OWE4YjljYzZAMTcyLjIyLjAuNg=="
        }
      }

我们不仅难以理解数据,也很难定位哪些字段可能会包含值或者会频繁使用。

因此,调用 _disk_usage API 和 _field_usage_stats API,从中分析数据成了调优之前必要工作

  • _source: store_size: 27.8mb , store_percentage: 36.979777%, usage: 2489930, usage_detail: ('stored_fields', 2489930)
  • _id: store_size: 26.7mb , store_percentage: 35.502739%, usage: 2491026, usage_detail: ('inverted_index', 343232), ('stored_fields', 2489930)
  • time_bucket: store_size: 4.2mb , store_percentage: 5.657617%, usage: 6, usage_detail: ('doc_values', 6), ('points', 6)
  • _seq_no: store_size: 4.2mb , store_percentage: 5.627694%, usage: 0, usage_detail:
  • value: store_size: 2.7mb , store_percentage: 3.600615%, usage: 0, usage_detail:
  • summation: store_size: 2mb , store_percentage: 2.777582%, usage: 0, usage_detail:
  • entity_id: store_size: 1.8mb , store_percentage: 2.487291%, usage: 6, usage_detail: ('doc_values', 6)
  • metric_table: store_size: 1.8mb , store_percentage: 2.400633%, usage: 18625, usage_detail: ('inverted_index', 37251)
  • count: store_size: 449.6kb , store_percentage: 0.583405%, usage: 0, usage_detail:
  • service_id: store_size: 445.8kb , store_percentage: 0.578414%, usage: 85, usage_detail: ('inverted_index', 209)
  • _version: store_size: 408.3kb , store_percentage: 0.529785%, usage: 0, usage_detail:
  • percentage: store_size: 384.7kb , store_percentage: 0.499202%, usage: 0, usage_detail:
  • total: store_size: 356.6kb , store_percentage: 0.462709%, usage: 0, usage_detail:
  • match: store_size: 232kb , store_percentage: 0.301037%, usage: 0, usage_detail:
  • source_service_id: store_size: 199kb , store_percentage: 0.258202%, usage: 6, usage_detail: ('inverted_index', 15)
  • dest_service_id: store_size: 197.9kb , store_percentage: 0.256800%, usage: 6, usage_detail: ('inverted_index', 14)
  • dest_endpoint: store_size: 115.3kb , store_percentage: 0.149610%, usage: 0, usage_detail:
  • precision: store_size: 107.4kb , store_percentage: 0.139355%, usage: 0, usage_detail:
  • source_endpoint: store_size: 101kb , store_percentage: 0.131136%, usage: 0, usage_detail:
  • source_service_instance_id: store_size: 100kb , store_percentage: 0.129858%, usage: 0, usage_detail:
  • dest_service_instance_id: store_size: 99.3kb , store_percentage: 0.128939%, usage: 0, usage_detail:
  • component_id: store_size: 64.6kb , store_percentage: 0.083919%, usage: 0, usage_detail:
  • component_ids: store_size: 64.6kb , store_percentage: 0.083852%, usage: 0, usage_detail:
  • int_value: store_size: 39.5kb , store_percentage: 0.051355%, usage: 0, usage_detail:
  • uuid: store_size: 28.1kb , store_percentage: 0.036489%, usage: 0, usage_detail:
  • numerator: store_size: 26.2kb , store_percentage: 0.034065%, usage: 0, usage_detail:
  • s_num: store_size: 21.6kb , store_percentage: 0.028058%, usage: 0, usage_detail:
  • total_num: store_size: 21.6kb , store_percentage: 0.028058%, usage: 0, usage_detail:
  • denominator: store_size: 21.4kb , store_percentage: 0.027872%, usage: 0, usage_detail:
  • double_value: store_size: 16kb , store_percentage: 0.020834%, usage: 0, usage_detail:
  • t_num: store_size: 14.4kb , store_percentage: 0.018767%, usage: 0, usage_detail:
  • double_summation: store_size: 7.3kb , store_percentage: 0.009496%, usage: 0, usage_detail:
  • end_time: store_size: 4.2kb , store_percentage: 0.005495%, usage: 12, usage_detail: ('doc_values', 12), ('points', 12)
  • start_time: store_size: 4.2kb , store_percentage: 0.005493%, usage: 60, usage_detail: ('doc_values', 30), ('points', 60)
  • layer: store_size: 1.9kb , store_percentage: 0.002502%, usage: 22, usage_detail: ('points', 22)
  • message: store_size: 1.6kb , store_percentage: 0.002143%, usage: 0, usage_detail:
  • name: store_size: 1.5kb , store_percentage: 0.001951%, usage: 0, usage_detail:
  • type: store_size: 1.5kb , store_percentage: 0.001951%, usage: 0, usage_detail:
  • service: store_size: 1.5kb , store_percentage: 0.001946%, usage: 30, usage_detail: ('inverted_index', 42)
  • service_instance: store_size: 1.4kb , store_percentage: 0.001939%, usage: 0, usage_detail:
  • endpoint: store_size: 1.4kb , store_percentage: 0.001937%, usage: 0, usage_detail:
  • tag_value: store_size: 379b , store_percentage: 0.000480%, usage: 0, usage_detail:
  • tag_key: store_size: 313b , store_percentage: 0.000397%, usage: 1, usage_detail: ('doc_values', 1)
  • tag_type: store_size: 188b , store_percentage: 0.000238%, usage: 1, usage_detail: ('inverted_index', 3)
  • _primary_term: store_size: 0b , store_percentage: 0.000000%, usage: 0, usage_detail:
  • _recovery_source: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • __soft_deletes: store_size: 0b , store_percentage: 0.000000%, usage: 0, usage_detail:
  • address: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • agent_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • dataset: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • datatable_count: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • datatable_summation: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • datatable_value: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • dest_process_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • detect_type: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • ebpf_profiling_schedule_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • endpoint_traffic_name: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • endpoint_traffic_name_match: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • instance_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • instance_traffic_name: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • label: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • labels_json: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • last_ping: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • last_update_time_bucket: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • parameters: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • process_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • profiling_support_status: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • properties: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • remote_service_name: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • represent_service_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • represent_service_instance_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • service_group: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • service_instance_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • service_name: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • service_traffic_name: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • service_traffic_name_match: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • short_name: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • source_process_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • span_name: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:
  • task_id: store_size: 0 , store_percentage: 0.000000%, usage: 0, usage_detail:

从上面的数据,我们可以知道:优化的重点应该放在占比最多的_id字段和_source字段,并且,大部分的字段都没有被使用,可将其设置为runtime。

synthetic _source

因此,初步的修改的方案为:

  1. 通过ingest pipeline删掉原始的_id字段
  2. 通过配置"_source":{"mode":"synthetic"},将_source字段改为从列存中组合提取
  3. 对于不常使用的字段,设置为runtime

我们可以通过修改index template来实现以上变化:

代码语言:json
AI代码解释
复制
POST  _index_template/sw_metrics-all
{
  
  "index_patterns": [
          "sw_metrics-all-*"
        ],
  "template": {
    "settings": {
      "index": {
        "routing": {
          "allocation": {
            "include": {
              "_tier_preference": "data_content"
            }
          }
        },
        # 删除冗长的_id字段,由ES自动生成
        "default_pipeline":"remove_id",
        "refresh_interval": "30s",
        "analysis": {
          "analyzer": {
            "oap_analyzer": {
              "type": "stop"
            }
          }
        },
        "number_of_shards": "1",
        "number_of_replicas": "1"
      }
    },
    "mappings": {
      # 动态字段均使用 runtime
      "dynamic": "runtime",
      # 使用合成 _source
      "_source": {
      "mode": "synthetic"
    },
      "dynamic_templates": [],
      "properties": {
        "address": {
          "type": "keyword"
        },
        "agent_id": {
          "type": "keyword"
        },
    ...
    },
    "aliases": {
      "sw_metrics-all": {}
    }
  }
}

通过以上的核心改造。我们可以看到,索引大小出现了明显的缩减,整体由75.3mb变为了27.8mb,减少了63.1%:

  • stored_field: 41.7mb -> 4.3mb
  • inverted_inex: 15.2mb -> 7.7mb
使用所有优化措施
使用所有优化措施

谨慎检查调优可能对业务的影响

但考虑到在 skywalking 的配置中, _id字段是将多个字段的值组合之后的自定义_id字段(如:endpoint_relation_server_side_20231026_VXNlcg==.0-VXNlcg==-YXBw.1-Lw==)。在进行以上改造后,变为elasticsearch自动生成的值(如:33453423abf240deb822a9ffc7049c57),导致应用无法正常工作:

修改_id后无法读值
修改_id后无法读值

因此,我们放弃了对_id的改造。即便如此,也仍然节省了40%的存储空间:

仅优化synthetic _source
仅优化synthetic _source

此时,Skywalking可以正常工作:

仅优化后 _source 仍可正常工作
仅优化后 _source 仍可正常工作

如果把压缩打开则达到了50%。( 注意:Skywalking中大部分的数据都是base64格式,导致压缩的比率不高)

"index.codec": "best_compression"
"index.codec": "best_compression"

总结

至此,我们完成了一次简单的日志成本调优。

在上一篇文章《Elasticsearch最佳实践:不同版本之间的存储成本对比》中,我们向大家展示了仅通过升级版本而无需进行任何调优配置,就能获得的提升效果。而在本文,通过调优我们还能看到巨大的提升。日志场景再减少40%。指标场景最高减少63%。同一份日志数据,对比6.8版本上的91mb,在8.8上经过优化后,减少到43mb。而同一份指标数据,对比6.8版本上的270mb,减少到了80mb。

值得我们关注的调优手段,包括但不限于以下手段:

  • dynamtic runtime field
  • match_only_text field
  • doc_value_only field
  • synthetic _source
  • 压缩

虽然本文的调优能够带来更多的收益,但相对于上篇文章仅仅需要做的升级操作,通过本文的案例,我们也显然意识到,调优需要更多的专家知识(特别需要掌握_field_usage_stats API 和 _disk_usage API 的使用),也需要对业务更加了解并能谨慎的反复验证修改数据结构可能对应用带来的影响,才能达到最终的降本目的。

但反过来说,这也是因为 Elasticsearch 提供了所需灵活性,我们才能按需定制我们的应用和数据。

最后,如果你对本文的内容有任何疑问或建议,欢迎在评论区留言,我们将尽快回复你。同时,也请继续关注我们这一系列主题的文章。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Elasticsearch最佳实践:不同版本之间的存储成本对比
作为日志分析场景中最广泛使用的技术解决方案之一,Elasticsearch经常被竞争对手进行比较。特别是随着日志数据量的增加,日志场景中广泛比较的核心指标包括数据写入吞吐量、存储成本、查询速度和分析能力。作为一个不断创新和迭代的产品,Elasticsearch 在日志分析场景中不断引入不同的新功能,以满足客户在日志场景中不断增长的需求。
点火三周
2023/10/25
4.4K0
Elasticsearch最佳实践:不同版本之间的存储成本对比
如何分析和优化 Elastic 部署的存储占用
你是否曾经查看你的索引,想要了解更多关于存储消耗的细节?或者你使用默认设置导入了自定义数据,想知道数据建模的哪些部分可以产生最大的影响?在这篇博客文章中,我们将探讨如何使用 Elastic 最近推出的 磁盘使用 API 来回答这些问题。
点火三周
2025/03/07
1560
如何分析和优化 Elastic 部署的存储占用
Elasticsearch深入:字段的存储
在 Elasticsearch 中,通常每个文档的每一个字段都会被存储在 shard 里存放 source 的地方,比如:
HLee
2021/01/04
2.2K0
Elasticsearch深入:字段的存储
Elasticsearch Index Monitoring(索引监控)之Index Stats API详解
本文将详细介绍Elasticsearch Index Monitoring监控命令之Index Stats API。
丁威
2019/06/11
4.5K0
Elasticsearch Index Monitoring(索引监控)之Index Stats API详解
Elasticsearch 重要mapping参数详解(三)
我们先来看一下一些常用的参数的简介,大致明白这些参数的含义,后面会对一些重要的参数做一个更加详细一些的说明。
问道白发
2019/12/15
6.8K2
Elasticsearch 重要mapping参数详解(三)
别再说你不会ElasticSearch调优了,都给你整理好了
ES 发布时带有的默认值,可为 ES 的开箱即用带来很好的体验。全文搜索、高亮、聚合、索引文档 等功能无需用户修改即可使用,当你更清楚的知道你想如何使用 ES 后,你可以作很多的优化以提高你的用例的性能,下面的内容告诉你 你应该/不应该 修改哪些配置。
Bug开发工程师
2019/05/05
5.7K0
Elasticsearch:inverted index,doc_values及source
这个几个概念分别指的是什么?有什么用处?如何配置它们?只有我们熟练地掌握了这些概念,我们才可以正确地使用它们。
腾讯云大数据
2020/09/29
1.3K0
Elasticsearch:inverted index,doc_values及source
Elasticsearch调优实践
本文基于ES 5.6.4,从性能和稳定性两方面,从linux参数调优、ES节点配置和ES使用方式三个角度入手,介绍ES调优的基本方案。当然,ES的调优绝不能一概而论,需要根据实际业务场景做适当的取舍和调整,文中的疏漏之处也随时欢迎批评指正。
技术姐
2018/07/04
14K3
Elasticsearch调优实践
30 个 ElasticSearch 调优知识点,都给你整理好了!
ES发布时带有的默认值,可为es的开箱即用带来很好的体验。全文搜索、高亮、聚合、索引文档 等功能无需用户修改即可使用,当你更清楚的知道你想如何使用es后,你可以作很多的优化以提高你的用例的性能,下面的内容告诉你 你应该/不应该 修改哪些配置。
肉眼品世界
2021/09/03
7470
Elasticsearch调优实践
在规模比较大的集群中,可以防止新建shard时扫描所有shard的元数据,提升shard分配速度。
HLee
2021/02/08
5960
Elasticsearch调优实践
Elasticsearch Mapping
Elasticsearch Mapping用于定义文档。比如:文档所拥有的字段、文档中每个字段的数据类型、哪些字段需要进行索引等。本文将先后从mapping type、mapping parameter、mapping field和mapping explosion这四个维度展开。
程序猿杜小头
2022/12/01
9410
Elasticsearch调优实践
背景 Elasticsearch(ES)作为NOSQL+搜索引擎的有机结合体,不仅有近实时的查询能力,还具有强大的聚合分析能力。因此在全文检索、日志分析、监控系统、数据分析等领域ES均有广泛应用。而完整的Elastic Stack体系(Elasticsearch、Logstash、Kibana、Beats),更是提供了数据采集、清洗、存储、可视化的整套解决方案。  本文基于ES 5.6.4,从性能和稳定性两方面,从linux参数调优、ES节点配置和ES使用方式三个角度入手,介绍ES调优的基本方案。当然,ES
腾讯技术工程官方号
2018/07/12
3.7K1
Elasticsearch: 理解 mapping 中的 store 属性
默认情况下,对字段值进行索引以使其可搜索,但不存储它们 (store)。 这意味着可以查询该字段,但是无法检索原始字段值。在这里我们必须理解的一点是: 如果一个字段的 mapping 中含有 store 属性为 true,那么有一个单独的存储空间为这个字段做存储,而且这个存储是独立于 _source 的存储的。它具有更快的查询。存储该字段会占用磁盘空间。如果需要从文档中提取(即在脚本中和聚合),它会帮助减少计算。在聚合时,具有store属性的字段会比不具有这个属性的字段快。 此选项的可能值为 false 和 true。
腾讯云大数据
2020/10/28
1.9K0
Elasticsearch: 理解 mapping 中的 store 属性
Elasticsearch最佳实践 之 日志场景优化
       Elasticsearch可广泛应用于日志分析、全文检索、结构化数据分析等多种场景,大幅度降低维护多套专用系统的成本,在开源社区非常受欢迎。然而Elasticsearch为满足多种不同的使用场景,底层组合使用了多种数据结构,部分数据结构对具体的用户使用场景可能是冗余的,从而导致默认情况下无法达到性能和成本最优化。
老生姜
2018/12/10
6.9K1
Elasticsearch最佳实践 之 日志场景优化
《Elasticsearch 源码解析与优化实战》第18章:写入速度优化
在 Es 的默认设置,是综合考虑数据可靠性,搜索实时性,写入速度等因素的,当你离开默认设置,追求极致的写入速度时,很多是以牺牲可靠性和搜索实时性为代价的。有时候,业务上对两者要求并不高,反而对写入速度要求很高。
HLee
2021/05/25
1.6K0
《Elasticsearch 源码解析与优化实战》第18章:写入速度优化
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之行存(一)
在Lucene中索引文档时,原始字段信息经过分词、转换处理后形成倒排索引,而原始内容本身并不直接保留。因此,为了检索时能够获取到字段的原始值,我们需要依赖额外的数据结构。Lucene提供了两种解决方案:Stored Field和doc_values。
公众号:码到三十五
2024/03/19
1.2K0
深入解析Elasticsearch的内部数据结构和机制:行存储、列存储与倒排索引之行存(一)
《Elasticsearch 源码解析与优化实战》第20章:磁盘使用量优化
优化磁盘使用量与建立索引时的映射参数和索引元数据字段密切相关,在介绍具体的优化措施之前,我们先介绍这两方面的基础知识。
HLee
2021/07/27
9010
《Elasticsearch 源码解析与优化实战》第20章:磁盘使用量优化
深入理解Elasticsearch的索引映射(mapping)
在Elasticsearch中,映射类似于关系型数据库中的表结构定义。它描述了索引中字段的类型、如何索引这些字段以及如何处理这些字段的查询。每个索引都有一个与之关联的映射类型,尽管在Elasticsearch 7.x中,每个索引只能有一个映射类型(与之前版本中的多个映射类型不同)。
公众号:码到三十五
2024/03/19
1.4K0
不要将数据库中的“分库分表”理论盲目应用到 Elasticsearch
近期在优化索引时,我遇到了一些挑战。我们的环境是7节点16*32G的机器,我在尝试内存优化。当前的文档总量为5亿,然而mapping设计和shard设计都出现了问题。每个节点上有480个shard,这是一个相当离谱的数量。
铭毅天下
2023/08/18
3620
不要将数据库中的“分库分表”理论盲目应用到 Elasticsearch
ElasticSearch 6.x 学习笔记:14.mapping参数
官方文档 https://www.elastic.co/guide/en/elasticsearch/reference/6.1/mapping-params.html ElasticSearch提供了丰富的映射参数对字段的映射进行参数设计,比如字段的分词器、字段权重、日期格式、检索模型等等。
程裕强
2022/05/06
1.3K0
推荐阅读
相关推荐
Elasticsearch最佳实践:不同版本之间的存储成本对比
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验