ElasticSearch(5)------ElasticSearch原理
前言
在前面的博文中,我们一起在Kibana中对ElasticSearch中的查询文档的语法进行了了解,在本文中,我们来看一下ElasticSearch底层的一些容错原理,主备切换等.
正文
1. 分片,primary shard和replica shard
ElasticSearch是一个分布式的搜索引擎,在我们创建索引的时候,会自动的对一个index进行分片.我们不用关心数据是按照什么机制分片,存在那个分片中.
简单来说,1个index,如果在创建的时候指定了3个分片,也就是shard
,那么它的数据就会保存在这3个shard上.一个shard代表一个ES实例,也就是一个服务器,这三台服务器的数据加起来,才是一个index完整的数据.
在搜索的时候,ES内部会自动进行负载均衡,保证每个shard上的请求均匀.
如果是集群环境下,ES会指定一个master节点,该节点的职责是操作集群,如创建或者删除索引,跟踪集群的节点,分配哪些分片给对应的节点.
ES集群中的每个节点都可以接受请求,如果一个节点接受到了一个查询的请求,且在自己的shard中没有发现数据,那么它会把这个请求转发到有相关数据的其他节点上,之后将查询到的数据返回给该shard,然后返回给客户端.
在集群情况下,我们需要给每一个shard指定primary shard和replica shard,其中replica shard是前者的副本,作为高可用的实现来保证ES的容错率.
在创建索引的时候,primary shard的数量就已经确定,且不可改变了,而replica shard的数量是可以随时修改的.
基于ES集群自动发现的机制,我们需要对ES进行扩容的时候,只需要进行水平扩容或者垂直扩容即可,ES会自动发现我们增加的节点到集群中.
扩容方式有以下两种:
- 水平扩容: 增加服务器来增加ES的存储能力
- 垂直扩容: 更换旧的服务器为更高配置的新服务器,增加ES的能力.
2. ElasticSearch的容错机制
如果一个ES集群中有3台服务器,每台服务器上存在3个shard.分布如下图:
其中P1,P2,P3分别代表三个primary shard,R1,2,3分别代表对于的replica shard.
此时,如果master宕机了,那么ElasticSearch的容错处理过程如下:
- 选举一台服务器作为master
- 新选出的master会把挂掉的primary shard的某一个replica shard提升为primary shard,此时集群的状态是yellow
- 重启故障机,新的master会把所有的副本都复制一份到该节点上,且同步宕机以后的数据修改.
文档的核心元数据
在前面,我们查询出来的文档是下面这种格式的:
{
"_index" : "index3",
"_type" : "user",
"_id" : "1",
"_version" : 10,
"_seq_no" : 9,
"_primary_term" : 5,
"found" : true,
"_source" : {
"name" : "张三",
"gender" : true,
"age" : 30,
"birthday" : "1991-04-07",
"money" : 321.55
}
}
在这里有很多的字段,我们的文档信息都在_source
这个字段中,像_index
、_type
这种字段就属于文档的元数据.
_index
: 说明了一个文档存储在哪个索引中_type
: 表示文档属于索引的哪个类型_id
: 文档的唯一标识,可以手动通过POST方式指定,也可以通过PUT当时由ES生成._source
: 里面包含我们添加文档的信息,查询的时候可以根据该字段来指定返回结果中包含哪些字段.
分页查询中的deep paging问题
所谓deep paging就是深度查询,比如在多个primary shard上查询第100页的数据,每页显示10条.这种情况就是deep paging
这种深度查询,在查询的时候是这样的:
每个shard把0到999条数据全部搜索出来,然后返回给协调节点,协调节点将这些数据按照_score
分数排序,取出第100页的10条数据返回给客户端.
问题:
- 耗费网络带宽,如果搜索过深,在给协调节点传输数据的时候会很耗费带宽
- 消耗内存,查询出来的数据要被协调节点保存在内存中
- 消耗cpu,要对所有的查询结果进行排序,这个过程消耗cpu
在实际项目中应该尽量少使用深度查询.
总结
ElasticSearch的使用还是很简单的,使用Kibana,我们可以很方便的操作es中的数据,在下面的博文中,我们在我们的java中来使用ES.