一、基本概念
ElasticSearch是一个可扩展的开源搜索引擎,并可以存储数据,它是面向Nosql的数据库,使用json作为文档的序列化格式,半结构化的数据是通常是变化的,因此在索引一个文档的时候不必提前定义好索引和类型,与mysql有如下图所示的对比。
二、倒排索引的原理
es是在lucense上做了进一步的封装,将文档采用分词器切分成词,建立词与文档的映射,采用倒排索引进行搜索。倒排索引的基本结构如下所示:
那么倒排索引如何建立的呢?现有如下图2-1所示文档集合,分词器会将文档切分成一系列的单词集合,单词同文档一样有个唯一标识id,那么需要数据结构记录某个单词出现在哪些文档,出现了多少次,也就是词频(这个用于做相似性计算,展示给用户结果排序使用),也可以记录在文档中出现的位置。这就转化为了如图2-2所示的对应关系。
图2-2
比如当搜索“加盟”单词时,会搜索到编号为2、3、5的文档,单词在该文档中出现过一次。
三、分片与集群
我们索引的文档是存储在分片上的,分片(Shard),是Elasticsearch中的最小存储单元。默认情况下,Elasticsearch会为每个索引分配5个分片,这些分片是主分片,一旦确定,在后期水平扩展时,也只是增加副本分片的数量,所以确定主分片应该考虑周全,根据索引下的数据量以及后期数据的增长情况考虑。在扩大集群规模时,副本分片可以做冗余备份,可以响应客户端请求,从而提高性能。但是如果机器数量一定的情况下并不是分片越多越好,因为这样的话其他分片所占用的cpu以及硬件资源等会响应减少。那如果知道索引是放在分片1还是分片2呢?是通过如下公式进行计算,其中routing是文档的id.
shard = hash(routing) % number_of_primary_shards
一个索引可以存储在多个分片,分片可以分布在集群的不同节点上,elasticsearch集群环境不是靠zookeeper进行协调的,当一个节点被选举成为主节点时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。任何节点都可以成为主节点。作为用户,我们可以将请求发送到 集群中的任何节点,包括主节点。每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。可能由于通信问题,主节点没有响应,其他节点认为主节点挂掉,会重新选举主节点,可能会出现多个主节点的现象,称之为脑裂现象。
如何避免脑裂,通常有以下方法
1、设置参数discovery.zen.minimum_master_nodes 为n/2+1,即过半选举
2、discovery.zen.ping.timeout可以设置的大一些,不是说一旦通信失败立马认为节点挂掉,可以延迟认为挂掉的时间