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

网站流量利用企业官方网站格式

网站流量利用,企业官方网站格式,百度一下网页打开,做网站需要云数据库吗文章目录 概要ElasticSearch介绍es分页方法es分页性能对比表方案对比 From/Size参数深度分页问题Scroll#性能对比向前翻页 总结个人思考 概要 好久没更新文章了#xff0c;最近研究了一下es的深分页解决方案。和大家分享一下#xff0c;祝大家国庆节快乐。 ElasticSearch介… 文章目录 概要ElasticSearch介绍es分页方法es分页性能对比表方案对比 From/Size参数深度分页问题Scroll#性能对比向前翻页 总结个人思考 概要 好久没更新文章了最近研究了一下es的深分页解决方案。和大家分享一下祝大家国庆节快乐。 ElasticSearch介绍 Elasticsearch 是一个分布式、可扩展、实时的搜索与数据分析引擎在使用过程中有一些典型的使用场景比如分页、遍历等。 在使用关系型数据库中我们被告知要注意甚至被明确禁止使用深度分页同理在 Elasticsearch 中也应该尽量避免使用深度分页。 这篇文章主要介绍 Elasticsearch 中分页相关内容 es分页方法 From/Size参数ScrollScroll ScanSliced ScrollSearch After es分页性能对比表 分页方式1~1049000~4901099000~999010from size8ms30ms117msScroll7ms66ms36msSearch After8ms8ms7ms 方案对比 方案原理优点缺点使用场景from size类似 msql的 limit 0,100; limit fromsize灵活性好实现简单适合浅分页无法实现深度分页问题当查询数量超过10000就会报错top10000以内的查询Scroll首次查询会在内存中保存一个历史快照以及游标scroll_id,记录当前消息查询的终止位置下次查询的时候将基于游标进行消费(不管while语句循环多少次scrollid在设置的时效内使用的是同一个)不具备实时性一般是用于大量数据导出。适合深分页无法反应数据的实时性(快照版本),维护成本高需要维护一个 scroll_id最适合离线场景海量数据的导出(比如笔者刚遇到的将es中20w的数据导入到excel),需要查询海量结果集的数据Search Afterstep1在查询第1页的时候设置全局唯一性的字段进行组合排序step2查询数据之后取出最后一笔数据的sort值传到search_after进行查询step3基于上一笔的sort值查询排在它之后的数据以此来实现分页不能够随机跳转分页只能是一页一页的向后翻当有新数据进来也能实时查询到并且需要至少指定一个唯一不重复字段来排序一般是_id和时间字段海量数据的实时分页性能最好,适合深分页,能够反映数据的实时变更 From/Size参数 在ES中分页查询默认返回最顶端的10条匹配hits。 如果需要分页需要使用from和size参数。 from参数定义了需要跳过的hits数默认为0 size参数定义了需要返回的hits数目的最大值。 一个基本的ES查询语句是这样的 POST /my_index/my_type/_search{query: { match_all: {}},from: 100,size: 10}上面的查询表示从搜索结果中取第100条开始的10条数据。 ** 那么这个查询语句在ES集群内部是怎么执行的呢** 在ES中搜索一般包括两个阶段query 和 fetch 阶段可以简单的理解query 阶段确定要取哪些docfetch 阶段取出具体的 doc。 Query阶段 图片 如上图所示描述了一次搜索请求的 query 阶段· Client 发送一次搜索请求node1 接收到请求然后node1 创建一个大小为from size的优先级队列用来存结果我们管 node1 叫 coordinating node。 coordinating node将请求广播到涉及到的 shards每个 shard 在内部执行搜索请求然后将结果存到内部的大小同样为from size 的优先级队列里可以把优先级队列理解为一个包含top N结果的列表。 每个 shard 把暂存在自身优先级队列里的数据返回给 coordinating nodecoordinating node 拿到各个 shards 返回的结果后对结果进行一次合并产生一个全局的优先级队列存到自身的优先级队列里。 在上面的例子中coordinating node 拿到(from size) * 6条数据然后合并并排序后选择前面的from size条数据存到优先级队列以便 fetch 阶段使用。 另外各个分片返回给 coordinating node 的数据用于选出前from size条数据所以只需要返回唯一标记 doc 的_id以及用于排序的_score即可这样也可以保证返回的数据量足够小。 coordinating node 计算好自己的优先级队列后query 阶段结束进入 fetch 阶段。 ❝ Fetch阶段 ❞ query 阶段知道了要取哪些数据但是并没有取具体的数据这就是 fetch 阶段要做的。 上图展示了 fetch 过程 coordinating node 发送 GET 请求到相关shards。 shard 根据 doc 的_id取到数据详情然后返回给 coordinating node。 coordinating node 返回数据给 Client。 coordinating node 的优先级队列里有from size 个_doc _id但是在 fetch 阶段并不需要取回所有数据在上面的例子中前100条数据是不需要取的只需要取优先级队列里的第101到110条数据即可。 需要取的数据可能在不同分片也可能在同一分片coordinating node 使用 「multi-get」 来避免多次去同一分片取数据从而提高性能。 「这种方式请求深度分页是有问题的」 我们可以假设在一个有 5 个主分片的索引中搜索。当我们请求结果的第一页结果从 1 到 10 每一个分片产生前 10 的结果并且返回给 协调节点 协调节点对 50 个结果排序得到全部结果的前 10 个。 现在假设我们请求第 1000 页—结果从 10001 到 10010 。所有都以相同的方式工作除了每个分片不得不产生前10010个结果以外。然后协调节点对全部 50050 个结果排序最后丢弃掉这些结果中的 50040 个结果。 「对结果排序的成本随分页的深度成指数上升。」 「注意1」 size的大小不能超过index.max_result_window这个参数的设置默认为10000。 如果搜索size大于10000需要设置index.max_result_window参数 PUT _settings {index: {max_result_window: 10000000} } [^1] _doc将在未来的版本移除详见 https://www.elastic.co/cn/blog/moving-from-types-to-typeless-apis-in-elasticsearch-7-0 https://elasticsearch.cn/article/158 深度分页问题 Elasticsearch 的From/Size方式提供了分页的功能同时也有相应的限制。 举个例子一个索引有10亿数据分10个 shards然后一个搜索请求from1000000size100这时候会带来严重的性能问题CPU内存IO网络带宽。 在 query 阶段每个shards需要返回 1000100 条数据给 coordinating node而 coordinating node 需要接收10 * 1000100 条数据即使每条数据只有 _doc _id 和 _score这数据量也很大了 「在另一方面我们意识到这种深度分页的请求并不合理因为我们是很少人为的看很后面的请求的在很多的业务场景中都直接限制分页比如只能看前100页。」 比如有1千万粉丝的微信大V要给所有粉丝群发消息或者给某省粉丝群发这时候就需要取得所有符合条件的粉丝而最容易想到的就是利用 from size 来实现不过这个是不现实的这时可以采用 Elasticsearch 提供的其他方式来实现遍历。 深度分页问题大致可以分为两类 「随机深度分页随机跳转页面」 「滚动深度分页只能一页一页往下查询」 「下面介绍几个官方提供的深度分页方法」 Scroll ❝ Scroll遍历数据 ❞ 我们可以把scroll理解为关系型数据库里的cursor因此scroll并不适合用来做实时搜索而更适合用于后台批处理任务比如群发。 这个分页的用法「不是为了实时查询数据」而是为了「一次性查询大量的数据甚至是全部的数据」。 因为这个scroll相当于维护了一份当前索引段的快照信息这个快照信息是你执行这个scroll查询时的快照。在这个查询后的任何新索引进来的数据都不会在这个快照中查询到。 但是它相对于from和size不是查询所有数据然后剔除不要的部分而是记录一个读取的位置保证下一次快速继续读取。 不考虑排序的时候可以结合SearchType.SCAN使用。 scroll可以分为初始化和遍历两部初始化时将「所有符合搜索条件的搜索结果缓存起来注意这里只是缓存的doc_id而并不是真的缓存了所有的文档数据取数据是在fetch阶段完成的」可以想象成快照。 在遍历时从这个快照里取数据也就是说在初始化后对索引插入、删除、更新数据都不会影响遍历结果。 「基本使用」 POST /twitter/tweet/_search?scroll1m {size: 100,query: {match : {title : elasticsearch}} }初始化指明 index 和 type然后加上参数 scroll表示暂存搜索结果的时间其它就像一个普通的search请求一样。 会返回一个_scroll_id_scroll_id用来下次取数据用。 「遍历」 POST /_search?scroll1m {scroll_id:XXXXXXXXXXXXXXXXXXXXXXX I am scroll id XXXXXXXXXXXXXXX }这里的scroll_id即 上一次遍历取回的_scroll_id或者是初始化返回的_scroll_id同样的需要带 scroll 参数。 重复这一步骤直到返回的数据为空即遍历完成。 「注意每次都要传参数 scroll刷新搜索结果的缓存时间」。另外「不需要指定 index 和 type」。 设置scroll的时候需要使搜索结果缓存到下一次遍历完成「同时也不能太长毕竟空间有限。」 「优缺点」 缺点 「scroll_id会占用大量的资源特别是排序的请求」 同样的scroll后接超时时间频繁的发起scroll请求会出现一些列问题。 「是生成的历史快照对于数据的变更不会反映到快照上。」 「优点」 适用于非实时处理大量数据的情况比如要进行数据迁移或者索引变更之类的。 Scroll Scan ES提供了scroll scan方式进一步提高遍历性能但是scroll scan不支持排序因此scroll scan适合不需要排序的场景 「基本使用」 Scroll Scan 的遍历与普通 Scroll 一样初始化存在一点差别。 POST /my_index/my_type/_search?search_typescanscroll1msize50 {query: { match_all: {}} }需要指明参数 search_type赋值为scan表示采用 Scroll Scan 的方式遍历同时告诉 Elasticsearch 搜索结果不需要排序。 scroll同上传时间。 size与普通的 size 不同这个 size 表示的是每个 shard 返回的 size 数最终结果最大为 number_of_shards * size。 「Scroll Scan与Scroll的区别」 Scroll-Scan结果「没有排序」按index顺序返回没有排序可以提高取数据性能。 初始化时只返回 _scroll_id没有具体的hits结果 size控制的是每个分片的返回的数据量而不是整个请求返回的数据量。 Sliced Scroll 如果你数据量很大用Scroll遍历数据那确实是接受不了现在Scroll接口可以并发来进行数据遍历了。 每个Scroll请求可以分成多个Slice请求可以理解为切片各Slice独立并行比用Scroll遍历要快很多倍。 POST /index/type/_search?scroll1m {query: { match_all: {}},slice: {id: 0,max: 5} }POST ip:port/index/type/_search?scroll1m {query: { match_all: {}},slice: {id: 1,max: 5} }上边的示例可以单独请求两块数据最终五块数据合并的结果与直接scroll scan相同。 其中max是分块数id是第几块。 ❝ 官方文档中建议max的值不要超过shard的数量否则可能会导致内存爆炸。 ❞ Search After Search_after是 ES 5 新引入的一种分页查询机制其原理几乎就是和scroll一样因此代码也几乎是一样的。 「基本使用」 第一步 POST twitter/_search {size: 10,query: {match : {title : es}},sort: [{date: asc},{_id: desc}] }返回出的结果信息 {took : 29,timed_out : false,_shards : {total : 1,successful : 1,skipped : 0,failed : 0},hits : {total : {value : 5,relation : eq},max_score : null,hits : [{...},sort : [...]},{...},sort : [124648691,624812]}]}}上面的请求会为每一个文档返回一个包含sort排序值的数组。 这些sort排序值可以被用于search_after参数里以便抓取下一页的数据。 比如我们可以使用最后的一个文档的sort排序值将它传递给search_after参数 GET twitter/_search {size: 10,query: {match : {title : es}},search_after: [124648691, 624812],sort: [{date: asc},{_id: desc}] }若我们想接着上次读取的结果进行读取下一页数据第二次查询在第一次查询时的语句基础上添加search_after并指明从哪个数据后开始读取。 「基本原理」 es维护一个实时游标它以上一次查询的最后一条记录为游标方便对下一页的查询它是一个无状态的查询因此每次查询的都是最新的数据。 由于它采用记录作为游标因此「SearchAfter要求doc中至少有一条全局唯一变量每个文档具有一个唯一值的字段应该用作排序规范」 「优缺点」 「优点」 无状态查询可以防止在查询过程中数据的变更无法及时反映到查询中。 不需要维护scroll_id不需要维护快照因此可以避免消耗大量的资源。 「缺点」 由于无状态查询因此在查询期间的变更可能会导致跨页面的不一值。 排序顺序可能会在执行期间发生变化具体取决于索引的更新和删除。 至少需要制定一个唯一的不重复字段来排序。 它不适用于大幅度跳页查询或者全量导出对第N页的跳转查询相当于对es不断重复的执行N次search after而全量导出则是在短时间内执行大量的重复查询。 SEARCH_AFTER不是自由跳转到任意页面的解决方案而是并行滚动多个查询的解决方案。 总结 分页方式 性能 优点 缺点 场景 from size 低 灵活性好实现简单 深度分页问题 数据量比较小能容忍深度分页问题 scroll 中 解决了深度分页问题 无法反应数据的实时性快照版本维护成本高需要维护一个 scroll_id 海量数据的导出需要查询海量结果集的数据 search_after 高 性能最好不存在深度分页问题能够反映数据的实时变更 实现复杂需要有一个全局唯一的字段连续分页的实现会比较复杂因为每一次查询都需要上次查询的结果它不适用于大幅度跳页查询 海量数据的分页 ES7版本变更 参照https://www.elastic.co/guide/en/elasticsearch/reference/master/paginate-search-results.html#scroll-search-results 在7.*版本中ES官方不再推荐使用Scroll方法来进行深分页而是推荐使用带PIT的search_after来进行查询 从7.*版本开始您可以使用SEARCH_AFTER参数通过上一页中的一组排序值检索下一页命中。 使用SEARCH_AFTER需要多个具有相同查询和排序值的搜索请求。 如果这些请求之间发生刷新则结果的顺序可能会更改从而导致页面之间的结果不一致。 为防止出现这种情况您可以创建一个时间点(PIT)来在搜索过程中保留当前索引状态。 POST /my-index-000001/_pit?keep_alive1m 返回一个PIT ID {id: 46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA }在搜索请求中指定PIT GET /_search {size: 10000,query: {match : {user.id : elkbee}},pit: {id: 46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA, keep_alive: 1m},sort: [ {timestamp: {order: asc, format: strict_date_optional_time_nanos, numeric_type : date_nanos }}] }#性能对比 分别分页获取1 - 1049000 - 4901099000 - 99010范围各10条数据前提10w条性能大致是这样 向前翻页 对于向前翻页ES中没有相应API但是根据官方说法https://github.com/elastic/elasticsearch/issues/29449ES中的向前翻页问题可以通过翻转排序方式来实现即 对于某一页正序search_after该页的最后一条数据id为下一页则逆序search_after该页的第一条数据id则为上一页。 国内论坛上有人使用缓存来解决上一页的问题 总结 如果数据量小fromsize在10000条内或者只关注结果集的TopN数据可以使用from/size 分页简单粗暴数据量大深度翻页后台批处理任务数据迁移之类的任务使用 scroll 方式数据量大深度翻页用户实时、高并发查询需求使用 search after 方式 个人思考 Scroll和search_after原理基本相同他们都采用了游标的方式来进行深分页。 这种方式虽然能够一定程度上解决深分页问题。但是它们并不是深分页问题的终极解决方案深分页问题 ** 必须避免! **。 对于Scroll无可避免的要维护scroll_id和历史快照并且还必须保证scroll_id的存活时间这对服务器是一个巨大的负荷。 对于Search_After如果允许用户大幅度跳转页面会导致短时间内频繁的搜索动作这样的效率非常低下这也会增加服务器的负荷同时在查询过程中索引的增删改会导致查询数据不一致或者排序变化造成结果不准确。 Search_After本身就是一种业务折中方案它不允许指定跳转到页面而只提供下一页的功能。 Scroll默认你会在后续将所有符合条件的数据都取出来所以它只是搜索到了所有的符合条件的doc_id(这也是为什么官方推荐用doc_id进行排序因为本身缓存的就是doc_id如果用其他字段排序会增加查询量)并将它们排序后保存在协调节点(coordinate node)但是并没有将所有数据进行fetch而是每次scroll读取size个文档并返回此次读取的最后一个文档以及上下文状态用以告知下一次需要从哪个shard的哪个文档之后开始读取。 这也是为什么官方不推荐scroll用来给用户进行实时的分页查询而是适合于大批量的拉取数据因为它从设计上就不是为了实时读取数据而设计的。
http://www.pierceye.com/news/852175/

