当先锋百科网

首页 1 2 3 4 5 6 7

ES的核心概念

十万个为什么

什么是ES

Elasticsearch是一个基于Lucene库的搜索引擎。它提供了一个分布式、支持多租户的全文搜索引擎,具有HTTP Web接口和无模式JSON文档。Elasticsearch是用Java开发的,并在Apache许可证下作为开源软件发布。官方客户端在Java.NETC#)、PHPPythonApache GroovyRuby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。

Elasticsearch是与名为Logstash的数据收集和日志解析引擎以及名为Kibana的分析和可视化平台一起开发。这三个产品被设计成一个集成解决方案,称为“Elastic Stack”(以前称为“ELK stack”)。

为什么要使用ES

  • 数据库模糊查询是全表扫描,时间慢,性能耗费大。
  • 数据库模糊查询无法无法查询关键字中间被隔开的情况,无法满足搜索需求。

什么是全文检索

全文检索主要来说的话就是倒排索引的应用,对于数据库模糊查询而言,以name字段为例,数据库要对整个表进行全表扫描,而如果根据name分词建立了倒排索引,就可以对倒排索引的词条进行扫描,可能很快就能找到该数据。

比如数据库100w行,模糊查询必然扫描100w次。而name分词之后可能有1000w个词,但是不需要整个扫描完,可能10w次就解决了。

并且数据库的模糊查询要对每一行中的数据进行模糊匹配,如果该数据字节数很多的话,会更加损耗性能,而分词只需要比较一下是否相等就可以了。

或许你会想到扫描1000w次这种极端情况,这个Lucene的倒排索引算法会对该情况有处理,后面再介绍。

什么是正排索引

正排索引是指,当要找内容包含一个字符串的文件时,对逐个文件依次进行查找,从头查到尾,一直扫描完所有的文件位置。

  • 优点:查找准确率高
  • 缺点:查询速度慢(在数据量大的情况下)

典型的正排索引有MySQL中的like关键字搜索、编辑器中的ctrl+f搜索都是正排索引。

什么是倒排索引

举个例子:在字典中,会以偏旁为部首建立一个目录,我们会先查找这个目录,根据这个目录在找到对应的内容。这个目录就类似于倒排索引,根据目录找到的内容就是文档。

倒排索引是根据属性来确定文档的位置,而不是根据记录来确定属性。

如果给定如下数据源:

文档id文档内容
0it is what it is
1what is it
2it is a banana

则Lucene可以根据该文档(数据源)创建出类似于这样的数据结构:

"a":      {(2, 2)}
"banana": {(2, 3)}
"is":     {(0, 1), (0, 4), (1, 1), (2, 1)}
"it":     {(0, 0), (0, 3), (1, 2), (2, 0)} 
"what":   {(0, 2), (1, 0)}

这就是倒排索引,它包含着该属性的文档id、位置(position)与词频。

对于“a”,它的文档id是2,位置是2,词频是1;对于“is”,文档id分别是0、1、2,位置分别是1、4、1、1,词频是4。

如果我们执行短语搜索"what is it" 我们得到这个短语的全部单词各自的结果所在文档为文档0和文档1。但是这个短语检索的连续的条件仅仅在文档1得到。

什么是Lucene

Lucene就是一个jar包,里面包含了封装好的各种建立倒排索引和进行搜索的api。

用Lucene我们可以通过已有的数据(数据源)去建立索引,Lucene会在本地磁盘中帮助我们组织索引的数据结构(就是在本地存储索引库),然后我们就可以用Lucene提供的api对磁盘中的索引库中的数据进行搜索。

为什么有了Lucene还要有ES

Lucene不支持分布式存储与检索,只能在单台服务器上使用。

如果使用Lucene,在数据量很大的情况下,超过了单台机器的承受范围,就必须用多台机器进行数据的存储和搜索,如果我们自己来实现,会很麻烦:

  1. 如何高性能的建立索引、执行搜索很麻烦
  2. 跟多台机器通信的过程,很麻烦
  3. 保证原生Lucene分布式系统的高可用性很麻烦

