性能优化
使用 Elasticsearch 做索引设计…
适用于使用 Elasticsearch 进行索引/mapping 设计、查询与聚合优化、批量写入、安全与集群维护的场景。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
使用 Elasticsearch 做索引特定
解决思路
- 按查询模式设计 indices 和 mappings,而不是先建索引再想查询。
- 通过合适的 analysis 和 indexing 优化搜索性能。
- 使用合适的 shard sizing 和 cluster configuration。
- 实施安全与访问控制。
- 监控 cluster health 并持续优化查询。
- 显式定义 mappings,不要依赖 dynamic mapping。
- 为每个字段选择合适的数据类型。
- 对不参与搜索的字段关闭 indexing。
- 精确匹配用 keyword,全文检索用 text。
- 按示例 mapping 配置:product_id 用 keyword;name 用 text + keyword 子字段(ignore_above: 256);description 用 text + english analyzer;price 用 scaled_float(scaling_factor: 100);category、tags 用 keyword;created_at 用 date;metadata 用 object 且 enabled: false;location 用 geo_point。
- 使用 keyword 存精确值,用于 filtering、aggregations、sorting。
- 使用 text 进行带 analysis 的全文搜索。
- 使用 date 存日期/时间值,并指定 format。
- 使用 numeric types:long、integer、short、byte、double、float、scaled_float。
- 使用 boolean 存 true/false 值。
- 使用 geo_point 存 latitude/longitude pairs。
- 使用 nested 存需要独立查询的对象数组。
- 按示例设置 index settings:number_of_shards: 3、number_of_replicas: 1、refresh_interval: “30s”;配置 custom_analyzer:tokenizer standard,filter 为 lowercase、asciifolding、synonym_filter;synonym_filter 使用 synonym 类型,同义词如 laptop, notebook 和 phone, mobile, smartphone。
- 每个 shard 目标大小 20-40GB。
- 按每 GB heap 约 20 个 shards 来规划。
- 避免 oversharding(过多小 shard)。
- 时间序列数据考虑按时间建立 indices。
- 按示例设置 shard:number_of_shards: 3、number_of_replicas: 1。
- 配置 ILM policy:hot 阶段 min_age: 0ms,rollover max_size: 50gb、max_age: 7d。
- warm 阶段 min_age: 30d,执行 shrink number_of_shards: 1 和 forcemerge max_num_segments: 1。
- delete 阶段 min_age: 90d,执行 delete。
- 全文搜索用 match query,可设置 operator: and、fuzziness: AUTO。
- 精确匹配用 term query,例如 term status: active。
- 组合查询用 bool query,包含 must、filter、should、must_not。
- 非评分查询使用 filter context(可缓存)。
- 只有需要评分时才用 must。
- 避免在词项开头使用 wildcards。
- 精确匹配使用 keyword 字段。
- 用 size 参数限制结果大小。
- 按示例组合查询:must 中用 multi_match(fields: [“name^3”, “description”, “tags^2”],type: best_fields);filter 中用 term active: true 和 range created_at: gte now-30d;设置 size: 20、from: 0、_source: [“name”, “price”, “category”]。
- 常见聚合模式:terms 聚合 category(size: 10)并嵌套 avg_price 的 avg 聚合(field: price)。
- 使用 range 聚合 price,ranges 为 {to: 100}、{from: 100, to: 500}、{from: 500}。
- 使用 date_histogram 聚合 created_at,calendar_interval: month。
- 只需要聚合时设置 size: 0。
- terms 聚合设置合适的 shard_size。
- 分页聚合使用 composite aggregations。
- 考虑用 aggs filters 缩小聚合范围。
- 批量操作使用 bulk API。
- bulk 请求最优大小 5-15MB。
- 监控 rejected requests(thread pool queue full)。
- 批量索引期间禁用 refresh 以提升性能。
- 按示例:POST _bulk 写入文档;批量前 PUT /products/_settings 设置 refresh_interval: “-1”;批量后设回 “1s” 并 POST /products/_refresh。
- 文档更新用 POST /products/_update/1,doc 中更新 price、updated_at。
- 按查询更新用 POST /products/_update_by_query,query 匹配 term category: electronics,script.source 设置 ctx._source.on_sale = true。
- 自定义 product_analyzer:type custom,tokenizer standard,filter 为 lowercase、asciifolding、english_stop、english_stemmer。
- 自定义 autocomplete_analyzer:type custom,tokenizer standard,filter 为 lowercase、edge_ngram_filter。
- 定义 filter:english_stop 用 stop 类型、stopwords: _english_;english_stemmer 用 stemmer 类型、language: english;edge_ngram_filter 用 edge_ngram 类型、min_gram: 2、max_gram: 15。
- 用 POST /products/_analyze 测试 analyzer,例如 analyzer: product_analyzer、text: “Wireless Bluetooth Headphones”。
- 自动补全:mapping 中 name 用 text,并添加子字段 suggest 类型 completion。
- 建议查询用 suggest.product-suggest,prefix: wire,completion.field: name.suggest,size: 5。
- 高亮:query 中 match description: wireless,highlight.fields.description 设置 pre_tags: [“<em>”]、post_tags: [“</em>”]、fragment_size: 150。
- Filter queries 自动缓存。
- 频繁重复条件使用 filter context。
- 监控 cache hit rates。
- 避免深度分页,改用 search_after。
- 限制返回的 _source 字段。
- 排序和聚合使用 doc_values。
- 为常见排序顺序预排序 index。
- 按示例使用 search_after:query match_all,size: 20,search_after: [1705329600000, “product_123”],sort 为 created_at desc、_id asc。
- 检查 cluster health:GET _cluster/health、GET _cat/indices?v、GET _cat/shards?v、GET _nodes/stats。
- 维护索引:POST /products/_forcemerge?max_num_segments=1、POST /products/_cache/clear、POST /products/_refresh。
- 配置慢查询日志:PUT /products/_settings,设置 index.search.slowlog.threshold.query.warn: “10s”、index.search.slowlog.threshold.query.info: “5s”、index.search.slowlog.threshold.fetch.warn: “1s”。
- 索引级安全:PUT _security/role/products_reader,indices.names: [“products*”],privileges: [“read”]。
- 字段级安全:PUT _security/role/limited_access,indices.names: [“users”],privileges: [“read”],field_security.grant: [“name”, “email”, “created_at”]。
- 索引别名:POST _aliases,actions 添加 {add: {index: “products_v2”, alias: “products”}},移除 {remove: {index: “products_v1”, alias: “products”}}。
- 带转换的 reindex:POST _reindex,source.index: products_v1,dest.index: products_v2,script.source 设置 ctx._source.migrated_at = new Date().toString().
适用边界 · 注意事项
- 未部署 Elasticsearch 或只需简单关系型查询时,不适用。
- 不要对不搜索的字段建立索引,也不要依赖 dynamic mapping。
- 避免 oversharding、深度分页和以 wildcard 开头的查询。