Elasticsearch踩过的坑

使用mapping优化索引字段

Elasticsearch做日志存储默认的字符串类型会生成 field_name (text类型)  field_name.keyword(keyword类型) 两个字段,对于很多字段我们查询都是用来聚合和精确匹配(term)查询,我们只要指定改字段为keyword就可以了。

使用mapping指定索引字段的类型

PUT twitter/_mapping/_doc 
{
  "properties": {
    "email": {
      "type": "keyword"
    }
  }
}

对于日志存储每天生成索引的,每个索引字段都是一样的,每次都要指定索引字段有点麻烦,es可以用 Index Templates来解决

PUT _template/test
{
  "index_patterns": ["te*", "bar*"],
  "settings": {
    "number_of_shards": 1
  },
  "mappings": {
    "type1": {
      "_source": {
        "enabled": false
      },
      "properties": {
        "host_name": {
          "type": "keyword"
        },
        "created_at": {
          "type": "date",
          "format": "EEE MMM dd HH:mm:ss Z YYYY"
        }
      }
    }
  }
}

以后创建的以te*,bar*匹配的索引都会使用模板里properties所定义的字段。

Elasticsearch官方的说法:Sometimes it is useful to have both a full text (text) and a keyword (keyword) version of the same field: one for full text search and the other for aggregations and sorting. This can be achieved withmulti-fields.


内存溢出问题

Elasticsearch做日志存储,供业务人员做查询,一开始运行的很快,随着时间的推移,数据越来越大,索引越来越多突然哪天运行一个大的查询,挂了。。。。。查询了es的错误日志发现是内存溢出了。查阅官方的文档,

https://www.elastic.co/guide/cn/elasticsearch/guide/current/_limiting_memory_usage.html#_limiting_memory_usage

官方的说法 indices.fielddata.cache.size 控制为 fielddata 分配的堆空间大小。 当你发起一个查询,分析字符串的聚合将会被加载到 fielddata,如果这些字符串之前没有被加载过。如果结果中 fielddata 大小超过了指定 大小 ,其他的值将会被回收从而获得空间。

默认情况下,设置都是 unbounded ,Elasticsearch 永远都不会从 fielddata 中回收数据。

这个默认设置是刻意选择的:fielddata 不是临时缓存。它是驻留内存里的数据结构,必须可以快速执行访问,而且构建它的代价十分高昂。如果每个请求都重载数据,性能会十分糟糕。

时间的推移,fielddata把堆空间用完,没法再给新的查询数据分配内存,内存溢出了。

为了防止发生这样的事情,可以通过在 config/elasticsearch.yml 文件中增加配置为 fielddata 设置一个上限:

indices.fielddata.cache.size:  20% 

可以设置堆大小的百分比,也可以是某个值,例如: 5gb 。

断路器 indices.breaker.fielddata.limit fielddata 断路器默认设置堆的 60% 作为 fielddata 大小的上限。 indices.breaker.request.limit request 断路器估算需要完成其他请求部分的结构大小,例如创建一个聚合桶,默认限制是堆内存的 40%。 indices.breaker.total.limit total 揉合  request 和  fielddata 断路器保证两者组合起来不会使用超过堆内存的 70%。

最好为断路器设置一个相对保守点的值。 记住 fielddata 需要与 request 断路器共享堆内存、索引缓冲内存和过滤器缓存。Lucene 的数据被用来构造索引,以及各种其他临时的数据结构。 正因如此,它默认值非常保守,只有 60% 。过于乐观的设置可能会引起潜在的堆栈溢出(OOM)异常,这会使整个节点宕掉。

另一方面,过度保守的值只会返回查询异常,应用程序可以对异常做相应处理。异常比服务器崩溃要好。这些异常应该也能促进我们对查询进行重新评估:为什么单个查询需要超过堆内存的 60% 之多?

设置:
PUT /_cluster/settings
{
  "persistent" : {
    "indices.breaker.fielddata.limit" : "40%" 
  }
}

设置保守的 fielddata 和 断路器是服务器稳定的重要配置。


脚本查询问题


突然有一天查不到数据了,报了个下面的错误:


把脚本存储到es里

PUT _scripts/calculate-score
{
  "script": {
    "lang": "painless",
    "source": "Math.log(_score * 2) + params.my_modifier"
  }

}

脚本查询里的代码用id替换,解决

POST ledger/_search?size=0
{
    "aggs": {
        "profit": {
            "scripted_metric": {
                "init_script" : {
                    "id": "my_init_script"
                },
                "map_script" : {
                    "id": "my_map_script"
                },
                "combine_script" : {
                    "id": "my_combine_script"
                },
                "reduce_script" : {
                    "id": "my_reduce_script"
                }
            }
        }
    }
}



  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值