内存吞金兽(Elasticsearch)的那些事儿 -- 常见问题痛点及解决方案
1、大数据量的查询效率如何保证:
查询的流程:往 ES 里写的数据,实际上都写到磁盘文件里去了,查询的时候,操作系统会将磁盘文件里的数据自动缓存到 Filesystem Cache 里面去
最佳的情况下,就是机器的内存,至少可以容纳总数据量的一半,仅仅在 es 中就存少量的数据,就是要用来搜索的那些索引,如果内存留给 filesystem cache 的是 100G,那么将索引数据控制在 100G 以内,这样的话,数据几乎全部走内存来搜索,性能非常之高,一般可以在 1 秒以内,但是生成环境的数据量往往还是会很多,有大致四种方案:
1)数据预热
平时看的人很多的数据,每隔一会儿,去搜索一下热数据,刷到 filesystem cache
里去,后面用户实际上来看这个热数据的时候,就是直接从内存里搜索了;
2)冷热分离
将大量的访问很少、频率很低的数据,单独写一个索引,然后将访问很频繁的热数据单独写一个索引。最好是将冷数据写入一个索引中,然后热数据写入另外一个索引中,这样可以确保热数据在被预热之后,尽量都让他们留在 filesystem os cache
里,别让冷数据给冲刷掉。
3)es+Hbase架构:
es只存储索引字段,其他数据放到mysql/hbase中;
举例说明:id,name,age .... 30 个字段。现在搜索,只需要根据 id,name,age 三个字段来搜索。如果往 es 里写入一行数据所有的字段,就会导致说 90% 的数据是不用来搜索的,结果硬是占据了 es 机器上的 filesystem cache 的空间,单条数据的数据量越大,就会导致 filesystem cahce 能缓存的数据就越少。其实,仅仅写入 es 中要用来检索的少数几个字段就可以了,比如说就写入es id,name,age 三个字段,然后你可以把其他的字段数据存在 mysql/hbase 里,我们一般是建议用 es + hbase 这么一个架构。
4)document 模型设计
对于 MySQL,我们经常有一些复杂的关联查询。es 里面的复杂的关联查询尽量别用,一旦用了性能一般都不太好。
要先在 Java 系统里就完成关联,将关联好的数据直接写入 es 中。搜索的时候,就不需要利用 es 的搜索语法来完成 join 之类的关联搜索了。
2、分页查询痛点及解决方案:
假设现在要查询第100页的10条数据,但是对于es来说,from=1000000,size=100,这时 es需要从各个分片上查询出来10000100条数据,然后汇总计算后从其中取出100条。如果有5个分片则需要查询出来5*10000100条数据,如果现在有并发的100个查询请求,就会有50亿左右的数据,占用的内存是非常高的,所以在使用es的分页查询过程中,刚开始翻页可能速度比较快,可能到第一百页查询就需要4-5s,翻到1000页以后,系统资源占用成指数级上升,很容易就会出现OOM直接报错。
分页方案:
1)基本的from-size查询,es为了避免深度分页带来的内存开销,from最大值设定到了10000,目前后台运营的翻页最多关心近10页的数据;
2)search after按照第一个检索到的最后显示的“balance”和‘_id’值,作为下一个检索search_after的参数,例如假定size是10,当查询990-1000时,通过上次传递的最后一个检索到的值,在分片上就可以取到10条文档,不支持上一页查询。
3)scroll查询
scroll查询原理是在第一次查询的时候一次性生成一个快照,根据上一次的查询的id来进行下一次的查询,这个就类似于关系型数据库的游标,然后每次滑动都是根据产生的游标id进行下一次查询,这种性能比上面说的分页性能要高出很多,基本都是毫秒级的。
注意点:scroll不支持跳页查询。
使用场景:对实时性要求不高的查询。
代码:
设置查询条件
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); .must(builder); |
首次查询
- 第一次查询,跟平时的search查询一样需要设置index和type以及查询条件。
- 如果把查询类型设置成SCAN,那么不能获取结果并且不支持排序,只能获得scrollId,如果使用默认设置或者不设置,那么第一次在获取id的同时也可以获取到查询结果。
- 这个size大小的意思不是总分页的大小,实际数量应该是:所以实际返回的数量是:分片的数量*size
- 滚动时间设置是指在这个查询搜索结果的缓存时间,时间不能太久,毕竟内存空间是有限的。
.setQuery(boolQueryBuilder) .setSearchType(.setSearchType(SearchType.DEFAULT)) .execute().actionGet(); //第一次查询 for (SearchHit searchHit : response1.getHits().hits()) { biz handle....; } |
第二次查询
} response1 = client.prepareSearchScroll(response1.getScrollId()).setScroll(TimeValue.timeValueMinutes( 5 )) .execute().actionGet(); } |
4) 利用scroll-scan遍历数据
使用场景:500w用户,需要遍历所有用户发送数据,并且对顺序没有要求,这个时候我们可以使用scroll-scan。
查询 .setQuery(boolQueryBuilder) .setSearchType(SearchType.SCAN) .execute().actionGet(); 获取结果 SearchResponse response1 = client.prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMinutes( 5 )) .execute().actionGet(); } response1 = client.prepareSearchScroll(response1.getScrollId()).setScroll(TimeValue.timeValueMinutes( 5 )) .execute().actionGet(); } |
scroll和scroll-scan区别
scroll支持排序,scroll-scan不支持排序,是按照索引顺序返回,可以提高查询效率。
scroll-scan第一次查询只支持返回id,没有结果。
总结:
- es的分页查询不支持深度分页,如果偏要使用要结合具体业务场景进行使用。不能当成关系型数据库中的分页进行使用。
- 要想提高产品体验和查询效率不能过于依赖技术,要结合需求进行分析以提高体验,因为很多搜索类产品都不支持深度分页。
- 如果在不涉及排序的情况下尽量使用scroll-scan,它是按照索引顺序返回,提高效率。
内存吞金兽(Elasticsearch)的那些事儿 -- 常见问题痛点及解决方案的更多相关文章
- 内存吞金兽(Elasticsearch)的那些事儿 -- 认识一下
背景及常见术语 背景 Elasticsearch 是一个开源的搜索引擎,建立在一个全文搜索引擎库 Apache Lucene 基础之上. Lucene 可以说是当下最先进.高性能.全功能的搜索引擎库- ...
- java虚拟机内存不足,“Could not create the Java Virtual Machine”问题解决方案
java虚拟机内存不足,"Could not create the Java Virtual Machine"问题解决方案 在运行java程序时,遇到问题"Could n ...
- Elasticsearch生产环境遇到的问题以及解决方案
Elasticsearch是一个开源的分布式实时搜索与分析引擎,支持云服务.它是基于Apache Lucene搜索引擎的类库创建的,提供了全文搜索能力.多语言支持.专门的查询语言.支持地理位置服务.基 ...
- 【腾讯优测干货分享】如何降低App的待机内存(二)——规范测试流程及常见问题
本文来自于腾讯优测公众号(wxutest),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/806TiugiSJvFI7fH6eVA5w 作者:腾讯TMQ专项测 ...
- 干货 | Elasticsearch 集群健康值红色终极解决方案【转】
题记 Elasticsearch当清理缓存( echo 3 > /proc/sys/vm/drop_caches )的时候,出现 如下集群健康值:red,红色预警状态,同时部分分片都成为灰色. ...
- java虚拟机内存不足,“Could not create the Java Virtual Machine”问题解决方案
在运行java程序时,遇到问题"Could not create the Java Virtual Machine."如下截图:
- elasticsearch进行远程访问,所面对的问题解决方案
elasticsearch6.2进行远程访问,修改yml文件后,启动会报错: 上面四个问题解决方案如下: 问题1,问题2,问题3,解决如下: 注意: 针对第二个问题,你可能在limits.d目录中没有 ...
- Elasticsearch 集群健康值红色终极解决方案
文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247483905&idx=1&sn=acaff63 ...
- Plan B
王兴曾经说过: 2019 年是过去 10 年中最差的一年,也是未来 10 年中最好的一年. 之前我希望王兴预判错了,但现在我发现这位掌控着生活消费类数据的大佬应该不是扯淡. 今年的内部和外部环境真的很 ...
随机推荐
- linux学习之路第二天(xshell和xftp的使用图解)
以上xshell的连接过程 2.远程上传和下载文件xftp6 一定要换成22和sftp,否则连接不上 如果出现中文乱码的情况 先点击那个小齿轮 再点击选项 把编码编程UTF-8就ok了
- Maven | 把jar包安装到本地仓库
使用的场景 自己写的工具类想安装到本地 从Maven仓库中下载不下来的jar 使用的步骤 首先要保证自己的Maven配置全局环境变量,如果没有配置过maven全局变量,可以按照下面的步骤配置一下: 先 ...
- [zebra源码]分片语句ShardPreparedStatement执行过程
主要过程包括: 分库分表的路由定位 sql语句的 ast 抽象语法树的解析 通过自定义 SQLASTVisitor (MySQLSelectASTVisitor) 遍历sql ast,解析出逻辑表名 ...
- CDN相关知识及CDN绕过
#什么是CDN? 内容分发网络(Content Delivery Network,简称CDN)是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络.CDN应用广泛,支持多种行业 ...
- 洛谷 P4008 [NOI2003]文本编辑器
先推广一下 求赞 我们考虑这样的一个问题 给你一个序列,要求你支持插入,删除,查询单点值 如果用数组,查询O(1),插入删除最坏O(n) 如果用链表,插入删除O(1),查询最坏O(n) 如果用平衡树- ...
- NFS共享存储服务
NFS共享存储服务 一.NFS共享 1)NFS(Network File System)网络文件系统 ...
- CTF-wtc_rsa_bbq-writeup
wtc_rsa_bbq 题目信息: 附件: cry200 解题思路: 1.观察cry200文件,发现该文件是一个二进制文件,用二进制模式查看,发现开头为50 4B 03 04,判断该文件是一个zip文 ...
- C语言:交换两个变量的值
#include <stdio.h> int main() { int a,b; //方法一:借助第三个变量 int t; a=1,b=2; t=a; a=b; b=t; printf(& ...
- 案例分享:Qt+Arm基于RV1126平台的内窥镜软硬整套解决方案(实时影像、冻结、拍照、录像、背光调整、硬件光源调整,其他产品也可使用该平台,如视频监控,物联网产品等等)
自研产品系列方案 1. 基于瑞芯微的 RV1126 芯片平台: 2. 外接 USB 摄像头(OV9734. OV6946.OV2740 等 UVC 模块)作为图像输入源: 3. 可通过 LED ...
- 【论文阅读】End to End Learning for Self-Driving Cars
前言引用 [1] End to End Learning for Self-Driving Cars从这里开始 [1.1] 这个是相关的博客:2016:DRL前沿之:End to End Learni ...