相关文章:

  • asp网站静态化seo关键词排名优化软件怎么选
  • wordpress apache版本北京seo招聘
  • 南京玄武网站建设信息服务公司的经营范围有哪些
  • 旅游网站建设与翻译wordpress 显示作者
  • 网站建设与维护报告总结国家外汇管理局网站怎么做报告
  • 南沙区网站建设网站开发人员薪酬
  • 设计外贸英文网站简述网站开发的流程
  • 电商网站设计是干什么的如何建设cpa影视网站
  • wordpress设置阅读全文什么是seo搜索引擎优化
  • 网站名重复网站建设的经验之谈
  • 网站优化软件排名器有含义的公司名
  • 像wordpress一样的网站吗老徐蜂了网站策划书
  • ps做网站首页效果特效wordpress无法修改密码
  • 蚌埠网站设计一句话宣传自己的产品
  • 织梦开发供需网站杭州互联网企业排名
  • 网站结构分析关键词林俊杰的寓意
  • 网站备案 超链接青岛胶南做网站的
  • 国内ui做的好的网站网站底部 图标
  • 网站开发维护人员天津微外卖网站建设
  • 保定网站建设推广公司怎么样雄安优秀网站建设
  • 上海集团网站建设做网站用asp好吗
  • h5网站建设价格wp-wordpress
  • 简单描述一下网站制作的流程投资理财产品的网站建设
  • 企业网站制作托管东营高端网站建设
  • 可以推广网站建立网站接受投注是什么意思
  • 微网站制作网站开发创建自己网站的步骤
  • 人才网网站开发手册外链发布平台大全
  • 福州网站备案wordpress打开媒体链接设置
  • 大学网站建设考核办法永春网站设计
  • 哪个设计网站赚钱百度地图网页版进入