写在前面:因工作需要涉及ES,于是有了这篇笔记摘要。本笔记适合有一定ES基础但又不特别了解的程序员。在读此文章前,您需要有下面基础
- ES的安装
- head插件的使用
- 索引、类型、文档的概念
参考文章
- Elasticsearch权威指南
- Elasticsearch服务器开发(第2版)
##1. 集群与节点
一个集群可包括多个节点,如上图有3个节点,一个集群须有一个节点是主节点,图中Xorn(带星标的)为主节点。
启动一个节点后,它尝试寻找与它同集群名的主节点,找到则一起组成集群,没找到则自己成为主节点。
主节点(master)任务:处理请求,管理集群。新建或删除索引、增加或移除节点等。主节点不参与文档级别的变更或搜索,
我们访问的节点负责收集各节点返回的数据,最后一起返回给客户端。
当主节点与其它节点断开,则其它节点自动选择一个新的主节点。
将刚才的主节点服务器停掉,自动从其余2个节点选出主节点,Ringer。
2. 分片与副本
分片的概念与索引有关。我们知道
- 索引(index)相当于关系型数据库中的数据库.
- 类型(type)相当于表
- 文档(document)相等于一行数据
分片:有个问题是若索引的数据过大了,性能会有影响。所以将索引数据分成几份,每份就是一个分片。而将这些分片都放在同一个节点(服务器)上没有实际意义,性能还是上不去,所以将它们分散到各个节点(即整个集群中),当查询某些数据时,这些节点共同计算,算好了合起来再返回。这样多台节点(服务器)算比一台性能要好不少。这是分布式的意义,也是分片的原因所在。
另外还有一个概念是副本,就是分片的复制品。为了防止某个节点突然宕机导致数据丢失,加了分片的拷贝和分片一起分散在集群中。有了副本后,分片称为主分片。默认一个索引有5个分片,1个副本。 主分片负责所有的写操作,如新建、删除和更新,操作完成后再将结果同步到相应的副本上。
以上图posts索引为例。posts索引有5个分片。0,1,2,3,4代表这5个分片。分散在Korvus和Ringer这两个节点中。图中主节点用加粗的绿框表示。其余为副本。如Korvue节点中3、4分片为主分片,Ringer节点中0、1、2分片为主分片,其余为副本。
你也可以这样理解:索引数据太大,将索引分成了5份(分片),为防止丢失又对每份进行了备份(副本)。 这样一个索引就有了2套一样的数据,每套5份分散在集群中。
当索引创建完成的时候,主分片的数量就固定了,但是复制分片的数量可以随时调整。
设置分片及副本的请求
curl -XPUT localhost:9200/newnode?pretty -d ‘{“settings”:{“number_of_shards”:3,”number_of_replicas”:1}}’
新建一个索引,newnode,设置分片数为3,副本为1(意味着每个分片有一个副本)
图中用红笔标注的即是我们新建的索引,可以看到它与其他三个索引不太一样。因为它只有3个分片,一个副本,加起来就是6分分片的数据。这6分分散到了3个节点中。
3. 路由
路由也是ES中的重要概念。上节提到分片,现在的问题是,当索引(即新建)或检索一个文档,ES如何知道去哪个分片查数据?索引可是由多个分片组成,每个分片还分散到各个节点上,就如上图所见。
不难想到,要想定位到文档,当我们创建文档时,必定以某种规则放到哪个分片中,取的时候再以这种规则取才可以。
这种规则就是路由的定位,具体如下:
shard = hash(routing) % number_of_primary_shards
公式没有难度,计算出哪个shard就放到哪个shard中。其中的routing默认是该文档的主键_id。这也印证了创建的文档会随机分到某个分片中。不过,我们可以指定routing值,让文档放到固定的分片中。
PUT -XPUT localhost:9200/newnode/city/1?routing=beijing -d ‘{“area”:”chaoyang”}’
我们指定了路由值为beijing,并添加了一条数据。
查询时需指定路由值:
curl ‘localhost:9200/newnode/city/1?pretty&routing=beijing’
返回:1
2
3
4
5
6
7
8
9
10
11{
"_index" : "newnode",
"_type" : "city",
"_id" : "1",
"_version" : 1,
"_routing" : "beijing",
"found" : true,
"_source" : {
"area" : "chaoyang"
}
}
当查询时我们若不指定路由则会查不到,因为不指定则用文档的_id即1做路由,而我们创建时指定的路由是beijing。
4. 关于索引、查询过程
本节不是讲关于索引或查询的用法,而是其所经历的过程,只有了解了原理再学用法才游刃有余。
- 索引、删除操作属于写请求,需要在主分片操作。
一般来说,索引(新建)文档较为简单。以新建一个文档为例:
- 请求会发送到某一节点,该节点称为请求节点。
- 请求节点将请求转发到相应主分片所在节点,并在此分片完成创建文档工作。
- 主分片创建完成后,将请求分发至分片的副本
- 副本完成操作后,主分片给请求节点消息,请求节点再返回给客户端。
图片来自elasticsearch权威指南,侵删。
replication参数指定索引操作是同步或是异步,当值为sync(也是默认值)时,同步,即当主分片和副本都完成后才返回结果。若为async时,主分片完成后即返回,不等副本完成与否。
- 搜索过程主要分为两步:发散过程和收集过程
- 发散过程:请求节点将搜索请求分发给各相应分片以副本(同一份分片副本发送一份即可)。
- 收集过程 :每个分片完成自己搜索过程,并返回自己的结果给请求节点,请求节点再处理后返回结果给客户端。
这里涉及一个问题: 分页。默认查询10条数据,而在收集过程中,是每个分片都会返回自己的前10条数据,若有5个分片,在收集过程中时已有50条数据。然后请求节点再从这50条数据查询前10条返回。