后端存储实战课
李玥
京东零售计算存储平台部资深架构师
立即订阅
2989 人已学习
课程目录
已更新 10 讲 / 共 26 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (2讲)
开篇词 | 从今天起,换种方式学存储
免费
课前加餐 | 电商系统是如何设计的?
创业篇 (7讲)
01 | 创建和更新订单时,如何保证数据准确无误?
02 | 流量大、数据多的商品详情页系统该如何设计?
03 | 复杂而又重要的购物车系统,应该如何设计?
04 | 事务:账户余额总是对不上账,怎么办?
05 | 分布式事务:如何保证多个系统间的数据是一致的?
06 | 如何用Elasticsearch构建商品搜索系统?
07|MySQL HA:如何将“删库跑路”的损失降到最低?
高速增长篇 (1讲)
08 | 一个几乎每个系统必踩的坑儿:访问数据库超时
后端存储实战课
登录|注册

06 | 如何用Elasticsearch构建商品搜索系统?

李玥 2020-03-10
你好,我是李玥。
搜索这个特性可以说是无处不在,现在很少有网站或者系统不提供搜索功能了,所以,即使你不是一个专业做搜索的程序员,也难免会遇到一些搜索相关的需求。搜索这个东西,表面上看功能很简单,就是一个搜索框,输入关键字,然后搜出来想要的内容就好了。
搜索背后的实现,可以非常简单,简单到什么程度呢?我们就用一个 SQL,LIKE 一下就能实现;也可以很复杂,复杂到什么程度呢?不说百度谷歌这种专业做搜索的公司,其他非专业做搜索的互联网大厂,搜索团队大多是千人规模,这里面不仅有程序员,还有算法工程师、业务专家等等。二者的区别也仅仅是,搜索速度的快慢以及搜出来的内容好坏而已。
今天这节课,我们就以电商中的商品搜索作为例子,来讲一下,如何用 ES(Elasticsearch) 来快速、低成本地构建一个体验还不错的搜索系统。

理解倒排索引机制

