如何在多个Google App Engine实例间保持全局变量持久性?
我们的情况是这样的: 我们正在做一个学校项目,目的是让多个团队在城市里用智能手机边走边玩一个城市游戏。 这样一来,我们可能会有10部智能手机在城市里活动,它们会不断发送自己的位置,并从谷歌的应用引擎请求数据。
同时,有人会在网页浏览器前观察这些团队的活动,并给他们发送消息等等。
我们使用谷歌应用引擎提供的数据存储来保存这些团队发送和请求的所有数据,包括消息的存储和检索等。 但我们很快发现,我们的读取和写入次数达到了上限,因此我们开始寻找解决方案,希望能在不消耗谷歌提供的有限资源的情况下,获取定期更新(这部分最耗费读取和写入次数)。显然,因为这是一个学校项目,我们不想为更多的读取和写入付费。
把这些信息存储在全局变量中看起来是一个简单快捷的解决方案,确实如此……但当我们开始真正测试时,发现有些数据会消失然后又重新出现。后来发现这是因为云端的请求太多,导致创建了新的实例,而实例之间的全局变量并不会保持一致。
所以我们的问题是: 我们能否确保这些全局变量在谷歌应用引擎的每个运行实例中始终保持一致? 或者 我们能否将运行的实例数量限制为“1”,无论请求有多少? 或者 有没有其他更好的方法来存储这些数据,而不使用数据存储,也不使用全局变量?
4 个回答
这个问题挺有意思的。先说点不太好的消息,我觉得没有更好的数据存储方法;你无法阻止新的实例出现,也不能让不同的实例总是拥有相同的数据。
你可以让这些实例定期和数据库里的主记录同步。通过聪明地选择同步的频率,并一次性下载或上传信息,你可以把读取和写入的次数控制在一个合适的水平。不过,这种方法其实有点儿像临时拼凑的解决方案。
虽然我找到了其他很多东西的配额限制,但我找不到免费读写的限制,所以可能这些限制非常小。不过你用10部智能手机就碰到限制,这让我觉得有点不对劲。你确定这些手机在合理的频率下进行数据请求吗?听起来你可能在不必要地频繁请求数据。
首先,肯定要使用memcache,正如Tim Delaney所说的那样。光这一点就可能解决你的问题。
如果还是不行,你可以考虑使用推送模型。这样做的好处是,用户不会一直向你请求新数据,而是只有在数据真的发生变化时才会请求。如果更新的数据量小到可以直接在推送消息中发送,那么你就不需要担心因为memcache未命中而导致的数据读取,或者其他重复的工作:你只需在数据变化时读取一次,然后把它推送给所有人。
推送的第一个选择是C2DM(适用于Android)或APN(适用于iOS)。这两者在发送的数据量和更新频率上都有一些限制。
如果你想要更高级一点的方案,可以考虑使用XMPP。这种方式可以让你更频繁地更新数据,并且(我认为)可以发送更大的数据包,但可能需要更多的工程技术。作为起点,可以查看关于Android和iOS的Stack Overflow问题。
祝你玩得开心!
你应该使用memcache。假如你使用的是ndb(新数据库)库,它可以自动缓存查询的结果。显然,这对你的写入操作帮助不大,但可以显著提高你读取数据的速度。
你需要把它和数据存储结合起来,因为memcache里的数据随时可能被清除。如果你愿意冒一点(小)风险,可能会丢失一些更新,你可以只用memcache。你可以在数据存储中只保存一个消息ID,然后让控制器定期检查每个消息ID在memcache中是否都有对应的条目。如果有缺失,控制器就需要重新把它放进去。