Redis 有序集合(zset)取交集(zinterstore)操作耗时测试
? ? ? ? ?取交集的場景很多,比如公眾號文章顯示有多少個好友已讀,又或者群聊成員列表顯示有多少個好友已經入群。最近遇到一個類似場景,一開始的覺得線上數據量較大,redis 取交集操作時間復雜度在O(N),實時計算會不會不合適?是否離線計算更好?請教了組內資深大佬,大佬說數據量不大的情況下redis計算挺快的。聽了之后感覺需要實際測試一下,不然貿然上線心里沒底。下面是測試流程,有需要的同學可以參考下。
? ? ? ? 假定測試目標是統計在線用戶中付費用戶數量,測試結果如下圖,先說結論:耗時和數據集大小以及數據集重合度有關(廢話,耗時肯定和數據集大小有關^_^)。測試結果也和zinterstore 的時間復雜度是一致的。下圖右側是提高重合度的結果,耗時明顯有增加。
ZINTERSTORE 時間復雜度: O(N*K)+O(M*log(M)) 這里N表示有序集合中成員數最少的數字,K表示有序集合數量。M表示結果集中重合的數量。測試設備:
????????騰訊云服務器 16核 32G內存
數據集通過redis lua腳本跑出
create_data.lua 腳本:
-- 1000 用戶量 redis.call("del","online_user_1000", "rich_user_1000","online_user_5000","rich_user_5000","online_user_10000","rich_user_10000","online_user_50000","rich_user_50000","online_user_100000","rich_user_100000") for i = 1, 1000, 1 do redis.call("zadd", "online_user_1000", math.random(1000000)*math.random(100000), math.random(10000000)) redis.call("zadd", "rich_user_1000", math.random(1000000)*math.random(100000), math.random(10000000)) end-- 5000 用戶量 for i = 1, 5000, 1 do redis.call("zadd", "online_user_5000", math.random(1000000)*math.random(100000), math.random(10000000)) redis.call("zadd", "rich_user_5000", math.random(1000000)*math.random(100000), math.random(10000000)) end-- 10000 用戶量 for i = 1, 10000, 1 do redis.call("zadd", "online_user_10000", math.random(1000000)*math.random(100000), math.random(10000000)) redis.call("zadd", "rich_user_10000", math.random(1000000)*math.random(100000), math.random(10000000)) end-- 50000 用戶量 for i = 1, 50000, 1 do redis.call("zadd", "online_user_50000", math.random(1000000)*math.random(100000), math.random(10000000)) redis.call("zadd", "rich_user_50000", math.random(1000000)*math.random(100000), math.random(10000000)) end-- 100000 用戶量 for i = 1, 100000, 1 do redis.call("zadd", "online_user_100000", math.random(1000000)*math.random(100000), math.random(10000000)) redis.call("zadd", "rich_user_100000", math.random(1000000)*math.random(100000), math.random(10000000)) end-- 500000 用戶量 for i = 1, 500000, 1 do redis.call("zadd", "online_user_500000", math.random(1000000)*math.random(100000), math.random(10000000)) redis.call("zadd", "rich_user_500000", math.random(1000000)*math.random(100000), math.random(10000000)) end-- 1000000 用戶量 for i = 1, 1000000, 1 do redis.call("zadd", "online_user_1000000", math.random(1000000)*math.random(100000), math.random(10000000)) redis.call("zadd", "rich_user_1000000", math.random(1000000)*math.random(100000), math.random(10000000)) endreturn "OK"?測試工具:redis-benchmark
測試命令如下,-n表示執行次數
redis-benchmark -n 10000 zinterstore inter_user_1000 2 online_user_1000 rich_user_1000 redis-benchmark -n 10000 zinterstore inter_user_5000 2 online_user_5000 rich_user_5000 redis-benchmark -n 10000 zinterstore inter_user_10000 2 online_user_10000 rich_user_10000 redis-benchmark -n 10000 zinterstore inter_user_50000 2 online_user_50000 rich_user_50000 redis-benchmark -n 10000 zinterstore inter_user_100000 2 online_user_100000 rich_user_100000 redis-benchmark -n 10000 zinterstore inter_user_500000 2 online_user_500000 rich_user_500000 redis-benchmark -n 10000 zinterstore inter_user_1000000 2 online_user_1000000 rich_user_1000000測試截圖:
? ? ? ? ?在我的業務場景里,數據集一般在1萬以下,上限不會超過100萬,結合本次實測結果,實時計算應該沒啥問題。測試過程中也發現,雖然單個請求耗時不大,但是如果存在大量請求,并且這些請求對應數據規模很大,則勢必占用redis server大量處理時間,帶來普通請求的延遲或者超時,這一點也需要在業務中考慮。
總結
以上是生活随笔為你收集整理的Redis 有序集合(zset)取交集(zinterstore)操作耗时测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux JQ 命令学习笔记
- 下一篇: linux cmake编译源码,linu