es 分片底层时如何工作的?面试题
答: 分片底层对应的是一个Lucene库,而Lucene底层使用倒排索引技术实现。
正排索引(正向索引):
我们MySQL为例,用id字段存储博客文章的编号,用context存储文件的内容。
CREATE TABLE blog (id INT PRIMARY KEY AUTO_INCREMENT, context TEXT);
INSERT INTO blog VALUES (1,'I am Jason Yin, I love Linux ...')
此时,如果我们查询文章内容包含"Jason Yin"的词汇的时候,就比较麻烦了,因为要进行全表扫描。
SELECT * FROM blog WHERE context LIKE 'Jason Yin';
在工作中尽量少用 like , 或者禁用
全表扫描是非常耗时的。
倒排索引(反向索引):
ES使用一种称为"倒排索引"的结构,它适用于快速的全文检索。
倒排索引中有以下三个专业术语:
词条:
指的是最小的存储和查询单元,换句话说,指的是您想要查询的关键字(词)。
对应英文而言通常指的是一个单词,而对于中文而言,对应的是一个词组。
词典(字典):
它是词条的集合,底层通常基于"Btree+"和"HASHMap"实现。
倒排表:
记录了词条出现在什么位置,出现的频率是什么。
倒排表中的每一条记录我们称为倒排项。
倒排索引的搜索过程:
(1)首先根据用户需要查询的词条进行分词后,将分词后的各个词条字典进行匹配,验证词条在词典中是否存在;
(2)如果上一步搜索结果发现词条不在字典中,则结束本次搜索,如果在词典中,就需要去查看倒排表中的记录(倒排项);
(3)根据倒排表中记录的倒排项来定位数据在哪个文档中存在,而后根据这些文档的"_id"来获取指定的数据;
综上所述,假设有10亿篇文章,对于mysql不创建索引的情况下,会进行全表扫描搜索"Jason Yin"。而对于ES而言,其只需要将倒排表中返回的id进行扫描即可,而无须进行全量查询。