假设现在我们有3个node,6个shard,则每个node上分配2个shard,此时最多容忍1台机器挂了,因为2台机器有4个shard,能存放下3个primary shard。此时如果我们进行水平扩容,将node变为6个,则每个node有1个shard,每个shard能使用的IO/CPU/Memory资源更多,性能会更好。 另外假设我们现在还是3个node,但是将shard变为9个,则每个node有3个shard,此时虽然每个shard使用的资源少了,但是容错性提高了,最多能容忍2个node故障,因为剩余的1个node还有3个shard,能包含所有数据。
index类似于mysql中的database,mysql中会将不同用途的数据放到不同的database中,es也一样,将同类的(fields基本相同)的document放到一起,这样带来的好处是不同index不会相互影响,因为不同index的shard是分类的,这就意味着彼此的shard操作不会影响。举个例子: 假设我们有一个book_index,存放了所有的书籍信息,供用户在线检索,另外还有一个需求是后台人员对book信息进行一些统计分析操作,由于这些操作都是非常耗时的,因此如果放在同一个index中,势必会影响线上浏览。
文档id的生成有两种方式:自动和手动。 手动的场景适合:假设数据来源是mysql系统,里面有自己的唯一id了,此时es只是辅助mysql进行一些检索操作,此时就用外部系统的id即可 自动:数据就是存在于es中,通过es的GUUID算法保证id的唯一,自动生成的id,长度为20个字符,URL安全,base64编码,GUID,分布式系统并行生成时不可能会发生冲突
source元字段的内容是在我们创建一个document的时候,使用的那个放在request body中的json串,默认情况下,在get的时候,会原封不动的给我们返回回来。 在我们查询的时候,如果带上_source参数,就可以定制返回的结果了。
1、document的全量替换
(1)语法与创建文档是一样的,如果document id不存在,那么就是创建;如果document id已经存在,那么就是全量替换操作,替换document的json串内容 (2)document是不可变的,如果要修改document的内容,第一种方式就是全量替换,直接对document重新建立索引,替换里面所有的内容 (3)es会将老的document标记为deleted,然后新增我们给定的一个document,当我们创建越来越多的document的时候,es会在适当的时机在后台自动删除标记为deleted的document
2、document的强制创建
(1)创建文档与全量替换的语法是一样的,有时我们只是想新建文档,不想替换文档,如果强制进行创建呢? (2)PUT /index/type/id?op_type=create,PUT /index/type/id/_create
3、document的删除
(1)DELETE /index/type/id (2)不会理解物理删除,只会将其标记为deleted,当数据越来越多的时候,在后台自动删除 (3)当我们删除完一个document后,再次PUT新建的时候,会在原来deleteverion基础上再加一
es通过version来进行乐观锁控制,语法是通过在参数version实现
?version=1
?version=1&version_type=external
version_type=external,唯一的区别在于,_version,只有当你提供的version与es中的_version一模一样的时候,才可以进行修改,只要不一样,就报错;当version_type=external的时候,只有当你提供的version比es中的_version大的时候,才能完成修改
es,_version=1,?version=1,才能更新成功 es,_version=1,?version>1&version_type=external,才能成功,比如说?version=2&version_type=external
partial update不需要传递整个json对象,而是只需要修改的filed,但是在服务端执行partial update的时候,其实和PUT还是一样的,都是先去读document,更新字段后,将老的document标记为删除,然后创建一个新的document,与全量update不同的是将get。modify。update操作放在了服务端,这样子减少了网络开销,提高性能。
partial update的时候是在server进行了乐观锁控制,1. 取到version 2.修改后更新,我们可以通过指定retry来声明重复1,2步骤的次数。