文章目录

  • 前言
  • 一、故事的开始:搜索中的“飞花令”——倒排索引
    • ES基本概念
    • 倒排索引
    • 为什么ES搜索效率比数据库的正排索引快?
    • 倒排索引不变性:索引写入磁盘后不会改变
  • 二、“飞花令”的冠军——自顶向下介绍ES集群、读写原理
    • ES集群、读写概览
      • 1. 集群
        • 1.1 扩展
        • 1.2 容灾
      • 2. 文档写
      • 3. 文档读
      • 4. **分片越多越好吗???**
    • ES集群内部原理
      • 1. 新增数据-动态更新索引
      • 2. 删除数据——段合并
      • 3. 近实时搜索
  • 三、身为观众,我有百度——ES中的数据分析
    • 1. 分析
    • 2. 打分
  • 总结与思考

前言

我们每天都会用到搜索引擎,那么,思考几个问题:输入“2020年美国大选结果是啥?”后,

  • 搜索引擎如何从海量数据中,以一种可以接受的延迟将最优的结果展现出来?
  • 海量的数据是如何存储的,原理是什么?
  • 对于大选新闻,如何实时的发布,让用户能搜索到?

一、故事的开始:搜索中的“飞花令”——倒排索引

小时候,老师提问《山居秋暝》,小李子很快能够想到:

空山新雨后,天气晚来秋。

明月松间照,清泉石上流。

竹喧归浣女,莲动下渔舟。

随意春芳歇,王孙自可留。

长大了,小李子去参加中国诗词大会,董卿问,包含流的诗句,,,当场懵逼了。

为什么很容易就能够根据题目想到整首诗,却很难根据诗中某个内容,想到整首诗?
从专业角度来讲,是因为大脑中建立了 《山居秋暝》–> 诗 的索引,而没有 流 --> 诗 的索引。

搜索引擎为什么快,是因为它也做了索引

这时候就会有人问,那这索引怎么做?岂不是诗中的每个字都要指向这首诗,也就是这首诗要做40个索引??

显然,我们有更好的办法,即对于一个汉字,可以指向多首诗。例如,对于流

  • 流 --> 《山居秋暝》、《于北平作》、《春日望海》……

这就是倒排索引

要想真正的理解ES中的倒排索引,还要了解ES中的基本概念。

ES基本概念

ES是一个基于Luncene开发的开源分布式搜索引擎

许多年前,一个刚结婚的名叫 Shay Banon 的失业开发者,跟着他的妻子去了伦敦,他的妻子在那里学习厨师。 在寻找一个赚钱的工作的时候,为了给他的妻子做一个食谱搜索引擎,他开始使用 Lucene 的一个早期版本。

直接使用 Lucene 是很难的,因此 Shay 开始做一个抽象层,Java 开发者使用它可以很简单的给他们的程序添加搜索功能。 他发布了他的第一个开源项目 Compass。

后来 Shay 获得了一份工作,主要是高性能,分布式环境下的内存数据网格。这个对于高性能,实时,分布式搜索引擎的需求尤为突出, 他决定重写 Compass,把它变为一个独立的服务并取名 Elasticsearch。

第一个公开版本在2010年2月发布,从此以后,Elasticsearch 已经成为了 Github 上最活跃的项目之一,他拥有超过300名 contributors(目前736名 contributors )。 一家公司已经开始围绕 Elasticsearch 提供商业服务,并开发新的特性,但是,Elasticsearch 将永远开源并对所有人可用。

据说,Shay 的妻子还在等着她的食谱搜索引擎…​

核心术语

  1. ES中的核心:索引、文档、字段,和数据库中的概念相对应
  • 索引 --> 表
  • 文档 --> 行
  • 字段 --> 列
  1. Mapping:处理es中数据的方式和规则

  2. 近实时NRT:从索引一个文档到该文档能被搜索到只有一个轻微的延迟(1s内)
  3. 集群、结点、分片、分段后文会讲

倒排索引

