【Redis】關於zrevrangebyscore獲取zset數據出現member缺失、重複的問題

1、問題描述

有一個存儲Zset,Score是時間戳,Member是結構體,選擇(ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]),count取值是30。 這個Zset中的數目比較多,13w多,昨天結果驗證發現,有一個數據丟失了,有兩個數據被重複選擇。

2、key結構及操作模型

Key:userbirthts
Score:時間戳
Member:結構體如下

命令:
增加:ZADD
查詢:ZREVRANGEBYSCORE
刪除:ZREMRANGEBYSCORE
刪除:ZREM

3、分析

通過監控看到在執行 zrangebyscore期間其他命令的調用情況。
Redis命令監控
按30的count去遍歷的zset,但是在遍歷的過程中,會有zadd和zrem操作,重複讀取和漏讀取的情況是因爲zadd和zrem操作引起每個數據的排位變化,而遍歷的offset還是排位順序去獲取數據,這過程就會出現問題。

  • 如果是zadd,zadd的member處於你當前遍歷的offset之前,則該插入點之後的所有數據的offset都會+1,那麼會有member會被重複讀取,新增的這個不會被讀取到,如果新增的這個member在offset之後,則沒有影響。
  • 如果是zrem,zrem的member處於你當前遍歷的offset之前,則該刪除點之後的所有數據的offset都會-1,那麼就會有member被跳過了,如果刪除的這個member在遍歷的offset之後,則沒有影響。

4、優化建議

方法一:如果指定範圍內的member不多的話,直接一次性range出來

方法二:按zrangebyscore的min和max分成n個區間,各個區間一次性全部獲取數據

方法三:確保zrangebyscore期間沒有zadd和zrem操作

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章