簡體   English   中英

Redis 客戶端可以同時更新緩存導致錯誤的 state 被保存

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM