写入优化

优化思路:结合业务特点,牺牲部分特性(稳定性、实时性、可靠性)来换取写入性能上的提升。
稳定性:稳定运行,机器宕机后的数据恢复(分片机制)
实时性:写入到查询的时间(refresh)
可靠性:存储数据正确(flush)

具体优化

  1. 提前创建好并配置好mapping,避免插入时动态创建,对于有规律创建的索引(如按日期,自增id),可使用索引模板(模板的主要作用:可以帮助简化创建索引的语句,将模板中的配置和映射应用到创建的索引中)
  2. 修改索引创建时的字段和存储配置,这里主要是指两个属性,source默认为true,会存住doc对应的json数据,当source为false时说明原有数据不会被存储,说明es仅用作搜索,而不存储数据,仅仅能根据倒排索引获取对应的doc_id,用该doc_id可以从其他的数据源获得数据
    store默认为false,是字段的属性,为ture时表示是否需要对该字段进行不属于source的额外存储.单独建立倒排索引。应用场景是source中数据过大,某个字段又要频繁被使用,单独存储可以让其解析过程变快
    适当优化上述两个属性可以减少IO开销
    store与sourcesource
  3. 使用bulk批量写入
  4. 写入时配置路由,写入固定分片,避免批量写入时数据被均匀分配到大量分片上,这个过程需要全部写入成功才会算做是成功,如果某个分片出现长尾请求,会影响整性能。单使用路由要注意负载均衡问题,避免大量数据都写入统一分片
  5. 不自定义doc_id, 避免es对齐进行唯一性检查
  6. 减少副本数,因为主分片写完后要写副分片,大多数场景下数据设置一个即可,甚至在有数据源情况下可以不设置
  7. shard存储量控制,最大不超过30G,10G左右比较好,分片尽量分散,不要让多个分片在一个机器上
  8. refresh控制,大量写入下可以设置为-1(及buffer满以后再进行refresh),牺牲实时性来换取写入速度
  9. 尽量少的flush,flush会影响io性能,牺牲稳定性来换取写入速度
  10. 段合并控制,在非业务高峰期定时合并,es提供功能
  11. index buffer 当大量写入数据时,可以适当调大
  12. 机器尽量选用8C,16G以上

查询优化

查询分为两类

  1. Get查询:以doc_id查询(实时)直接根据id获得数据
  2. Search查询:根据内容查询,匹配到doc_id,再拿到具体数据,二阶段查询(需要倒排索引)(近实时)

正常es会在各节点分别做查询,再在协调节点
思路:宏观上为减少搜索数量,缩小搜索范围,微观上围绕充分利用ES的倒排索引和内部查询优化能力

具体优化

  1. 选择合适的字段类型,字段不做range时,使用keyword,如日期,数字类型,反之需要做range时,必须要使用对应字段类型
  2. 尽量不要使用通配符查询wildcard(key)
  3. 提前知道doc_id的场景使用doc_id查询更快
  4. 查询使用路由,只查询指定分片,避免多分片的查询聚合,这个需要写入时就只定分片
  5. bool子句中用 filter代替must, filter不计算相关分,且能够缓存
  6. 使用source, 只需要的字段字段
  7. 对数据量过大的索引进行拆分
  8. 大量数据翻页查询使用深度分页,但是不能跳页,只能使用滚动查询
  9. 通过段合并,减少段的数量,