Elasticsearch ES索引

ES是一个基于RESTful web接口而且构建在Apache Lucene之上的开源分布式搜索引擎。
同时ES仍是一个分布式文档数据库,其中每一个字段都可被索引,并且每一个字段的数据都可被搜索,可以横向扩展至数以百计的服务器存储以及处理PB级的数据。
能够在极短的时间内存储、搜索和分析大量的数据。一般做为具备复杂搜索场景状况下的核心发动机。
ES就是为高可用和可扩展而生的。一方面能够经过升级硬件来完成系统扩展,称为垂直或向上扩展(Vertical Scale/Scaling Up)。
另外一方面,增长更多的服务器来完成系统扩展,称为水平扩展或者向外扩展(Horizontal Scale/Scaling Out)。尽管ES可以利用更强劲的硬件,可是垂直扩展毕竟仍是有它的极限。真正的可扩展性来自于水平扩展,经过向集群中添加更多的节点来分担负载,增长可靠性。ES天生就是分布式的,它知道如何管理多个节点来完成扩展和实现高可用性。意味应用不须要作任何的改动。
 
Gateway,表明ES索引的持久化存储方式。在Gateway中,ES默认先把索引存储在内存中,而后当内存满的时候,再持久化到Gateway里。当ES集群关闭或重启的时候,它就会从Gateway里去读取索引数据。好比LocalFileSystem和HDFS、AS3等。
DistributedLucene Directory,它是Lucene里的一些列索引文件组成的目录。它负责管理这些索引文件。包括数据的读取、写入,以及索引的添加和合并等。
River,表明是数据源。是以插件的形式存在于ES中。 
Mapping,映射的意思,很是相似于静态语言中的数据类型。好比咱们声明一个int类型的变量,那之后这个变量只能存储int类型的数据。好比咱们声明一个double类型的mapping字段,则只能存储double类型的数据。
Mapping不只是告诉ES,哪一个字段是哪一种类型。还能告诉ES如何来索引数据,以及数据是否被索引到等。
Search Moudle,搜索模块,支持搜索的一些经常使用操做
Index Moudle,索引模块,支持索引的一些经常使用操做
Disvcovery,主要是负责集群的master节点发现。好比某个节点忽然离开或进来的状况,进行一个分片从新分片等。这里有个发现机制。
发现机制默认的实现方式是单播和多播的形式,即Zen,同时也支持点对点的实现。另一种是以插件的形式,即EC2。
Scripting,即脚本语言。包括不少,这里很少赘述。如mvel、js、python等。   
Transport,表明ES内部节点,表明跟集群的客户端交互。包括 Thrift、Memcached、Http等协议
RESTful Style API,经过RESTful方式来实现API编程。
3rd plugins,表明第三方插件。
Java(Netty),是开发框架。
JMX,是监控。
使用案例
一、将ES做为网站的主要后端系统
好比如今搭建一个博客系统,对于博客帖子的数据能够直接在ES上存储,而且使用ES来进行检索,统计。ES提供了持久化的存储、统计和不少其余数据存储的特性。
注意:可是像其余的NOSQL数据存储同样,ES是不支持事务的,若是要事务机制,仍是考虑使用其余的数据库作真实库。
 
二、将ES添加到现有系统
有些时候不须要ES提供全部数据的存储功能,只是想在一个数据存储的基础之上使用ES。好比已经有一个复杂的系统在运行,可是如今想加一个搜索的功能,就可使用该方案。
 
三、将ES做为现有解决方案的后端部分
由于ES是开源的系统,提供了直接的HTTP接口,而且如今有一个大型的生态系统在支持他。好比如今咱们想部署大规模的日志框架、用于存储、搜索和分析海量的事件,考虑到现有的工具能够写入和读取ES,能够不须要进行任何开发,配置这些工具就能够去运做。
 
设计结构
一、逻辑设计
文档
文档是能够被索引的信息的基本单位,它包含几个重要的属性:
是自我包含的。一篇文档同时包含字段和他们的取值。
是层次型的。文档中还能够包含新的文档,一个字段的取值能够是简单的,例如location字段的取值能够是字符串,还能够包含其余字段和取值,好比能够同时包含城市和街道地址。
拥有灵活的结构。文档不依赖于预先定义的模式。也就是说并不是全部的文档都须要拥有相同的字段,并不受限于同一个模式
{
  "name":"meeting",
  "location":"office",
  "organizer":"yanping"
}
{
  "name":"meeting",
  "location":{
    "name":"sheshouzuo",
       "date":"2019-6-28"
  },
  "memebers":["leio","shiyi"]
}
类型
类型是文档的逻辑容器,相似于表格是行的容器。在不一样的类型中,最好放入不一样的结构的文档。
字段
ES中,每一个文档,实际上是以json形式存储的。而一个文档能够被视为多个字段的集合。
映射
每一个类型中字段的定义称为映射。例如,name字段映射为String。
索引
索引是映射类型的容器一个ES的索引很是像关系型世界中的数据库,是独立的大量文档集合。
 
