当前位置: 首页 > news >正文

云南 网站建设/互联网营销顾问是做什么的

云南 网站建设,互联网营销顾问是做什么的,网站制作联盟,深圳建设网站首页待到秋来九月八,我花开后百花杀背景:大胆尝试实践:学习踩坑最终解决背景: 那是年初在某个交付项目,从用户侧获知了一个elastic search作为分布式数据库的一个瓶颈,那就是单次查询量超过了ES的默认单次查询…

待到秋来九月八,我花开后百花杀

  • 背景:
  • 大胆尝试实践:
  • 学习
  • 踩坑
  • 最终解决

背景:

那是年初在某个交付项目,从用户侧获知了一个elastic search作为分布式数据库的一个瓶颈,那就是单次查询量超过了ES的默认单次查询上限10000。

在大部分业务下,为了执行ES的数据查询,开发者往往都直接使用了query某个条件获取数据,这些条件对应的数据大多都不会超过10000,因此在一般测试下难以发现这类问题。但系统经过经年累月的使用,数据量在不断增长,又因业务需求不可清除旧数据的情况下,这类问题就诞生了。
在这里插入图片描述

于是,我想到Elasticsearch 中,传统的分页查询使用from+size的模式,类似如下语句:

GET /<index>/_search
{"from": 0,"size": 10,"query": {"match_all": {}}
}

那我们可以大可尝试使用while的方式,每次在拼接query时改变from的值为from+size,那么我每次拿到的就是下一个分页,如此往复,那也可以实现无穷尽也。

大胆尝试实践:

public void search() {int from = 0;long total = 0;int size = 100;while (true) {NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder().withPageable(PageRequest.of(from, size)).withSort(new FieldSortBuilder("id").order(SortOrder.DESC)).build();SearchHits<Book> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, Book.class);if (!searchHits.hasSearchHits()) {break;}for (SearchHit<Book> searchHit : searchHits.getSearchHits()) {Book book = searchHit.getContent();}page++;System.out.println(page);System.out.println(total += searchHits.getSearchHits().size());}
}

实现完成,点击运行。

Yes!我失败了。

于是,我意识到我并没有认真看关于报错的信息,在我自我批评和自我反省下,再次对报错信息认真解读
在这里插入图片描述
强大的Elasticsearch已经告诉了我答案,建议我扩大index.max_result_window的上限参数,或者参阅scroll api的文档。

学习

至此,开启了我对Elasticsearch Search Scroll API(滚动查询)的学习和探索!

在浅显的入门Scroll API之后,相比之下,自己之前的想法就像是关公面前耍了一次大刀——小聪明了,总结我自己的想法,那就是当程序运行到极限时,我的代码就好似拼装了以下的一个查询语句,尝试在可视化插件中执行该语句,发现依然会报错,报错与单次查询10000条并无差别。

GET /<index>/_search
{"from": 9980,"size": 10010,"query": {"match_all": {}}
}
{"type": "illegal_argument_exception","reason": "Result window is too large, from + size must be less than or equal to: [10000] but was [19990]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level setting."
}

对于此类问题,Elasticsearch Search为我们提供了一个与springBoot集成的强大依赖ElasticsearchRestTemplate,可以参考官方的 API 文档:
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.9/java-rest-high-search-scroll.html

尝试使用解决问题:

public void scrollSearch() {NativeSearchQuery query = new NativeSearchQueryBuilder().withSort(new FieldSortBuilder("id").order(SortOrder.DESC))//排序.build();nativeSearchQuery.setMaxResults(1000);long scrollTimeOut = 60 * 1000;// 第一次查询SearchScrollHits<Book> searchScrollHits = elasticsearchRestTemplate.searchScrollStart(scrollTimeOut, query, Book.class, IndexCoordinates.of("ss.index.book"));while (searchScrollHits.hasSearchHits()) {System.out.println(total += searchScrollHits.getSearchHits().size());for (SearchHit<Book> searchHit : searchScrollHits.getSearchHits()) {Book book = searchHit.getContent();}// 再次查询searchScrollHits = elasticsearchRestTemplate.searchScrollContinue(searchScrollHits.getScrollId(), scrollTimeInMillis, Book.class, IndexCoordinates.of("book"));}
}

最后,感谢大家的聆听和阅读,我拿到了我期望的10000条以后的数据,

我以为我这次终于成功了,但我的麻烦才刚刚开始。

踩坑

该问题上线之后不久,一切都运行顺利,我以为已经高枕无忧的时候,我的麻烦再次来临。

用户侧反应了两个问题:

一、查询得时候发现有返回重复的数据。

二、从ES获取后上传数据发生了数据堆积。

查看日志,发现有大量的报错,报错信息表示存放的 scroll_id 超出了默认的500限制。

在这里插入图片描述

trying to creat too many scroll aontexts。Must be less than or equal to: [500].This limit can be set by changing the [search.max_open_scroll_context] setting.

因此我对问题做出以下分析

1、虽然进行 scroll 查询时会记录一个 scroll_id,但只有新请求时才会生成新的 scroll_id,这就有一定概率导致查询到的返回结果出现重复数据的可能。

2、scroll 开启时间过长,导致 scroll_id 的清除时间太久产生堆积,所以引起了数据查询延迟,引起了数据堆积。

这次由于我认真读取了报错信息,但我不愿以牺牲上限为代价,不然那将是无底洞式的调大上限,于是我在原先代码基础上做出了修改:

    public void scrollSearch() {NativeSearchQuery query = new NativeSearchQueryBuilder().withSort(new FieldSortBuilder("id").order(SortOrder.DESC))//排序.build();nativeSearchQuery.setMaxResults(1000);long scrollTimeOut = 60 * 1000;// 第一次查询SearchScrollHits<Book> searchScrollHits = elasticsearchRestTemplate.searchScrollStart(scrollTimeOut, query, Book.class, IndexCoordinates.of("ss.index.book"));//记录新请求SearchScrollHits<Book> newHits;while (searchScrollHits.hasSearchHits()) {System.out.println(total += searchScrollHits.getSearchHits().size());for (SearchHit<Book> searchHit : searchScrollHits.getSearchHits()) {Book book = searchHit.getContent();}// 再次查询try {newHits = elasticsearchRestTemplate.searchScrollContinue(searchScrollHits.getScrollId(), scrollTimeInMillis, Book.class, IndexCoordinates.of("book"));searchScrollHits = newHits;} finally {elasticsearchRestTemplate.searchScrollClear(Lists.newArrayList(searchScrollHits.getScrollId()));}}}

这样,我每次发出查询请求获得数据之后,都会清除掉上一次生成的scroll_id,如此保证scroll_id不会超出500;

不出意外的,我又出意外了,显然我在对scroll_id理解上出了问题,它不是对每页的标记,而是每一次滚动查询整个生命周期的唯一id,上述代码导致的结果就是我永远只能拿到前两页的内容,之后因为找不到生命周期的唯一id报错。
在这里插入图片描述

最终解决

那么最终导致scroll_id堆积的原因也找到了:searchScrollStart入参从来都不是什么TimeOut时间,而是scroll_id存在的生命周期时间,如果这个时间过大,那么scroll_id就得不到及时清理,最终超过500进而报错,解决方案就会有两种:

1.根据实际每次请求的调用需求时间,调整scroll_id的生命周期,保持在一个合适的时间,从而防止堆积

2.动态清理scroll_id

显然第一种是在难为我胖虎,我选择了第二种,将searchScrollStart视为一次滚动查询请求的开始,searchScrollHits.hasSearchHits()为false时视为结束,此时searchScrollClear在合适不过。

第三次修改:

public void scrollSearch() {NativeSearchQuery query = new NativeSearchQueryBuilder().withSort(new FieldSortBuilder("id").order(SortOrder.DESC)).build();// 设置每页数据量nativeSearchQuery.setMaxResults(1000);long scrollTimeInMillis = 60 * 1000;// 第一次查询SearchScrollHits<Book> searchScrollHits = elasticsearchRestTemplate.searchScrollStart(scrollTimeInMillis, nativeSearchQuery, Book.class, IndexCoordinates.of("book"));String scrollId = searchScrollHits.getScrollId();while (searchScrollHits.hasSearchHits()) {System.out.println(total += searchScrollHits.getSearchHits().size());for (SearchHit<Book> searchHit : searchScrollHits.getSearchHits()) {Book book = searchHit.getContent();}// 再次查询searchScrollHits = elasticsearchRestTemplate.searchScrollContinue(scrollId, scrollTimeInMillis, Book.class, IndexCoordinates.of("book"));scrollId = searchScrollHits.getScrollId();}List<String> scrollIds = new ArrayList<>();scrollIds.add(scrollId);// 清除 scrollelasticsearchRestTemplate.searchScrollClear(scrollIds);
}

至此,才是真正的谢谢大家的阅读啦~~~good bye!

http://www.jmfq.cn/news/5127049.html

相关文章:

  • web前端开发难不难学/seo优化包括
  • 做网站怎么找优质客户/广东疫情最新资讯
  • 有做足球裁判跑动数据的网站吗/推广技术
  • 怎么找网站做公示/无锡seo公司找哪家好
  • 网站建设推广新闻/网站推广费用
  • 知名企业网站/网站维护推广的方案
  • 国外优秀门户网站/培训学校加盟
  • 高校邦营销型网站建设答案/百度指数网页版
  • 福田区建设局网站/网店代运营的套路
  • 河南企业网站推广/整站关键词排名优化
  • wordpress适合做什么网站/友情链接的网站有哪些
  • 图片制作在线网页/seo推广优化平台
  • 哪个网站可以做ppt/湖南省人民政府
  • 社区平安建设基层网站/市场营销师报名官网
  • 个人网站系统/seo费用
  • 免费在线建站/山东今日头条新闻
  • 河南建设监理协会网站6/微信营销模式
  • 重庆seo网站建设优化/设计师培训班多少钱
  • 天津公司网站开发/活动宣传推广方案怎么写
  • 怎样做农村电商网站/茶叶网络推广方案
  • 祥网站建设/百度seo优化关键词
  • 上海提供虚拟注册地址的园区/广州seo关键词优化费用
  • 合肥网站建设sina/西安专业网络推广公司
  • 绵阳最有实力的公司网站建设/今天最新的新闻
  • 北京网站建设设计/seo编辑招聘
  • 上海的招聘网站有哪些/线上营销推广公司
  • 通化网站开发/色盲怎么治疗
  • iis 网站后台/最成功的网络营销案例
  • 建站模板哪里好/山东进一步优化
  • 专业免费网站建设/成都网站seo技术