From 7fb067ea12d888533c4dd58b93114d1f7f719c17 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sun, 2 Dec 2018 22:53:20 +0800 Subject: [PATCH] docs(es): add es-optimizing-query-performance.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ElasticSearch在数据量很大(数十亿级别)时如何提高查询效率? --- README.md | 6 +- .../es-optimizing-query-performance.md | 74 ++++++++++++++++++ img/es-search-process.png | Bin 0 -> 24299 bytes 3 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 docs/high-concurrency/es-optimizing-query-performance.md create mode 100644 img/es-search-process.png diff --git a/README.md b/README.md index a6e70c8..600b002 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,6 @@ 本系列知识出自中华石杉,我对这部分知识做了一个系统的整理,方便学习查阅。 -可以关注石杉老师的微信公众号:**石杉的架构笔记** @shishan100,有很多干货噢~ - ## [分布式系统](/docs/distributed-system/distributed-system-interview.md) ### 系统拆分 @@ -50,8 +48,8 @@ ### 搜索引擎 - [es 的分布式架构原理能说一下么(es 是如何实现分布式的啊)?](/docs/high-concurrency/es-architecture.md) -- [es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗?](/docs/high-concurrency/es-write-query-search.md) -- es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊? +- [es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?](/docs/high-concurrency/es-write-query-search.md) +- [es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊?](/docs/high-concurrency/es-optimizing-query-performance.md) - es 生产集群的部署架构是什么?每个索引的数据量大概有多少?每个索引大概有多少个分片? ### [缓存](/docs/high-concurrency/why-cache.md) diff --git a/docs/high-concurrency/es-optimizing-query-performance.md b/docs/high-concurrency/es-optimizing-query-performance.md new file mode 100644 index 0000000..0133493 --- /dev/null +++ b/docs/high-concurrency/es-optimizing-query-performance.md @@ -0,0 +1,74 @@ +## 面试题 +es 在数据量很大的情况下(数十亿级别)如何提高查询效率啊? + +## 面试官心理分析 +这个问题是肯定要问的,说白了,就是看你有没有实际干过 es,因为啥?其实 es 性能并没有你想象中那么好的。很多时候数据量大了,特别是有几亿条数据的时候,可能你会懵逼的发现,跑个搜索怎么一下 5~10s,坑爹了。第一次搜索的时候,是 5~10s,后面反而就快了,可能就几百毫秒。 + +你就很懵,每个用户第一次访问都会比较慢,比较卡么?所以你要是没玩儿过 es,或者就是自己玩玩儿 demo,被问到这个问题容易懵逼,显示出你对 es 确实玩儿的不怎么样? + +## 面试题剖析 +说实话,es 性能优化是没有什么银弹的,啥意思呢?就是**不要期待着随手调一个参数,就可以万能的应对所有的性能慢的场景**。也许有的场景是你换个参数,或者调整一下语法,就可以搞定,但是绝对不是所有场景都可以这样。 + +### 性能优化的杀手锏——filesystem cache +你往es里写的数据,实际上都写到磁盘文件里去了,查询的时候,操作系统会将磁盘文件里的数据自动缓存到 `filesystem cache` 里面去。 + +![es-search-process](/img/es-search-process.png) + +es 的搜索引擎严重依赖于底层的 `filesystem cache`,你如果给 `filesystem cache` 更多的内存,尽量让内存可以容纳所有的 `idx segment file索引数据文件,那么你搜索的时候就基本都是走内存的,性能会非常高。 + +性能差距究竟可以有多大?我们之前很多的测试和压测,如果走磁盘一般肯定上秒,搜索性能绝对是秒级别的,1秒、5秒、10秒。但如果是走 `filesystem cache`,是走纯内存的,那么一般来说性能比走磁盘要高一个数量级,基本上就是毫秒级的,从几毫秒到几百毫秒不等。 + +这里有个真实的案例。某个公司 es 节点有 3 台机器,每台机器看起来内存很多,64G,总内存就是 `64 * 3 = 192G`。每台机器给 es jvm heap 是 `32G`,那么剩下来留给 `filesystem cache` 的就是每台机器才 `32G`,总共集群里给 `filesystem cache` 的就是 `32 * 3 = 96G` 内存。而此时,整个磁盘上索引数据文件,在 3 台机器上一共占用了 `1T` 的磁盘容量,es 数据量是 `1T`,那么每台机器的数据量是 `300G`。这样性能好吗? `filesystem cache` 的内存才 100G,十分之一的数据可以放内存,其他的都在磁盘,然后你执行搜索操作,大部分操作都是走磁盘,性能肯定差。 + +归根结底,你要让 es 性能要好,最佳的情况下,就是你的机器的内存,至少可以容纳你的总数据量的一半。 + +根据我们自己的生产环境实践经验,最佳的情况下,是仅仅在 es 中就存少量的数据,就是你要**用来搜索的那些索引**,如果内存留给 `filesystem cache` 的是 100G,那么你就将索引数据控制在 `100G` 以内,这样的话,你的数据几乎全部走内存来搜索,性能非常之高,一般可以在 1 秒以内。 + +比如说你现在有一行数据。`id name age ....` 30 个字段。但是你现在搜索,只需要根据 `id name age` 三个字段来搜索。如果你傻乎乎往 es 里写入一行数据所有的字段,就会导致说 `90%` 的数据是不用来搜索的,结果硬是占据了 es 机器上的 `filesystem cache` 的空间,单条数据的数据量越大,就会导致 `filesystem cahce` 能缓存的数据就越少。其实,仅仅写入 es 中要用来检索的**少数几个字段**就可以了,比如说就写入es `id name age` 三个字段,然后你可以把其他的字段数据存在 mysql/hbase 里,我们一般是建议用 `es + hbase` 这么一个架构。 + +hbase 的特点是**适用于海量数据的在线存储**,就是对 hbase 可以写入海量数据,但是不要做复杂的搜索,做很简单的一些根据 id 或者范围进行查询的这么一个操作就可以了。从 es 中根据 name 和 age 去搜索,拿到的结果可能就 20 个 `doc id`,然后根据 `doc id` 到 hbase 里去查询每个 `doc id` 对应的**完整的数据**,给查出来,再返回给前端。 + +写入 es 的数据最好小于等于,或者是略微大于 es 的 filesystem cache 的内存容量。然后你从 es 检索可能就花费 20ms,然后再根据 es 返回的 id 去 hbase 里查询,查 20 条数据,可能也就耗费个 30ms,可能你原来那么玩儿,1T 数据都放es,会每次查询都是 5~10秒,现在可能性能就会很高,每次查询就是 50ms。 + +### 数据预热 +假如说,哪怕是你就按照上述的方案去做了,es 集群中每个机器写入的数据量还是超过了 `filesystem cache` 一倍,比如说你写入一台机器 60G 数据,结果 `filesystem cache` 就 30G,还是有 30G 数据留在了磁盘上。 + +其实可以做**数据预热**。 + +举个例子,拿微博来说,你可以把一些大V,平时看的人很多的数据,你自己提前后台搞个系统,每隔一会儿,自己的后台系统去搜索一下热数据,刷到 `filesystem cache` 里去,后面用户实际上来看这个热数据的时候,他们就是直接从内存里搜索了,很快。 + +或者是电商,你可以将平时查看最多的一些商品,比如说 iphone 8,热数据提前后台搞个程序,每隔 1 分钟自己主动访问一次,刷到 `filesystem cache` 里去。 + +对于那些你觉得比较热的,经常会有人访问的数据,最好**做一个专门的缓存预热子系统**,就是对热数据每隔一段时间,就提前访问一下,让数据进入 `filesystem cache` 里面去。这样下次别人访问的时候,一定性能会好一些。 + +### 冷热分离 +es 可以做类似于 mysql 的水平拆分,就是说将大量的访问很少、频率很低的数据,单独写一个索引,然后将访问很频繁的热数据单独写一个索引。最好是将**冷数据写入一个索引中,然后热数据写入另外一个索引中**,这样可以确保热数据在被预热之后,尽量都让他们留在 `filesystem os cache` 里,**别让冷数据给冲刷掉**。 + +你看,假设你有 6 台机器,2 个索引,一个放冷数据,一个放热数据,每个索引 3 个shard。3 台机器放热数据 index;另外 3 台机器放冷数据 index。然后这样的话,你大量的时候是在访问热数据 index,热数据可能就占总数据量的 10%,此时数据量很少,几乎全都保留在 `filesystem cache` 里面了,就可以确保热数据的访问性能是很高的。但是对于冷数据而言,是在别的 index 里的,跟热数据 index 不在相同的机器上,大家互相之间都没什么联系了。如果有人访问冷数据,可能大量数据是在磁盘上的,此时性能差点,就 10% 的人去访问冷数据,90% 的人在访问热数据,也无所谓了。 + +### document 模型设计 +对于 MySQL,我们经常有一些复杂的关联查询。在 es 里该怎么玩儿,es 里面的复杂的关联查询尽量别用,一旦用了性能一般都不太好。 + +最好是先在 Java 系统里就完成关联,将关联好的数据直接写入 es 中。搜索的时候,就不需要利用 es 的搜索语法来完成 join 之类的关联搜索了。 + +document 模型设计是非常重要的,很多操作,不要在搜索的时候才想去执行各种复杂的乱七八糟的操作。es 能支持的操作就是那么多,不要考虑用 es 做一些它不好操作的事情。如果真的有那种操作,尽量在 document 模型设计的时候,写入的时候就完成。另外对于一些太复杂的操作,比如 join/nested/parent-child 搜索都要尽量避免,性能都很差的。 + +### 分页性能优化 +es 的分页是较坑的,为啥呢?举个例子吧,假如你每页是 10 条数据,你现在要查询第 100 页,实际上是会把每个 shard 上存储的前 `1000` 条数据都查到一个协调节点上,如果你有个 5 个shard,那么就有 5000 条数据,接着协调节点对这 5000 条数据进行一些合并、处理,再获取到最终第 100 页的 10 条数据。 + +分布式的,你要查第100页的10条数据,不可能说从5个 shard,每个 shard 就查 2 条数据?最后到协调节点合并成 10 条数据?你必须得从每个 shard 都查 1000 条数据过来,然后根据你的需求进行排序、筛选等等操作,最后再次分页,拿到里面第 100 页的数据。你翻页的时候,翻的越深,每个 shard 返回的数据就越多,而且协调节点处理的时间越长。非常坑爹。所以用 es 做分页的时候,你会发现越翻到后面,就越是慢。 + +我们之前也是遇到过这个问题,用 es 作分页,前几页就几十毫秒,翻到 10 页 or 几十页的时候,基本上就要 5~10秒 才能查出来一页数据了。 + +有什么解决方案吗? +#### 不允许深度分页/默认深度分页性能很惨 +你系统不允许翻那么深的页,跟产品经理说,默认翻的越深,性能就越差。 + +#### 类似于 app 里的推荐商品不断下拉出来一页一页的 +类似于微博中,下拉刷微博,刷出来一页一页的,你可以用 `scroll api`,关于如何使用,自行上网搜索。 + +scroll 会一次性给你生成**所有数据的一个快照**,然后每次翻页就是通过**游标移动**,获取下一页下一页这样子,性能会比上面说的那种分页性能也高很多很多,基本上都是毫秒级的。 + +但是 唯一的一点就是,这个适合于那种类似微博下拉翻页的,**不能随意跳到任何一页的场景**。也就是说,你不能先进入第 10 页,然后去 120 页,然后又回到 58 页,不能随意乱跳页。所以现在很多产品,都是不允许你随意翻页的,app,也有一些网站,做的就是你只能往下拉,一页一页的翻。 + +另外,这个 scroll 是要保留一段时间内的数据快照的,你需要确保用户不会持续不断翻页翻几个小时。 \ No newline at end of file diff --git a/img/es-search-process.png b/img/es-search-process.png new file mode 100644 index 0000000000000000000000000000000000000000..cab0652f137e402622ff4ed99a86075a64b2c2d8 GIT binary patch literal 24299 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�sXjBUL5I$ENpD21O)^FauwR7 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 literal 0 HcmV?d00001