总之就是很麻烦。

而如果使用es:

  1. 自动维护数据分布到多个节点的索引建立,以及搜索请求到各个节点的执行
  2. 保证分布式系统高可用性
  3. 封装了更多高级功能:复杂搜索功能、聚合分析功能、基于地理位置的搜索(距离我当前位置xxx公里内的烤肉店)

ES与Lucene该如何选择

如果是单服务器,且服务器的内存不高,并且应用数据量较小,则可以直接使用Lucene去建立倒排索引并使用它的API,因为ES相对而言会比较占用内存。

ES核心概念

  • 字段 Field

    相当于mysql中的字段。

  • 文档 Document

    一个document相当于mysql中的记录。

    {
        "id": "1",
        "name": "高渐离"
    }
    

    如上就是一个document,而id就是field。

    +----+-------+
    | id |  name |
    +----+--------
    |  1 | 高渐离 |
    +----+-------+
    
  • 类型 Type

    一个Type中可以存储多个Document,相当于mysql中的表。

    在Elasticsearch 7.X之后的版本,type被弃用了。

  • 索引 Index

    一个Index中可以存储多个Type,相当于mysql中的库。

  • 映射 mapping

    相当于数据库中表结构的定义。

    +----------+--------------+------+-----+---------+----------------+
    | Field    | Type         | Null | Key | Default | Extra          |
    +----------+--------------+------+-----+---------+----------------+
    | id       | int(11)      | NO   | PRI | NULL    | auto_increment |
    | name     | varchar(30)  | YES  |     | NULL    |                |
    +----------+--------------+------+-----+---------+----------------+
    
  • 近实时 Near Realtime(NRT)

    近实时,一方面是指从写入数据到数据可被检索有一个小延迟(1s),另一方面是指ES执行检索和分析是秒级的。

    比如Github使用的搜索引擎就是ES,当我们创建一个仓库之后是可以近实时的被检索到的。

  • 集群 Cluster

    集群包含多个节点,每个节点属于哪个集群通过配置来决定,对于中小型项目,刚开始集群就一个节点是很正常的。

  • 节点 Node

    每一个启动的ES进程就是一个节点。

    集群中的节点可以配置自己的名称,节点的名称在运维的时候很重要,如果没有配置则随机分配。

    节点默认会加入名为elasticsearch的集群,如果直接启动一堆节点,则它们自动组成一个名为Elasticsearch的集群,当然一个节点也会组成名为Elasticsearch的集群。

  • 分片 Shard

    单台机器可能无法存储过大的数据,当数据量过大时,ES可以将一个Index中的数据切分为多个Shard,分布在多台服务器上存储。而Index实际上是指向一个或者多个物理分片的逻辑命名空间。

    有了Shard就可以横向存储,更为方便的存储更多数据、并且让检索与分析分布到不同的服务器上去执行,提高吞吐量和性能,每个Shard都是一个Lucene的实例,并且其本身就是一个完整的搜索引擎。但是应用程序是直接与索引而不是分片进行交互的。

    横向存储是指,比如此时有3T数据,而一个节点最多只能存储1T,这时Index就会被拆分为多个Shard,每个Shard存储这个Index的一部分数据,这些Shard散落在多台服务器上,而如果此时又增加了4T数据,此时很简单,只需要重新建立一个新的Index,并将其拆为4个Shard即可。

    单台机器也可以存储多个Shard

  • 副本 Replica

    服务器可能会宕机,此时Shard就会丢失,因此可以为每个Shard创建多个Replica副本。

    Replica可以在Shard故障时提供备用服务,并且提升检索的吞吐量。

    Replica与Shard不能位于同一个节点上。

Elasticsearch在默认情况下会给每个Index分配5个Shard和1个Replica,但是Shard和Replica不能再同一台机器上,所以当启动Elasticsearch单个进程时,Replica副本是无法正常创建的。

所以在后面我们用kibana(postman\浏览器\elasticsearch-head等皆可)请求Elasticsearch的API查看集群状态时会发现ES的状态是Yellow(不健康的)。