ES-2 索引

一、读写原理

(一)简介

Elasticsearch中的每个索引都分为分片 ,每个分片可以有多个副本。这些副本称为复制组,在添加或删除文档时必须保持同步。如果我们不这样做,从一个副本中读取将导致与从另一个副本中读取的结果截然不同的结果。保持碎片副本同步并从中提供读取的过程就是我们所说的数据复制模型。

Elasticsearch的数据复制模型基于主-备份模型,并在Pacific Research的Microsoft Research 论文中得到了很好的描述 。该模型基于具有来自复制组的单个副本,该副本充当主要分片。其他副本称为副本分片。主要作为所有索引操作的主要入口点。它负责验证它们并确保它们是正确的。一旦主要接受了索引操作,主要负责将操作复制到其他副本。

(二)基本写模型

Elasticsearch中的每个索引操作首先使用路由解析为复制组,通常基于文档ID。确定复制组后,操作将在内部转发到组的当前主分片。主分片负责验证操作并将其转发到其他副本。由于副本可以脱机,因此不需要将主副本复制到所有副本。相反,Elasticsearch维护了一个应该接收操作的分片副本列表。此列表称为 同步副本表 并由主节点维护。也就是说,还保存了一个已经操作过的列表,保证已经处理了已经向用户确认的所有索引和删除操作。主要负责维护此不变量,因此必须将所有操作复制到此集合中的每个副本。

主分片遵循以下基本流程:

  • 验证传入操作并在结构无效时拒绝它(例如:有一个对象字段,其中包含一个数字)
  • 在本地执行操作,即索引或删除相关文档。这也将验证字段的内容并在需要时拒绝(例如:关键字值太长,无法在Lucene中进行索引)。
  • 将操作转发到当前同步副本集中的每个副本。如果有多个副本,则这是并行完成的。
  • 一旦所有副本成功执行了操作并响应主服务器,主服务器就会确认成功完成对客户端的请求。

故障处理

在索引处理过程中可能会出现许多问题 - 磁盘可能会损坏,节点可能会相互断开连接,或者某些配置错误可能会导致复制副本上的操作失败,尽管它在主服务器上成功。这些很少见,但主要必须回应它们。

当主分片发生故障的时候,托管主分片的节点会向主服务器发送关于他的情况,这个时候索引操作会进行一定时间的等待(默认是1分钟)才进行操作,等待是为了让主服务器从其他的副本的分片中选出一个主分片。随后的操作会通过新的主分片进行执行。注意的是,主服务器也会监控各个分片的健康状态,可能主动把一个主分片转换成非主分片(比如:当存放主分片的节点发生网络故障的时候,就会做这种处理)。

一旦主分片上操作成功之后,主分片就必须要去解决复制副本的时候可能发生的潜在故障,这种错误通常可能发生在网络故障或者响应故障上,所有的这些副本节点共享一个同步副本集,如果处理副本失败的话,存放主分片的节点会向主节点发送消息请求主节点将故障节点从同步副本集中移除,如果主节点成功从同步副本集移除,那么操作就成功了。注意的是,主节点也会重新寻找一个节点来创建副本分片,从而来修复整个复制组的健康状况。

当主分片向副本分片转发操作请求的时候,副本分片会检查这个主分片是否还是活跃的主分片,如果发现这个分片是由于网络故障或者long - GC而被隔离,那么副本分片会认为主分片还没有意识到自己被降级了,于是就会拒绝操作,主分片收到这个响应之后,就会去请求主节点,发现自己已经被降级了,就会把请求路由到新的主分片。

当没有副本分片的时候,主分片的操作就没法被副本分片进行验证了,这样的话,主分片就不会通过副本分片的响应发现自己是过期的主分片了,也就是说,这样的话,主节点就知道这个主分片是唯一一个好的分片了,这样的话,主节点就不会把主分片进行降价处理而去寻找别的节点作为主分片了。

(三)基本读模型

