使用Objectify Appengine存储大blob

xyb*_*rek 5 google-app-engine objectify

我有这个类,我想使用Objectify持久化,这个类将表示大于1MB的数据,因此有一个Blob对象列表,它表示存储的字节数组的片段,其大小小于1MB:

@Entity
public class BigBlob {

    @Id
    private Long id;
    public static final int FRAGMENT_LIMIT = 777 * 1024;
    @Serialized
    private List<Blob> fragments = new ArrayList<Blob>();

    ...

}
Run Code Online (Sandbox Code Playgroud)

然而,"片段"是@Serialized,它将使这个BigBlob类/对象的大小大于1MB.

导致此错误:

com.google.apphosting.api.ApiProxy$RequestTooLargeException: The request to API call datastore_v3.Put() was too large.
Run Code Online (Sandbox Code Playgroud)

如果我使用@Embedded注释,我会收到此错误:

Cannot place array or collection properties inside @Embedded arrays or collections
Run Code Online (Sandbox Code Playgroud)

如何确保"片段"作为单独的实体存储?

顺便说一下,我已经有了字节分块逻辑,它会切断整个字节数组并将片段放入其中List,Blob因此这个问题与如何切割字节无关.

我想知道的更多是坚持不懈的一面.

sti*_*ure 2

Rick 的答案确实是最好的 - 将 blob 存储在 blobstore 中,特别是如果您是 GAE 新手并且对数据存储有概念问题的话。

另一方面,使用分割实体来存储 blob 有一些充分的理由,特别是当您存储接近 1M 边缘的数据时。您不会希望使用 100MB blob 来执行此操作,但 2MB blob 是有意义的。

首先,您不需要序列化或嵌入。这些只是在单个实体内构建数据的简单方法。

此外,没有神奇的注释可以让您跨实体分割 blob。你必须手工完成这一切。您不需要实际创建“主”或根实体;只需创建所有具有由 id 定义的父级(但没有实际实体)的实体片段,并使用祖先()查询来获取所有片段。

  • 与 put() 或 get() 实体的简单性相比,文件 API 是一个庞然大物,并且使用普通的 blob 上传 URL 对程序逻辑具有高度侵入性。关于事务 - 为什么您*不*想要跨越 blobstore 和数据存储的事务?我经常编写一个 blob 以及该 blob 的一些附加元数据。我必须经历一些重大的困难才能使操作应该是事务性的。 (3认同)
  • 当然可以,但是与 blobstore 相关的 API 使用起来很麻烦,并且无法轻松地与其他数据存储工作进行事务处理。有时,即使使用多实体攻击,使用数据存储也会变得相当容易。另一方面,blobstore 存储比数据存储存储便宜,因此不应轻率地做出此选择。 (2认同)