经典面试问题: ES如何实现毫秒级的数据查询返回?

电脑杂谈  发布时间:2020-07-18 15:21:55  来源:网络整理

mysql获取当前时间_php mysql 获取当前时间_mysql 获取当前毫秒

链接: zhuanlan.zhihu.com/p/60458049

程序员Xiaole(ID: study_tech)的第921条推文来源: 百度

回顾过去: Spring Boot God操作-多个数据源服务层打包

文字

面试问题

es当数据量很大(数十亿个级别)时,如何提高查询效率?

访调员的心理分析

这个问题肯定是要问的. 坦率地说,这取决于您是否真正完成了es,因为什么?实际上,es的性能不如您想象的好. 很多时候,数据量很大,尤其是当有数亿条数据时,您可能会很惊讶地发现如何运行5到10秒的搜索,这是作弊的. 首次搜索的时间是5到10秒,但稍后会更快,可能是几百毫秒.

mysql获取当前时间_mysql 获取当前毫秒_php mysql 获取当前时间

您非常困惑,每个用户第一次访问都会变慢,它会更难吗?因此,如果您以前从未玩过es,或者只是自己玩过演示,那么在被问到这个问题时很容易感到困惑,这表明您确实不喜欢es玩吗?

面试问题分析

说实话,ES性能优化没有灵丹妙药,这是什么意思?只是不要期望随意调整参数,您可以处理所有无所不能的慢速性能场景. 在某些情况下,您可以更改参数或调整语法,但这在所有情况下都不可能实现.

性能优化的杀手-文件系统缓存

您写入es的数据实际上已写入磁盘文件. 查询时,操作系统会自动将磁盘文件中的数据缓存到文件系统缓存中.

es的搜索引擎严重依赖于基础文件系统缓存. 如果为文件系统高速缓存提供更多的内存,并尝试使该内存可用于所有idx段文件索引数据文件,则基本上在搜索时使用该内存. 是的,性能会很高.

性能差距有多大?我们以前的许多测试和压力测试中,如果转到磁盘,通常是一秒钟,搜索性能肯定处于第二级,即1秒,5秒,10秒. 但是,如果您使用文件系统缓存,则它是纯内存. 一般而言,性能比磁盘高一个数量级. 基本上是毫秒,范围从几毫秒到几百毫秒.

这是一个真实的案例. 一家公司的es节点有3台计算机,每台计算机似乎都有很多内存,即64G,总内存为64 * 3 = 192G. 每台计算机的es jvm堆为32G,因此,每台计算机的文件系统缓存剩余量为32G. 群集中的文件系统缓存总计为32 * 3 = 96G内存. 此时,整个磁盘上的索引数据文件在3台计算机上总共占用1T的磁盘容量. es的数据量为1T,因此每台计算机的数据量为300G. 这个表现好吗?文件系统缓存的内存只有100G,十分之一的数据可以存储在内存中,其余的存储在磁盘上,然后执行搜索操作,大多数操作来自磁盘,并且性能绝对很差.

mysql 获取当前毫秒_php mysql 获取当前时间_mysql获取当前时间

归根结底,您必须使es性能更好. 最好的情况是,计算机的内存至少可以容纳总数据的一半.

根据我们自己在生产环境中的实践经验,在最佳情况下,es中仅存储少量数据,这是您要搜索的索引. 如果为文件系统缓存保留的内存为100G,则您可以将索引数据控制在100G以内. 在这种情况下,几乎所有数据都在内存中搜索,并且性能非常高,通常在1秒之内.

例如,您现在有一行数据. ID,名称,年龄.... 30个字段. 但是,如果您现在搜索,则仅需要基于三个字段id,名称和年龄进行搜索. 如果您将一行数据的所有字段愚蠢地写入es,将导致90%的数据未用于搜索,结果是它占用了es机器上文件系统缓存的空间. 单个数据的数据量越大,将导致文件系统缓存较少的数据. 实际上,只写几个字段用于es中检索就足够了,例如,写es id,name,age三个字段,然后可以将其他字段数据存储在mysql / hbase中,通常建议使用诸如es + hbase之类的架构.

hbase的特点是它适用于海量数据的存储,即,您可以将海量数据写入hbase,但不执行复杂的搜索,只需根据id或range进行简单的操作即可. 从es到按名称和年龄进行搜索,结果可能是20个doc id,然后根据doc id到hbase来查询与每个doc id对应的完整数据,找出并返回前端.

写入es的数据应小于或等于es或稍大于es文件系统高速缓存的内存容量. 然后可能需要20毫秒才能从es中检索,然后根据es返回的id在hbase中进行查询,并检查20条数据,这也可能需要30毫秒. 也许您是在玩这种游戏,并且每次都将1T的数据放入es中. 查询时间为5〜10s,现在性能可能很高,每个查询为50ms.

数据预热

假设即使遵循上述方案,es群集中每台计算机写入的数据量也超过文件系统缓存的两倍. 例如,如果在计算机上写入60G数据,则结果是文件系统. 缓存仅30G,而磁盘上仍保留30G数据.

实际上,可以预热数据.

