Azure上的游戏记分牌

时间:2017-03-27 03:49:02

标签: database azure storage azure-storage azure-data-lake

您可以向我推荐一种在Azure云上存储游戏分数的替代解决方案吗?我正在寻找托管廉价运行易于扩展的上下存储选项。

输入数据:{ "player": 1, "score": 10 }(分数可能已经计算过,无需总结。)

应该有两种类型的查询选项:
1.获得球员在记分牌中的位置 2.获得位置X和Y之间的位置(球员和得分)。

应用程序无法在写入时间内告诉记分牌中玩家的位置 - 后端数据库解决方案应提供该信息,或者数据布局应允许快速计算所有玩家之间的位置。 非实时准确性是可以接受的。

当前的后端技术选择:Azure Web App(.NET Core),存储(表,Blob,队列)。
使用SQL服务器显然该怎么做,但是我想避免将SQL服务器带到技术堆栈。由于多个Web服务器,保留在内存中也不是一种选择。

您是否知道如何使用任何其他Azure服务存储和检索此类数据? DocumentDB,Data Lake,还有其他吗?

3 个答案:

答案 0 :(得分:1)

计算列表中位置的问题是,当您的数据可以分布在多个服务器上时,很难进行排名(以及一般的窗口操作)。随着数据的增长,这将成为一项昂贵的操作,并且不能很好地扩展。

Data Lake支持窗口功能,包括RANK() and DENSE_RANK()。您需要使用一些有代表性的数据对此进行良好测试,以了解性能如何。

另一种选择是以特定间隔预先计算排名并将整个记分板“缓存”到表存储中;如果对用户造成延误是可以接受的(例如,你可以说排名每小时更新一次)

然后你可以有一个预定的WebJob:

  1. 读取得分高于阈值的所有得分记录,按得分排序
  2. 为玩家等级创建一个新表格,例如player-scores-170401-124200
  3. 为整体排名创建一个新表格,例如scoreboard-170401-124200
  4. 将排名记分板分批写入新表
  5. 通过这种方式,您可以在player-scores上查询PartitionKey=player以获得个人排名,并使用不等式过滤器查询scoreboard以获取位置窗口。

    查询(这是您可能应该优化的操作)变得非常便宜和简单,因为它是每条信息的单个事务。

    运行计算也不算太贵,交易成本是您需要关注的事情。假设 n 得分记录:

    • 您可以批量阅读100.交易〜= n / 100
    • 您可以批量写入100个相同的分区。交易〜= 2n / 100
    • 您可以选择保留历史排名,也可以在一次交易中删除整个表格

    因此,1M记录的总交易次数为:

    1000000*3/100 = 30,000 per run

    每天每小时做一次(720k交易),每天花费大约2-3美分(当然不包括存储费用)。在我的书中运行起来很便宜: - )

答案 1 :(得分:0)

如果您使用表格,那么您的第一个查询很简单,您可以使用玩家ID(玩家的唯一标识符,无论您选择的是什么)作为您的分区键,得分可以是同一实体的属性。当您想要阅读(您的查询1)时,您只需使用唯一的玩家ID进行点查询并获得分数。

你的第二个查询有点棘手。您可能希望避免下载整个表并在客户端进行内存排序,这是客户端和表服务世界中最差的组合。

因此,需要在此处选择不同的分区键以针对第二个查询进行优化。您可以做的一件事是创建一个范围的桶并获得该范围的唯一哈希值。 IE浏览器。如果你正在编写一个位置为19的玩家并且你将你的铲斗大小选为50,那么这将是你的第一个位置在1到50之间的玩家。在将位置19的玩家写入桌面之前,你的立面(或适配器等)您调用它)客户端中的代码层会检测到这是第一个存储桶,为该存储桶生成一个哈希并将该播放器写入表中,并将生成的哈希值作为分区密钥和实际播放器唯一ID作为其行键和其余属性。

您为存储桶生成的哈希可能只是桶的下限和上限的哈希等。确保使用加密哈希而不是Object.GethashCode,因为它可以为完全相同的对象返回不同的哈希值,并且应该不能用于他的目的。

当你想要获得范围X和Y之间的所有玩家时,你需要查询你知道哪些覆盖范围的分区,而不是整个表。并且您可以使用确切的分区键(表示存储桶的哈希值)来查询分区,这样它就会很有效。

当您插入播放器时,您需要为第一个查询创建2个实体1,为第二个查询创建第二个实体,并插入两个实体。此过程也称为非规范化数据,以针对不同的查询需求进行优化。希望这有助于理解如何使用Azure表优化这一点。

答案 2 :(得分:0)

Azure表存储有利于存储纯数据,而且价格低廉且易于扩展。但它对复杂查询没有好处。如果满足您的需求,您可以选择Table Storage来节省一些资金。价格范围从每千兆字节4.5到12美分。

Azure DocumentDB是一个分布式文档数据库。它比Azure Table Storage更强大,但也更昂贵。价格:每千兆字节/月25美分。

Azure Data Lake Store是针对大数据分析工作负载的优化存储,我们经常将其用于批量,交互式,流式分析和机器学习数据,如日志文件,物联网数据,点击流,大型数据集

如果可以满足您的需求,最好选择Azure表存储。根据您的描述,我建议您使用Azure表存储并使用不同的分区键优化查询。有关如何设计可扩展和高性能的表,下面的链接供您参考。

Azure Storage Table Design Guide: Designing Scalable and Performant Tables

  

获得玩家在记分牌中的位置。

如果我们想获得位置(排名),存储数据的最佳方式是使用分数作为分区键。如果我们只知道当前玩家的id,​​我们需要在查询位置之前获得当前玩家的得分。要根据玩家ID查询玩家,最好通过将玩家ID设置为分区键,在Azure表存储中存储另一个游戏数据副本。

  

获得位置X和Y之间的位置(玩家和得分)。

使用分数作为分区键适用于此场景。

总之,我建议您存储两个不同的游戏数据副本。一个是使用得分作为分区键,另一个是使用玩家ID作为分区键。

  

对于这两个查询,我都不知道该职位

您的查询的结果数据是按分区键排序。因此结果计数是您的玩家的位置(排名)。

例如,在将分数设置为分区键后,您可以使用小于分数的分区键(例如10)来查询实体范围,实体count是分数为10的玩家的位置。