Redis是游戲資料庫重要選型之一,華為雲GaussDB(for Redis)能及時上報用戶下線行為,被廣泛應用於排行榜等多種業務場景。 ...
本文分享自華為雲社區《GaussDB(for Redis) 游戲實踐:玩家下線行為上報》,作者:GaussDB 資料庫
為保護未成年人的身心健康,2007年國家推出網路游戲防沉迷系統,對未成年人的游戲時間進行限制。游戲廠家需要及時感知用戶的下線時間並上報。Redis是游戲資料庫重要選型之一,在基於開源Redis實現以上功能時,感知用戶下線行為延遲大,導致上報時間不准確。華為雲GaussDB(for Redis)作為一款企業級游戲資料庫,具備卓越的企業級能力,能及時上報用戶下線行為,並被廣泛應用於排行榜等多種業務場景。
一、基於Redis的用戶下線上報實現
實現用戶下線上報能力的常見方式
使用Redis key過期功能,結合鍵空間通知功能可以實現用戶下線上報,常見使用方式如下:
1)用戶登錄後,為每一個用戶key設置一個過期時間(3-5分鐘)
2)游戲客戶端,定期每分鐘上報一次心跳。收到心跳後,服務端重置游戲用戶key的過期時間
3)為避免網路波動造成的未及時上報,若5分鐘內,收到心跳,則重置過期時間;若未收到,將觸發key過期,系統判定用戶下線。
因此,Redis鍵空間通知功能要及時感知key過期,以確保上報時間的準確性。
Redis鍵空間通知功能
Redis鍵空間通知(keyspace notification),允許用戶通過訂閱頻道或模式, 以接收key的修改、過期等通知。對於每個key的修改,鍵空間通知都會發送兩種不同類型的事件。以DB0用戶mykey過期為例,Redis會發送兩條消息,相當於執行了兩個publish命令:
- PUBLISH __keyspace@0__:mykey expire
- PUBLISH __keyevent@0__:expire mykey
通過訂閱頻道 __keyspace@0__:mykey 可以接收 0 號資料庫中所有修改鍵 mykey 的事件, 而訂閱頻道 __keyevent@0__:expire 則可以接收 0 號資料庫中所有執行 expire 命令的鍵。其中以 keyspace 為首碼的頻道被稱為鍵空間通知,而以 keyevent 為首碼的頻道則被稱為鍵事件通知。
可以通過命令CONFIGSET notify-keyspace-events [parameter]來開啟或者關閉鍵空間通知功能,若parameter為空則表示關閉該功能,若不空則開啟。通常將參數設置為“AKE”,表示發送所有類型通知。
字元 |
發送的通知 |
K |
鍵空間通知,所有通知以 __keyspace@<db>__ 為首碼 |
E |
鍵事件通知,所有通知以 __keyevent@<db>__ 為首碼 |
g |
DEL 、 EXPIRE 、 RENAME 等類型無關的通用命令的通知 |
$ |
字元串命令的通知 |
l |
列表命令的通知 |
s |
集合命令的通知 |
h |
哈希命令的通知 |
z |
有序集合命令的通知 |
x |
過期事件:每當有過期鍵被刪除時發送 |
e |
驅逐(evict)事件:每當有鍵因為 maxmemory 政策而被刪除時發送 |
A |
參數 g$lshzxe 的別名 |
通過以下命令,可以訂閱DB0所有過期的用戶key
redis-cli --csv psubscribe '__keyevent@0__:expire'
二、GaussDB(for Redis)與開源Redis key過期鍵空間通知延時對比
Redis規格:都採用4GB的規格
測試步驟:
1)使用memtier_benchmark預置10w個key
2)使用客戶端定期key過期事件
3)使用python腳本,對其中的3w個key設置10s過期時間
4) 分別在有業務流量和無業務流量場景,統計收到3w個key過期的通知耗時
測試結果:
無業務流量收到全部key過期耗時 |
有業務流量全部key過期耗時 |
|
GaussDB(for Redis) |
9秒 |
9秒 |
開源Redis |
3分41秒 |
3分44秒 |
可以看出,在有無業務流量場景下,GaussDB(for Redis)僅需9秒可以完成全部key過期的上報,而社區Redis需要4分鐘左右才能完成上報,嚴重影響用戶下線行為上報的準確性。
三、原理分析
開源Redis鍵空間通知功能採用了惰性刪除和定期刪除兩種策略,即在訪問的時候進行過期檢查,同時後臺以一定頻率執行定期檢查任務,可以通過修改配置文件redis.conf的hz選項來調整這個頻率。每次過期任務會按以下流程進行刪除操作:
- 從設置了過期時間的key的集合中隨機檢查20個key。
- 刪除檢查中發現的所有過期key。
- 如果檢查結果中25%以上的key已過期,則開始新一輪任務。
可以註意到,開源Redis並不是一次運行就檢查所有的庫中所有的鍵,而是隨機檢查一定數量的鍵,從而導致上報延時長。而GaussDB(for Redis)後臺有一個實時線程會對key進行持續掃描,及時上報過期key,也不會影響前臺寫操作。
四、總結
GaussDB(for Redis)是一款超越開源Redis的企業級KV資料庫,在游戲場景中,除了被應用在游戲玩家下線場景,還被廣泛應用在玩家數據存儲、排行榜、好友關係、消息推送等場景。採用存算分離的架構,既能滿足游戲業務對高併發的性能指標要求,又能降本增效,深受游戲開發者的青睞。