今天看了下get的实现原理,对其中realtime这个参数的使用不解
从 request.refresh() && !request.realtime() 这个逻辑可以得出,只有设置了refresh并且realtime是关闭的情况下,才会在此处主动触发一次refresh。
然后有关realtime的逻辑还在IntrenalGet中出现过一次:
那问题就是,第一个逻辑干嘛还要有一个realtime的判断。而且默认realtime 从controller来的时候是true,那么在上文!request.realtime() 就是false,也就是默认情况下,这里面的refresh是不会执行的(等于refresh在这一步被架空了)。所以这块是做什么用的呢?感觉意义不明确
@Override
protected GetResponse shardOperation(GetRequest request, ShardId shardId) {
IndexService indexService = indicesService.indexServiceSafe(shardId.getIndex());
IndexShard indexShard = indexService.getShard(shardId.id());
if (request.refresh() && !request.realtime()) {
indexShard.refresh("refresh_flag_get");
}
GetResult result = indexShard.getService().get(request.type(), request.id(), request.storedFields(),
request.realtime(), request.version(), request.versionType(), request.fetchSourceContext());
return new GetResponse(result);
}
这块是其中的一个实现。从 request.refresh() && !request.realtime() 这个逻辑可以得出,只有设置了refresh并且realtime是关闭的情况下,才会在此处主动触发一次refresh。
然后有关realtime的逻辑还在IntrenalGet中出现过一次:
if (get.realtime()) {
VersionValue versionValue = versionMap.getUnderLock(get.uid().bytes());
if (versionValue != null) {
if (versionValue.isDelete()) {
return GetResult.NOT_EXISTS;
}
if (get.versionType().isVersionConflictForReads(versionValue.getVersion(), get.version())) {
throw new VersionConflictEngineException(shardId, get.type(), get.id(),
get.versionType().explainConflictForReads(versionValue.getVersion(), get.version()));
}
refresh("realtime_get");
}
}
在这里如果开启了realtime且能够起到刷新的作用。那问题就是,第一个逻辑干嘛还要有一个realtime的判断。而且默认realtime 从controller来的时候是true,那么在上文!request.realtime() 就是false,也就是默认情况下,这里面的refresh是不会执行的(等于refresh在这一步被架空了)。所以这块是做什么用的呢?感觉意义不明确
3 个回复
rochy - rochy_he
赞同来自:
简单来说就是 realtime = true 的时候,Get 会直接从 translog 读取内容
hapjin
赞同来自:
2,GET API 会触发 refresh 操作。参考:docs-get
3,看ES6.3.2源码注释的话,普通 GET 操作应该是不会从translog读数据的。结合上面第2条和下面的源码注释,如果UPDATE了一个文档且尚未refreshed,那么GET 就会触发refresh。
(org.elasticsearch.index.engine.InternalEngine#get) 4,调用了org.elasticsearch.index.engine.InternalEngine#refresh(java.lang.String, org.elasticsearch.index.engine.Engine.SearcherScope)方法,并不一定会真正的发生refresh动作,参考:org.apache.lucene.search.ReferenceManager#doMaybeRefresh方法的实现。
5,很好奇 GET 操作会触发refresh吗?或者说:GET操作在什么情况下会触发refresh。
6,除了这条语句:request.refresh() && !request.realtime() 外,还有个地方会调用refresh()方法:
org.elasticsearch.index.get.ShardGetService#innerGet方法的 readFromTranslog参数是false
xieqiao
赞同来自: