游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

京东面试题ElasticSearch深度分页解决方案

  前言
  Elasticsearch是一个实时的分布式搜索与分析引擎,在使用过程中,有一些典型的使用场景,比如分页、遍历等。
  在使用关系型数据库中,我们被告知要注意甚至被明确禁止使用深度分页,同理,在Elasticsearch中,也应该尽量避免使用深度分页。
  这篇文章主要介绍Elasticsearch中分页相关内容!FromSize参数
  在ES中,分页查询默认返回最顶端的10条匹配hits。
  如果需要分页,需要使用from和size参数。from参数定义了需要跳过的hits数,默认为0;size参数定义了需要返回的hits数目的最大值。
  一个基本的ES查询语句是这样的:POSTmyindexmytypesearch{query:{matchall:{}},from:100,size:10}
  上面的查询表示从搜索结果中取第100条开始的10条数据。
  那么,这个查询语句在ES集群内部是怎么执行的呢?
  在ES中,搜索一般包括两个阶段,query和fetch阶段,可以简单的理解,query阶段确定要取哪些doc,fetch阶段取出具体的doc。Query阶段
  如上图所示,描述了一次搜索请求的query阶段:Client发送一次搜索请求,node1接收到请求,然后,node1创建一个大小为fromsize的优先级队列用来存结果,我们管node1叫coordinatingnode。coordinatingnode将请求广播到涉及到的shards,每个shard在内部执行搜索请求,然后,将结果存到内部的大小同样为fromsize的优先级队列里,可以把优先级队列理解为一个包含topN结果的列表。每个shard把暂存在自身优先级队列里的数据返回给coordinatingnode,coordinatingnode拿到各个shards返回的结果后对结果进行一次合并,产生一个全局的优先级队列,存到自身的优先级队列里。
  在上面的例子中,coordinatingnode拿到(fromsize)6条数据,然后合并并排序后选择前面的fromsize条数据存到优先级队列,以便fetch阶段使用。
  另外,各个分片返回给coordinatingnode的数据用于选出前fromsize条数据,所以,只需要返回唯一标记doc的id以及用于排序的score即可,这样也可以保证返回的数据量足够小。
  coordinatingnode计算好自己的优先级队列后,query阶段结束,进入fetch阶段。Fetch阶段
  query阶段知道了要取哪些数据,但是并没有取具体的数据,这就是fetch阶段要做的。
  上图展示了fetch过程:coordinatingnode发送GET请求到相关shards。shard根据doc的id取到数据详情,然后返回给coordinatingnode。coordinatingnode返回数据给Client。
  coordinatingnode的优先级队列里有fromsize个docid,但是,在fetch阶段,并不需要取回所有数据,在上面的例子中,前100条数据是不需要取的,只需要取优先级队列里的第101到110条数据即可。
  需要取的数据可能在不同分片,也可能在同一分片,coordinatingnode使用multiget来避免多次去同一分片取数据,从而提高性能。
  这种方式请求深度分页是有问题的:
  我们可以假设在一个有5个主分片的索引中搜索。当我们请求结果的第一页(结果从1到10),每一个分片产生前10的结果,并且返回给协调节点,协调节点对50个结果排序得到全部结果的前10个。
  现在假设我们请求第1000页结果从10001到10010。所有都以相同的方式工作除了每个分片不得不产生前10010个结果以外。然后协调节点对全部50050个结果排序最后丢弃掉这些结果中的50040个结果。
  对结果排序的成本随分页的深度成指数上升。
  注意1:
  size的大小不能超过index。maxresultwindow这个参数的设置,默认为10000。
  如果搜索size大于10000,需要设置index。maxresultwindow参数PUTsettings{index:{maxresultwindow:10000000}}
  注意2:
  doc将在未来的版本移除,详见:https:www。elastic。cocnblogmovingfromtypestotypelessapisinelasticsearch70https:elasticsearch。cnarticle158
  深度分页问题
  Elasticsearch的FromSize方式提供了分页的功能,同时,也有相应的限制。
  举个例子,一个索引,有10亿数据,分10个shards,然后,一个搜索请求,from1000000,size100,这时候,会带来严重的性能问题:CPU,内存,IO,网络带宽。
  在query阶段,每个shards需要返回1000100条数据给coordinatingnode,而coordinatingnode需要接收101000,100条数据,即使每条数据只有docid和score,这数据量也很大了?
  在另一方面,我们意识到,这种深度分页的请求并不合理,因为我们是很少人为的看很后面的请求的,在很多的业务场景中,都直接限制分页,比如只能看前100页。
  比如,有1千万粉丝的微信大V,要给所有粉丝群发消息,或者给某省粉丝群发,这时候就需要取得所有符合条件的粉丝,而最容易想到的就是利用fromsize来实现,不过,这个是不现实的,这时,可以采用Elasticsearch提供的其他方式来实现遍历。
  深度分页问题大致可以分为两类:随机深度分页:随机跳转页面滚动深度分页:只能一页一页往下查询
  下面介绍几个官方提供的深度分页方法ScrollScroll遍历数据
  我们可以把scroll理解为关系型数据库里的cursor,因此,scroll并不适合用来做实时搜索,而更适合用于后台批处理任务,比如群发。
  这个分页的用法,不是为了实时查询数据,而是为了一次性查询大量的数据(甚至是全部的数据)。
  因为这个scroll相当于维护了一份当前索引段的快照信息,这个快照信息是你执行这个scroll查询时的快照。在这个查询后的任何新索引进来的数据,都不会在这个快照中查询到。
  但是它相对于from和size,不是查询所有数据然后剔除不要的部分,而是记录一个读取的位置,保证下一次快速继续读取。
  不考虑排序的时候,可以结合SearchType。SCAN使用。
  scroll可以分为初始化和遍历两部,初始化时将所有符合搜索条件的搜索结果缓存起来(注意,这里只是缓存的docid,而并不是真的缓存了所有的文档数据,取数据是在fetch阶段完成的),可以想象成快照。
  在遍历时,从这个快照里取数据,也就是说,在初始化后,对索引插入、删除、更新数据都不会影响遍历结果。
  基本使用POSTtwittertweetsearch?scroll1m{size:100,query:{match:{title:elasticsearch}}}
  初始化指明index和type,然后,加上参数scroll,表示暂存搜索结果的时间,其它就像一个普通的search请求一样。
  会返回一个scrollid,scrollid用来下次取数据用。
  遍历POSTsearch?scroll1m{scrollid:XXXXXXXXXXXXXXXXXXXXXXXIamscrollidXXXXXXXXXXXXXXX}
  这里的scrollid即上一次遍历取回的scrollid或者是初始化返回的scrollid,同样的,需要带scroll参数。
  重复这一步骤,直到返回的数据为空,即遍历完成。
  注意,每次都要传参数scroll,刷新搜索结果的缓存时间。另外,不需要指定index和type。
  设置scroll的时候,需要使搜索结果缓存到下一次遍历完成,同时,也不能太长,毕竟空间有限。
  优缺点
  缺点:scrollid会占用大量的资源(特别是排序的请求)同样的,scroll后接超时时间,频繁的发起scroll请求,会出现一些列问题。是生成的历史快照,对于数据的变更不会反映到快照上。
  优点:
  适用于非实时处理大量数据的情况,比如要进行数据迁移或者索引变更之类的。ScrollScan
  ES提供了scrollscan方式进一步提高遍历性能,但是scrollscan不支持排序,因此scrollscan适合不需要排序的场景
  基本使用
  ScrollScan的遍历与普通Scroll一样,初始化存在一点差别。POSTmyindexmytypesearch?searchtypescanscroll1msize50{query:{matchall:{}}}
  需要指明参数:searchtype:赋值为scan,表示采用ScrollScan的方式遍历,同时告诉Elasticsearch搜索结果不需要排序。scroll:同上,传时间。size:与普通的size不同,这个size表示的是每个shard返回的size数,最终结果最大为numberofshardssize。
  ScrollScan与Scroll的区别ScrollScan结果没有排序,按index顺序返回,没有排序,可以提高取数据性能。初始化时只返回scrollid,没有具体的hits结果size控制的是每个分片的返回的数据量,而不是整个请求返回的数据量。SlicedScroll
  如果你数据量很大,用Scroll遍历数据那确实是接受不了,现在Scroll接口可以并发来进行数据遍历了。
  每个Scroll请求,可以分成多个Slice请求,可以理解为切片,各Slice独立并行,比用Scroll遍历要快很多倍。POSTindextypesearch?scroll1m{query:{matchall:{}},slice:{id:0,max:5}}POSTip:portindextypesearch?scroll1m{query:{matchall:{}},slice:{id:1,max:5}}
  上边的示例可以单独请求两块数据,最终五块数据合并的结果与直接scrollscan相同。
  其中max是分块数,id是第几块。官方文档中建议max的值不要超过shard的数量,否则可能会导致内存爆炸。
  SearchAfter
  Searchafter是ES5新引入的一种分页查询机制,其原理几乎就是和scroll一样,因此代码也几乎是一样的。
  基本使用:
  第一步:POSTtwittersearch{size:10,query:{match:{title:es}},sort:〔{date:asc},{id:desc}〕}
  返回出的结果信息:{took:29,timedout:false,shards:{total:1,successful:1,skipped:0,failed:0},hits:{total:{value:5,relation:eq},maxscore:null,hits:〔{。。。},sort:〔。。。〕},{。。。},sort:〔124648691,624812〕}〕}}
  上面的请求会为每一个文档返回一个包含sort排序值的数组。
  这些sort排序值可以被用于searchafter参数里以便抓取下一页的数据。
  比如,我们可以使用最后的一个文档的sort排序值,将它传递给searchafter参数:GETtwittersearch{size:10,query:{match:{title:es}},searchafter:〔124648691,624812〕,sort:〔{date:asc},{id:desc}〕}
  若我们想接着上次读取的结果进行读取下一页数据,第二次查询在第一次查询时的语句基础上添加searchafter,并指明从哪个数据后开始读取。
  基本原理
  es维护一个实时游标,它以上一次查询的最后一条记录为游标,方便对下一页的查询,它是一个无状态的查询,因此每次查询的都是最新的数据。
  由于它采用记录作为游标,因此SearchAfter要求doc中至少有一条全局唯一变量(每个文档具有一个唯一值的字段应该用作排序规范)
  优缺点
  优点:无状态查询,可以防止在查询过程中,数据的变更无法及时反映到查询中。不需要维护scrollid,不需要维护快照,因此可以避免消耗大量的资源。
  缺点:由于无状态查询,因此在查询期间的变更可能会导致跨页面的不一值。排序顺序可能会在执行期间发生变化,具体取决于索引的更新和删除。至少需要制定一个唯一的不重复字段来排序。它不适用于大幅度跳页查询,或者全量导出,对第N页的跳转查询相当于对es不断重复的执行N次searchafter,而全量导出则是在短时间内执行大量的重复查询。
  SEARCHAFTER不是自由跳转到任意页面的解决方案,而是并行滚动多个查询的解决方案。总结
  分页方式性能优点缺点场景fromsize低灵活性好,实现简单深度分页问题数据量比较小,能容忍深度分页问题scroll中解决了深度分页问题无法反应数据的实时性(快照版本)维护成本高,需要维护一个scrollid海量数据的导出需要查询海量结果集的数据searchafter高性能最好不存在深度分页问题能够反映数据的实时变更实现复杂,需要有一个全局唯一的字段连续分页的实现会比较复杂,因为每一次查询都需要上次查询的结果,它不适用于大幅度跳页查询海量数据的分页ES7版本变更
  参照:https:www。elastic。coguideenelasticsearchreferencemasterpaginatesearchresults。htmlscrollsearchresults
  在7。版本中,ES官方不再推荐使用Scroll方法来进行深分页,而是推荐使用带PIT的searchafter来进行查询;
  从7。版本开始,您可以使用SEARCHAFTER参数通过上一页中的一组排序值检索下一页命中。
  使用SEARCHAFTER需要多个具有相同查询和排序值的搜索请求。
  如果这些请求之间发生刷新,则结果的顺序可能会更改,从而导致页面之间的结果不一致。
  为防止出现这种情况,您可以创建一个时间点(PIT)来在搜索过程中保留当前索引状态。POSTmyindex000001pit?keepalive1m返回一个PITID:{id:46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGwgAAAAA}
  在搜索请求中指定PIT:GETsearch{size:10000,query:{match:{user。id:elkbee}},pit:{id:46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGwgAAAAA,keepalive:1m},sort:〔{timestamp:{order:asc,format:strictdateoptionaltimenanos,numerictype:datenanos}}〕}性能对比
  分别分页获取110,4900049010,9900099010范围各10条数据(前提10w条),性能大致是这样:
  向前翻页
  对于向前翻页,ES中没有相应API,但是根据官方说法(https:github。comelasticelasticsearchissues29449),ES中的向前翻页问题可以通过翻转排序方式来实现即:对于某一页,正序searchafter该页的最后一条数据id为下一页,则逆序searchafter该页的第一条数据id则为上一页。国内论坛上,有人使用缓存来解决上一页的问题:https:elasticsearch。cnquestion7711
  总结如果数据量小(fromsize在10000条内),或者只关注结果集的TopN数据,可以使用fromsize分页,简单粗暴数据量大,深度翻页,后台批处理任务(数据迁移)之类的任务,使用scroll方式数据量大,深度翻页,用户实时、高并发查询需求,使用searchafter方式个人思考
  Scroll和searchafter原理基本相同,他们都采用了游标的方式来进行深分页。
  这种方式虽然能够一定程度上解决深分页问题。但是,它们并不是深分页问题的终极解决方案,深分页问题必须避免!!。
  对于Scroll,无可避免的要维护scrollid和历史快照,并且,还必须保证scrollid的存活时间,这对服务器是一个巨大的负荷。
  对于SearchAfter,如果允许用户大幅度跳转页面,会导致短时间内频繁的搜索动作,这样的效率非常低下,这也会增加服务器的负荷,同时,在查询过程中,索引的增删改会导致查询数据不一致或者排序变化,造成结果不准确。
  SearchAfter本身就是一种业务折中方案,它不允许指定跳转到页面,而只提供下一页的功能。
  Scroll默认你会在后续将所有符合条件的数据都取出来,所以,它只是搜索到了所有的符合条件的docid(这也是为什么官方推荐用docid进行排序,因为本身缓存的就是docid,如果用其他字段排序会增加查询量),并将它们排序后保存在协调节点(coordinatenode),但是并没有将所有数据进行fetch,而是每次scroll,读取size个文档,并返回此次读取的最后一个文档以及上下文状态,用以告知下一次需要从哪个shard的哪个文档之后开始读取。
  这也是为什么官方不推荐scroll用来给用户进行实时的分页查询,而是适合于大批量的拉取数据,因为它从设计上就不是为了实时读取数据而设计的。
  来源:https:mp。weixin。qq。comsp5nLhvJq2Myd1G9cvNKlWA

