写入优化
优化思路:结合业务特点,牺牲部分特性(稳定性、实时性、可靠性)来换取写入性能上的提升。
稳定性:稳定运行,机器宕机后的数据恢复(分片机制)
实时性:写入到查询的时间(refresh)
可靠性:存储数据正确(flush)
具体优化
- 提前创建好并配置好mapping,避免插入时动态创建,对于有规律创建的索引(如按日期,自增id),可使用索引模板(模板的主要作用:可以帮助简化创建索引的语句,将模板中的配置和映射应用到创建的索引中)
- 修改索引创建时的字段和存储配置,这里主要是指两个属性,source默认为true,会存住doc对应的json数据,当source为false时说明原有数据不会被存储,说明es仅用作搜索,而不存储数据,仅仅能根据倒排索引获取对应的doc_id,用该doc_id可以从其他的数据源获得数据
store默认为false,是字段的属性,为ture时表示是否需要对该字段进行不属于source的额外存储.单独建立倒排索引。应用场景是source中数据过大,某个字段又要频繁被使用,单独存储可以让其解析过程变快
适当优化上述两个属性可以减少IO开销
store与sourcesource - 使用bulk批量写入
- 写入时配置路由,写入固定分片,避免批量写入时数据被均匀分配到大量分片上,这个过程需要全部写入成功才会算做是成功,如果某个分片出现长尾请求,会影响整性能。单使用路由要注意负载均衡问题,避免大量数据都写入统一分片
- 不自定义doc_id, 避免es对齐进行唯一性检查
- 减少副本数,因为主分片写完后要写副分片,大多数场景下数据设置一个即可,甚至在有数据源情况下可以不设置
- shard存储量控制,最大不超过30G,10G左右比较好,分片尽量分散,不要让多个分片在一个机器上
- refresh控制,大量写入下可以设置为-1(及buffer满以后再进行refresh),牺牲实时性来换取写入速度
- 尽量少的flush,flush会影响io性能,牺牲稳定性来换取写入速度
- 段合并控制,在非业务高峰期定时合并,es提供功能
- index buffer 当大量写入数据时,可以适当调大
- 机器尽量选用8C,16G以上
查询优化
查询分为两类
- Get查询:以doc_id查询(实时)直接根据id获得数据
- Search查询:根据内容查询,匹配到doc_id,再拿到具体数据,二阶段查询(需要倒排索引)(近实时)
正常es会在各节点分别做查询,再在协调节点
思路:宏观上为减少搜索数量,缩小搜索范围,微观上围绕充分利用ES的倒排索引和内部查询优化能力
具体优化
- 选择合适的字段类型,字段不做range时,使用keyword,如日期,数字类型,反之需要做range时,必须要使用对应字段类型
- 尽量不要使用通配符查询wildcard(key)
- 提前知道doc_id的场景使用doc_id查询更快
- 查询使用路由,只查询指定分片,避免多分片的查询聚合,这个需要写入时就只定分片
- bool子句中用 filter代替must, filter不计算相关分,且能够缓存
- 使用source, 只需要的字段字段
- 对数据量过大的索引进行拆分
- 大量数据翻页查询使用深度分页,但是不能跳页,只能使用滚动查询
- 通过段合并,减少段的数量,