例如,以微博为例. 您可以放置​​一些大的Vs和许多平时观看的人的数据,并且可以提前在后台构建系统. 每时每刻,您的后台系统都会搜索热门数据. 闪到文件系统缓存中,当用户稍后实际查看热数据时,他们直接从内存中搜索,而且速度非常快.

php mysql 获取当前时间_mysql获取当前时间_mysql 获取当前毫秒

或者通过电子商务,您可以预先在后台制作一些最常查看的产品,例如iPhone 8,热点数据,并每1分钟主动访问一次,并将其刷新到文件系统缓存中.

对于那些您认为相对较热且经常被人们访问的数据,最好制作一个特殊的缓存预热子系统,该子系统将在每个特定时间段之前访问该热数据,以使数据进入文件系统. 缓存一起去. 因此,下次有人访问时,性能肯定会好得多.

冷热分离

可以执行类似于mysql的水平拆分,即为很少访问且频率很低的大量数据编写一个单独的索引,然后为经常访问的热数据编写一个单独的索引. 最好将冷数据写入一个索引,然后将热数据写入另一个索引,以确保将热数据预热后尽可能多地保留在文件系统的os缓存中. 不要让冷数据被冲洗掉.

看,假设您有6台机器,2个索引,一个用于冷数据,一个用于热数据以及每个索引3个分片. 三台计算机发布热量数据索引,其他三台计算机发布冷数据索引. 然后,在这种情况下,您将花费大量时间访问热数据索引,并且热数据可能占总数据量的10%. 此时,数据量非常小,几乎所有数据都保留在文件系统缓存中,因此您可以确保对热数据的访问. 性能很高. 但是对于冷数据,它位于另一个索引中,并且与热数据索引不在同一台计算机上,并且每个人之间都没有联系. 如果有人访问冷数据,则磁盘上可能有大量数据. 此时,性能很差. 只有10%的人正在访问冷数据,而90%的人正在访问热数据. 没关系.

文档模型设计

对于MySQL,我们经常会有一些复杂的相关查询. 如何在es中玩游戏,尽量不要在es中使用复杂的关系查询,一旦使用,性能通常会不好.

最好先在Java系统中完成关联,然后将关联的数据直接写入es. 搜索时,无需使用es的搜索语法即可完成相关的搜索,例如join.

文档模型设计非常重要. 有很多操作. 搜索时,不想执行各种复杂而混乱的操作. es可以支持很多操作. 不要考虑使用es做不容易操作的事情. 如果有这样的操作,请在设计和编写文档模型时尝试完成它. 另外,应尽可能避免一些过于复杂的操作,例如加入/嵌套/父子搜索mysql 获取当前毫秒,并且性能非常差.

php mysql 获取当前时间_mysql 获取当前毫秒_mysql获取当前时间

寻呼性能优化

es的分页非常棘手,为什么?例如,如果每页有10条数据,现在您要查询100页. 实际上,将在协调节点上检查存储在每个分片上的前1000条数据. 如果分片为5 A,则有5000条数据,然后协调节点将合并并处理这5000条数据,然后在第100页上获得最后的10条数据.

分布式,您需要检查第100页上的10个数据. 不能说从5个分片中,每个分片都将检查2个数据,最后在协调节点上合并为10个数据吗?您必须检查每个分片中的1000条数据,然后根据需要进行分类,过滤等,最后再次分页以获取第100页的数据. 翻页时,翻得越深,每个分片返回的数据越多mysql 获取当前毫秒,并且协调节点的处理时间越长,这非常容易欺骗. 因此,使用es进行分页时,您会发现向后旋转的次数越多,速度就越慢.

我们之前也遇到过此问题. 使用es进行分页,前几页需要数十毫秒. 转到10或数十页时,基本上需要5到10秒才能找到一页数据. 上

有什么解决办法吗?

不允许进行深度分页(默认深度分页性能非常差)

告诉产品经理,您的系统不允许打开如此深的页面. 默认情况下,转得越深,性能越差.

类似于应用程序中的推荐产品,这些产品会被逐页地下拉

类似于微博,您可以向下滚动并逐页滚动浏览微博,可以使用滚动api,并在Internet上搜索使用方法.

Scroll将立即为您生成所有数据的快照,然后每次向后滑动时,您将在光标scroll_id中移动以获取下一页. 该性能将优于上面提到的分页性能. 它要高得多,基本上是毫秒. 但是,唯一的一点是,它适用于类似于微博下拉页面且无法随意跳转到任何页面的场景. 换句话说,您不能先进入第10页,然后进入第120页,然后再回到第58页,并且您不能随机跳转页面. 因此,现在许多产品不允许您随意翻页. 对于应用程序和某些网站,您只能向下滚动并翻页.

必须在初始化期间指定scroll参数,以告知es保存此搜索上下文的时间. 您需要确保用户不会在几个小时内继续翻页,否则他们可能会因超时而失败.

除了使用滚动API之外,您还可以使用search_after. search_after的想法是使用上一页的结果来帮助检索下一页的数据. 显然,此方法不允许您随意翻页,而只能翻页. 初始化时,您需要使用唯一值字段作为排序字段.

特别声明: 以上内容(包括图片或视频)也由“网易”自媒体平台的用户上传和发布. 该平台仅提供信息存储服务.


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/ruanjian/article-284859-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...