【问题标题】:cassandra highscore卡桑德拉高分
【发布时间】:2012-03-29 03:43:07
【问题描述】:

如果我只想查询:

1. Username, Xp, OtherUserData
2. User with the N-th highest Xp

我将如何进行数据结构和查询。

对于 1. 我的结构类似于: { 用户名:{ Xp, OtherUserData}}

我是否只需要对所有用户进行 2. 的查询,还是有更好的选择?

【问题讨论】:

    标签: database database-design cassandra data-modeling


    【解决方案1】:

    我不完全确定你在问什么(Xp 是用户的分数吗?),但这里有一个猜测:

    要存储用户数据,请为每个用户创建一行,键入他们的用户名(假设这是唯一且固定的),然后为每个项目创建一个列:

    username ->  Xp      other    ...
                 value   value    ...
    

    要维护一个高分表,请使用单行(可能在不同的列族中),包含所有用户(或高于某个阈值的用户),列名是分数,并指定一个数字 ( LongType) 比较器,以便按分数对列进行排序:

    highscores -> 1000      1001      99999999   ...
                  user123   user345   user789    ...
    

    然后,您可以通过查询此排序行中的最后或前 N 列来检索最高的 N 分。如果该行太大,您可以从该行中删除低分。

    更新:正如您所指出的,多个用户可能获得相同的分数。一个快速而肮脏的解决方案是将值设为用户列表:

    highscores -> 1000      
                  "user123, user567, user899"
    

    如果您不太可能获得大量相同分数的用户,这是可以容忍的,但由于您需要读取、更新和写入列表,这很尴尬。

    您可以使用超级列,但通常不推荐使用这些。

    否则您可能会使用composite column keys 以便区分用户,但保持按分数排序的列。

    【讨论】:

    • 如何处理两个分数相同的用户?
    【解决方案2】:

    仅使用一排进行分类可能非常危险,因为每一排只能坐在一个 Cassandra 实例上。因此,您系统中的所有玩家都将写入该 ONE 密钥 - 在一台机器上 - 存在集群中节点过载的风险。这可能会导致所有集群失败,因为节点在尝试恢复时试图承担宕机节点的负载时发生奇怪的连锁反应(我们在生产机器上发生过这种情况,因为硬编码测试的错误) key 将接收所有本应在每个人的单独行中的写入)。

    一种解决方案是根据用户的分数对他们进行分组:

    • 0-> 1000 = 桶A
    • 1001 -> 5000 = 桶B
    • 5001 -> 15000 = 桶 C 等等。

    我建议将较低级别的存储桶变小。

    并用列名作为复合来编写您的列: CompositeType(LongType, UTF8Type)

    例如,如果您使用 UUID 作为玩家 id 并使用 longs 作为分数,我们会得到:

    • 500089845:f7bc41d8-c1c6-489c-bb2c-f86fccc7681c
    • 4100085589:2ae91e9f-1512-4ef8-8441-9f48e21fb11b

    您可以使用串联的字符串来做到这一点,但您必须写入所有前导零,这样 UTF8 比较器才能按正确的顺序排列所有分数。

    1. 000000500089845:f7bc41d8-c1c6-489c-bb2c-f86fccc7681c
    2. 000004100085589:2ae91e9f-1512-4ef8-8441-9f48e21fb11b

    没有前导零将是

    1. 000004100085589:2ae91e9f-1512-4ef8-8441-9f48e21fb11b
    2. 000000500089845:f7bc41d8-c1c6-489c-bb2c-f86fccc7681c

    这样您就不必阅读来修改具有相同分数的人的向量、json、复合或超级列,因为每个分数都是一个单独的列。您可以在列中放置您想要的任何信息,以便您可以在一次读取中获取所有内容(无需通过另一次读取来获取玩家信息,我个人会使用包含我需要的所有内容的 json 或字节序列化对象来做到这一点) .

    要阅读:对您想要的行进行反向范围查询(最高优先)就可以了。

    您也可以通过更改存储桶的性质来改变系统的风格,只要您有足够的行来接触所有节点,从而在您的令牌环上分担负载。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-30
      • 2015-10-19
      • 2015-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      相关资源
      最近更新 更多