检索技术核心20讲
陈东
奇虎360商业产品事业部资深总监
立即订阅
2345 人已学习
课程目录
已完结 29 讲
0/4登录后,你可以任选4讲全文学习。
课前必学 (2讲)
开篇词 | 学会检索,快人一步!
免费
导读 | 三步走策略,轻松搞定检索!
基础技术篇 (8讲)
01 | 线性结构检索:从数组和链表的原理初窥检索本质
02 | 非线性结构检索:数据频繁变化的情况下,如何高效检索?
03 | 哈希检索:如何根据用户ID快速查询用户信息?
04 | 状态检索:如何快速判断一个用户是否存在?
05 | 倒排索引:如何从海量数据中查询同时带有“极”和“客”的唐诗?
测一测 | 检索算法基础,你掌握了多少?
特别加餐 | 倒排检索加速(一):工业界如何利用跳表、哈希表、位图进行加速?
特别加餐 | 倒排检索加速(二):如何对联合查询进行加速?
进阶实战篇 (13讲)
06 | 数据库检索:如何使用B+树对海量磁盘数据建立索引?
07 | NoSQL检索:为什么日志系统主要用LSM树而非B+树?
08 | 索引构建:搜索引擎如何为万亿级别网站生成索引?
09 | 索引更新:刚发布的文章就能被搜到,这是怎么做到的?
10 | 索引拆分:大规模检索系统如何使用分布式技术加速检索?
11|精准Top K检索:搜索结果是怎么进行打分排序的?
12 | 非精准Top K检索:如何给检索结果的排序过程装上“加速器”?
13 | 空间检索(上):如何用Geohash实现“查找附近的人”功能?
14 | 空间检索(下):“查找最近的加油站”和“查找附近的人”有何不同?
15 | 最近邻检索(上):如何用局部敏感哈希快速过滤相似文章?
16 | 最近邻检索(下):如何用乘积量化实现“拍照识花”功能?
特别加餐 | 高性能检索系统中的设计漫谈
测一测 | 高性能检索系统的实战知识,你掌握了多少?
系统案例篇 (4讲)
17 | 存储系统:从检索技术角度剖析LevelDB的架构设计思想
18 | 搜索引擎:输入搜索词以后,搜索引擎是怎么工作的?
19 | 广告系统:广告引擎如何做到在0.1s内返回广告信息?
20 | 推荐引擎:没有搜索词,“头条”怎么找到你感兴趣的文章?
结束语 (2讲)
结束语 | 成长和进化,技术如此,我们亦如此
免费
结课测试 | 这些检索知识,你都掌握了吗?
检索技术核心20讲
15
15
1.0x
00:00/00:00
登录|注册

特别加餐 | 高性能检索系统中的设计漫谈

陈东 2020-05-04
你好,我是陈东。欢迎来到检索专栏的第三次加餐时间。
在进阶篇的讲解过程中,我们经常会提起一些设计思想,包括索引与数据分离、减少磁盘 IO、读写分离和分层处理等方案。这些设计思想看似很简单,但是应用非常广泛,在许多复杂的高性能系统中,我们都能看到类似的设计和实现。不过,前面我们并没有深入来讲,你可能理解得还不是很透彻。
所以,今天我会把专栏中出现过的相关案例进行汇总和对比,再结合相应的案例扩展,以及进一步的分析讨论,来帮助你更好地理解这些设计思想的本质。并且,我还会总结出一些可以参考的通用经验,让你能更好地设计和实现自己的高性能检索系统。

设计思想一:索引与数据分离

