es mysql延迟_ES 近实时搜索 更新延迟问题
一、問題發(fā)現(xiàn)
有段代碼更新 ES中的數(shù)據(jù)狀態(tài),將未讀置成已讀。是查一批,更新一批,再查再更新。
public Boolean updateDealStatus(WarningQuery warningQuery) {
....省略不重要的代碼
while (true) {
// 調(diào)用服務(wù)
// ES查詢不分頁一次就出來10條
List list = warningEsDao.findByQuery(WarningZsdRiskEsEntity.class, warningZsdRiskQuery, esSort);
// 為空或者null就不繼續(xù)跑了
if (list == null || list.isEmpty()) {
break;
}
log.info("查詢出來的數(shù)量" + list.getSize());
// 將一批數(shù)據(jù)都置成已讀
for (WarningZsdRiskEsEntity esEntity : list) {
esEntity.setDealStatus(1);
esEntity.setModified(System.currentTimeMillis());
warningEsDao.save(esEntity);
}
}
return true;
}
在測試的時候發(fā)現(xiàn)有問題。
我提前看了ES里這個范圍的數(shù)據(jù)就27條,結(jié)果打印查詢數(shù)量的日志log.info("查詢出來的數(shù)量" + list.getSize());的結(jié)果類似這樣。
查詢出來的數(shù)量 10
查詢出來的數(shù)量 10
查詢出來的數(shù)量 10
查詢出來的數(shù)量 10
查詢出來的數(shù)量 10
查詢出來的數(shù)量 10
查詢出來的數(shù)量 10
查詢出來的數(shù)量 10
查詢出來的數(shù)量 10
查詢出來的數(shù)量 8
查詢出來的數(shù)量 7
查詢出來的數(shù)量 2
查詢出來的數(shù)量 0
這個肯定是有問題的,27就行了,結(jié)果查了這么多次。這個問題的原因就是?–??–ES 更新數(shù)據(jù)是有延遲的,也就是搜索只能支持“近實時”。
二、ES 近實時搜索介紹
在 Elasticsearch 中,寫入和打開一個新段的輕量的過程叫做 refresh 。 默認情況下每個分片會每秒自動刷新一次。這就是為什么我們說 Elasticsearch 是 近 實時搜索:
文檔的變化并不是立即對搜索可見,但會在一秒之內(nèi)變?yōu)榭梢姟?/p>
這些行為可能會對新用戶造成困惑: 他們索引了一個文檔然后嘗試搜索它,但卻沒有搜到。這個問題的解決辦法是用 refresh API 執(zhí)行一次手動刷新
POST /_refresh // 刷新(Refresh)所有的索引。
POST /blogs/_refresh // 只刷新(Refresh) blogs 索引
盡管刷新是比提交輕量很多的操作,它還是會有性能開銷。當寫測試的時候, 手動刷新很有用,但是不要在生產(chǎn)環(huán)境下每次索引一個文檔都去手動刷新。 相反,你的應(yīng)用需要意識到 Elasticsearch 的近實時的性質(zhì),并接受它的不足。
三、解決問題
好知道了ES 的這個特性,造成了我們的bug 那就 揚長避短。
兩種解決方法:
1、更新后等1s在去查。
2、用Scroll 去查,一次查詢有個快照。我們只會摟一次快照版本的數(shù)據(jù),然后進行寫操作置狀態(tài)。就不用管了。不會把一次已經(jīng)置了狀態(tài)的再摟出來的。
第二種方法的代碼 。
public Boolean updateDealStatus(WarningQuery warningQuery) {
....省略不重要的代碼
// 滑輪初始設(shè)置為null
String scrollId = null;
while (true) {
// 調(diào)用服務(wù)
// ES查詢
EsScrollResponse response = warningEsDao.listByQueryScroll(WarningZsdRiskEsEntity.class, warningZsdRiskQuery, scrollId, 200);
// 為空或者null就不繼續(xù)跑了
if (response == null || response.getData() == null || response.getData().isEmpty()) {
break;
}
// 將一批數(shù)據(jù)都置成已讀
for (WarningZsdRiskEsEntity esEntity : response.getData()) {
esEntity.setDealStatus(1);
esEntity.setModified(System.currentTimeMillis());
warningEsDao.save(esEntity);
}
scrollId = response.getScrollId();
}
return true;
}
總結(jié)
以上是生活随笔為你收集整理的es mysql延迟_ES 近实时搜索 更新延迟问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: dbartisan mysql_Syba
- 下一篇: java arraylist 函数_Ja