在 AppEngine 中思考
Posted
技术标签:
【中文标题】在 AppEngine 中思考【英文标题】:Thinking in AppEngine 【发布时间】:2010-11-01 21:01:07 【问题描述】:我正在寻找资源来帮助将我的设计技能从传统的 RDBMS 数据存储迁移到 AppEngine DataStore(即:“软架构”风格)。我看过几个演示文稿,都涉及到总体主题和一些具体技术。
我想知道是否有一个地方我们可以从经验(“来自战壕”)中汇集知识,以重新思考数据的结构方式,尤其是移植现有应用程序。我们在很大程度上基于 Hibernate,并且可能已经在我们的数据模型上走错了路,生成了一些我们的数据库正在努力解决的粗糙查询。
如果出现以下情况,请回复:
-
您已将一个重要的应用程序移植到 AppEngine
您已经在 AppEngine 中从头开始创建了一种通用类型的应用程序
您尚未完成 1 或 2,但正在考虑并希望分享您迄今为止的发现。
【问题讨论】:
Stack Overflow 上有一个类似的问题:***.com/questions/103727/… 【参考方案1】:我想知道是否有一个地方我们可以从经验中汲取知识
各种 Google 群组对此都有好处,但我不知道是否有任何直接适用于 Java-GAE —— 到目前为止,我的 GAE 经验都是 Python (我很自豪地说 Guido van Rossum 是 Python 的发明者,现在在谷歌的 App Engine 工作,他告诉我,我教了他一些关于他的创意如何工作的东西——他的建议提到,这是我现在最自豪的一个,在我的 LinkedIn 上所有的人中轮廓;-)。 [我在 Google 工作,但我对 App Engine 的影响非常有限——我致力于“构建云”、集群和网络管理软件,而 App Engine 旨在使该基础架构对第三方开发人员有用]。
确实有很多关于如何最好地对数据进行非规范化和分片以实现最佳 GAE 扩展和性能的文章和演示文稿——尽管它们的质量参差不齐。到目前为止出版的书都是马马虎虎;在接下来的几个月里还会有更多,希望是更好的(我有一个项目要写其中一个,有两个非常熟练的朋友,但我们都很忙,最终放弃了它)。总的来说,我会推荐谷歌 I/O 视频和谷歌在其应用引擎网站和博客中祝福的文章,加上来自 appenginefan's blog 的每一点内容——Guido 称赞我教他 GAE,我在主要是从 appenginefan 那里学到的(部分是通过 Palo Alto 的精彩 app engine meetup,但他的博客也很棒;-)。
【讨论】:
【参考方案2】:我玩过 Google App Engine for Java,发现它有很多缺点:
这不是通用的 Java 应用程序托管。特别是,您无法访问完整的 JRE(例如,无法创建线程等)。鉴于这一事实,您几乎必须从头开始构建您的应用程序,并牢记 Google App Engine JRE。移植任何非平凡的应用程序都是不可能的。
与您的数据存储问题更相关...
数据存储性能极差。我试图每小时写 5000 个天气观测——没什么太大的——但我做不到,因为我不断地遇到数据存储和 HTTP 请求的超时异常。使用“低级”数据存储 API 有所帮助,但还不够。
我想在 24 小时后删除那些天气观测,以免填满我的配额。同样,由于删除操作花费了太长时间,所以无法执行此操作。这个问题又导致我的数据存储配额被填满。疯狂的是,您无法轻松删除 GAE 数据存储中的大量数据。
有些功能是我喜欢的。 Eclipse 集成很时髦。 apppot 应用程序服务器 UI 比使用 Tomcat 好一百万倍(例如,日志的漂亮视图)。但对我来说,这些缺点远远超过了这些好处。
总之,我经常发现自己不得不shave the yak,才能做一些在任何普通Java/应用程序托管环境中都非常简单的事情。
【讨论】:
您将数据存储性能归类为“糟糕”——您能否详细说明您在做什么?数据存储交互的一个重要组成部分是往返时间;批处理操作在这里有很大的不同。 @Nick 不幸的是,您不能批处理。请参阅is.gd/YWPj“保存多个对象...”,尽管他们说他们正在解决这个问题。同样,使用低级 API 可以获得类似批处理的性能,但仍然太慢。我试图坚持每小时大约 5000 次的天气观测(温度、压力等)。没有什么戏剧性的。 我不相信这是正确的。通过 Java 中的 JPA 或 JDO 可以进行批量获取和放置。我已经在一些代码示例中看到了这一点。 googleappengine.blogspot.com/2009/06/…(参见该页面上的第 5 项) @马克。我相信那个 Python 示例并不指向高级 PersistenceManager API,而是指向低级数据存储 API(再次参见 is.gd/YWPj is.gd/Z4Pv)。正如我所提到的,这是我为提高性能所做的。但是还是太慢了。我最终“填充”了一个数据结构,并通过 cron 逐渐将其保存在更小的块中。这个解决方案很烦人,它增加了很多复杂性。当需要删除旧数据以避免配额问题时,我又遇到了超时问题。那时我认为 GAE 持久性框架太不成熟,不可扩展。 @Julien:你可以在 Python 中进行批处理,这个问题同时被标记了。您还没有确切地说出您在做什么,所以我无法评论是否有更好的方法,但可伸缩性是您有时必须首先跳过箍的原因 - 您的代码也可以工作1qps 与 1kqps 一样。【参考方案3】:超时时间很紧,性能还可以,但不是很好,所以我发现自己使用了额外的空间来节省时间;例如,我在交易卡和玩家之间有一个多对多的关系,所以我复制了谁拥有什么的信息:卡对象有一个玩家列表,玩家对象有一个卡列表。
通常将所有信息存储两次会很愚蠢(并且容易不同步),但效果非常好。
他们最近在 Python 中发布了一个远程 API,因此您可以获得数据存储的交互式 shell,这样您就可以在没有任何超时或限制的情况下使用数据存储(例如,您可以删除大量数据,或重构模型) ;这非常有用,因为否则正如 Julien 提到的那样,很难进行任何批量操作。
【讨论】:
【参考方案4】:非关系型数据库设计本质上尽可能地涉及非规范化。
示例:由于 BigTable 没有提供足够的聚合功能,RDBMS 世界中的 sum(cash) 选项不可用。相反,它必须存储在模型中,并且必须覆盖模型保存方法以计算非规范化字段总和。
想到的基本设计是每个模板都有自己的模型,其中所有需要填充的字段都以非规范化的形式出现在相应的模型中;并且您的模型中有一个完整的信号更新机器人复杂性。
【讨论】:
以上是关于在 AppEngine 中思考的主要内容,如果未能解决你的问题,请参考以下文章