es的一致性主要有两个方面:html
使用lucene索引机制带来的refresh问题java
使用分片和复制带来的副本一致性问题(consistency:one、all、quorum
)git
外部因素的话,就是若是使用db跟es的同步机制的话,那么这里的同步有必定的延时,另外也有可能由于异常状况发生不一致的状况,好比事务回滚之类的。github
org.springframework.data.elasticsearch.repository.support.AbstractElasticsearchRepositoryspring
@Override public <S extends T> S save(S entity) { Assert.notNull(entity, "Cannot save 'null' entity."); elasticsearchOperations.index(createIndexQuery(entity)); elasticsearchOperations.refresh(entityInformation.getIndexName()); return entity; } public <S extends T> List<S> save(List<S> entities) { Assert.notNull(entities, "Cannot insert 'null' as a List."); Assert.notEmpty(entities, "Cannot insert empty List."); List<IndexQuery> queries = new ArrayList<IndexQuery>(); for (S s : entities) { queries.add(createIndexQuery(s)); } elasticsearchOperations.bulkIndex(queries); elasticsearchOperations.refresh(entityInformation.getIndexName()); return entities; }
一旦有更改就refresh到filesystem cache,这样就能够被搜索到。json
可是还有一个问题,一旦有多个replication,就涉及到一致性的问题。segmentfault
若是consistency是one,那么写入速度快,不能保证读到最新的更改;curl
若是是quorum则是相对折中的版本,write的时候,W>N/2,即参与写入操做的节点数W,必须超过副本节点数N的一半。若是是quorum策略,则读取要保证一致性的话,就得使用read quorum,读取N个副本中的W个而后仲裁获得最新数据。或者是指定从primary上面去读。
相关的类async
org/elasticsearch/action/WriteConsistencyLevel.java org/elasticsearch/action/RealtimeRequest.java
realtime request
es提供了realtime request,就是从translog里头读,能够保证是最新的。elasticsearch
public class GetRequest extends SingleShardRequest<GetRequest> implements RealtimeRequest { //...... }
可是注意get是最新的,可是检索等其余方法不是(若是须要搜索出来也是最新的,须要refresh,这个会刷新该shard但不是整个index,所以若是read请求分发到repliac shard,那么可能读到的不是最新的数据,这个时候就须要指定preference=_primary
)。
all策略即强一致的策略
若是要保证读的强一致:
当write consistency不是all的时候,须要指定从primary shard读
当write consistency为all的时候,并且replication是sync模式(默认),无需额外指定,若是replication是async模式,则须要从primary shard读取。
curl -XGET 192.168.99.100:9200/myindex/_settings curl -XPUT '192.168.99.100:9200/myindex/_settings' -d ' { "index" : { "action.write_consistency" : "all" } }'
可是都须要在update的时候手工refresh。
若是是读多写少的应用(特别是replica很少的时候),则能够指定write consistency为all,这样就能够很好地利用replica shard的读来提高es的读性能呢。