关系型数据库与ES的结构上的对比
 
 
二、物理设计
节点
一个节点是一个ES的实例,在服务器上启动ES以后,就拥有了一个节点,若是在另外一个服务器上启动ES,这就是另外一个节点。甚至能够在一台服务器上启动多个ES进程,在一台服务器上拥有多个节点。多个节点能够加入同一个集群。
当ElasticSearch的节点启动后,它会利用多播(multicast)(或者单播,若是用户更改了配置)寻找集群中的其它节点,并与之创建链接。这个过程以下图所示:
 
节点主要有3种类型,第一种类型是client_node,主要是起到请求分发的做用,相似路由。第二种类型是master_node,是主的节点,全部的新增,删除,数据分片都是由主节点操做(elasticsearch底层是没有更新数据操做的,上层对外提供的更新其实是删除了再新增),固然也能承担搜索操做。第三种类型是date_node,该类型的节点只能作搜索操做,具体会分配到哪一个date_node,就是由client_node决定,而data_node的数据都是从master_node同步过来的
分片
一个索引能够存储超出单个结点硬件限制的大量数据。好比,一个具备10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。
 
为了解决这个问题,ES提供了将索引划分红多份的能力,这些份就叫作分片。当你建立一个索引的时候,你能够指定你想要的分片的数量。每一个分片自己也是一个功能完善而且独立的“索引”,这个“索引”能够被放置到集群中的任何节点上。
分片之因此重要,主要有两方面的缘由:
 
一、容许你水平分割/扩展你的内容容量
容许你在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操做,进而提升性能/吞吐量
至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是彻底由ES管理的,对于做为用户的你来讲,这些都是透明的。
 
二、在一个网络/云的环境里,失败随时均可能发生,在某个分片/节点不知怎么的就处于离线状态,或者因为任何缘由消失了。这种状况下,有一个故障转移机制是很是有用而且是强烈推荐的。为此目的,ES容许你建立分片的一份或多份拷贝,这些拷贝叫作复制分片,或者直接叫复制。
复制之因此重要,主要有两方面的缘由:
(1)在分片/节点失败的状况下,提供了高可用性。由于这个缘由,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是很是重要的。
(2)扩展你的搜索量/吞吐量,由于搜索能够在全部的复制上并行运行
总之,每一个索引能够被分红多个分片。一个索引也能够被复制0次(意思是没有复制)或屡次。一旦复制了,每一个索引就有了主分片(做为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量能够在索引建立的时候指定。在索引建立以后,你能够在任什么时候候动态地改变复制数量,可是不能改变分片的数量。
 
默认状况下,ES中的每一个索引被分片5个主分片和1个复制,这意味着,若是你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个彻底拷贝),这样的话每一个索引总共就有10个分片。一个索引的多个分片能够存放在集群中的一台主机上,也能够存放在多台主机上,这取决于你的集群机器数量。主分片和复制分片的具体位置是由ES内在的策略所决定的。
三、插件HEAD
elasticsearch-head是一个界面化的集群操做和管理工具
 
● node:即一个 Elasticsearch 的运行实例,使用多播或单播方式发现 cluster 并加入。
● cluster:包含一个或多个拥有相同集群名称的 node,其中包含一个master node。
● index:类比关系型数据库里的DB,是一个逻辑命名空间。
● alias:能够给 index 添加零个或多个alias,经过 alias 使用index 和根据index name 访问index同样,可是,alias给咱们提供了一种切换index的能力,好比重建了index,取名● customer_online_v2,这时,有了alias,我要访问新 index,只须要把 alias 添加到新 index 便可,并把alias从旧的 index 删除。不用修改代码。
● type:类比关系数据库里的Table。其中,一个index能够定义多个type,但通常使用习惯仅配一个type。
● mapping:类比关系型数据库中的 schema 概念,mapping 定义了 index 中的 type。mapping 能够显示的定义,也能够在 document 被索引时自动生成,若是有新的 field,Elasticsearch 会自动推测出 field 的type并加到mapping中。
● document:类比关系数据库里的一行记录(record),document 是 Elasticsearch 里的一个 JSON 对象,包括零个或多个field。
● field:类比关系数据库里的field,每一个field 都有本身的字段类型。
● shard:是一个Lucene 实例。Elasticsearch 基于 Lucene,shard 是一个 Lucene 实例,被 Elasticsearch 自动管理。以前提到,index 是一个逻辑命名空间,shard 是具体的物理概念,建索引、查询等都是具体的shard在工做。shard 包括primary shard 和 replica shard,写数据时,先写到primary shard,而后,同步到replica shard,查询时,primary 和 replica 充当相同的做用。replica shard 能够有多份,也能够没有,replica shard的存在有两个做用,一是容灾,若是primary shard 挂了,数据也不会丢失,集群仍然能正常工做;二是提升性能,由于replica 和 primary shard 都能处理查询。另外,如上图右侧红框所示,shard数和replica数均可以设置,可是,shard 数只能在创建index 时设置,后期不能更改,可是,replica 数能够随时更改。可是,因为 Elasticsearch 很友好的封装了这部分,在使用Elasticsearch 的过程当中,咱们通常仅须要关注 index 便可,不需关注shard。
 
