ElasticSearch的踩坑日记-----refresh时间导致修改数据失败

踩坑场景:
ES新增一条记录,log字段为空---->调取接口获得log日志------>修改刚才新加的记录, 将log日志查到该记录的log字段中。
代码类似如下

//ElasticSearch新增一条记录
User u = new User();//User有个log属性
u.setName("zhangsan");
u.setAge(18);
ElasticsearchUtil.addData(u);
。
。
//调接口获得log值,set到user中
    String result = schemeHttpClient.sendHttpPostJson(url, jsonObject.toJSONString());
    u.setLog(result );
    。
    。
 //在ElasticSearch中更新user
   ElasticsearchUtil.update(u);
   题外话,与本次踩坑无关:ES的update操作,并不是在原来的数据上做修改的,而是找到该数据的索引Id,把原来的数据删掉,再重新插入一条,索引id是相同的。

自己测试的时候发现,log时而能更新进来,时而更新不进来。
所以自己先对代码做了修改
修改如下

//ElasticSearch新增一条记录
User u = new User();//User有个log属性
u.setName("zhangsan");
u.setAge(18);
ElasticsearchUtil.addData(u);
。
。

//先睡一会
Thread.sleep(1000);


//调接口获得log值,set到user中
    String result = schemeHttpClient.sendHttpPostJson(url, jsonObject.toJSONString());
    u.setLog(result );
    。
    。
 //在ElasticSearch中更新user
   ElasticsearchUtil.update(u);

先修改为1000,发现能成功的次数变多了,然后增大时间,修改为5000,发现都能成功,百度了一下终于找到原因.ElasticSearch的踩坑日记-----refresh时间导致修改数据失败_第1张图片
当我们向ES发送请求的时候,我们发现es貌似可以在我们发请求的同时进行搜索。而这个实时建索引并可以被搜索的过程实际上是一次es 索引提交(commit)的过程,如果这个提交的过程直接将数据写入磁盘(fsync)必然会影响性能,所以es中设计了一种机制,即:先将index-buffer中文档(document)解析完成的segment写到filesystem cache之中,这样避免了比较损耗性能io操作,又可以使document可以被搜索。以上从index-buffer中取数据到filesystem cache中的过程叫做refresh。es默认的refresh间隔时间是1s,这也是为什么ES可以进行近乎实时的搜索。

所以,当我们最开始的程序执行完插入es后,还没来得及refresh到cache区域,就要去检索它的索引id并修改它,这样肯定会有失败的,这也是为什么我们把时间修改为5000ms的时候次次都能成功了,因为es的cache区域已经存在该数据了,再去检索它的索引id并修改它肯定能成功了。

解决办法:
所以我修改了一下es的refresh时间
put /index/_setting
{
“index” : {
“refresh_interval” : “500ms”
}
}
ElasticSearch的踩坑日记-----refresh时间导致修改数据失败_第2张图片
然后代码里再让他睡1000ms,就完事啦!

你可能感兴趣的:(ElasticSearch)