Quelle est la meilleure méthode de sérialisation pour les objets dans memcached?

Mon application Python utilise actuellement l'API Python-memcached pour définir et obtenir des objets dans memcached. Cette API utilise le module pickle natif de Python pour sérialiser et désérialiser les objets Python.

Cette API permet de stocker simplement et rapidement des listes Python imbriquées, des dictionnaires et des tuples dans memcached, et la lecture de ces objets dans l'application est complètement transparente - cela fonctionne simplement.

Mais je ne veux pas me limiter à utiliser Python exclusivement, et si tous les objets memcached sont sérialisés avec pickle, les clients écrits dans d'autres langues ne fonctionneront pas.

Voici les options de sérialisation multiplateforme que j'ai considérées:

  1. XML-le principal avantage est qu'il est lisible par l'homme, mais ce n'est pas important dans cette application. XML prend également beaucoup d'espace, et il est coûteux à analyser.

  2. JSON-semble être un bon standard multi-plateforme, mais je ne suis pas sûr qu'il conserve le caractère de types d'objets lors de la lecture à partir de memcached. Par exemple, selon ce post les tuples sont transformés en listes lors de l'utilisation de simplejson ; en outre, il semble que l'ajout d'éléments à la structure JSON pourrait casser le code écrit dans l'ancienne structure

  3. Google Protocol Buffers - je suis vraiment intéressé par cela car il semble très rapide et compact-au moins 10 fois plus petit et plus rapide que XML; ce N'est pas lisible par l'homme, mais ce n'est pas important pour cette application; et il semble conçu pour soutenir la croissance de la structure sans casser l'ancien code

Compte tenu des priorités de cette application, Quelle est la méthode de sérialisation d'objet idéale pour memcached?

  1. support multiplateforme (Python, Java, C#, C++, Ruby, Perl)

  2. gestion des structures de données imbriquées

  3. sérialisation rapide / désérialisation

  4. mémoire minimale empreinte

  5. flexibilité pour changer de structure sans casser l'ancien code
24
demandé sur Community 2009-02-01 00:17:24

5 réponses

Une considération majeure est "Voulez-vous avoir à spécifier chaque définition de structure"?

Si vous êtes D'accord avec cela, alors vous pouvez jeter un oeil à:

  1. tampons de protocole - http://code.google.com/apis/protocolbuffers/docs/overview.html
  2. Épargne http://developers.facebook.com/thrift/ (plus orientée vers les services)

Ces deux solutions nécessitent des fichiers de support pour définir chaque structure de données.


Si vous préférez ne pas encourir la surcharge du développeur de Pré-définir chaque structure, alors jetez un oeil à:

  1. JSON (via Python cjson, et PHP JSON natif). Les deux sont vraiment très rapides si vous n'avez pas besoin de transmettre du contenu binaire (comme des images, etc...).
  2. Encore un autre langage de balisage @ http://www.yaml.org / . aussi très rapide si vous obtenez la bonne bibliothèque.

Cependant, je crois que ces deux ont eu des problèmes avec transporter du contenu binaire, c'est pourquoi ils ont été exclus de notre utilisation. Note: YAML peut avoir un bon support binaire, vous devrez vérifier les bibliothèques clientes - voir ici: http://yaml.org/type/binary.html


Dans notre entreprise, nous avons déployé notre propre bibliothèque (Extruct) pour la sérialisation inter-langues avec le support binaire. Nous avons actuellement (décemment) des implémentations rapides en Python et PHP, bien qu'il ne soit pas très lisible par l'homme en raison de l'utilisation de base64 sur tous les cordes (binaire de soutien). Finalement, nous les porterons en C et utiliserons un codage plus standard.

Les langages dynamiques comme PHP et Python deviennent vraiment lents si vous avez trop d'itérations dans une boucle ou si vous devez regarder chaque caractère. C d'autre part brille à de telles opérations.

Si vous souhaitez voir L'implémentation D'Extruct, faites-le moi savoir. (coordonnées à http://blog.gahooa.com/ sous "à propos de moi")

7
répondu gahooa 2009-02-19 06:14:44

J'ai essayé plusieurs méthodes et réglé sur JSON compressé comme le meilleur équilibre entre la vitesse et l'empreinte mémoire. La fonction Pickle native de Python est légèrement plus rapide, mais les objets résultants ne peuvent pas être utilisés avec des clients non-Python.

Je vois une compression 3:1 de sorte que toutes les données correspondent à memcache et que l'application obtient des temps de réponse inférieurs à 10ms, y compris le rendu de la page.

Voici une comparaison de JSON, Thrift, Protocol Buffers et YAML, avec et sans de compression:

Http://bouncybouncy.net/ramblings/posts/more_on_json_vs_thrift_and_protocol_buffers/

On dirait que ce test a obtenu les mêmes résultats que j'ai obtenus avec JSON compressé. Comme je n'ai pas besoin de prédéfinir chaque structure, cela semble être la réponse multiplateforme la plus rapide et la plus petite.

7
répondu mb. 2009-03-01 20:47:27

"support multiplateforme (Python, Java, C#, C++, Ruby, Perl)"

Dommage que ce critère soit le premier. L'intention derrière la plupart des langages est d'exprimer les structures de données fondamentales et le traitement différemment. C'est ce qui fait de plusieurs langues un "problème": elles sont toutes différentes.

Une seule représentation qui est bonne dans de nombreuses langues est généralement impossible. Il y a des compromis dans la richesse de la représentation, de la performance ou de l'ambiguïté.

JSON rencontre le critères restants bien. Les Messages sont compacts et analysent rapidement (contrairement à XML). La nidification est traitée très bien. Changer la structure sans casser le code est toujours incertain - si vous supprimez quelque chose, l'ancien code se cassera. Si vous modifiez quelque chose qui était requis, l'ancien code se cassera. Si vous ajoutez des choses, cependant, JSON gère cela aussi.

J'aime lisible par l'homme. Cela aide avec beaucoup de débogage et de dépannage.

La subtilité d'avoir des tuples Python se transformer en listes n'est pas un problème intéressant. L'application réceptrice connaît déjà la structure reçue et peut la modifier (si cela compte.)


Modifier les performances.

Analyse des documents XML et JSON depuis http://developers.de/blogs/damir_dobric/archive/2008/12/27/performance-comparison-soap-vs-json-wcf-implementation.aspx

XmlParse 0.326 jsonParse 0.255

JSON semble être beaucoup plus rapide pour le même contenu. J'ai utilisé le Python SimpleJSON et les modules ElementTree en python 2.5.2.

2
répondu S.Lott 2009-02-01 04:13:31

Vous pourriez être intéressé par ce lien:

Http://kbyanc.blogspot.com/2007/07/python-serializer-benchmarks.html

Une alternative: MessagePack semble être le sérialiseur le plus rapide. Peut-être que vous pouvez lui donner un essai.

2
répondu GrosBedo 2010-09-16 02:07:53

Hesse répond à toutes vos exigences. Il y a une bibliothèque python ici:

Https://github.com/bgilmore/mustaine

La documentation officielle du protocole se trouve ici:

Http://hessian.caucho.com/

Je l'utilise régulièrement en Java et en Python. Cela fonctionne et ne nécessite pas d'écrire des fichiers de définition de protocole. Je ne pouvais pas vous dire comment le sérialiseur Python fonctionne, mais la version Java est raisonnablement efficace:

Https://github.com/eishay/jvm-serializers/wiki/

1
répondu stickfigure 2012-02-16 21:25:25