如何清理redis中不活跃的玩家? [英] How to clean up inactive players in redis?
问题描述
我正在制作一个使用 redis 存储游戏状态的游戏.它可以很好地跟踪位置和玩家,但我没有清理不活跃玩家的好方法.
I'm making a game that uses redis to store game state. It keeps track of locations and players pretty well, but I don't have a good way to clean up inactive players.
每次玩家移动时(这是一个半慢速移动的游戏.想想每秒 1-5 帧),我用新位置更新哈希并删除旧位置键.
Every time a player moves (it's a semi-slow moving game. Think 1-5 frames per second), I update a hash with the new location and remove the old location key.
跟踪活跃玩家的最佳方式是什么?我想到了以下
What would be the best way to keep track of active players? I've thought of the following
- 为用户设置一些密钥以使其过期.更新每一次心跳或移动.问题是位置存储在散列中,因此如果用户密钥过期,玩家仍将在同一位置.
- 相同,但使用 pub/sub 监听过期并完成清理(似乎过于复杂)
- 将心跳存储在一个排序集中,每 X 秒运行一个进程以查找老玩家.每次心跳更新分数.
- 彻底改变我存储位置的方式,以便我可以使用过期..不知何故?
还有其他想法吗?
推荐答案
也许使用 单独 redis 数据结构(虽然是同一个数据库)来跟踪用户活动和用户位置.
Perhaps use separate redis data structures (though same database) to track user activity and user location.
例如,使用redis集单独跟踪当前在线的用户:
For instance, track users currently online separately using redis sets:
[我的代码片段是在 python 中使用 redis-python 绑定,并改编自 示例应用 在 Flask(python 微框架)中;示例应用程序和框架均由 Armin Ronacher 提供.]
[my code snippet is in python using the redis-python bindings, and adapted from example app in Flask (python micro-framework); example app and the framework both by Armin Ronacher.]
from redis import Redis as redis
from time import time
r1 = redis(db=1)
当下面的函数被调用时,它会根据当前的 unix 时间(以分钟为单位)创建一个密钥然后将用户添加到具有该密钥的集合中.我想你会想要将到期时间设置为 10 分钟,因此在任何给定时间,您都可以使用 10 个密钥(每分钟一次).
when the function below is called, it creates a key based on current unix time in minutes and then adds a user to a set having that key. I would imagine you would want to set the expiry at say 10 minutes, so at any given time, you have 10 keys live (one per minute).
def record_online(player_id):
current_time = int(time.time())
expires = now + 600 # 10 minutes TTL
k1 = "playersOnline:{0}".format(now//60)
r1.sadd(k1, player_id)
r1.expire(k1, expires)
所以为了让所有活跃用户只需 union 所有的实时密钥(在本例中,即 10键,一个纯粹的任意数字),如下所示:
So to get all active users just union all of the live keys (in this example, that's 10 keys, a purely arbitrary number), like so:
def active_users(listOfKeys):
return r1.sunion(listOfKeys)
这解决了由于 TTL 导致的清理"问题——不活跃的用户不会出现在你的实时密钥中,因为它们会不断回收——即,活跃用户只被锁定到不持久的旧时间戳在此示例中(但可能在到期前由 redis 写入永久存储).无论如何,这会从您的活动 redis 数据库中清除非活动用户.
This solves your "clean-up" issues because of the TTL--the inactive users would not appear in your live keys because they constantly recycle--i.e., in active users are only keyed to old timestamps which don't persist in this example (but perhaps are written to a permanent store by redis before expiry). In any event, this clears inactive users from your active redis db.
这篇关于如何清理redis中不活跃的玩家?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!