使用Score + GUID作为使用Azure表存储的游戏的RowKey

时间:2016-07-17 22:17:28

标签: azure-storage query-performance azure-table-storage

我想创建一个使用Azure表存储作为排行榜的游戏。

如果我希望Azure表存储向我提供已排序/分页列表,我建议使用该分数作为我的表实体的RowKey。 (我将附加一个播放器GUID,以确保每个生成的RowKey都是唯一的。)

以下是我对此建议的关注:

  • 其他玩家可以影响玩家的分数(比如降低分数),因此可能会考虑并发问题。如果游戏客户端试图更新玩家的分数,并且我使用之前的分数来搜索表格实体,那么如果另一个客户端已经更新了该行,我可能无法找到该行。

  • 如果使用其他字段搜索表实体(分区+属性),例如播放器名称,则查询不会是最佳的。

哪种方法可以更好地执行行更新?我应该尝试使用锁定技术并通过RowKey搜索吗?或者我使用用户名搜索?

或者,我是否应该放弃使用得分作为RowKey的想法,并在检索完整的表格以在排行榜中显示页面后在内存中进行排序?

目前假设分数更新和排行榜查看同样频繁。

2 个答案:

答案 0 :(得分:1)

利用RowKeyPartitionKey来满足您的要求是不合适的。由于分区键和行键的组合是表存储中实体的标识。在插入操作中定义它们后,您再也无法更新。有关详细说明,请参阅MSDN https://social.msdn.microsoft.com/Forums/azure/en-US/7ad92641-3b0b-4faa-989f-3506fab47325/can-we-update-partition-key-or-row-key-in-azure-table-storage?forum=windowsazuredata上的主题。

此外,正如https://azure.microsoft.com/en-us/documentation/articles/storage-table-design-guide/#sorting-data-in-the-table-service的说明:

  

Table服务返回基于PartitionKey按升序排序的实体,然后返回RowKey。

因此,Azure表存储在您的方案中不太合适。您可以利用Azure SQL Database来满足您的要求。

答案 1 :(得分:0)

我想象了一个使用Azure Tables实现排行榜的解决方案。我不想仅仅为了扩展排行榜而将Redis或SQL服务器集成到MMO中。排行榜对于MMO中的众多问题非常有用,因此使用天蓝色表来存储可扩展且廉价的解决方案真是太棒了。

我想象的解决方案将使用两个(或三个)表:

  1. 包含以下字段的表格: playerId(RowKey和PartitionKey是它的一部分) currentScore(双倍)。这用于直接查找玩家的分数。

  2. 包含以下字段的表格: PartitionKey = 3中描述的二叉树叶节点的ID RowKey = LeadingZeros(得分)+" _" + LeadingZeros(PlayerId)

  3. 在azure(表格)中的某处创建一个二叉树。存储以下信息:

    • 节点ID
    • MaxScore(在此节点内)
    • MinScore(在此节点内)
    • 得分计数(此节点中存储的得分数,仅当它是叶节点时)
  4. 以上是如何存储它的总体思路。现在,处理并发更新可以通过使用azure表本身的并发机制来解决(如果二进制树存储在其中)。可以使用第三个azure表来存储二进制树节点,每个记录一个,而不是将分区树存储在单个行中。显然,这个二叉树增长的方式是限制每个叶节点添加多少个玩家。

    有关此解决方案的问题尚未得到解答,因为它尚未实施,我认为插入/更新性能是一个潜在的有趣问题。

    读取性能可以通过简单地缓存结果并每隔几秒更新一次来解决,这是大多数使用排行榜的应用程序都可以接受的。

    最后,在理想的世界中,围绕一个非常易于使用的代码包装所有这些复杂的结构,允许您在项目中创建任意数量的排行榜,而无需Redis和SQL的成本和麻烦。

    今年晚些时候,我可能会尝试实现类似上述解决方案的方法,如果在我到达之前没有人使用某些功能性C#代码回复此线程:)