我正在尝试设计一款使用Google AppEngine存储/处理/查询数据的应用,然后通过Cloud Endpoints API尽可能实时地向移动设备提供这些数据。
这是一个直接的解决方案,但我正在努力在AppEngine之间取得适当的平衡,性能,成本和延迟。
场景(类比)是用户签到(每天多次来自不同地点,城市,国家/地区),我们希望允许用户通过其设备查询所有数据并提供最新信息尽可能。
我们可以使用Memcache存储最新的签到,每隔5分钟推送到数据存储区,但这可能无法很好地扩展并且不健壮! 使用Cron作业运行任务队列/映射缩减以获取聚合,每30分钟获取每个位置的平均值并更新数据存储区。
挑战在于对数据存储区使用尽可能少的读/写,因为最后的“24小时”数据每5分钟就会发生变化,因此最后几周的数据,上个月的数据也是如此。数据必须在某种程度上是动态的,所以它不是固定的时间点,它们总是在变化 - 这就是问题所在!
设置它不是问题,但要以有效的方式进行设置,平衡用户的性能/延迟和成本/配额对我们来说并不容易!
简单的解决方案是使用SQL,并运行日期范围查询,但这不会很好地扩展。
我们最终可以使用BigTable& BigQuery用于“所有时间”时间段查询,但为了在其他时间段内通过API为用户提供尽可能实时的数据,这是一个非常大的挑战!
AppEngine架构/方法的任何建议都将受到严重欢迎。
非常感谢。
答案 0 :(得分:0)
Push Queue比Memcache更强大,可以添加新的签到。 Memcache和get_entity_group_version(key)会减少阅读量。
从用户历史记录中提前统计每日,每周,每月和每年维度的统计数据(例如大多数和最不受欢迎的位置),以减少查询记录计数(与分析数据库相同)。设计您的实时查询,以便将过去存储的聚合数据与您尚未聚合的少量当前数据合并。
答案 1 :(得分:0)
首先,写入数据存储区需要几毫秒。当您的用户点击刷新按钮(或您提供的任何内容)时,数据将是“实时”的。
通常,开发人员会在出现同步/拥塞问题时关注实时,即每个用户都可以更新某些内容(例如对某个项目进行出价),并且所有用户都必须获得相同的数据(最高出价)即时的。在您的情况下,如果用户获得1秒钟的签到次数会有什么危害?
其次,Memcache中的数据可能随时丢失。在您提出的解决方案中(每5分钟更新一次数据存储),您可能会在5分钟内丢失所有数据。
我宁愿在相反的方向上使用Memcache:从数据存储中读取数据,将其放入Memcache中60秒(或更长时间)到期,为Memcache中的所有用户提供服务,然后刷新它。这将使您的读数最小化。当然,我会这样做,除非您的用户绝对必须知道在过去60秒内发生了多少签到。
真正的问题是如何建模数据以优化写入。如果您不想丢失数据,则必须记录数据存储区中的每个签入。您可以通过确保没有不必要的索引字段来保存,从其他字段中分离出经常更新的字段等。