Stockage de gros blob avec Objectify Appengine

J'ai cette classe que je veux persister en utilisant Objectify, cette classe représentera une donnée supérieure à 1 Mo donc il y a une liste d'objets Blob qui représente un fragment du tableau d'octets stocké qui a une taille inférieure à 1 Mo:

@Entity
public class BigBlob {

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

    ...

}

Pourtant, les "fragments" sont @Serialized, ce qui rendra la taille de cette classe/objet BigBlob supérieure à 1 Mo.

Provoquant cette erreur:

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

Si j'utilise l'annotation @Embedded, j'obtiens cette erreur:

Cannot place array or collection properties inside @Embedded arrays or collections

Comment puis-je m'assurer que les "fragments" sont stockés en tant qu'entité séparée?

BTW, j'ai déjà la logique de segmentation octet qui coupe tout le tableau d'octets et mettre les fragments dans un List de Blob donc cette question ne se rapporte pas à la façon de couper les octets .

Surtout ce que je veux savoir est plus sur le côté persistant.

5

2 Réponses

Vous devriez le stocker dans le Blobstore et juste sauvegarder le Blobkey dans Objectify. Objectify fonctionne sur le datastore, pas sur le blobstore.

4
ajouté

La réponse de Rick est vraiment la meilleure blobs de magasin dans le blobstore, surtout si vous êtes nouveau à GAE et avoir des problèmes conceptuels avec le datastore.

D'un autre côté, il existe de bonnes raisons d'utiliser des entités fractionnées pour stocker des blobs, en particulier si vous stockez des données proches du bord 1M. Vous ne voudriez pas faire cela avec des blobs de 100MB, mais des blobs de 2MB peuvent avoir du sens.

Tout d'abord, vous ne voulez pas sérialisé ou incorporé. Ce sont simplement des moyens de structurer les données au sein d'une même entité.

En outre, il n'y a pas d'annotation magique qui vous permet de diviser les blobs entre les entités. Vous devez tout faire à la main. Vous n'avez pas besoin de créer réellement une entité «maître» ou racine; Il suffit de créer tous les fragments d'entité avec un parent défini par un identifiant (mais pas d'entité réelle) et d'utiliser une requête ancêtre() pour récupérer toutes les pièces.

2
ajouté
@stickfigure Vous voulez dire que l'API FileService télécharge réellement des fichiers lorsque j'écris un fichier AppengineFile? Dans mon cas, j'ai stocké des métadonnées avec Objectify et stocké en utilisant les octets à l'aide de Fileservice api.
ajouté l'auteur xybrek, source
Vous pouvez certainement le faire, mais les API liées au blobstore sont difficiles à utiliser et ne peuvent pas être facilement transposées avec d'autres travaux de banque de données. Parfois, il est considérablement plus facile d'utiliser le magasin de données, même avec le hack à entités multiples. D'un autre côté, le stockage blobstore est moins cher que le stockage de banque de données, ce choix ne doit donc pas être fait de manière frivole.
ajouté l'auteur stickfigure, source
Comparé à la simplicité de put() ing ou de get() d'une entité, l'API Files est une monstruosité, et l'utilisation de l'URL de téléchargement blob normale est très invasive pour la logique du programme. En ce qui concerne les transactions - pourquoi ne voudriez-vous pas que vous vouliez des transactions qui couvrent blobstore et datastore? J'écris souvent un blob et des métadonnées supplémentaires pour ce blob. Je dois passer par des étapes importantes pour que l'opération soit transactionnelle.
ajouté l'auteur stickfigure, source
Avec tous les fichiers et les canaux et les verrous et les lecteurs et les écrivains, l'API Java Files se sent sur-ingénierie. L'API Python Files ne semble pas avoir le même problème, et cela ne s'explique pas par les différences de langue. Alors que vous avez encore besoin d'un peu de mémoire pour faire des blobs multi-entités, c'est un montant trivial et intuitif pour quelqu'un qui connaît déjà l'API de datastore. Mais vraiment, l'argument principal pour les blobs multi-entités est de pouvoir s'intégrer à la logique transactionnelle de votre application.
ajouté l'auteur stickfigure, source
"D'un autre côté, il existe de bonnes raisons d'utiliser des entités dédoublées pour stocker des blobs, surtout si vous stockez des données proches du bord 1M" - pas vraiment, il n'y a aucune raison de ne pas stocker les blobs inférieurs à 1MB le blobstore, aussi.
ajouté l'auteur Nick Johnson, source
Qu'en est-il des API blobstore avec lesquelles il est difficile de travailler? Et pourquoi avez-vous besoin d'une transaction qui couvre le blobstore et le datastore?
ajouté l'auteur Nick Johnson, source
Je ne sais pas pourquoi cela se qualifie de 'monstruosité' - c'est aussi simple que possible de réaliser ce qu'il faut faire, à mon avis. Et la comparaison ne porte pas sur un seul argument, mais sur l'infrastructure dont vous avez besoin pour construire une propriété BLOB sur plusieurs entités!
ajouté l'auteur Nick Johnson, source
Le stockage Google est lent avec les opérations en masse (par exemple, les archives) si vous avez plusieurs (millions) petites tâches. Il est peut-être préférable d'utiliser DataStore et de partager des blobs qui dépassent 1 Mo.
ajouté l'auteur xmedeko, source
Il y a toujours une limite de 10 Mo par requête, donc si vous divisez plus de 10 Mo de fichier, vous ne pouvez pas l'obtenir par une requête.
ajouté l'auteur xmedeko, source