金氧

GAE 数据保存方式

GAE 为应用提供了多种保存数据的方式,例如大家熟知的 Datastore,不过也有一些方式大家不太熟悉。本文将尽量全地列出所有 GAE 上保存数据的方式,并分别描述其优势与劣势,以便开发者更明晰地进行选择。

Datastore

大家最熟悉、使用最广泛的保存数据的方式自然是 Datastore 了。Datastore 是 GAE 的非关系型数据库,它提供了健壮、持久的存贮,也提供了最具灵活性性的数据存取操作。

优势

持久 - 保存在 datastore 里的数据是持久的。
读写 - 应用能够读写保存在 datastore 里的数据,并且 datastore 提供了事务机制以保证完整性。
全局一致 - 所有应用实例拥有同一个 datastore 视图。
灵活 - 通过查询(Query)与索引提供了多种获取数据的方式。

劣势

延迟 - datastore 是把数据保存在磁盘上,并提供了可靠保证,写操作必须确保数据已经被保存才返回(译注:异步 API 呢?),读操作不得不经常从磁盘取回数据(译注:底层如何进行缓存的呢?)

Memcache

Memcache 是大家最熟悉的“二级”存储机制,它缓存数据以避免重复进行代价高(译注:例如 CPU、API 耗时特别高的调用)的操作。Memcache 常作为其他 APIs 的缓存层,例如 datastore,缓存某种数据源生成的结果集。

优势

快 - 毫秒级别的存取操作(译注:1-4 毫秒,还是比较慢的-_-b)。
全局一致 - 所有应用实例拥有同一个 memcache 视图。Memcache 提供了操作数据的原子操作,保证完整性(译注:对象序列化)。

劣势

不可靠 - 数据可能随时被丢弃(译注:GAE 默认会尽可能长时间地持有缓存项)。

Blobstore

Blobstore 提供了便捷高效保存用户上传的大数据的方法。

优势

支持大文件 - 2GB(译注:没有在现在的官方文档里找到根据。另外,30 秒的请求限制能传 2G?-_-b)。
不用自己处理 blob。
提供了高性能的 blobs 存取,特别是对图片。
应用能够向读取本地文件一样读取 blob。

劣势

只读 - 应用不能自行创建 blobs,也不能修改已上传的 blobs。
需要要付费才能使用 blobstore。

实例内存

应用实例也能通过类成员(译注:Java 里是类字段)或 globals(译注:貌似是 Python 里的概念)在本地(译注:该实例 JVM)内存中缓存数据。这个方式提供了最快的存取速度,但却有一些不利的方面。

优势

快 - 能有多快有多快,因为数据保存在正在访问的同一个进程中。
方便 - 不需要 GAE APIs。
灵活 - 能够保存任何格式的数据,没有序列化/反序列化限制。

劣势

不可靠 - 实例可能在任何时间被启动或关闭,所以应用只应该用这种方式来进行缓存数据(译注:应用实例的 JVM 内存不是跨实例的哦,所以这种方式缓存的数据可能会有一致性问题,见下点)。
不全局一致 - 每个应用实例都拥有自己的运行环境,自己的本地变量。对某一实例中的变量修改并不会影响其他实例。
容量限制 - 实例的内存使用是有大小限制的。

本地文件

应用可以使用标准文件系统 APIs 来读取随应用一起上传的文件。

优势

快 - 读取本地文件只需要访问应用实例运行的机器磁盘,延迟与 Memcache 接近。
可靠 - 只要应用在服务,就能够读取到文件。
灵活 - 能够使用任何格式的文件。

劣势

只读 - 应用不能修改文件;这些文件的内容在部署的时候就已经确定了。
容量限制 - 单个文件最大 10MB,应用所有文件大小总和必须小于 150MB。

任务队列负荷(Payloads)

虽然这不是传统意义上的存贮,但任务队列是能够保存持有一定的数据的。

优势

快 - 任务运行时发送 payloads,获取这些数据不用调用额外的 API。
如果使用得到,可以不用保存任务数据(译注:?)。

劣势

意图单一 - payloads 是提供给任务队列任务的数据存贮。
容量限制 - 任务最大大小 10KB(译注:现在 Push 队列是 100KB,Pull 队列是 1MB),包含了负荷数据。

结论

GAE 提供了多种数据存储机制,我们得在应用场景下选择适当的存储方式。通常,较好的方案是组合使用这些数据保存方式,例如 datastore 与 memcache,本地文件与实例内存。

注:

  1. 原文中的链接是 GAE/Python 版的,译文中的链接是 GAE/Java 版的
  2. “优势”/“劣势”这两个词可能翻译不当....

附上原文(Storage options on App Engine

« GAE Java 将支持 Servlet 3 Java 7 的新特性一览表 »