我要说的第一个设计思想就是索引与数据分离。索引与数据分离是一种解耦的设计思想,它能帮助我们更好地聚焦在索引的优化上。
比如说,对于无法完全加载到内存中的数据,对它进行索引和数据分离之后,我们就可以利用内存的高性能来加速索引的访问了。第 6 讲中的线性索引的设计,以及 B+ 树中区分中间节点和叶子节点的设计,就都使用了索引和数据分离的设计思想。
那如果索引和数据都可以加载在内存中了,我们还需要使用索引和数据分离吗?在这种情况下,将索引和数据分离,我们依然可以提高检索效率。以第 5 讲中查找唐诗的场景为例,我们将所有的唐诗存在一个正排索引中,然后以关键词为 Key 建立倒排索引。倒排索引中只会记录唐诗的 ID,不会记录每首唐诗的内容。这样做会有以下 3 个优点。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《检索技术核心20讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(3)

  • 一步
    非聚集索引。如果要保证 MyISAM 的数据一致性,那我们需要在表级别上进行加锁处理。
    --------------------
    为什么 非聚集索引 即叶子节点保存的是指针,就不能有行级别的锁呢? 我保证指针指向的记录不能更新不就可以了吗?

    作者回复: 这是因为MySQL的锁机制是在引擎层实现,而不是是数据层实现。因此,行锁是加在索引上。oracle倒是把行锁加在了数据行上。

    2020-05-08
    4
  • 那时刻
    对于老师总结的这几部分,我的想法如下,不恰当的地方,烦请老师指正。
    1. 索引和数据分离
    我想到了存储计算分离的设计,比如消息队列Pulsar就是采用这样设计,存储消息的职责从Broker分离出来,交给专门存储集群,这样Broker就变成无状态的节点,灵活的集群调度。Bigquery和aws Aurora也是如此的设计。
    2. 减少磁盘 IO
    Kafka中通过分批,顺序读写IO,也使用Zero Copy加快数据读取速度
    3. 读写分离
    服务器在操作数据库的时候,采用读写分离,降低服务器的压力,但是得注意数据最终一致性问题。
    4. 分层处理
    在服务器和数据库中间加入Redis作为缓存,可以看做一种分层处理,来缓解直接访问数据库的压力。在ES里把数据分为冷热数据也有类似的思想。

    作者回复: 总结得挺好的~
    对于你提到的例子,在数据库和服务器间加入一个缓存层的设计,其实也是非常常见的例子,无论是使用memcached,还是Redis的案例都有。
    不过,分层处理和减少磁盘IO在某些场景下会有重叠。在我看来,单纯使用一个缓存层加载全部数据的话,我会将它归在“减少磁盘IO”中。但是如果是“将部分最热的数据装载到缓存中”,那么就是应用了二八原则的分层处理思想。

    2020-05-04
    1
  • 1. 索引和数据分离
    老师讲到的mysiam和innodb的例子,我觉得有点怪,因为数据操作影响到的数据结构全局还是局部,才是加锁范围的核心因素。这里我并没有看到直接联系,除非说mysiam的真实数据就在磁盘里连续存成了一个数组,但还是和数据索引分离不分离没啥子关系。
    而且其实我认为innodb这样的也算数据索引分离,毕竟索引页和数据页是分离的。我能想到的好像都是数据索引分离的机构,OLAP各种列存结构(数据按列分块存,并在基础上额外加一些minmax,skipindex等一些索引), 以及LSM为代表的一众TP数据库,像hbase中hfile数据块索引块,当然我隐约感觉磁盘存储的话索引数据不分离,有很大的复杂度,还想不太明白,不胡说八道了。
    2. 减少磁盘 IO
    老师讲的有的有点多啊,比较快想到的不一样的是各种编码的算法,hbase diff以及列存的delta dictionaryencoding等等。
    3. 读写分离
    读写分裂更广泛的含义在于把不同的workload的任务相互分开,使得不会相互影响。 实时数仓(Druid,pinot,以及阿里的adb)就一般采用lambda架构,把实时摄入的分一波,历史节点的数据分一波,实时摄入完了,数据迁移到历史节点。
    4. 分层处理
    说道分层处理,我就觉得国内不管教学也好,还是实际工作中也好,就通常比较聚焦在没一层的东东上。比如说数据库,我们会讲内存中长啥样,磁盘中讲啥样,问题是disk-base的数据库存储侧比较重要的一点在于怎么让数据尽可能的move 到上层的存储器,同时满足事务等约束,所以数据在各个层次之间的movement我就很少可看到人讲,学的时候老感觉缺一块。o(* ̄︶ ̄*)o,扯回主题,时序数据库就很抢到数据的分层结构,毕竟数据本身的特性——最近的数据越有价值摆在这里,所以一般都会按时间进行切片,不同的切片去灵活部署到不同的dataserver或者采用不同的数据结构。

    作者回复: 1.的确,一般来说,我们是对数据进行加锁,但innodb是对索引加锁,而不是对记录加锁。这也是理解innosb特点的关键。有兴趣可以深入研究一下。
    4.你说到了很好的一个点:数据在不同层之间是怎么移动的?这个的确也很重要。我下一篇正好就会讲到一个内存数据往磁盘写的例子,敬请期待。

    2020-05-06
收起评论
3
返回
顶部