##cluster
-
一个集群包含多个具有相同集群名(cluster.name)的节点(node),加减节点,集群都会重新均匀分配数据到每个节点。
-
集群会选举一个master节点,负责管理集群,比如增删index、加减节点;master无需负责文档级别的更新和搜索;每个节点都可以成为master。 客户端可以请求任意一个节点,包括master;每个节点都知道文档的具体位置以及可以把请求指向给拥有文档的节点;被请求的节点负责响应请求。
-
GET /_cluster/health
- green:所有主分片和副本分片正常。
- yellow:所有主分片正常,但不是所有副本分片正常。
- red:不是所有主分片正常。
- 副本分片是主分片的拷贝,用于容灾和提供文档读请求服务。
- 一个index的主分片数在index建立时确定的,不能修改,但是副本分片数可以在任何时候修改,也就是说,一个index的数据存储量一开始就确定了(不考虑节点本身硬件扩展),但是主分片和副本分片都可以提供读请求服务比如文档搜索,因此后期增加节点,虽然不能增加数据存储量,但可以增加搜索的吞吐量。
一个新的index会先存储到主分片,然后并行地复制到副本分片。
- 如果master节点挂了,集群会先选举一个节点作为新的master,新的master会立刻把对应挂了的主分片的副本分片升级为主分片,这个升级是瞬间完成的。如果把旧的master重新启动,集群会把副本分片分配给旧master,如果旧master还保留挂了时的分片,那么集群仅仅复制旧master挂了的那段时间内主分片的变更到旧master。
- document metadata
_index:小写,不能以下划线开始,不能包含逗号。
_type:大小写,不能以下划线开始,不能包含逗号。
_id:_index、_type、_id三者联合全局唯一,标识一个document。
##indexing
- 指定_id
PUT /index/type/id { "field":"value" }
不指定_id,es会自动生成,自动生成的_id是22位长,url-safe,Base64-encoded的UUID
POST /index/type/ { "field":"value" }
- ?pretty 参数会让返回美化的JSON,但是_source不会美化,原样返回。
##updating
document是不能更改的,如果要修改,只能替换整个document(reindex)。当reindex一个document(即再添加一个具有相同_index、_type、_id的document)时,es在内部把旧的document的标记成deleted,然后添加新的document,此时_version会递增。旧的document不会立即被删除,es会在后续添加更多数据时自动删除。旧的document不可以再被访问。
##部分更新document
POST /index/type/id/_update {...}
相当于
1. GET /index/type/id
2. 合并field,新的field覆盖旧的field
3. PUT /index/type/id
{...}
##update一个可能不存在的document
POST /index/type/id/_update { "upsert":{ "field":"value" } }
如果document不存在,就会按upsert 创建document。
##Creating
因为添加一个具有相同_index、_type、_id的document时,es会自动覆盖,所以如果想确保添加的document是唯一的,可以让es自动生成_id:
POST /index/type/ { "field":"value" }
如果想指定_id,但不想es覆盖已经存在的document,可以
PUT /index/type/id?op_type=create {...}
或
PUT /index/type/id/_create {...}
成功创建,返回201 Created;如果存在相同的document,则返回409 Conflict
##deleting
DELETE /index/type/id
_version会递增,document不会立即被删除,es会在后续添加更多数据时自动删除。旧的document不可以再被访问。
##冲突
- 当两个进程同时读同一个数据(比如数量9),然后处理(比如累加1)并更新,这时es只会保存最后的更新,即最后数量是10,但正确的应该是11,这样就丢失了其中一个更新,这就叫冲突。
- es用乐观锁,通过版本控制来处理冲突.每次更新(create/index/update/delete),_version元数据都会累加1,若操作的version不等于当前的_version,就会返回错误,操作失败。
###内部version
PUT /index/type/id?version=1
通过传version,告诉es当前version是1时才能处理这条数据,如果当前version不是1,则返回409错误。当前version会变成传入version+1。update/delete操作都可以传version。
###外部version
可以自行定义数据的version,比如时间戳,version必须是大于0小于9.2e+18的整型。create/update/delete都可以传外部version。
PUT /index/type/id?version=2&version_type=external {...}
如果当前version小于传入的version时才能处理这条数据,如果当前version大于等于2,则返回409错误。当前version会变成传入version。
##部分update和冲突
部分update时,es内部会自动传version来避免发生冲突而丢失数据,如果冲突发生了,update会失败,这时应该重试。
POST /index/type/id/_update?retry_on_conflict=5 {...}
重试5次,默认0
##批量create/index/update/delete
POST /_bulk {action:{metadata}}\n {request body}\n
bulk请求会把请求数据load进内存,所以批量数据不应该太大,一次批量大小最好在5~15M。