我想创建一个使用Azure表存储作为排行榜的游戏。
如果我希望Azure表存储向我提供已排序/分页列表,我建议使用该分数作为我的表实体的RowKey。 (我将附加一个播放器GUID,以确保每个生成的RowKey都是唯一的。)
以下是我对此建议的关注:
其他玩家可以影响玩家的分数(比如降低分数),因此可能会考虑并发问题。如果游戏客户端试图更新玩家的分数,并且我使用之前的分数来搜索表格实体,那么如果另一个客户端已经更新了该行,我可能无法找到该行。
如果使用其他字段搜索表实体(分区+属性),例如播放器名称,则查询不会是最佳的。
哪种方法可以更好地执行行更新?我应该尝试使用锁定技术并通过RowKey搜索吗?或者我使用用户名搜索?
或者,我是否应该放弃使用得分作为RowKey的想法,并在检索完整的表格以在排行榜中显示页面后在内存中进行排序?
目前假设分数更新和排行榜查看同样频繁。
答案 0 :(得分:1)
利用RowKey
或PartitionKey
来满足您的要求是不合适的。由于分区键和行键的组合是表存储中实体的标识。在插入操作中定义它们后,您再也无法更新。有关详细说明,请参阅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上的主题。
Table服务返回基于PartitionKey按升序排序的实体,然后返回RowKey。
因此,Azure表存储在您的方案中不太合适。您可以利用Azure SQL Database来满足您的要求。
答案 1 :(得分:0)
我想象了一个使用Azure Tables实现排行榜的解决方案。我不想仅仅为了扩展排行榜而将Redis或SQL服务器集成到MMO中。排行榜对于MMO中的众多问题非常有用,因此使用天蓝色表来存储可扩展且廉价的解决方案真是太棒了。
我想象的解决方案将使用两个(或三个)表:
包含以下字段的表格: playerId(RowKey和PartitionKey是它的一部分) currentScore(双倍)。这用于直接查找玩家的分数。
包含以下字段的表格: PartitionKey = 3中描述的二叉树叶节点的ID RowKey = LeadingZeros(得分)+" _" + LeadingZeros(PlayerId)
在azure(表格)中的某处创建一个二叉树。存储以下信息:
以上是如何存储它的总体思路。现在,处理并发更新可以通过使用azure表本身的并发机制来解决(如果二进制树存储在其中)。可以使用第三个azure表来存储二进制树节点,每个记录一个,而不是将分区树存储在单个行中。显然,这个二叉树增长的方式是限制每个叶节点添加多少个玩家。
有关此解决方案的问题尚未得到解答,因为它尚未实施,我认为插入/更新性能是一个潜在的有趣问题。
读取性能可以通过简单地缓存结果并每隔几秒更新一次来解决,这是大多数使用排行榜的应用程序都可以接受的。
最后,在理想的世界中,围绕一个非常易于使用的代码包装所有这些复杂的结构,允许您在项目中创建任意数量的排行榜,而无需Redis和SQL的成本和麻烦。
今年晚些时候,我可能会尝试实现类似上述解决方案的方法,如果在我到达之前没有人使用某些功能性C#代码回复此线程:)