写入
ES支持四种对文档的数据写操作
create:如果在PUT数据的时候当前数据已经存在,则数据会被覆盖,如果在PUT的时候加上操作类型create,此时如果数据已存在则会返回失败,因为已经强制指定了操作类型为create,ES就不会再去执行update操作。
delete:删除,ES对文档的删除是懒删除机制,即标记删除。(.del文件)
index:创建索引
update:包括全量替换、部分替换
写流程
es中数据写入都是在主分片中;副本分片不支持写入,只读的
客户端发起写入请求到node x,node x根据文档id进行一系列计算,在路由表中确定当前数据在分片a,分片a的主分片位于node y上,将数据转发至node y
数据在node y写入成功后,将数据的同步请求转发至分片a的副本分片上,等待所有副本数据写入成功(根据写入一致性策略),将结果报告给node x,并由node x将结果返回给客户端
写入一致性策略
参数:wait_for_active_shards
确定客户端返回数据之前必须处于active 的分片数(包括主分片和副本)
默认为 wait_for_active_shards = 1,即只需要主分片写入成功
设置为 all
或任何正整数,最大值为索引中的分片总数 ( number_of_replicas + 1
)。
如果当前 active 状态的副本没有达到设定阈值,写操作必须等待并且重试,默认等待时间30秒,直到 active 状态的副本数量超过设定的阈值或者超时返回失败为止。
如果主分片写入失败,默认等待1分钟
写入原理
1. 客户端的操作会先写入内存缓冲区,内存缓冲区有固定大小,等内存缓冲区满了或者时间间隔到了(1s)
2. 执行refresh操作,生成对应的segment文件(lucene的索引文件),并立刻同步到OS cache中
3. segment文件同步到OS chache后,segment处于open状态,此时,segment中的数据就可以查询了(此时,数据还没有同步到磁盘中)
4. OS cache中的数据满了会执行fsync操作,将数据同步到OS disk
5. OS cache中的数据是断电易失的,需要Translog来保证数据安全,translog是append的形式写的,直接写在磁盘上。OS cache同步到OS disk后,会同步后会清空translog
refresh操作可以手动执行,减少数据延迟
segment文件越来越多,segment消耗操作系统句柄,需要定期进行合并,
merge操作:
将多个segment文件合并成一个大的segment文件
merge操作也消耗资源,不能过于频繁
OS cache满了,或者translog满了,都会触发fsync操作
flush:是把内存中的数据(包括translog和segments)都刷到磁盘
写入调优
分为两种情况,高频低量和低频高量
1. 关闭副本,写入成功后再打开副本(低频高量)
2. 增加 flush 时间间隔:减小数据写入磁盘的频率
3. 增加refresh_interval的参数值:减少segment文件的创建
4. 增加Buffer大小:本质也是减少refresh
5. 禁用swap
6. 使用多个工作线程
7. 避免使用稀疏数据
8. max_result_window参数:分页返回的最大数值,默认10000,对JVM的一种保护机制
查询调优
写入性能和查询性能不可能都会好的,要看项目更侧重哪个
要写入实时性换取查询性能
1. 避免大单页查询
2. 避免单个文档过大
3. 增加内存:OS cache
4. 使用filter代替query
5. 避免深度分页
6. 使用keyword类型:不分词,integer、long
7. 避免使用脚本
深度分页
问题
当from + size
大于10000
的时候,就会出现问题
没有指定排序字段的情况下,默认按照评分score来排序
scroll search
一般情况下要避免进行深度分页,无法避免可以使用scroll search 滚动查询
es7开始,官方不推荐使用滚动查询,因为无法保存索引状态
滚动查询适用于单个请求中检索大量结果,不适用与To C端
scroll用法
查询条件加scroll
GET my-index-000001/_search?scroll=1m
{
"size": 100,
"query": {
"match": {
"message": "foo"
}
}
}
'
scroll的值是时间,例如,上面的查询结果只在1分钟内生效,时间单位越小越好
查询结果会返回scroll_id,用于下一页查询
Scroll上下文的存活时间是滚动的,下次执行查询会刷新,也就是说,不需要足够长来处理所有数据,它只需要足够长来处理前一批结果。
保持旧段处于活动状态意味着需要更多的磁盘空间和文件句柄。
为防止因打开过多Scrolls而导致的问题,不允许用户打开超过一定限制的Scrolls。
默认情况下,打开Scrolls的最大数量为 500。此限制可以通过search.max_open_scroll_context
集群设置进行更新 。
问题
scroll search很消耗资源,不要滥用
search after
search after 是无状态的,推荐使用
需要有固定唯一的排序
用法
查询条件需要有固定唯一的排序
查询结果会返回sort,
下一页查询时,使用上一页的sort
问题
search afer只能往后查询,不能查询前面的内容