Pregunta

Mi aplicación Python actualmente utiliza la API python-memcached para configurar y obtener objetos en memcached. Esta API utiliza el módulo de encurtido nativo de Python para serializar y deserializar los objetos de Python.

Esta API hace que sea simple y rápido almacenar listas anidadas de Python, diccionarios y tuplas en memcached, y leer estos objetos nuevamente en la aplicación es completamente transparente, simplemente funciona.

Pero no quiero limitarme a usar Python exclusivamente, y si todos los objetos memcached se serializan con pickle, los clientes escritos en otros idiomas no funcionarán.

Aquí están las serializaciones multiplataforma opciones que he considerado:

  1. XML: el principal beneficio es que es legible por humanos, pero eso no es importante en esta aplicación. XML también ocupa mucho espacio y es costoso analizarlo.

  2. JSON: parece un buen estándar multiplataforma, pero no estoy seguro de que conserve el carácter de los tipos de objetos cuando se lee desde memcached. Por ejemplo, según esta publicación las tuplas se transforman en listas cuando se usa simplejson ; Además, parece que agregar elementos a la estructura JSON podría romper el código escrito en la estructura anterior

  3. Google Protocol Buffers - Estoy realmente interesado en esto porque parece muy rápido y compacto, al menos 10 veces más pequeño y más rápido que XML; no es legible para humanos, pero eso no es importante para esta aplicación; y parece diseñado para soportar el crecimiento de la estructura sin romper el código antiguo

Teniendo en cuenta las prioridades de esta aplicación, ¿cuál es el método de serialización de objetos ideal para memcached?

  1. Soporte multiplataforma (Python, Java, C #, C ++, Ruby, Perl)

  2. Manejo de estructuras de datos anidados

  3. Serialización / deserialización rápida

  4. Huella de memoria mínima

  5. Flexibilidad para cambiar la estructura sin romper el código antiguo
¿Fue útil?

Solución 2

Probé varios métodos y me decidí por JSON comprimido como el mejor equilibrio entre velocidad y huella de memoria. La función Pickle nativa de Python es un poco más rápida, pero los objetos resultantes no se pueden usar con clientes que no sean Python.

Estoy viendo una compresión 3: 1, por lo que todos los datos se ajustan a Memcache y la aplicación obtiene tiempos de respuesta inferiores a 10 ms, incluida la representación de la página.

Aquí hay una comparación de JSON, Thrift, Protocol Buffers y YAML, con y sin compresión:

http://bouncybouncy.net/ramblings/posts/more_on_json_vs_thrift_and_protocol / p < >

Parece que esta prueba obtuvo los mismos resultados que obtuve con JSON comprimido. Como no necesito predefinir cada estructura, esta parece ser la respuesta multiplataforma más rápida y más pequeña.

Otros consejos

Una consideración importante es " ¿desea tener que especificar cada definición de estructura " ?

Si está de acuerdo con eso, puede echar un vistazo a:

  1. Protocol Buffers - http://code.google.com/apis/protocolbuffers /docs/overview.html
  2. Thrift - http://developers.facebook.com/thrift/ (más orientado a los servicios )

Ambas soluciones requieren archivos de soporte para definir cada estructura de datos.


Si prefiere no incurrir en la sobrecarga del desarrollador de predefinir cada estructura, eche un vistazo a:

  1. JSON (a través de python cjson y PHP json nativo). Ambos son realmente muy rápidos si no necesita transmitir contenido binario (como imágenes, etc.).
  2. Sin embargo, otro lenguaje de marcado @ http://www.yaml.org/ . También realmente rápido si obtienes la biblioteca correcta.

Sin embargo, creo que ambos han tenido problemas con el transporte de contenido binario, por lo que se descartaron para nuestro uso. Nota: YAML puede tener un buen soporte binario, deberá verificar las bibliotecas del cliente. Consulte aquí: http://yaml.org/type/binary.html


En nuestra empresa, lanzamos nuestra propia biblioteca (Extruct) para la serialización entre idiomas con soporte binario. Actualmente tenemos implementaciones (decentemente) rápidas en Python y PHP, aunque no es muy legible para los humanos debido al uso de base64 en todas las cadenas (soporte binario). Eventualmente los trasladaremos a C y usaremos una codificación más estándar.

Los lenguajes dinámicos como PHP y Python se vuelven realmente lentos si tienes demasiadas iteraciones en un bucle o tienes que mirar cada carácter. C, por otro lado, brilla en tales operaciones.

Si desea ver la implementación de Extruct, hágamelo saber. (información de contacto en http://blog.gahooa.com/ en " Acerca de mí quot;)

" Soporte multiplataforma (Python, Java, C #, C ++, Ruby, Perl) "

Lástima que este criterio sea el primero. La intención detrás de la mayoría de los idiomas es expresar las estructuras de datos fundamentales y el procesamiento de manera diferente. Eso es lo que hace que varios idiomas sean & Quot; problema & Quot ;: todos son diferentes.

Una representación única que sea buena en muchos idiomas es generalmente imposible. Hay compromisos en la riqueza de la representación, el rendimiento o la ambigüedad.

JSON cumple con los criterios restantes muy bien. Los mensajes son compactos y se analizan rápidamente (a diferencia de XML). La anidación se maneja muy bien. Cambiar la estructura sin romper el código siempre es dudoso: si elimina algo, el código antiguo se romperá. Si cambia algo requerido, el código anterior se romperá. Sin embargo, si está agregando cosas, JSON también se encarga de esto.

Me gusta la lectura humana. Ayuda con mucha depuración y solución de problemas.

La sutileza de hacer que las tuplas de Python se conviertan en listas no es un problema interesante. La aplicación receptora ya conoce la estructura que se está recibiendo y puede modificarla (si es importante).


Editar sobre rendimiento.

Analizando los documentos XML y JSON de 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 parece ser significativamente más rápido para el mismo contenido. Usé los módulos Python SimpleJSON y ElementTree en Python 2.5.2.

Puede interesarle este enlace:

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

Una alternativa: MessagePack parece ser el serializador más rápido que existe. Tal vez puedas intentarlo.

Hessian cumple con todos sus requisitos. Aquí hay una biblioteca de Python:

https://github.com/bgilmore/mustaine

La documentación oficial para el protocolo se puede encontrar aquí:

http://hessian.caucho.com/

Lo uso regularmente tanto en Java como en Python. Funciona y no requiere escribir archivos de definición de protocolo. No podría decirle cómo funciona el serializador de Python, pero la versión de Java es razonablemente eficiente:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top