Django memcached不一致

时间:2012-07-30 21:32:52

标签: python django memcached tornado

所以,这个问题相当复杂。我会尽力解释。任何帮助将非常感激。提前致谢!

我正在构建一个使用tornadio2 + Memcached的应用程序,并且在尝试从缓存中提取时发现了一些令人费解的事情。

对于初学者来说,这是我的broadcast_to_players()函数:

def broadcast_to_players(self, g_id, event, message, update_secret=False, dont_update_self=False):
    the_game = cache.get(g_id)
    for player in the_game.player_list:
        if update_secret == True:
            secret = self.get_secret()
            message['k'] = secret
            player.secret_key = secret
        if dont_update_self == True:
            if not self.session_id == player.session_id:
                single_session = self.session.server._sessions.get(player.session_id)
                single_session.conn.emit(event, message)
        else:
            single_session = self.session.server._sessions.get(player.session_id)
            single_session.conn.emit(event, message)
    cache.set(g_id, the_game)

    ## FOR TESTING PURPOSES ##
    if update_secret == True:
        other_game = cache.get(g_id)
        for player in other_game.player_list:
            print "player.secret_key in broadcast_to_players = %s" % player.secret_key

正如您所看到的,它从缓存中抓取the_game,对其进行操作,修改消息,更新我的player_list中的玩家,然后发送消息。然后,它将游戏设置为缓存。之后,(出于测试目的)我再次抓住它并测试每个播放器的secret_key值是否在缓存中。他们这样做。

但是,当我尝试再次从缓存中抓取相同的游戏时,它会显示secret_key =无

def check_player(self, g_id, key):
    the_game = cache.get(g_id) #I'm able to 
    the_player = None
    for player in the_game.player_list:
        if player.secret_key == key:
            the_player = player
    return the_player

正在缓存游戏,但是游戏模型中没有更新player_list。这是我的游戏和玩家模型:
http://pastebin.com/t66qgeeb - 游戏模型
http://pastebin.com/7FjpeSLx - 玩家模型

正如您所看到的,Player模型通过User与Game建立了多对多的关系。另外,我有许多非持久性变量(对于正在玩的游戏),我保留在我的Django模型类中。我的猜测是,这可能与我抓住与我的游戏相关的所有玩家,将它们放入player_list,然后尝试更新它们这一事实有关。并且memcached没有那么深的副本?我不知道,我一直绞尽脑汁试图弄明白。任何帮助都将非常感激。谢谢!

2 个答案:

答案 0 :(得分:2)

确定。让我们一点一点地移动:

  1. 不要在memcached中放置大对象 - 你很有可能 未命中。
  2. 在这种情况下 - 拆分键。您必须拥有一个游戏键,一个关键玩家列表以及游戏中每个玩家的键。
  3. 按键player_<g_id>_<key>将播放器存储在memcache中 - 然后您就可以轻松获得播放器了。
  4. 让我们把它们放在一起:

    def broadcast_to_players(self, g_id, event, message, update_secret=False, dont_update_self=False):
        the_game = cache.get(g_id)
        player_list = cache.get('game_%s_players' % g_id) #Getting list of players ids
        for player_key in player_list:
            player = cache.get('game_%s_%s' % (g_id, player_key))
            if update_secret == True:
                secret = self.get_secret()
                message['k'] = secret
                player.secret_key = secret
                player.save() #We are storing secret in db, right?
                cache.set('game_secret_%s_%s' % (g_id, secret), player_key) #Making player availiable in game by secret
                cache.set('player_%s_secret' % (player_key, ), secret) #Making player secret available by player id
            if dont_update_self == True:
                if not self.session_id == player.session_id:
                    single_session = self.session.server._sessions.get(player.session_id)
                    single_session.conn.emit(event, message)
            else:
                single_session = self.session.server._sessions.get(player.session_id)
                single_session.conn.emit(event, message)
        cache.set(g_id, the_game)
    
    def check_player(self, g_id, key):
        return cache.get('game_secret_%s_%s' % (g_id, key))
    

    在使用键/值存储时,您应该如何思考。

答案 1 :(得分:1)

您的“用于测试目的”部分并未真正测试任何内容。它不仅迭代属于原始'the_game'对象的播放器列表,而不是你刚从缓存中获得的'other_game',print语句然后打印局部变量的值'secret',而不是player.secret_key的值。