Subidas de API
La función de subida de contenido multimedia permite que la API BigQuery almacene datos en la nube y los ponga a disposición del servidor. Entre los tipos de datos que se pueden subir se incluyen fotos, vídeos, archivos PDF, archivos ZIP o cualquier otro tipo de datos.
Opciones de subida
La API de BigQuery te permite subir determinados tipos de datos binarios o contenido multimedia. Las características específicas de los datos que puedes subir se especifican en la página de referencia de cualquier método que admita subidas de contenido multimedia:
- Tamaño máximo de archivo de subida: la cantidad máxima de datos que puedes almacenar con este método.
- Tipos MIME de contenido multimedia aceptados: los tipos de datos binarios que puedes almacenar con este método.
Puede enviar solicitudes de subida de cualquiera de las siguientes formas. Especifica el método que estás usando con el parámetro de solicitud uploadType
.
- Subida multiparte:
uploadType=multipart
. Para transferir rápidamente archivos más pequeños y metadatos. Transfiere el archivo junto con los metadatos que lo describen, todo en una sola solicitud. - Subida reanudable:
uploadType=resumable
. Para que la transferencia sea fiable, lo cual es especialmente importante en el caso de archivos de mayor tamaño. Con este método, se usa una solicitud de inicio de sesión que puede incluir metadatos de forma opcional. Esta es una buena estrategia para la mayoría de las aplicaciones, ya que también funciona con archivos más pequeños a cambio de una solicitud HTTP adicional por cada subida.
Cuando subes contenido multimedia, usas un URI especial. De hecho, los métodos que admiten la subida de contenido multimedia tienen dos endpoints URI:
El URI /upload del contenido multimedia. El formato del endpoint de subida es el URI de recurso estándar con el prefijo "/upload". Usa este URI cuando transfieras los datos multimedia.
Ejemplo:
POST /upload/bigquery/v2/projects/projectId/jobs
El URI de recurso estándar de los metadatos. Si el recurso contiene algún campo de datos, esos campos se usan para almacenar metadatos que describen el archivo subido. Puede usar este URI al crear o actualizar valores de metadatos.
Ejemplo:
POST /bigquery/v2/projects/projectId/jobs
Subida multiparte
Si tiene metadatos que quiere enviar junto con los datos que va a subir, puede hacer una sola solicitud multipart/related
. Esta opción es adecuada si los datos que envías son lo suficientemente pequeños como para volver a subirlos por completo si falla la conexión.
Para usar la subida multiparte, haz una solicitud POST
al URI /upload del método y añade el parámetro de consulta uploadType=multipart
. Por ejemplo:
POST https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=multipart
Los encabezados HTTP de nivel superior que se deben usar al hacer una solicitud de subida multiparte son los siguientes:
Content-Type
. Asigna el valor multipart/related e incluye la cadena de límite que estés usando para identificar las partes de la solicitud.Content-Length
. Se asigna al número total de bytes del cuerpo de la solicitud. La parte multimedia de la solicitud debe ser inferior al tamaño máximo de archivo especificado para este método.
El cuerpo de la solicitud tiene el formato de un tipo de contenido multipart/related
[RFC2387] y contiene exactamente dos partes. Las partes se identifican mediante una cadena de límite y la cadena de límite final va seguida de dos guiones.
Cada parte de la solicitud multipartita necesita un encabezado Content-Type
adicional:
- Parte de metadatos: debe aparecer en primer lugar y
Content-Type
debe coincidir con uno de los formatos de metadatos aceptados. - Parte multimedia: debe ser la segunda y
Content-Type
debe coincidir con uno de los tipos de MIME multimedia aceptados del método.
Consulta la referencia de la API para ver la lista de tipos MIME de medios admitidos y los límites de tamaño de los archivos subidos de cada método.
Nota: Para crear o actualizar solo la parte de los metadatos, sin subir los datos asociados, simplemente envía una solicitud POST
o PUT
al endpoint de recurso estándar:
https://www.googleapis.com/bigquery/v2/projects/projectId/jobs
Ejemplo: Subida multiparte
En el ejemplo siguiente se muestra una solicitud de subida multiparte para la API BigQuery.
POST /upload/bigquery/v2/projects/projectId/jobs?uploadType=multipart HTTP/1.1 Host: www.googleapis.com Authorization: Bearer your_auth_token Content-Type: multipart/related; boundary=foo_bar_baz Content-Length: number_of_bytes_in_entire_request_body --foo_bar_baz Content-Type: application/json; charset=UTF-8 { "configuration": { "load": { "sourceFormat": "NEWLINE_DELIMITED_JSON", "schema": { "fields": [ {"name": "f1", "type": "STRING"}, {"name": "f2", "type": "INTEGER"} ] }, "destinationTable": { "projectId": "projectId", "datasetId": "datasetId", "tableId": "tableId" } } } } --foo_bar_baz Content-Type: */* CSV, JSON, AVRO, PARQUET, or ORC data --foo_bar_baz--
Si la solicitud se realiza correctamente, el servidor devuelve el código de estado HTTP 200 OK
junto con los metadatos:
HTTP/1.1 200 Content-Type: application/json { "configuration": { "load": { "sourceFormat": "NEWLINE_DELIMITED_JSON", "schema": { "fields": [ {"name": "f1", "type": "STRING"}, {"name": "f2", "type": "INTEGER"} ] }, "destinationTable": { "projectId": "projectId", "datasetId": "datasetId", "tableId": "tableId" } } } }
Subida reanudable
Para subir archivos de datos de forma más fiable, puedes usar el protocolo de subida reanudable. Este protocolo te permite reanudar una operación de subida después de que un error de comunicación haya interrumpido el flujo de datos. Es especialmente útil si transfieres archivos grandes y es probable que se produzca una interrupción de la red u otro error de transmisión (por ejemplo, al subir archivos desde una aplicación cliente móvil). También puede reducir el uso del ancho de banda en caso de que se produzcan errores en la red, ya que no tendrás que volver a subir archivos grandes desde el principio.
Para usar la subida reanudable, sigue estos pasos:
- Inicia una sesión reanudable. Haz una solicitud inicial al URI de subida que incluya los metadatos, si los hay.
- Guarda el URI de la sesión reanudable. Guarda el URI de sesión devuelto en la respuesta de la solicitud inicial. Lo usarás en las solicitudes restantes de esta sesión.
- Sube el archivo. Envía el archivo multimedia al URI de la sesión reanudable.
Además, las aplicaciones que usan la subida reanudable deben tener código para reanudar una subida interrumpida. Si se interrumpe una subida, averigua cuántos datos se han recibido correctamente y, a continuación, reanuda la subida desde ese punto.
Nota: Los URIs de subida caducan al cabo de una semana.
Paso 1: Inicia una sesión reanudable
Para iniciar una subida reanudable, haz una solicitud POST
al URI /upload del método y añade el parámetro de consulta uploadType=resumable
. Por ejemplo:
POST https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable
En esta solicitud inicial, el cuerpo está vacío o solo contiene los metadatos. El contenido real del archivo que quieras subir se transferirá en solicitudes posteriores.
Usa los siguientes encabezados HTTP con la solicitud inicial:X-Upload-Content-Type
. Se asigna al tipo MIME del contenido multimedia de los datos de subida que se transferirán en solicitudes posteriores.X-Upload-Content-Length
. Se define como el número de bytes de datos de subida que se transferirán en solicitudes posteriores. Si no se conoce la longitud en el momento de enviar esta solicitud, puede omitir este encabezado.- Si proporcionas metadatos:
Content-Type
. Se define según el tipo de datos de los metadatos. Content-Length
. Se establece en el número de bytes proporcionado en el cuerpo de esta solicitud inicial. No es obligatorio si usas la codificación de transferencia fragmentada.
Consulta la referencia de la API para ver la lista de tipos MIME de medios admitidos y los límites de tamaño de los archivos subidos de cada método.
Ejemplo: Solicitud de inicio de sesión reanudable
En el ejemplo siguiente se muestra cómo iniciar una sesión reanudable para la API de BigQuery.
POST /upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable HTTP/1.1 Host: www.googleapis.com Authorization: Bearer your_auth_token Content-Length: 38 Content-Type: application/json; charset=UTF-8 X-Upload-Content-Type: */* X-Upload-Content-Length: 2000000 { "configuration": { "load": { "sourceFormat": "NEWLINE_DELIMITED_JSON", "schema": { "fields": [ {"name": "f1", "type": "STRING"}, {"name": "f2", "type": "INTEGER"} ] }, "destinationTable": { "projectId": "projectId", "datasetId": "datasetId", "tableId": "tableId" } } } }
Nota: Para enviar una solicitud inicial de actualización reanudable sin metadatos, deja vacío el cuerpo de la solicitud y asigna el valor 0
al encabezado Content-Length
.
En la siguiente sección se describe cómo gestionar la respuesta.
Paso 2: Guarda el URI de la sesión reanudable
Si la solicitud de inicio de sesión se realiza correctamente, el servidor de la API responde con un código de estado HTTP 200 OK
. Además, proporciona un encabezado Location
que especifica el URI de la sesión reanudable. El encabezado Location
, que se muestra en el ejemplo de abajo, incluye una parte del parámetro de consulta upload_id
que proporciona el ID de subida único que se debe usar en esta sesión.
Ejemplo: Respuesta de inicio de sesión reanudable
Esta es la respuesta a la solicitud del paso 1:
HTTP/1.1 200 OK Location: https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2 Content-Length: 0
El valor del encabezado Location
, tal como se muestra en la respuesta de ejemplo anterior, es el URI de sesión que usarás como endpoint HTTP para subir el archivo o consultar el estado de la subida.
Copia y guarda el URI de sesión para poder usarlo en solicitudes posteriores.
Paso 3: Sube el archivo
Para subir el archivo, envía una solicitud PUT
al URI de subida que has obtenido en el paso anterior. El formato de la solicitud de subida es el siguiente:
PUT session_uri
Los encabezados HTTP que se deben usar al hacer las solicitudes de subida de archivos reanudables incluyen Content-Length
. Asigna a este campo el número de bytes que vas a subir en esta solicitud, que suele ser el tamaño del archivo que se va a subir.
Ejemplo: Solicitud de subida de archivos reanudable
A continuación, se muestra una solicitud reanudable para subir el archivo CSV, JSON, AVRO, PARQUET u ORC de 2.000.000 bytes completo del ejemplo actual.
PUT https://www.googleapis.com/upload/bigquery/v2/projects/projectId/jobs?uploadType=resumable&upload_id=xa298sd_sdlkj2 HTTP/1.1 Content-Length: 2000000 Content-Type: */* bytes 0-1999999
Si la solicitud se realiza correctamente, el servidor responde con un HTTP 201 Created
, junto con los metadatos asociados a este recurso. Si la solicitud inicial de la sesión reanudable hubiera sido un PUT
para actualizar un recurso, la respuesta correcta sería 200 OK
, junto con los metadatos asociados a este recurso.
Si se interrumpe la solicitud de subida o recibes una respuesta HTTP 503 Service Unavailable
o cualquier otra respuesta 5xx
del servidor, sigue el procedimiento descrito en Reanudar una subida interrumpida.
Subir el archivo en fragmentos
Con las subidas reanudables, puedes dividir un archivo en fragmentos y enviar una serie de solicitudes para subir cada fragmento en secuencia. No es el método recomendado, ya que las solicitudes adicionales conllevan costes de rendimiento y, por lo general, no son necesarias. Sin embargo, es posible que tengas que usar la fragmentación para reducir la cantidad de datos transferidos en una sola solicitud. Esto resulta útil cuando hay un límite de tiempo fijo para las solicitudes individuales, como ocurre con determinadas clases de solicitudes de Google App Engine. También te permite hacer cosas como proporcionar indicaciones de progreso de subida para navegadores antiguos que no admiten el progreso de subida de forma predeterminada.
Reanudar una subida interrumpida
Si una solicitud de subida se termina antes de recibir una respuesta o si recibes una respuesta HTTP 503 Service Unavailable
del servidor, debes reanudar la subida interrumpida. Para hacer esto:
- Estado de la solicitud. Consulta el estado actual de la subida enviando una solicitud
PUT
vacía al URI de subida. En esta solicitud, los encabezados HTTP deben incluir un encabezadoContent-Range
que indique que se desconoce la posición actual en el archivo. Por ejemplo, definaContent-Range
como*/2000000
si la longitud total del archivo es de 2.000.000. Si no sabes el tamaño completo del archivo, asigna el valorContent-Range
a*/*
.Nota: Puedes solicitar el estado entre fragmentos, no solo si se interrumpe la subida. Esto resulta útil, por ejemplo, si quieres mostrar indicaciones del progreso de la subida en navegadores antiguos.
- Obtener el número de bytes subidos. Procesa la respuesta de la consulta de estado. El servidor usa el encabezado
Range
en su respuesta para especificar los bytes que ha recibido hasta el momento. Por ejemplo, un encabezadoRange
de0-299999
indica que se han recibido los primeros 300.000 bytes del archivo. - Suba los datos restantes. Por último, ahora que ya sabes dónde reanudar la solicitud, envía los datos restantes o el fragmento actual. Ten en cuenta que, en ambos casos, debes tratar los datos restantes como un fragmento independiente, por lo que debes enviar el encabezado
Content-Range
cuando reanudes la subida.
Ejemplo: Reanudar una subida interrumpida
1) Solicita el estado de la subida.
En la siguiente solicitud se usa el encabezado Content-Range
para indicar que se desconoce la posición actual en el archivo de 2.000.000 bytes.
PUT {session_uri} HTTP/1.1 Content-Length: 0 Content-Range: bytes */2000000
2) Extrae de la respuesta el número de bytes que se han subido hasta el momento.
La respuesta del servidor usa la cabecera Range
para indicar que ha recibido los primeros 43 bytes del archivo. Usa el valor superior del encabezado Range
para determinar dónde empezar la subida reanudada.
HTTP/1.1 308 Resume Incomplete Content-Length: 0 Range: 0-42
Nota: Es posible que la respuesta de estado sea 201 Created
o 200 OK
si la subida se ha completado. Esto puede ocurrir si la conexión se interrumpe después de que se hayan subido todos los bytes, pero antes de que el cliente reciba una respuesta del servidor.
3) Reanuda la subida desde el punto en el que se interrumpió.
La siguiente solicitud reanuda la subida enviando los bytes restantes del archivo, empezando por el byte 43.
PUT {session_uri} HTTP/1.1 Content-Length: 1999957 Content-Range: bytes 43-1999999/2000000 bytes 43-1999999
Prácticas recomendadas
Cuando subas contenido multimedia, te recomendamos que tengas en cuenta algunas prácticas recomendadas relacionadas con la gestión de errores.
- Reanuda o vuelve a intentar las subidas que fallen debido a interrupciones de la conexión o a cualquier error
5xx
, incluidos los siguientes:500 Internal Server Error
502 Bad Gateway
503 Service Unavailable
504 Gateway Timeout
- Usa una estrategia de tiempo de espera exponencial si se devuelve algún error del servidor
5xx
al reanudar o volver a intentar las solicitudes de subida. Estos errores pueden producirse si un servidor está sobrecargado. El retroceso exponencial puede ayudar a aliviar este tipo de problemas durante los periodos de gran volumen de solicitudes o de tráfico de red intenso. - Otros tipos de solicitudes no se deben gestionar con un tiempo de espera exponencial, pero puedes volver a intentar enviar algunas de ellas. Cuando vuelvas a intentar enviar estas solicitudes, limita el número de veces que lo haces. Por ejemplo, tu código podría limitar los reintentos a diez o menos antes de informar de un error.
- Gestiona los errores
404 Not Found
y410 Gone
al hacer subidas reanudables reiniciando toda la subida desde el principio.
Tiempo de espera exponencial
El tiempo de espera exponencial es una estrategia de gestión de errores estándar para las aplicaciones de red en la que el cliente vuelve a intentar periódicamente una solicitud fallida durante un periodo de tiempo cada vez mayor. Si un volumen elevado de solicitudes o un tráfico de red intenso provoca que el servidor devuelva errores, el retroceso exponencial puede ser una buena estrategia para gestionar esos errores. Por el contrario, no es una estrategia adecuada para abordar errores que no estén relacionados con el volumen de la red o los tiempos de respuesta, como las credenciales de autorización no válidas o los errores de archivo no encontrado.
Si se usa correctamente, el retardo exponencial aumenta la eficiencia del uso del ancho de banda, reduce el número de solicitudes necesarias para obtener una respuesta correcta y maximiza el rendimiento de las solicitudes en entornos simultáneos.
A continuación se indica el flujo para implementar el retardo exponencial simple:
- Realizar una solicitud a la API.
- Recibir una respuesta
HTTP 503
, que indica que debes volver a intentar enviar la solicitud. - Espera 1 segundo más random_number_milliseconds y vuelve a intentar la solicitud.
- Recibir una respuesta
HTTP 503
, que indica que debes volver a intentar enviar la solicitud. - Espera 2 segundos más random_number_milliseconds y vuelve a intentar la solicitud.
- Recibir una respuesta
HTTP 503
, que indica que debes volver a intentar enviar la solicitud. - Espera 4 segundos más random_number_milliseconds y vuelve a intentar la solicitud.
- Recibir una respuesta
HTTP 503
, que indica que debes volver a intentar enviar la solicitud. - Espera 8 segundos más random_number_milliseconds y vuelve a intentar la solicitud.
- Recibir una respuesta
HTTP 503
, que indica que debes volver a intentar enviar la solicitud. - Espera 16 segundos más random_number_milliseconds y vuelve a intentar la solicitud.
- Detenerlo. Informa o registra un error.
En el flujo anterior, random_number_milliseconds es un número aleatorio de milésimas de segundo menor o igual que 1000. Esto es necesario, ya que introducir un pequeño retraso aleatorio ayuda a distribuir la carga de forma más uniforme y evita la posibilidad de que el servidor se sobrecargue. El valor de random_number_milliseconds debe volverse a definir después de cada espera.
Nota: La espera siempre es (2 ^ n) + random_number_milliseconds, donde n es un entero que se incrementa monotónicamente y que se define inicialmente como 0. El número entero n se incrementa en 1 en cada iteración (cada solicitud).
El algoritmo está configurado para terminar cuando n es 5. Este límite impide que los clientes vuelvan a intentar la operación indefinidamente. El resultado es un retraso total de aproximadamente 32 segundos antes de que una solicitud se considere "un error irrecuperable". Puedes usar un número máximo de reintentos más alto, sobre todo si se está subiendo un archivo grande. Sin embargo, asegúrate de limitar el retraso de los reintentos a un valor razonable, por ejemplo, menos de un minuto.