• -------------------------------------------------------------
  • ====================================

Elasticsearch索引建议

elasticsearch dewbay 5年前 (2019-04-12) 1642次浏览 已收录 0个评论 扫描二维码

背景:
最近在做日志收集,用到 Elasticsearch 作为存储层,因为日志量比较大,一天近 2T,所以每时每刻都会有大量的插入操作。又由于是给开发人员查日志使用,所以查询的量比较小。
受限于存储空间,目前仅保留 7 天的日志,多数为一个业务模块一个索引,按天切分索引。

程序上怎么使用 Elasticsear 索引文档更有效率[1]

官方推荐使用 bulk 批量操作,并且使用一组线程去执行,以便达到更好的效率。使用 bulk 的时候,尽量不要让一次建立索引到量太小,会非常浪费资源。bulk 索引 1 条文档可能需要 23ms,但是 bulk 索引 1000 条文档可能只需要 200ms。
bulk 太快可能会收到 Elasticsearch 插入拒绝,这个时候可以稍微等一下再重试。尽量让一次 bulk 中的所有索引操作集中在几个分片中[2]。
出现插入拒绝时候,检查一下 bulk_queue 参数。有可能不是插入太快,而是队列太小。默认队列大小 200,可以根据自己的情况适当调大。我们的生产环境中,最大调过 30000。
索引文档时尽量使用 Elasticsearch 的自增 id,避免索引时候 Elasticsearch 去检查 id 冲突。
适当增大刷新间隔(refresh interval)。Elasticsearch 默认的刷新间隔为 1s,大量插入时候,可以增大至 30s。
关于索引和类型的取舍,建立多个索引还是一个索引下多个类型

如果一个模块的日志量比较小,那么按天切割会产生很多比较小的索引,进而产生很小的分片,这对 Elasticsearch 是一种资源浪费。所以这种情况下可以选择用 type 来作为日期分类。(有经验的同事还建议不使用 type 而直接加一个日期字段作为区分)
如果一个模块的日质量合适,那么按天切割是个不错的选择,此时一个索引里面只有一种类型。
如果一个模块日质量很大,甚至可以按照更细粒度的切分索引,例如按照 4 个小时一切分。
一个索引建立多少个分片,多少个副本

Elasticsearch 默认每个索引 5 个分片,每个分片 1 个副本。在这种情况下,一个索引最少有 10 个分片。副本在查询的时候可以加速,但是索引文档时候会慢一点
通常说来,对于可以预见的大索引,分片数最少要等于集群的节点数,这样保证每个节点有一个分片,Elasticsearch 处理时候能把数据分散到各个节点。由于业务扩张,Elasticsearch 集群也不总是一直不变,所以初期设置分片数时候建议是节点数的 1.5~3 倍。
上面说的日志量大小并没有很明确的限定,需要根据 Elasticsearch 部署的机器配置,Elasticsearch 启动时候配置的参数来决定。通常来说,按照一个分片 10G~20G 是合适的,即使给 Elasticsearch 分配了最大的 30-32G 的 JVM heap,最大的分片也不要超过 30G[3]。

分片太多会有什么问题

第一个问题是可能导致 Elasticsearch 打开文件句柄数不够,无法新建索引。整个集群的健康状态会变黄甚至变红
分片太多会导致 Elasticsearch 要管理的 mapping 数据变大,引起性能下降
Elasticsearch 和 Lucene 怎么看待类型(Tpye)和映射(mapping)[4]

Elasticsearch 中的类型对 Lucene 不可见,类型只是 Elasticsearch 中的概念。实现时存储在元数据(metadata)的 _type 字段中。type 就 Lucene 看来和普通字段没有区别。
Elasticsearch 中的映射对 Lucene 不可见,映射只是 Elasticsearch 中的概念,用于把我们的复杂 json 展开铺平,转换成 Lucene 接受的数据模式。
同一个索引中的多种 type 最好具有相似的 mapping,避免 Lucene 中大量的空闲字段,这种情况最终会导致性能问题。
如果同一个索引中存在多种 type,并且不同 type 具有相同的字段名,那么这个字段的类型和分词必须相同。
先了解 Elasticsearch 中数据类型[6],合理安排索引中的字段

Elasticsearch 中有多种数据类型,但受限于实现语言是 Java,所以对于 long 类型只支持到 63 位有符号数,如果是 C/C++系语言的 uint64 的值,建议都转化成字符串存储。避免小数值被存为数字,大数值是字符串
对于不确定的字段最好不要设置默认值。Elasticsearch 中一个索引的一个字段只能有一种数据类型,如果不确定这个字段是什么类型盲目设置默认值,可能导致后续插入时数据类型不匹配而插入失败
对于 json 数据类型要做限制。由于 Elasticsearch 会把 json 中字段全部拉平,如果 json 中的字段很多或者相差很大,会造成 mapping 超大,引起性能下降
最后还得时刻注意用 _cat 来检查 Elasticsearch 的状态[6]

参考链接:
[1]https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html
[2]http://stackoverflow.com/questions/20683440/elasticsearch-gives-error-about-queue-size
[3]https://qbox.io/blog/optimizing-elasticsearch-how-many-shards-per-index
[4]https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping.html
[5]https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html

[6]https://www.elastic.co/guide/en/elasticsearch/reference/current/cat.html

作者:阿奴波仔
来源:CSDN
原文:https://blog.csdn.net/xiangyubobo/article/details/67667408
版权声明:本文为博主原创文章,转载请附上博文链接!


露水湾 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Elasticsearch索引建议
喜欢 (0)
[]
分享 (0)
关于作者:
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址