刚刚我们说了,既然我们的数据大多都是存在数据库里,用 SQL 的 LIKE 也能实现匹配,也能搜出结果,为什么还要专门做一套搜索系统呢?我先来和你分析一下,为什么数据库不适合做搜索。
搜索的核心需求是全文匹配,对于全文匹配,数据库的索引是根本派不上用场的,那只能全表扫描。全表扫描已经非常慢了,这还不算,还需要在每条记录上做全文匹配,也就是一个字一个字的比对,这个速度就更慢了。所以,使用数据来做搜索,性能上完全没法满足要求。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《后端存储实战课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(12)

  • 李玥 置顶
    Hi,我是李玥。

    还是在这里回顾一下上节课的思考题:

    2PC也有一些改进版本,比如3PC、TCC这些,它们大体的思想和2PC是差不多的,解决了2PC的一些问题,但是也会带来新的问题,实现起来也更复杂,限于篇幅我们没法每个都详细地去讲解。在理解了2PC的基础上,课后请你自行去学习一下3PC和TCC,然后对比一下,2PC、3PC和TCC分别适用于什么样的业务场景?

    谈一下我的理解:

    3PC相比于2PC做了两个改进,一是事务执行器也增加了超时机制,避免我们课程中提到的因为协调者宕机,导致执行器长时间卡死的问题,另外,3PC在2PC之前增加一个询问阶段,这个阶段事务执行器可以去尝试锁定资源(但不等待),这样避免像2PC那样直接去锁定资源,而资源不可用的情况下,一直等待资源而卡住事务的情况。

    TCC可以理解为业务层面的2PC(也有观点主张TCC和2PC是完全不同的,我个人建议没必要在这些概念上较真,理解并正确使用才是关键),TCC同样分为Try和Confirm/Cancel 两个阶段,在Try阶段锁定资源,但不执行任何更新操作,Confirm阶段来执行所有更新操作并提交,如果失败进入Cancel阶段。Cancel阶段就是收拾烂摊子,把Confirm阶段做的数据更新都改回去,把Try阶段锁定的资源都释放。相比于2PC,TCC可以不依赖于本地事务,但是Cancel阶段的业务逻辑比较难实现。
    2020-03-10
    1
    7
  • Geek_c76e2d
    因为用户每输入一个字都可能会发请求查询搜索框中的搜索推荐。所以搜索推荐的请求量远高于搜索框中的搜索。es针对这种情况提供了suggestion api,并提供的专门的数据结构应对搜索推荐,性能高于match,但它应用起来也有局限性,就是只能做前缀匹配。再结合pinyin分词器可以做到输入拼音字母就提示中文。如果想做非前缀匹配,可以考虑Ngram。不过Ngram有些复杂,需要开发者自定义分析器。比如有个网址www.geekbang.com,用户可能记不清具体网址了,只记得网址中有2个e,此时用户输入ee两个字母也是可以在搜索框提示出这个网址的。以上是我在工作中针对前缀搜索推荐和非前缀搜索推荐的实现方案。

    作者回复: 👍👍👍

    2020-03-10
    26
  • hello
    老师,能否来一篇加餐,讲讲ES、MySQL、MongoDB、RocketMQ/Kafka、newSQL这些存储的对比,底层是基于什么原理擅长干哪些事,不擅长干哪些事?
    2020-03-10
    1
    7
  • 大秦皇朝
    李sir我还想再问下,根据我们不同的业务,选分词插件有啥讲究没?虽有点跑题,但是能不能简单说下,感谢~

    作者回复: 我没有专业做过搜索,我的朋友孙健(https://github.com/ansjsun)老师,他是开源分词项目ansj(https://github.com/NLPchina/ansj_seg)的作者,建议你和他讨论一下这个问题。

    2020-03-11
  • 大秦皇朝
    windows下测试避坑:
    分词插件icu支持路径中带空格或者说是可以es放在Program Files下;如果用ik的话,建议路径不要带空格,网上很多说权限之类的,我把权限调整了也不行,路径不带空格立马OK。
    2020-03-11
  • Jax
    老师您好,是否可以做一些电商这种海量数据下,后台管理系统存储方面的最佳实践。还有对于不同系统之间的数据同步,也希望得到一些比较好的实践方案或者工具。

    以下是比较具体的点:

    我在上家公司也是做电商系统的,不过我负责的是后台商品数据的维护系统。前台可以用各种缓存来提速,但是对于后台系统,该如何让系统变得比较快?尤其是后台管理系统往往会涉及大批量商品的价格,库存之类的更新,并且更新后业务团队希望能实时看到他们更新成功了,而且有不少更新的操作对丢数据的容忍度比较低,这种情况下缓存也很难做,所以想得到一些对于这种大批量数据后台管理系统的实践经验。

    对于数据同步,主要是有的原始数据存储在传统数据库,而为了速度,会存储到一些no sql产品做缓存,但是我们在实践中,经常会有一些丢数据,或者未能及时同步的情况发生,希望能得到这方面的一些经验分享。

    作者回复: 你提的这些问题,我们在后面的课程中都会讲到。

    比如,《11 | MySQL如何应对高并发(一):使用缓存保护MySQL》《17 | 大厂都是怎么做MySQL to Redis同步的?》这两节会讲怎么来更快更准确的更新缓存。

    《19 | 跨系统实时同步数据,分布式事务是唯一的解决方案吗?》这节课会讲如何在异构数据库之间来实时同步数据。

    2020-03-10
    1
  • 发条橙子 。
    老师 面试中经常会有问到几千万条数据列表的查询如何实现 ,本质就是考避免使用数据库而选择这种es来搜索是么 。 那几千万条数据在es中查询 “苹果” 是不是也会有性能之类的问题

    作者回复: 也不能说MySQL就慢,ES就快,最终查询性能还是要取决于数据总量和存储结构,当然ES它是内存数据库,占一些优势。

    后面我们会用几节课来讲,到底是什么因素影响查询快慢。

    2020-03-10
  • 旅途
    老师 您说的二次查找是指在第一次的查找结果中继续查找吗

    作者回复: 是的

    2020-03-10
  • 每天晒白牙
    老师,请教个问题,比如一个商品搜索系统,给一些商品打标签,然后支持根据商品信息和标签搜索商品,有啥方案吗?

    作者回复: 这个需求用ES很合适啊

    2020-03-10
    1
  • 每天晒白牙
    应该输入的时候就会实时去 ES 中检索吧
    2020-03-10
  • 墨雨
    那一般什么时候来更新索引呢?是建立一个定时任务来更新么

    作者回复: 写入数据的时候。

    2020-03-10
  • ELLIOT
    使用match query对商品名进行匹配,然后按score进行sort排序,选择前n项
    2020-03-10
收起评论
12
返回
顶部