日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

es mysql延迟_ES 近实时搜索 更新延迟问题

發布時間:2025/4/5 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 es mysql延迟_ES 近实时搜索 更新延迟问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、問題發現

有段代碼更新 ES中的數據狀態,將未讀置成已讀。是查一批,更新一批,再查再更新。

public Boolean updateDealStatus(WarningQuery warningQuery) {

....省略不重要的代碼

while (true) {

// 調用服務

// ES查詢不分頁一次就出來10條

List list = warningEsDao.findByQuery(WarningZsdRiskEsEntity.class, warningZsdRiskQuery, esSort);

// 為空或者null就不繼續跑了

if (list == null || list.isEmpty()) {

break;

}

log.info("查詢出來的數量" + list.getSize());

// 將一批數據都置成已讀

for (WarningZsdRiskEsEntity esEntity : list) {

esEntity.setDealStatus(1);

esEntity.setModified(System.currentTimeMillis());

warningEsDao.save(esEntity);

}

}

return true;

}

在測試的時候發現有問題。

我提前看了ES里這個范圍的數據就27條,結果打印查詢數量的日志log.info("查詢出來的數量" + list.getSize());的結果類似這樣。

查詢出來的數量 10

查詢出來的數量 10

查詢出來的數量 10

查詢出來的數量 10

查詢出來的數量 10

查詢出來的數量 10

查詢出來的數量 10

查詢出來的數量 10

查詢出來的數量 10

查詢出來的數量 8

查詢出來的數量 7

查詢出來的數量 2

查詢出來的數量 0

這個肯定是有問題的,27就行了,結果查了這么多次。這個問題的原因就是?–??–ES 更新數據是有延遲的,也就是搜索只能支持“近實時”。

二、ES 近實時搜索介紹

在 Elasticsearch 中,寫入和打開一個新段的輕量的過程叫做 refresh 。 默認情況下每個分片會每秒自動刷新一次。這就是為什么我們說 Elasticsearch 是 近 實時搜索:

文檔的變化并不是立即對搜索可見,但會在一秒之內變為可見。

這些行為可能會對新用戶造成困惑: 他們索引了一個文檔然后嘗試搜索它,但卻沒有搜到。這個問題的解決辦法是用 refresh API 執行一次手動刷新

POST /_refresh // 刷新(Refresh)所有的索引。

POST /blogs/_refresh // 只刷新(Refresh) blogs 索引

盡管刷新是比提交輕量很多的操作,它還是會有性能開銷。當寫測試的時候, 手動刷新很有用,但是不要在生產環境下每次索引一個文檔都去手動刷新。 相反,你的應用需要意識到 Elasticsearch 的近實時的性質,并接受它的不足。

三、解決問題

好知道了ES 的這個特性,造成了我們的bug 那就 揚長避短。

兩種解決方法:

1、更新后等1s在去查。

2、用Scroll 去查,一次查詢有個快照。我們只會摟一次快照版本的數據,然后進行寫操作置狀態。就不用管了。不會把一次已經置了狀態的再摟出來的。

第二種方法的代碼 。

public Boolean updateDealStatus(WarningQuery warningQuery) {

....省略不重要的代碼

// 滑輪初始設置為null

String scrollId = null;

while (true) {

// 調用服務

// ES查詢

EsScrollResponse response = warningEsDao.listByQueryScroll(WarningZsdRiskEsEntity.class, warningZsdRiskQuery, scrollId, 200);

// 為空或者null就不繼續跑了

if (response == null || response.getData() == null || response.getData().isEmpty()) {

break;

}

// 將一批數據都置成已讀

for (WarningZsdRiskEsEntity esEntity : response.getData()) {

esEntity.setDealStatus(1);

esEntity.setModified(System.currentTimeMillis());

warningEsDao.save(esEntity);

}

scrollId = response.getScrollId();

}

return true;

}

總結

以上是生活随笔為你收集整理的es mysql延迟_ES 近实时搜索 更新延迟问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。