我需要一些解决方案的灵感......
我们正在运行一个拥有大约80,000名活跃用户的在线游戏 - 我们希望扩展这一目标,因此设定了达到1-500,000个用户的目标。
游戏包含所有用户的高分,这是基于大量数据。需要在代码中处理此数据以计算每个用户的值。
计算出值后,我们需要对用户进行排名,并将数据写入高分数表。
我的问题是,为了为500.000用户生成一个高分,我们需要从数据库中加载25-30.000.000行的数据,总共大约1.5-2gb的原始数据。此外,为了对值进行排名,我们需要具有总值集 我们还需要尽可能多地生成高分 - 最好每30分钟一次。
现在我们可以使用蛮力 - 每30分钟加载30 mio记录,计算值并对它们进行排名,并将它们写入数据库,但我担心这会对数据库造成的压力,应用程序服务器和网络 - 如果可能的话 我认为解决这个问题的方法可能就是如何分解问题,但我看不出怎样。因此,我正在寻找基于这些信息的可能替代解决方案的一些灵感:
欢迎任何建议,链接到有关类似问题的好文章。
答案 0 :(得分:1)
有趣的问题。根据我的经验,批处理应该只作为最后的手段使用。在使用新数据插入/更新数据库时,通常最好让软件计算值。对于您的场景,这意味着它应该在每次插入或更新计算团队得分的任何数据时运行得分计算代码。使用团队记录将计算值存储在DB中。在计算值字段上放置一个索引。然后,您可以要求数据库对该字段进行排序,并且速度相对较快。即使有数百万条记录,它也应该能够在O(n)时间或更好的时间内返回前n个记录。我认为你甚至根本不需要高分表,因为查询速度足够快(除非你对高分表除了作为缓存之外还有其它需要)。该解决方案还为您提供实时结果。
答案 1 :(得分:1)
首先和formost:
一种可能的解决方案是:
结果仍需要一段时间,但至少性能不会受到太大影响。
答案 2 :(得分:1)
假设您的大部分2GB数据没有频繁更改,您可以每天计算和缓存(在db或其他地方)总计,然后根据自上次计算后提供的新记录添加差异。
在postgresql中,您可以将表聚类在表示插入记录的列上,并在该列上创建索引。然后,您可以对最近的数据进行计算,而无需扫描整个表。
答案 3 :(得分:0)
如何在数据库中保存这些分数,然后简单地在数据库中查询最高分数(以便计算在服务器端完成,而不是在客户端完成...因此无需移动数百万条记录。)
这听起来很直接......除非我错过了你的观点......让我知道。
答案 4 :(得分:0)
以滚动方式计算并存储每个活跃团队的得分。存储得分后,您应该能够在SQL中进行排序/排序/检索。为什么这不是一个选择?
答案 5 :(得分:0)
它可能会毫无结果,但我至少会在the way sorting is done较低的水平上看一眼,看看你是否能从中获得灵感。您可以一次抓取更多可管理的数据进行处理。
您是否运行测试以查看您对数据大小的担忧是否有效?如果软件针对它进行了优化,那么在中端服务器上投入大约2GB并不太困难。
答案 6 :(得分:0)
对我来说,这显然是一项工作,因为你应该能够将半百万分数记录保留在半本地,如果不是在RAM中。每次更新大数据库中的数据时,请对本地分数记录进行相应的调整。
对本地得分记录进行排序应该是微不足道的。 (它们几乎是为了开始。)
如果您只需要知道前100个或更高分数,那么排序就更容易了。您所要做的就是扫描列表并将每个元素插入排序为100个元素的列表。如果元素低于第一个元素,即99.98%的时间,则无需执行任何操作。
然后每天从整个数据库中运行一次大的更新,以消除任何蠕变的不一致。