为什么ES搜索效率比数据库的正排索引快?

  • tire 字典树

    对于数据库中的查询,是通过key-value,每个key都是唯一的。
    而在lucene4.x之前,采用的是tire的数据结构,它能够共享前缀,例如,对于英文的26字母,A开头的就以A为前缀开始查,这样查询的效率大大提升,并且空间也大大缩小
  • tire的不足
    tire只能共享前缀,其实还可以共享后缀——FST(Finite State Tranducer)有限状态转换器。

对于cat、deep、do、dog、dogs的存储结构
(查看网址:http://examples.mikemccandless.com/fst.py?terms=&cmd=Build+it%21)

FST可以将原字典压缩3-20倍,相对于HashMap,FST可以压缩到9-60分之一的大小,虽然FST的千万级别数据查询效率会比HashMap慢10倍,但是它的大小可以让他在内存中运行,抵消掉了时间上的不足。

倒排索引不变性:索引写入磁盘后不会改变

  • 不需要锁,不必担心同步问题
  • 可被内核的文件系统缓存,停留在内存中,大部分请求会直接请求到内存,不会落到磁盘上
  • filter缓存,在索引的生命周期始终有效。不需要再每次数据改变时重建
  • 写入单个较大的倒排索引使允许数据被压缩

二、“飞花令”的冠军——自顶向下介绍ES集群、读写原理

很遗憾,由于小李子的脑子装不下那么多诗,所以与冠军“擦肩而过”。
同样,我们的一台服务器是不可能装下那么多数据的,所以就要做集群。在这一部分我们要探索ES的集群、分片、备份、分段

ES集群、读写概览

1. 集群

一个ES集群可以有多个计算机结点,每个结点里面包含分片(主分片)和备份(副分片)

在ElasticSearch Head中新建索引时,要设置分片和副分片,这里的5和1的含义是:

  • 创建5个分片,负载到集群中的所有机器
  • 每个主分片都有一个副分片

    注意点:每个主分片的内容和副分片的内容是完全一致的,所以主副分片不能放在同一台机器上

我这里把第二台机器关掉了,所以它的副分片就没地方放,相当于只做了主分片,没有副分片。

1.1 扩展

当新增了一个计算机结点会发生什么?

  • 索引中的所有分片会自动均匀分布在所有结点
  • 因此,原集群中的分片,会部分迁移到新结点上

1.2 容灾

  • 当挂掉了一个结点,副分片直接升级为主分片

2. 文档写

  • 随机选取一个结点作为协调结点
  • 由协调结点进行文档路由并将内容转发到要写入的主分片
  • 由主分片进行数据同步,更新到副分片
  • 最后返回客户响应

3. 文档读

  • 随机选取协调结点
  • 找到主分片或副分片进行轮循读取
  • 响应给客户

4. 分片越多越好吗???

  • 每个索引和分片都会产生一定的资源开销
  • 索引、映射、状态信息存储在集群状态中
  • 分片中的一部分数据要保存在内存
  • 在单个结点中要尽量存储更多数据

考虑深度分页的情况:查询从9999开始的十条数据(有三个分片,每个上面存有10w条数据)

它并不是从每个分片中选出10个然后合并30个再从30中选10个。
而是

  • 每个分片选9999+10=10009个
  • 三个分片中合并为30027个
  • 再从里面选10个

所以,首先分片过多,会造成分页的性能下降
其次,深度分页这个伪需求会造成性能的极大浪费

ES集群内部原理

  • 集群:可以理解为部署了多台机器,所有机器的群体
  • 分片(shard):就是把索引库(对应数据库一个表)拆分为多份(把数据表中的数据拆分为多个片段),每份就是一个分片
  • 备份(replica):除了不能作为协调结点(coordinating node),其他的功能和主分片完全相同
  • 分段:可以根据业务来理解,对于一个新的商品信息的插入,正常情况是以当前时间来作为updateTime的,我们就可以根据分段来处理新增的数据是否要索引。假如我们设定的时间为2020.1.1,而我们人为的插入一条updateTime为2019.10.10的数据,那么,这条数据不会进行索引,用户自然就查不到。

1. 新增数据-动态更新索引

上文提到,索引创建后就不可变,那么如何新增数据呢?——新建索引
索引如何被新建?

  1. 新文档收集到内存索引缓存——>插入新数据先进缓存
  2. 缓存提交
    • 新段(包含这个新增数据的索引)写入磁盘
    • 包含新段名字的提交点写入磁盘
    • 磁盘进行同步,确保缓存数据刷到磁盘
  3. 将新段开启,让全文可见,可被搜索
  4. 内存缓存清空,等待接受新文档

2. 删除数据——段合并

在上面的过程中,每次回新建一个段,而每个段都会消耗一定的内存和CPU,当新增多个数据,会导致段的数量增多。因此,ES后端会对段进行合并。
新段关闭用来搜索,老段直接删除。
对于要删的文档,最初只是标记了删除,但在物理机上还存在,在进行段合并的时候,对于要删除的数据,才去除,不合并。

3. 近实时搜索

在上面的动态更新索引中已经谈到,新段创建后是存在缓存中的。这时候,为了提高检索效率,就已经可以被搜索,并不需要等到全部提交。


到此,我们解决了数据存储、实时发布的问题。
接下来我们要解决查询过程中如何筛选,如何将最优的信息放在最前面


三、身为观众,我有百度——ES中的数据分析

此时的我正在电视机前看中国诗词大会总决赛,紧张激动的飞花令又来了,董卿出了个“流”字,身为观众,我有百度,所以,我搜了个:“包含流字的诗句有哪些?”,百度果然没让我失望

很明显,我只用点开第一个链接就能获取到我所要的内容。
那么,百度是如何将数据从那么多的索引中筛选出来,并作出排序?

1. 分析

ES中存在一个叫分析器的东西,它由三个模块组成,我们以“包含流字的诗句有哪些?”为例

  • 字符过滤器:过滤、转换掉标点符号,介词等。这里会过滤掉“?”、“的”
  • 分词器:将语句中的单词进行拆分。不同的分词器有不同的规则
    • 包含
    • 诗句
    • 哪些
  • 分词过滤器:大小写转换、停用词、同义词转换
    • 包含 --> 带有、含有
    • 诗句 --> 诗词、古诗



项目中用到了elasticsearch-analysis-ik作为中文分词器

2. 打分

上面的分析是对于输入的,在展现给用户之前,要进行打分排序,找到最优结果。

  • TF-IDF(词频-逆文档频率) 算法
    字词的重要性随着它在文件中出现的次数成正比增加,同时会随着在语料库中的频率成反比下降。
    缺点:会受文章的长短影响,当文章长时,它里面出现的词的次数也会相增加。
  • Okapi BM25(Best Match25)算法

    ES6开始采用BM25算法

总结与思考

这篇文章基本上解决了以下几个问题

真正的搜索引擎远不止于此,如果对现有的知识做出的搜索引擎进行优化,我觉得:

  • 可以对实时热点数据进行缓存,减少查询负载(例如美国大选)
  • 减少分页数,靠后的那些分页可以直接舍弃不必存储

ES分布式搜索引擎的故事相关推荐

  1. ES分布式搜索引擎总结

    前言 业内目前来说事实上的一个标准,就是分布式搜索引擎一般大家都是用ElasticSearch,(原来的话使用的是Solr),但是确实,这两年大家一般都用更加易用的es. ElasticSearch ...

  2. es分布式搜索引擎在几十亿数据量级的场景下如何优化查询性能

    (1) 性能优化杀手锏--filesystem cache os cache,操作系统的缓存 你往es里写的数据,实际上都写到了磁盘文件里面去了,磁盘文件里面的数据操作系统会自动将里面的数据缓存到os ...

  3. ElasticSearch分布式搜索引擎——从入门到精通

    ES分布式搜索引擎 注意: 在没有创建库的时候搜索,ES会创建一个库并自动创建该字段并且设置为String类型也就是text 什么是elasticsearch? 一个开源的分布式搜索引擎,可以用来实现 ...

  4. 分布式搜索引擎01-elasticsearch-介绍、倒排索引原理、概念(文档和字段,索引和映射)、安装、索引库crud、文档crud、RestAPI(java代码实现es的crud)

    文章目录 分布式搜索引擎01 0.学习目标 1.初识elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 1.1.2.ELK技术栈 1.1.3.elasticse ...

  5. 倒排索引原理_拜托,面试请不要再问我分布式搜索引擎的架构原理!

    欢迎关注头条号:石杉的架构笔记 周一至周五早八点半!精品技术文章准时送上!!! 精品学习资料获取通道,参见文末 目录 (1)倒排索引到底是啥? (2)什么叫分布式搜索引擎? (3)ElasticSea ...

  6. es分布式结构原理是什么?

    elasticsearch设计的理念就是分布式搜索引擎,底层其实还是基于lucene的. 分布式 核心思想就是在多台机器上启动多个es进程实例,组成了一个es集群.es中存储数据的基本单位是索引,比如 ...

  7. elasticsearch(es)分布式全文检索引擎 简介

    0. 带着问题上路-ES是如何产生的? (1)思考:大规模数据如何检索? 如:当系统数据量上了10亿.100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题: 1)用什么数据库好?(MyS ...

  8. 0-6分布式搜索引擎02

    分布式搜索引擎02 在昨天的学习中,我们已经导入了大量数据到elasticsearch中,实现了elasticsearch的数据存储功能.但elasticsearch最擅长的还是搜索和数据分析. 所以 ...

  9. 微服务03 分布式搜索引擎 elasticsearch ELK kibana RestAPI 索引库 DSL查询 RestClient 黑马旅游

    分布式搜索引擎01 -- elasticsearch基础 0.学习目标 1.初识elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 elasticsearch是 ...

最新文章

  1. 源码分析shiro认证授权流程
  2. java调用jndi出错,无法使用Java JNDI上下文查找来访问对象
  3. 解决问题SyntaxError: Unexpected token import
  4. BlackBerry App之Hello World
  5. 基于Linux和MiniGUI的嵌入式系统软件开发指南(六)
  6. python自助电影售票机_Spring Cloud版——电影售票系统六使用 Spring Cloud Config 统一管理微服务配置...
  7. python壁纸数据抓取_python 多线程爬取壁纸网站的示例
  8. Spring 常见注解原理和自定义@interface注解
  9. 动易 转 html5,动易2005版系统默认风格及修改方法
  10. Jack Platts:Polkadot 在 Staking 上的设计
  11. android 固定比例图片裁剪插件,移动端添加图片裁剪的坑
  12. 【C++000】ASCII码转换公式(大小写转换)
  13. windows版微信多开
  14. 从一个技术人员角度来谈谈10000小时定律
  15. 用python生成excel文件_python通过openpyxl生成Excel文件的方法
  16. mvc 框架ember.js的简单介绍
  17. 【人物专访】FreeICQ的CTO龙云飞[1001]访谈
  18. Android Jetpack annotation
  19. mysql split 逗号分隔_mysql split函数用逗号分隔的实现
  20. Arcmap高级标注(通过表达式设置颜色/字体/换行等)

热门文章

  1. Python提示 TypeError: super(type, obj): obj must be an instance or subtype of type问题
  2. 通过二维码访问WEB程序
  3. EEG Artifacts
  4. 5分绩点转4分_意甲最新积分榜:AC米兰完胜5分领跑,那不勒斯4球横扫罗马
  5. 摘自林少波的《毕业5年决定你的一生》
  6. JMeter 测试组件介绍 - 物联网大并发测试实战 02
  7. map集合转实体对象集合
  8. 计算机机型及接口的选择,Intel系列电脑组装教程4:高端机型的选择,九代十代酷睿i9是首选...
  9. 37岁公司做到40亿美金,卖给马云!创业造车3年,公司上市,市值160亿美元!...
  10. 手把手教你从零搭建深度学习项目(可下载PDF版)