shard、node、cluster 在物理上构成了 Elasticsearch 集群,field、type、index 在逻辑上构成一个index的基本概念,在使用 Elasticsearch 过程当中,咱们通常关注到逻辑概念就好,就像咱们在使用MySQL 时,咱们通常就关注DB Name、Table和schema便可,而不会关注DBA维护了几个MySQL实例、master 和 slave 等怎么部署的同样。
ES中的索引原理
(1)传统的关系型数据库
二叉树查找效率是logN,同时插入新的节点没必要移动所有节点,因此用树型结构存储索引,能同时兼顾插入和查询的性能。所以在这个基础上,再结合磁盘的读取特性(顺序读/随机读),传统关系型数据库采用了B-Tree/B+Tree这样的数据结构作索引
(2)ES
采用倒排索引
那么,倒排索引是个什么样子呢?
 
首先,来搞清楚几个概念,为此,举个例子:
假设有个user索引,它有四个字段:分别是name,gender,age,address。画出来的话,大概是下面这个样子,跟关系型数据库同样
 
Term(单词):一段文本通过分析器分析之后就会输出一串单词,这一个一个的就叫作Term
Term Dictionary(单词字典):顾名思义,它里面维护的是Term,能够理解为Term的集合
Term Index(单词索引):为了更快的找到某个单词,咱们为单词创建索引
Posting List(倒排列表):倒排列表记录了出现过某个单词的全部文档的文档列表及单词在该文档中出现的位置信息,每条记录称为一个倒排项(Posting)。根据倒排列表,便可获知哪些文档包含某个单词。(PS:实际的倒排列表中并不仅是存了文档ID这么简单,还有一些其它的信息,好比:词频(Term出现的次数)、偏移量(offset)等,能够想象成是Python中的元组,或者Java中的对象)
(PS:若是类比现代汉语词典的话,那么Term就至关于词语,Term Dictionary至关于汉语词典自己,Term Index至关于词典的目录索引)
咱们知道,每一个文档都有一个ID,若是插入的时候没有指定的话,Elasticsearch会自动生成一个,所以ID字段就很少说了
上面的例子,Elasticsearch创建的索引大体以下:
name字段:
 
age字段:
 
gender字段:
 
address字段:
 
Elasticsearch分别为每一个字段都创建了一个倒排索引。好比,在上面“张三”、“北京市”、22 这些都是Term,而[1,3]就是Posting List。Posting list就是一个数组,存储了全部符合某个Term的文档ID。
只要知道文档ID,就能快速找到文档。但是,要怎样经过咱们给定的关键词快速找到这个Term呢?
固然是建索引了,为Terms创建索引,最好的就是B-Tree索引(MySQL就是B树索引最好的例子)。
咱们查找Term的过程跟在MyISAM中记录ID的过程大体是同样的
MyISAM中,索引和数据是分开,经过索引能够找到记录的地址,进而能够找到这条记录
在倒排索引中,经过Term索引能够找到Term在Term Dictionary中的位置,进而找到Posting List,有了倒排列表就能够根据ID找到文档了
(PS:能够这样理解,类比MyISAM的话,Term Index至关于索引文件,Term Dictionary至关于数据文件)
(PS:其实,前面咱们分了三步,咱们能够把Term Index和Term Dictionary当作一步,就是找Term。所以,能够这样理解倒排索引:经过单词找到对应的倒排列表,根据倒排列表中的倒排项进而能够找到文档记录)
为了更进一步理解,用两张图来具现化这一过程:
 https://blog.csdn.net/zhenwei1994/article/details/94013059
相关文章
相关标签/搜索