Elasticsearch中的读取可以是ID非常轻量级的查找,也可以是具有复杂聚合的大量搜索请求,这些聚合会消耗非常多的CPU性能。主备份模型的一个优点是它使所有分片副本保持一致(除了正在进行的操作)。因此,单个同步副本足以提供读取请求。
当节点收到读取请求时,该节点负责将其转发到保存相关分片的节点,整理响应并响应客户端。我们将该节点称为该请求的协调节点。基本流程如下:

  • 将读取请求解析为相关分片。请注意,由于大多数搜索将被发送到一个或多个索引,因此它们通常需要从多个分片中读取,每个分片代表数据的不同子集。
  • 从分片复制组中选择每个相关分片的活动副本。这可以是主分片或副本分片。默认情况下,Elasticsearch将简单地在分片副本之间循环。
  • 将分片级读取请求发送到所选副本。
  • 结合结果并做出回应。请注意,在通过ID查找的情况下,一旦一个分片读取到了,后续就会跳过。

分片读取失败

当一个分片响应失败的时候,协调节点会把请求发送给同一个复制组的其他分片,重复失败可能导致没有可用的分片。
为了保证快速的响应,下面这些操作可能会在部门分片失败的时候返回部分结果:

  • Search
  • Multi Search
  • Bulk
  • Multi Get

结果的响应仍提供200 OK HTTP状态代码。分片失败由响应头的timed_out和_shards字段进行标志。

二、索引操作

(一)显示所有的索引

curl -X GET "localhost:9200/_cat/indices?v"

health status index uuid pri rep docs.count docs.deleted store.size pri.store.size

刚安装的时候,没有任何索引。

(二)创建索引

1. 显示创建

①. 创建一个索引customer
curl -X PUT "localhost:9200/customer?pretty"
②. 再次查看所有索引
curl -X GET "localhost:9200/_cat/indices?v"

health status index    uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   customer BjeAF7BbRYaMQAK7VX_yqA   1   1          0            0       230b           230b

会发现,有一个索引,名字叫做customer,这个索引有1个分片,1个副本,但是没有任何文档。
另外,索引标记了黄色运行状况。回想一下我们之前的讨论,黄色表示某些副本尚未(尚未)分配。此索引发生这种情况的原因是因为默认情况下Elasticsearch为此索引创建了一个副本。由于我们目前只有一个节点在运行,因此在另一个节点加入集群的稍后时间点之前,尚无法分配一个副本(用于高可用性)。将该副本分配到第二个节点后,此索引的运行状况将变为绿色。

2. 自动创建索引

添加文档的时候,如果指定的索引不存在,那么就会自动创建索引。
自动创建的所以是通过模板来处理格式的。同时,是否自动创建索引受action.auto_create_index控制。
action.auto_create_index有以下几种设置方式:

  • 指明可以自动创建的索引名
    这种方式可以使用通配符:
    1. "+"表示要创建索引的名字
    2. "-"表示要禁止创建索引的名字
    3. "*"匹配0个或者多个字符
      如:
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
    "persistent": {
        "action.auto_create_index": "stus,teachers,-noidex_*,+idx_*" 
    }
}
'

这表明:stus,teachers或者是能匹配idx_的索引名会被自动创建索引;而-noidex_表示以noidex_开头的不会创建索引,一般情况下,+和-不会在同一个设置中使用,

  1. 完全禁止自动创建索引
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
    "persistent": {
        "action.auto_create_index": "false" 
    }
}
'

设置后,往不存在的索引中插入文档会报错
3. 完全允许创建索引

curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
    "persistent": {
        "action.auto_create_index": "true" 
    }
}
'

设置之后,就可以完全自动创建索引,默认情况就是这种。

3. 使用op_type

我们可以通过op_type=create来要求自动创建索引,那么如果索引已经存在,会抛出错误,如果不存在且满足action.auto_create_index设置,就会帮我们创建索引。
这有两种写法:

  • 显示的指明
curl -X PUT "localhost:9200/twitter/_create/1" -H 'Content-Type: application/json' -d'
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}
'
  • 直接在路径里面
curl -X PUT "localhost:9200/twitter/_doc/1?op_type=create" -H 'Content-Type: application/json' -d'
{
    "user" : "kimchy",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}
'

(三)删除索引

curl -X DELETE "localhost:9200/customer?pretty"

(四)路由

添加的文档会被放到哪个分片上,满足以下规则:
shard = hash(routing) % number_of_primary_shards
默认情况下,会使用id进行hash来获取。
我们也可以进行指定,

curl -X POST "localhost:9200/idx_test/_doc?routing=aaa&pretty" -H 'Content-Type: application/json' -d'
{
    "user" : "zhangsan",
    "post_date" : "2009-11-15T14:12:12",
    "message" : "trying out Elasticsearch"
}
'

那么,这个文档就会通过路由值aaa进行路由。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值