如何缓存复杂计算的临时数据

时间:2014-01-07 20:09:20

标签: symfony caching redis memcached varnish

我有一个应用程序,允许人们赌足球比赛的结果。 通过将下注的投注得分与游戏中的实际结果(=实体)进行比较来计算每个单个投注(=实体)的得分。 Bet's在Betrounds内打赌。 Betrounds是组织在游戏组(游戏组,例如单个比赛日)上下注的组织。单个用户组可以有几个响应。

总结关系模型: 用户组1:N BetRounds 1:N投注N:1游戏

在每个betround中,我创建一个结果表,向每个用户显示他们的结果点和位置。 为了计算一个用户的位置,我需要计算一个betround中每个用户的点数。 来自单个betrounds的这些点被聚合成组,并且在组内再次存在结果表。

示例

  • 用户组:20位用户
  • One Season有34个比赛日
  • 一场比赛日有9场比赛

为了计算该用户组的积分,我需要计算20 * 34 * 9 = 6120投注的积分。

由于这是很多要计算的,所以每次显示结果表时我都不想这样做。 我目前看到两个选项,以节省一些计算时间:

  1. 高速缓存
  2. 保存数据库中的中间结果(例如,在投注实体上)
  3. 也许是两者兼而有之。
  4.   
        
    1. 高速缓存
    2.   

    如果缓存是正确的方式,我不确定在哪个级别以及如何使其无效。 有几个选项可以缓存: - 单笔投注的结果 - 在一个betround内的单个用户的点结果 - 一个betround的整个结果表(点和位置) - 用户组内单个用户的结果 - 用户组的整个结果表

    我不确定如何缓存这些数据: - 只是位置和点的整数值 - 整个实体(例如投注) - 临时非持久性实体(例如代表结果表) - 表格的html输出

    然后依赖于格式如何缓存它: - 可以通过反向代理缓存html视图 - 值/实体可能通过redis / memcache等。

    将来我们可能会更改为单页应用程序,数据仅通过restapi提供,然后缓存html输出不是一个选项。

    依赖于缓存策略,问题就出现了如何使缓存无效并可选择加热缓存,以便在应用程序中永远不会计算结果,但只有在缓存失效并立即替换为新结果时才重新计算结果。

    我经常读到缓存失效是邪恶的。我不确定这是否适用于我的用例,因为所有点/结果/表格等仅在我的界面更新游戏结果时才会改变。这是积分变化的唯一时间。

      

    2.在数据库中保存中期结果(例如在投注实体上)

    我不确定这种情况是否适用于所有级别。我首先考虑将实际结果保存在赌注上,而不是总是将赌注分数与实际分数进行比较。这将使我的数据模型有点冗余,如果我的界面提取了错误的结果,我的复杂性增加了,之后正确的进入并且我的点数没有重新计算。

    在所有其他级别上,我需要创建新的临时实体来持久存储表结果。

      

    3.Mix of both

    我不确定混合两者是什么样的,如果它有意义,但我认为它可能是一种选择。

    任何建议,意见或经验都将受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

我只是稍微理解投注,所以希望这会有所帮助。

听起来你在问两个问题:

  1. 我何时计算结果?
  2. 我应该使用多少缓存?
  3. 对我而言,听起来有非常明显的事件发生,之后您可以成功计算出结果。您的设计应该利用这一点并在性质上进行。您应该有后台进程可以检测游戏何时完成。应该编写游戏结果,并且应该触发其他后台作业来计算依赖于该游戏的任何投注的结果。

    这也可能是任何涉及该游戏的缓存,该游戏产生的结果,或该游戏的任何投注结果,都应该被无效和/或刷新。

    应该根据缓存需要多少来缓存。缓存应与计算结果分开考虑。那不是缓存。这是计算结果并存储它们。您绝对不应该在页面查看请求期间计算结果,并且应该在相应事件(游戏结束)触发计算时提前完成。

    您的数据库应该始终代表您对所有内容的最新信息。如果可能的话,您应该尽量避免进行任何计算。

    我会先让所有活动和背景资料工作,然后看看你会得到什么样的表现。此时,您的应用程序应该只执行结果并将其粘贴到每个页面视图的视图中。如果那部分太慢,那么你应该开始考虑缓存你的views / templates / html。如前所述,当您的后台工作人员遇到新结果时,这些缓存可能会失效。