[英]Redis clients can update cache simultaneously causing wrong state to be saved
我一直在構建一個簡單的應用程序,它使用 Redis 作為緩存來存儲有關游戲的數據,其中每個用戶都有分數,並且在用戶完成任務后會為用戶更新分數。
我的問題是,當用戶完成一項任務時,他的分數會更新,這意味着它將通過用新值替換以前的值來更新 redis 中的記錄(在我的情況下,它將用新值替換整個房間 object,即使房間沒有改變,只有房間內玩家的分數發生了變化)。
問題是,如果多個用戶同時完成一項任務,他們將同時向每個用戶發送新記錄到 redis,只有最后一個用戶會收到更新。
例如:
在 redis 緩存中,這是起始值: { roomId: "...", score:[{ "player1": 0 }, { "player2": 0 }] }
玩家 1 完成任務並發送:
{ roomId: "...", score:[{ "player1": 1 }, { "player2": 0 }] }
同時玩家 2 完成一個任務並發送:
{ roomId: "...", score:[{ "player1": 0 }, { "player2": 1 }] }
在 redis 緩存中,首先會保存從 Player1 收到的值,然后是來自玩家 2 的值,這意味着緩存中的新值將是:
{ roomId: "...", score:[{ "player1": 0 }, { "player2": 1 }] }
盡管這是錯誤的,因為正確的值應該是: { roomId: "...", score:[{ "player1": 1 }, { "player2": 1 }] }
其中兩個更改都存在。
目前,我還在使用發布/訂閱系統來跟蹤更改,以便將所做的更改反映到每個服務器和連接到服務器的每個用戶。
我該怎么做才能解決這個問題? 作為參考,將下圖視為系統的體系結構:
問題似乎是您將一組讀/寫操作與其他操作交錯,這導致在更新密鑰時使用陳舊數據。 幸運的是,修復(相對)簡單:只需使用Lua 腳本、事務或更簡單的方法,通過單個RedisJSON命令,將您的讀/寫操作塊合並到一個原子單元中。
這是一個使用 RedisJSON 的示例。 使用JSON.SET
命令准備您的 JSON 鑰匙/文件,它將首先保存房間的所有分數:
> JSON.SET room:foo $ '{ "roomId": "foo", "score": [] }'
OK
之后,一旦需要將 append 項添加到分數數組中,請使用JSON.ARRAPPEND
命令:
> JSON.ARRAPPEND room:foo $.score '{ "player1": 123 }'
1
...
> JSON.ARRAPPEND room:foo $.score '{ "player2": 456 }'
2
取回整個 JSON 文檔就像運行一樣簡單:
> JSON.GET room:foo
"{\"roomId\":\"foo\",\"score\":[{\"player1\":123},{\"player2\":456}]}"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.