包白菜肉馅水饺,牢记3要2不要,肉馅多汁不腥不发柴包白菜肉馅水饺,牢记3要2不要,肉馅多汁不腥不发柴。亲爱的好朋友们,大家好我是大厨江一舟,今天又到了,给大家分享美食的时刻了,你们准备好了吗?咱们很多朋友在家包白菜肉馅水……用一道什么菜能证明你已经老了?七零后的我虽然算不上老人,但我已经在改革的大潮中步入中年,有时也会怀念过去生活的点点滴滴。记忆中的我当时虽然能勉强填饱肚子,但我们吃的主食也就是地瓜面(红暑面粉)煎饼和玉豆面(……为什么街边的咖啡店看起来人不多,却不倒闭啊?第一种:咖啡和甜点单价高,单客利润较高,人少但能维持住;第二种:店内人不多,但外卖单多,也能撑住;第三种:确实挣不到钱,但资金还没花完,好不容易开个自己梦想中的小资……本市体育企业,京彩体育贷融资服务方案发布北京日报客户端记者潘福达北京银行与北京市体育局近日联合举行战略合作协议签约暨京彩体育贷融资服务方案发布仪式。活动现场,双方联合发布了京彩体育贷融资服务方案。根据北京……87065W闪充优秀散热,realme真我GTNeo2真无短在2021年年中推出时,realme真我GTNeo2就以其优秀的质价比成为了热门选择,相信它曾给不少网友留下了深刻印象。而来到2022年,这款综合配置优秀的机型更是进入了大促优……中国女排扛把子李盈莹,能否抗起这面大旗重回巅峰随着朱婷做手术,张常宁做手术,颜妮退役,丁霞老去,这支辉煌的女排慢慢褪去光环!但是球迷对于这支有着传统优良作风的女排没有放弃,一直寄予希望!李盈莹现如今是这支女排的……2023年CES看点前瞻电动汽车站C位,元宇宙黑科技抢热度记者程璐编辑北京时间1月5日,2023年度国际消费电子展(CES)在美国拉斯维加斯正式拉开帷幕。全球陆续走出新冠疫情的阴霾后,CES也终于回归线下,预计参展人数将达……面馆汤底怎么熬?这问题问的,一个兑字,怎么看起来都像有弦外之音的感觉!不过这也确实是个让人纠结的问题,面馆的汤底究竟是不是兑出来的呢?先说比较常见的骨汤面的汤底吧,正经的骨汤面汤底……查出甲状腺结节,常吃洋葱,到底是好是坏呢?如今生活中,生活节奏相对较快,人们也处于亚健康的状态,所以像一些疾病的发病率是越来越高,就比如说甲状腺结节现在也是处于年轻化高发的趋势,严重影响人们的健康生活。甲状腺位于……东契奇防守糟糕想念布伦森,欧文是宫斗结果,独行侠艰难二选一如今的独行侠,已经到了进退两难的境地,虽然只落后雷霆0。5个胜场,但是由于下赛季前10顺位保护签在波尔津吉斯的交易中给了尼克斯,独行侠面对近在咫尺的季后赛附加赛和前10顺位首轮……死面大饼加什么原料凉了不硬?饼是面食中非常古老的一大类,在最早的时候面条都甚至被叫做汤饼、索饼,可见饼这类食物在美食界的世界中资格有多老。在众多的饼类做法当中,死面饼算是最简单最家常的一种,毕竟连发……在中国白酒几大香型中,哪一款香型消费者最容易接受?这个还真不好说。白酒香型大家都知道,像芝麻香和米香型受众太小,就不说了。那些想自立门户的新香型如陶香、邢想或者馥郁香等等更是没几个人知道。所以,就重点说一下目前最被大家接……
迪哥闯世界真的凉了吗?迪哥闯世界是谁?迪哥闯世界,真名陈迪兵迪哥闯世界,出生于湖北十堰市,现居四川省绵阳市郊区,现35岁,出生于8月13日,2018年2月1日在西瓜视频发布了第一个……十大宇宙真相在太空中裸露肌肤会怎样呢?1、冥王星上的冰比钢铁还要坚硬冥王星,因为距离太阳最远,所以也是太阳系里最冷的天体。最低温度可降到华氏390度。毋庸置疑,冥王星的表面全是冰,但是它跟地球上的冰还是有一点……吉林一酒席真豪横炒菜用铁锹,凉菜用手抓,喝酒用大碗,羡慕吗吉林一酒席真豪横:炒菜用铁锹,凉菜用手抓,喝酒用大碗,羡慕吗你见过最豪横的酒席是什么样子吗?有人说:那些有钱人置办的酒席很豪横,究其原因,每一桌都在数千乃至上万块钱,酒席……曝霍建华离婚净身出户!欲回内娱搭档刘亦菲,林心如要十亿抚养费霍建华和林心如结婚后,每年都会曝一次离婚。这一次的离婚消息,来得尤其凶猛,连知名娱记葛斯齐都说俩人已离婚,各路人士更是扒出各种离婚细节。葛思齐还放话,不信可以去调查……关于中国跨境电商政策对企业创新影响的结论首先,让我们先来了解关于中国跨境电商政策环境的结论。一是中国跨境电商政策体系已经初步建立。法律、部门规章、实施细则、地方法规等与跨境电商相关的政策法规类型比较完整。其中,《电子……夏天多吃这馅饺子,清淡清香营养高,一顿能吃30个,比肉馅还香夏天多吃这馅饺子,清淡清香营养高,一顿能吃30个,比肉馅还香肉馅和素馅饺子,大家更喜欢哪一种?在很多人看来,肉馅饺子才更美味更鲜嫩,但其实也有不少人,对素馅饺子情有独钟,……中国哪里的酸菜最好吃?吃过东北的白菜泡的酸菜无辣椒,相比之下,还是我居云南的好吃,腌制的是用苦菜放的佐料也多。出名的品牌有大理弥渡的小河淌水。弥渡的最好吃,玉溪市新平的也不错,富源白水的也可以。(第……上半年光伏装机超去年前十月,光伏协会开始研究组件回收红星资本局7月21日消息,由中国光伏行业协会主办的光伏行业2022年上半年发展回顾与下半年形势展望研讨会召开。中国光伏行业协会名誉理事长王勃华表示,今年上半年,国内光伏发……皮蛋搭配尖椒,味道奇特,又辣又香,百吃不厌平时大家在家里或是下饭店,都会经常吃上凉拌皮蛋。但是今天我为大家分享的是皮蛋的另一做法,那就是尖椒炒皮蛋。这道菜做法也非常的简单,适合在家里制作。在选材方面首先选用尖椒,……冰淇淋市场打破场景壁垒再度开战夏季到来,一年一度的雪糕大战再度打响。今年五一期间,五花八门、造型奇特的文创冰淇淋成为全国多家景点的旅游打卡项目,文创雪糕开始在社交媒体上刷屏。花样翻新的同时,不少消费者也发现……四川麻辣名菜水煮牛肉不简单,如何做出最嫩的水煮牛肉?多汁的牛肉和香脆的蔬菜加上大量的香料,四川水煮牛肉超级美味,让人上瘾。四川水煮牛肉是什么味道多汁的牛肉片和酥脆的蔬菜用大量的干辣椒、花椒、豆瓣酱、姜、大蒜等调味。热……乒乓球突尼斯赛八强诞生!国乒双打连赢六场,四位世界冠军出局2022年8月3日,乒乓球WTT突尼斯挑战赛继续进行,两项双打率先产生八强席位,国乒六对组合全胜,男双头号种子法尔克卡尔松,女双头号种子石川佳纯平野美宇,四位世界冠军首轮出局,……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网