首页 文章

Azure上的游戏记分牌

提问于
浏览
2

你可以推荐一个在Azure Cloud 上存储游戏分数的替代解决方案吗?我正在寻找 managedcheap to runeasily scalable up and down 存储选项 .

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

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

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

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

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

3 回答

  • 0

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

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


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

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

    • 读取得分高于阈值的所有得分记录,按得分排序

    • 为玩家等级创建一个新表格,例如 player-scores-170401-124200

    • 为整体排名创建一个新表格,例如 scoreboard-170401-124200

    • 将排名记分板批量写入新表

    通过这种方式,您可以在 PartitionKey=player 上查询 player-scores 以获得单个排名,并使用不等式过滤器查询 scoreboard 以获取位置窗口 .

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

    运行计算也不是想要密切关注的 . 假设n分数记录:

    • 您可以批量阅读100.交易〜= n / 100

    • 您可以批量写入100个相同的分区 . 交易〜= 2n / 100

    • 您可以选择保留历史排名,或在单个事务中删除整个表

    所以你的1M记录的总交易是:

    1000000*3/100 = 30,000 per run

    每天工作一天(720k交易),每天花费大约2-3美分(当然不包括存储成本) . 在我的书中运行起来很便宜:-)

  • 0

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

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

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

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

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

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

  • 1

    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的玩家的位置 .

相关问题