如何清理redis中不活跃的玩家? [英] How to clean up inactive players in redis?

查看:33
本文介绍了如何清理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

  1. 为用户设置一些密钥以使其过期.更新每一次心跳或移动.问题是位置存储在散列中,因此如果用户密钥过期,玩家仍将在同一位置.
  2. 相同,但使用 pub/sub 监听过期并完成清理(似乎过于复杂)
  3. 将心跳存储在一个排序集中,每 X 秒运行一个进程以查找老玩家.每次心跳更新分数.
  4. 彻底改变我存储位置的方式,以便我可以使用过期..不知何故?

还有其他想法吗?

推荐答案

也许使用 单独 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