¿Por qué protobuf es malo para grandes estructuras de datos?

3 minutos de lectura

Soy nuevo en protobuf. Necesito serializar una estructura similar a un gráfico complejo y compartirla entre los clientes de C++ y Python. Estoy tratando de aplicar protobuf porque:

  • Es independiente del lenguaje, tiene generadores tanto para C++ como para Python
  • es binario No puedo permitirme formatos de texto porque mi estructura de datos es bastante grande

Pero la guía del usuario de Protobuf dice:

Los búferes de protocolo no están diseñados para manejar mensajes grandes. Como regla general, si se trata de mensajes de más de un megabyte cada uno, puede ser el momento de considerar una estrategia alternativa.

https://developers.google.com/protocol-buffers/docs/techniques#large-data

Tengo estructuras similares a gráficos que a veces tienen un tamaño de hasta 1 Gb, muy por encima de 1 Mb.

¿Por qué protobuf es malo para serializar grandes conjuntos de datos? ¿Qué debo usar en su lugar?

Es solo una guía general, por lo que no se aplica a todos los casos. Por ejemplo, el proyecto OpenStreetMap utiliza un formato de archivo basado en búfer de protocolo para sus mapas, y los archivos suelen tener un tamaño de 10 a 100 GB. Otro ejemplo es el propio TensorFlow de Google, que utiliza protobuf y los gráficos que almacena suelen tener un tamaño de hasta 1 GB.

Sin embargo, OpenStreetMap no tiene el archivo completo como un solo mensaje. En cambio, consta de miles de mensajes individuales, cada uno de los cuales codifica una parte del mapa. Puede aplicar un enfoque similar, de modo que cada mensaje solo codifique, por ejemplo, un nodo.

El principal problema con protobuf para archivos grandes es que no admite acceso aleatorio. Deberá leer todo el archivo, incluso si solo desea acceder a un elemento específico. Si su aplicación leerá todo el archivo en la memoria de todos modos, esto no es un problema. Esto es lo que hace TensorFlow, y parece almacenar todo en un solo mensaje.

Si necesita un formato de acceso aleatorio que sea compatible con muchos idiomas, sugeriría HDF5 o sqlite.

  • Gracias, el acceso aleatorio desde el archivo no es un problema para mí, puedo precargar 1 gb en la memoria.

    – aleatorio

    30 de noviembre de 2017 a las 16:23

  • The main problem with protobuf for large files is that it doesn't support random access. Esta es la razón por la que TensorFlow lite usa Flat Buffers en lugar de Protobufs. FlatBuffers represents hierarchical data in a flat binary buffer. Los dispositivos móviles tienen mucha menos memoria para poder deserializar un archivo modelo solo para leer los metadatos.

    –Ben Butterworth

    14 oct 2020 a las 18:22


  • ¿Qué sucede si paso una imagen y la imagen es más grande que 8M? ¿Habrá una pérdida de rendimiento?

    – daohu527

    6 ago a las 14:01

Debería estar bien usar búferes de protocolo que sean mucho más grandes que 1 MB. Lo hacemos todo el tiempo en Google, y ni siquiera estaba al tanto de la recomendación que estás citando.

El problema principal es que deberá deserializar todo el búfer de protocolo en la memoria a la vez, por lo que vale la pena pensar si es mejor dividir sus datos en elementos más pequeños para que solo tenga parte de los datos en la memoria en una vez.

Si no puedes dividirlo, entonces no te preocupes. Continúe y use un búfer de protocolo masivo.

¿Ha sido útil esta solución?