Todos estos proporcionan serialización binaria, marcos RPC e IDL. Estoy interesado en las diferencias clave entre ellos y las características (rendimiento, facilidad de uso, soporte de lenguajes de programación).
Si conoce otras tecnologías similares, menciónelo en una respuesta.
protocol-buffers
thrift
asn.1
avro
andreypopp
fuente
fuente
Respuestas:
ASN.1 es un estándar ISO / ISE. Tiene un lenguaje fuente muy legible y una variedad de back-end, tanto binarios como legibles por humanos. Al ser un estándar internacional (¡y antiguo!), El idioma de origen es un poco complicado para la cocina (casi de la misma manera que el Océano Atlántico está un poco húmedo) pero está extremadamente bien especificado y tiene una cantidad decente de soporte . (Probablemente pueda encontrar una biblioteca ASN.1 para cualquier idioma que nombre si profundiza lo suficiente, y si no, hay buenas bibliotecas de lenguaje C disponibles que puede usar en las FFI). Es un lenguaje estandarizado, obsesivamente documentado y tiene algunos buenos tutoriales disponibles también.
El ahorro no es un estándar. Es originalmente de Facebook y luego fue de código abierto y actualmente es un proyecto de Apache de alto nivel. No está bien documentado, especialmente los niveles de tutoría, y a mi parecer (sin duda breve) no parece agregar nada que otros esfuerzos anteriores ya no hacen (y en algunos casos mejor). Para ser justos, tiene una cantidad bastante impresionante de idiomas que admite de forma inmediata, incluidos algunos de los de mayor perfil no convencionales. El IDL también es vagamente similar a C.
Protocol Buffers no es un estándar. Es un producto de Google que se está lanzando a la comunidad en general. Es un poco limitado en términos de lenguajes admitidos de fábrica (solo es compatible con C ++, Python y Java) pero tiene una gran cantidad de soporte de terceros para otros lenguajes (de calidad muy variable). Google hace casi todo su trabajo utilizando Protocol Buffers, por lo que es un protocolo probado en batalla, aunque no tan duro como ASN.1. Tiene una documentación mucho mejor que Thrift, pero, siendo un Producto de Google, es muy probable que sea inestable (en el sentido de un cambio constante, no en el sentido de no confiable). El IDL también es similar a C.
Todos los sistemas anteriores usan un esquema definido en algún tipo de IDL para generar código para un idioma de destino que luego se usa en la codificación y decodificación. Avro no. El tipeo de Avro es dinámico y sus datos de esquema se usan en tiempo de ejecución directamente tanto para codificar como para decodificar (lo que tiene algunos costos obvios en el procesamiento, pero también algunos beneficios obvios frente a los lenguajes dinámicos y la falta de necesidad de etiquetar tipos, etc.) . Su esquema usa JSON, lo que hace que sea más fácil administrar Avro en un nuevo idioma si ya hay una biblioteca JSON. Nuevamente, como con la mayoría de los sistemas de descripción de protocolos de reinvención de ruedas, Avro tampoco está estandarizado.
Personalmente, a pesar de mi relación de amor / odio con él, probablemente usaría ASN.1 para la mayoría de los propósitos de transmisión de mensajes y RPC, aunque en realidad no tiene una pila de RPC (tendrías que hacer uno, pero los COI hacen que Suficientemente simple).
fuente
...
marcadores de extensión o automática a travésEXTENSIBILITY IMPLIED
del encabezado del módulo. Protocol Buffers, IIRC, admite versiones manuales. No sé si es compatible con algo como la extensibilidad implícita (y soy demasiado vago para buscarlo). Thrift también admite algunas versiones, pero nuevamente me parece un proceso manual sin la extensibilidad implícita.EXTENSIBILITY IMPLIED
.Acabamos de hacer un estudio interno sobre serializadores, aquí hay algunos resultados (¡para mi referencia futura también!)
Ahorro = serialización + pila RPC
La mayor diferencia es que Thrift no es solo un protocolo de serialización, es una pila RPC completa que es como una pila SOAP moderna. Entonces, después de la serialización, los objetos podrían (pero no obligatorios) enviarse entre máquinas a través de TCP / IP. En SOAP, comenzó con un documento WSDL que describe completamente los servicios disponibles (métodos remotos) y los argumentos / objetos esperados. Esos objetos fueron enviados a través de XML. En Thrift, el archivo .thrift describe completamente los métodos disponibles, los objetos de parámetros esperados y los objetos se serializan a través de uno de los serializadores disponibles (con
Compact Protocol
un protocolo binario eficiente, que es el más popular en producción).ASN.1 = Gran papá
ASN.1 fue diseñado por personas de telecomunicaciones en los años 80 y es difícil de usar debido al soporte limitado de la biblioteca en comparación con los serializadores recientes que surgieron de la gente de CompSci. Hay dos variantes, la codificación DER (binaria) y la codificación PEM (ascii). Ambos son rápidos, pero DER es más rápido y tiene un tamaño más eficiente de los dos. De hecho, ASN.1 DER puede mantener fácilmente (y a veces superar) los serializadores que fueron diseñados 30 añosdespués de sí mismo, un testimonio de su diseño bien diseñado. Es muy compacto, más pequeño que Protocol Buffers y Thrift, solo superado por Avro. El problema es tener grandes bibliotecas que admitir y en este momento Bouncy Castle parece ser la mejor para C # / Java. ASN.1 es el rey en seguridad y sistemas criptográficos y no va a desaparecer, así que no se preocupe por las 'pruebas futuras'. Solo consigue una buena biblioteca ...
MessagePack = medio del paquete
No está mal, pero no es el más rápido, ni el más pequeño ni el mejor compatible. No hay razón de producción para elegirlo.
Común
Más allá de eso, son bastante similares. La mayoría son variantes del
TLV: Type-Length-Value
principio básico .Protocol Buffers (originado en Google), Avro (basado en Apache, utilizado en Hadoop), Thrift (originado en Facebook, ahora proyecto Apache) y ASN.1 (originado en Telecom) implican cierto nivel de generación de código donde primero expresa sus datos en un serializador específico del formato, entonces el "compilador" del serializador generará el código fuente para su idioma a través de la
code-gen
fase. La fuente de la aplicación usa estascode-gen
clases para IO. Tenga en cuenta que ciertas implementaciones (por ejemplo: la biblioteca Avro de Microsoft o ProtoBuf.NET de Marc Gavel) le permiten decorar directamente sus objetos POCO / POJO de nivel de aplicación y luego la biblioteca usa directamente esas clases decoradas en lugar de cualquier clase de código gen. Hemos visto que esta oferta mejora el rendimiento, ya que elimina una etapa de copia de objetos (desde los campos POCO / POJO de nivel de aplicación hasta los campos de generación de código).Algunos resultados y un proyecto en vivo para jugar
Este proyecto ( https://github.com/sidshetye/SerializersCompare ) compara serializadores importantes en el mundo C #. La gente de Java ya tiene algo similar .
fuente
There are two variants, DER (binary) encoding and PEM (ascii) encoding
. Tenga en cuenta que PEM es solo un dato binario codificado en base 64 dentro de los comentarios BEGIN END. Es posible que estos datos binarios se hayan generado utilizando la codificación DER, por lo que es extraño comparar PEM y DER.Además de la perspectiva del rendimiento, Uber evaluó recientemente varias de estas bibliotecas en su blog de ingeniería:
https://eng.uber.com/trip-data-squeeze/
¿El ganador para ellos? MessagePack + zlib para compresión
La lección aquí es que sus requisitos determinan qué biblioteca es la adecuada para usted. Para Uber, no podían usar un protocolo basado en IDL debido a la naturaleza sin esquema de la transmisión de mensajes que tienen. Esto eliminó un montón de opciones. También para ellos no solo entra en juego el tiempo de codificación / decodificación sin procesar, sino el tamaño de los datos en reposo.
Resultados de tamaño
Resultados de velocidad
fuente
Lo más importante de ASN.1 es que está diseñado para especificación, no para la implementación. Por lo tanto, es muy bueno para ocultar / ignorar los detalles de implementación en cualquier lenguaje de programación "real".
Es el trabajo del compilador ASN.1 aplicar Reglas de codificación al archivo asn1 y generar a partir de ambos código ejecutable. Las Reglas de codificación pueden darse en la notación de codificación (ECN) o pueden ser una de las estandarizadas como BER / DER, PER, XER / EXER. Es decir, ASN.1 son los Tipos y Estructuras, las Reglas de codificación definen la codificación en el cable y, por último, pero no menos importante, el Compilador la transfiere a su lenguaje de programación.
Los compiladores gratuitos admiten C, C ++, C #, Java y Erlang, que yo sepa. Los compiladores comerciales (muy caros y con patentes / licencias) son muy versátiles, generalmente actualizados y admiten a veces incluso más idiomas, pero pueden ver sus sitios (OSS Nokalva, Marben, etc.).
Es sorprendentemente fácil especificar una interfaz entre partes de culturas de programación totalmente diferentes (por ejemplo, personas "integradas" y "granjeros de servidores") utilizando estas técnicas: un archivo asn.1, la regla de codificación, por ejemplo, BER y, por ejemplo, un diagrama de interacción UML . No se preocupe cómo se implementa, ¡deje que todos usen "lo suyo"! Para mí ha funcionado muy bien. Por cierto: en el sitio de OSS Nokalva puede encontrar al menos dos libros gratuitos sobre ASN.1 (uno de Larmouth y el otro de Dubuisson).
En mi humilde opinión, la mayoría de los otros productos intentan ser solo otros generadores de trozos RPC, bombeando mucho aire al problema de la serialización. Bueno, si uno necesita eso, uno podría estar bien. Pero para mí, parecen reinvenciones de Sun-RPC (desde finales de los 80), pero, bueno, eso también funcionó bien.
fuente
Bono de Microsoft ( https://github.com/Microsoft/bond ) es muy impresionante con rendimiento, funcionalidades y documentación. Sin embargo, no es compatible con muchas plataformas de destino a partir de ahora (13 de febrero de 2015). Solo puedo suponer que es porque es muy nuevo. Actualmente es compatible con Python, C # y C ++. Lo está utilizando MS en todas partes. Lo intenté, para mí, como desarrollador de ac #, usar bond es mejor que usar protobuf, sin embargo, también he usado ahorro, el único problema que enfrenté fue con la documentación, tuve que probar muchas cosas para entender cómo se hacen las cosas.
Pocos recursos en Bond son los siguientes ( https://news.ycombinator.com/item?id=8866694 , https://news.ycombinator.com/item?id=8866848 , https://microsoft.github.io/ bond / why_bond.html )
fuente
Para el rendimiento, un punto de datos es el punto de referencia de jvm-serializers : son mensajes pequeños muy específicos, pero podrían ayudar si se encuentra en la plataforma Java. Creo que el rendimiento en general a menudo no será la diferencia más importante. Además: NUNCA tome las palabras de los autores como evangelio; muchos reclamos anunciados son falsos (el sitio msgpack, por ejemplo, tiene algunos reclamos dudosos; puede ser rápido, pero la información es muy incompleta, el caso de uso no es muy realista).
Una gran diferencia es si se debe usar un esquema (PB, Thrift al menos; Avro puede ser opcional; ASN.1 Creo que también; MsgPack, no necesariamente).
Además: en mi opinión, es bueno poder usar un diseño modular en capas; es decir, la capa RPC no debe dictar el formato de datos, la serialización. Lamentablemente, la mayoría de los candidatos los agrupan estrechamente.
Finalmente, al elegir el formato de datos, hoy en día el rendimiento no impide el uso de formatos de texto. Hay analizadores JSON increíblemente rápidos (y analizadores xml de transmisión bastante rápida); y cuando se considera la interoperabilidad de los lenguajes de script y la facilidad de uso, los formatos y protocolos binarios pueden no ser la mejor opción.
fuente