Realizar cargas reanudables

Descripción general

En esta página, se describe cómo realizar una solicitud de carga reanudable en las API de JSON y XML de Cloud Storage. Este protocolo te permite reanudar una operación de carga luego de que una falla de comunicación haya interrumpido el flujo de datos.

Para obtener información sobre el uso de cargas reanudables en Google Cloud CLI y las bibliotecas cliente, consulta Cómo las APIs y herramientas usan las cargas reanudables.

Roles obligatorios

A fin de obtener los permisos que necesitas para realizar una carga reanudable, pídele a tu administrador que te otorgue uno de los siguientes roles:

  • Para las cargas que incluyen un bloqueo de retención de objetos, pídele a tu administrador que te otorgue el rol de IAM de Administrador de objetos de almacenamiento (roles/storage.objectAdmin) para el bucket.

  • Para todos los demás casos, pídele a tu administrador que te otorgue el rol de IAM de usuario de objeto de almacenamiento (roles/storage.objectUser) para el bucket.

Estos roles predefinidos contienen los permisos necesarios para subir un objeto a un bucket en sus respectivos casos. Para ver los permisos exactos que son necesarios, expande la sección Permisos necesarios:

Permisos necesarios

  • storage.objects.create
  • storage.objects.delete
    • Este permiso solo es necesario para las cargas que reemplazan un objeto existente.
  • storage.objects.setRetention
    • Este permiso solo es necesario para las cargas que incluyen un bloqueo de retención de objetos.

También puedes obtener estos permisos con otros roles predefinidos o roles personalizados.

Para obtener más información sobre cómo otorgar roles en los buckets, consulta Usa IAM con buckets.

Inicia una sesión de carga reanudable

Para iniciar una sesión de carga reanudable, haz lo siguiente:

API de JSON

  1. Tener la gcloud CLI instalada e inicializada, lo que te permite generar un token de acceso para el encabezado Authorization.

  2. De manera opcional, crea un archivo JSON que contenga los metadatos que deseas configurar en el objeto que deseas subir. Por ejemplo, en el siguiente archivo JSON, se establecen los metadatos contentType del objeto que deseas subir a image/png:

    {
        "contentType": "image/png"
    }
  3. Usa cURL para llamar a la API de JSON con una solicitud de objeto POST:

    curl -i -X POST --data-binary @METADATA_LOCATION \
        -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Type: application/json" \
        -H "Content-Length: INITIAL_REQUEST_LENGTH" \
        "https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME"

    Donde:

    • METADATA_LOCATION es la ruta de acceso local al archivo JSON que contiene los metadatos opcionales que especificaste en el paso anterior. Si no incluyes un archivo de metadatos, excluye esto, junto con --data-binary @ y el encabezado Content-Type.
    • INITIAL_REQUEST_LENGTH es la cantidad de bytes en el cuerpo de esta solicitud inicial, por ejemplo, 79.
    • BUCKET_NAME es el nombre del bucket al que subes el objeto. Por ejemplo, my-bucket.
    • OBJECT_NAME es el nombre codificado en URL que deseas darle a tu objeto. Por ejemplo, pets/dog.png, codificado en URL como pets%2Fdog.png. Esto no es necesario si incluiste un name en el archivo de metadatos del objeto en el paso 2.

    Si habilitaste el uso compartido de recursos entre dominios, también debes incluir un encabezado Origin en esta solicitud de carga y en las posteriores.

    Los encabezados opcionales que puedes agregar a la solicitud incluyen X-Upload-Content-Type y X-Upload-Content-Length.

    Si la solicitud se completa de forma correcta, la respuesta incluye un código de estado 200.

  4. Guarda el URI de la sesión reanudable que se proporcionó en el encabezado Location de la respuesta a tu solicitud de objeto POST.

    Este URI se usa en las solicitudes posteriores para subir los datos del objeto.

API de XML

  1. Tener la gcloud CLI instalada e inicializada, lo que te permite generar un token de acceso para el encabezado Authorization.

  2. Usa cURL para llamar a la API de XML con una solicitud de objeto POST que tenga un cuerpo vacío:

    curl -i -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
        -H "Content-Length: 0" \
        -H "Content-Type: OBJECT_CONTENT_TYPE" \
        -H "x-goog-resumable: start" \
        "https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME"

    Donde:

    • OBJECT_CONTENT_TYPE es el tipo de contenido del objeto. Por ejemplo, image/png. Si no especificas un tipo de contenido, el sistema de Cloud Storage establece los metadatos Content-Type para que el objeto sea application/octet-stream.
    • BUCKET_NAME es el nombre del depósito al que subes el objeto. Por ejemplo, my-bucket.
    • OBJECT_NAME es el nombre codificado en URL que deseas darle a tu objeto. Por ejemplo, pets/dog.png, codificado en URL como pets%2Fdog.png.

    Si habilitaste el uso compartido de recursos entre dominios, también debes incluir un encabezado Origin en esta solicitud de carga y en las posteriores.

    Si la solicitud se completa de forma correcta, la respuesta incluye un mensaje de estado 201.

  3. Guarda el URI de la sesión reanudable que se proporcionó en el encabezado Location de la respuesta a tu solicitud de objeto POST.

    Este URI se usa en las solicitudes posteriores para subir los datos del objeto.

suba los datos

Una vez que inicias una carga reanudable, hay dos formas de subir los datos del objeto:

  • En un solo fragmento: este método suele ser el mejor, ya que requiere menos solicitudes y, por lo tanto, tiene un mejor rendimiento.
  • En varios fragmentos: usa este método si necesitas reducir la cantidad de datos transferidos en una sola solicitud, como cuando hay un límite de tiempo fijo para solicitudes individuales, o si no sabes cuál es el tamaño total de la carga en el momento en que se inicia.

Carga en un solo fragmento

Para subir los datos en un solo fragmento, sigue estos pasos:

API de JSON

  1. Usa cURL para llamar a la API de JSON con una solicitud de objeto PUT:

    curl -i -X PUT --data-binary @OBJECT_LOCATION \
        -H "Content-Length: OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • OBJECT_LOCATION es la ruta de acceso local a tu objeto. Por ejemplo, Desktop/dog.png.
    • OBJECT_SIZE es la cantidad de bytes en el objeto. Por ejemplo, 20000000.
    • SESSION_URI es el valor que se mostró en el encabezado Location cuando iniciaste la carga reanudable.

    De manera opcional, puedes incluir encabezados con el prefijo X-Goog-Meta- para agregar metadatos personalizados del objeto como parte de esta solicitud.

API de XML

  1. Usa cURL para llamar a la API de XML con una solicitud de objeto PUT:

    curl -i -X PUT --data-binary @OBJECT_LOCATION \
        -H "Content-Length: OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • OBJECT_LOCATION es la ruta de acceso local a tu objeto. Por ejemplo, Desktop/dog.png.
    • OBJECT_SIZE es la cantidad de bytes en el objeto. Por ejemplo, 20000000.
    • SESSION_URI es el valor que se mostró en el encabezado Location cuando iniciaste la carga reanudable.

Si la carga se completa en su totalidad, recibirás una respuesta 200 OK o 201 Created, junto con todos los metadatos asociados con el recurso.

Si la solicitud de carga se interrumpe o si recibes una respuesta 5xx, sigue el procedimiento que se describe en Reanuda una carga interrumpida.

Carga en varios fragmentos

Para subir los datos en varios fragmentos, sigue estos pasos:

API de JSON

  1. Crea un fragmento de datos a partir de los datos generales que deseas subir.

    El tamaño del fragmento debe ser un múltiplo de 256 KiB (256 x 1024 bytes), a menos que sea el último fragmento que complete la carga. Por lo general, los tamaños de fragmentos más grandes hacen que las cargas sean más rápidas, pero ten en cuenta que hay una relación entre la velocidad y el uso de la memoria. Se recomienda usar al menos 8 MiB para el tamaño del fragmento.

  2. Usa cURL para llamar a la API de JSON con una solicitud de objeto PUT:

    curl -i -X PUT --data-binary @CHUNK_LOCATION \
        -H "Content-Length: CHUNK_SIZE" \
        -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • CHUNK_LOCATION es la ruta de acceso local al fragmento que subes en este momento.
    • CHUNK_SIZE es la cantidad de bytes que subes en la solicitud actual. Por ejemplo, 8388608.
    • CHUNK_FIRST_BYTE es el byte inicial en el objeto completo que contiene el fragmento que deseas subir.
    • CHUNK_LAST_BYTE es el byte final del objeto completo que contiene el fragmento que deseas subir.
    • TOTAL_OBJECT_SIZE es el tamaño total del objeto que deseas subir.
    • SESSION_URI es el valor que se mostró en el encabezado Location cuando iniciaste la carga reanudable.

    Un ejemplo de Content-Range es Content-Range: bytes 0-8388607/20000000. Consulta Content-Range para obtener más información sobre este encabezado.

    Si la solicitud se completa de forma correcta, el servidor responde con 308 Resume Incomplete. La respuesta contiene un encabezado Range.

  3. Repite los pasos anteriores para cada fragmento restante de datos que desees subir y usa el valor superior que contiene el encabezado Range de cada respuesta para determinar dónde comenzar cada fragmento sucesivo. No debes suponer que el servidor recibió todos los bytes que se enviaron en una solicitud determinada.

    De manera opcional, en la solicitud final de la carga reanudable, puedes incluir encabezados con el prefijo X-Goog-Meta- para agregar metadatos personalizados del objeto.

API de XML

  1. Crea un fragmento de datos a partir de los datos generales que deseas subir.

    El tamaño del fragmento debe ser un múltiplo de 256 KiB (256 x 1024 bytes), a menos que sea el último fragmento que complete la carga. Por lo general, los tamaños de fragmentos más grandes hacen que las cargas sean más rápidas, pero ten en cuenta que hay una relación entre la velocidad y el uso de la memoria. Se recomienda usar al menos 8 MiB para el tamaño del fragmento.

  2. Usa cURL para llamar a la API de XML con una solicitud de objeto PUT:

    curl -i -X PUT --data-binary @CHUNK_LOCATION \
        -H "Content-Length: CHUNK_SIZE" \
        -H "Content-Range: bytes CHUNK_FIRST_BYTE-CHUNK_LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • CHUNK_LOCATION es la ruta de acceso local al fragmento que subes en este momento.
    • CHUNK_SIZE es la cantidad de bytes que subes en la solicitud actual. Por ejemplo, 8388608.
    • CHUNK_FIRST_BYTE es el byte inicial en el objeto completo que contiene el fragmento que deseas subir.
    • CHUNK_LAST_BYTE es el byte final del objeto completo que contiene el fragmento que deseas subir.
    • TOTAL_OBJECT_SIZE es el tamaño total del objeto que deseas subir.
    • SESSION_URI es el valor que se mostró en el encabezado Location cuando iniciaste la carga reanudable.

    Un ejemplo de Content-Range es Content-Range: bytes 0-8388607/20000000. Consulta Content-Range para obtener más información sobre este encabezado.

    Si la solicitud se completa de forma correcta, el servidor responde con 308 Resume Incomplete. La respuesta contiene un encabezado Range.

  3. Repite los pasos anteriores para cada fragmento restante de datos que desees subir y usa el valor superior que contiene el encabezado Range de cada respuesta para determinar dónde comenzar cada fragmento sucesivo. No debes suponer que el servidor recibió todos los bytes que se enviaron en una solicitud determinada.

Una vez que se completa la carga, recibirás una respuesta 200 OK o 201 Created, junto con todos los metadatos asociados al recurso.

Si se interrumpe alguna de las cargas de fragmentos, o si recibes una respuesta 5xx, debes reenviar el fragmento interrumpido en su totalidad o reanudar la carga interrumpida desde el punto en que se detuvo.

Verifica el estado de una carga reanudable

Si se interrumpe la carga reanudable, o no estás seguro de que se haya completado, puedes verificar su estado:

API de JSON

  1. Usa cURL para llamar a la API de JSON con una solicitud de objeto PUT:

    curl -i -X PUT \
        -H "Content-Length: 0" \
        -H "Content-Range: bytes */OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • OBJECT_SIZE es la cantidad total de bytes en el objeto. Si no sabes cuál es el tamaño completo del objeto, usa * para este valor.
    • SESSION_URI es el valor que se mostró en el encabezado Location cuando iniciaste la carga reanudable.

API de XML

  1. Usa cURL para llamar a la API de XML con una solicitud de objeto PUT:

    curl -i -X PUT \
        -H "Content-Length: 0" \
        -H "Content-Range: bytes */OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • OBJECT_SIZE es la cantidad total de bytes en el objeto. Si no sabes cuál es el tamaño completo del objeto, usa * para este valor.
    • SESSION_URI es el valor que se mostró en el encabezado Location cuando iniciaste la carga reanudable.

Una respuesta 200 OK o 201 Created indica que se completó la carga y que no es necesario realizar ninguna otra acción.

Una respuesta 308 Resume Incomplete indica que debes seguir subiendo los datos.

  • Si Cloud Storage aún no conserva ningún byte, la respuesta 308 no tiene un encabezado Range. En este caso, debes comenzar la carga desde el principio.
  • De lo contrario, la respuesta 308 tiene un encabezado Range, que especifica qué bytes conserva Cloud Storage hasta el momento. Usa este valor cuando reanudes una carga interrumpida.

Reanuda una carga interrumpida

Si una solicitud de carga se interrumpe antes de que recibas una respuesta, o si recibes una respuesta 503500, debes reanudar la carga interrumpida desde el punto en que se detuvo. Para reanudar una carga interrumpida, haz lo siguiente:

API de JSON

  1. Verifica el estado de la carga reanudable.

  2. Guarda el valor superior del encabezado Range que se encuentra en la respuesta a tu verificación de estado. Si la respuesta no tiene un encabezado Range, Cloud Storage aún no conservó ningún byte, y debes reanudar la carga desde el principio.

  3. Asegúrate de que los datos del objeto que estás a punto de subir comiencen en el byte que le sigue al valor superior en el encabezado Range.

  4. Si la solicitud interrumpida contenía encabezados con el prefijo X-Goog-Meta-, incluye esos encabezados en la solicitud para reanudar tu carga.

  5. Usa cURL para llamar a la API de JSON con una solicitud de objeto PUT que reanude la carga a partir del byte que le sigue al valor en el encabezado Range:

    curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \
        -H "Content-Length: UPLOAD_SIZE_REMAINING" \
        -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • PARTIAL_OBJECT_LOCATION es la ruta de acceso local a la parte restante de los datos que deseas subir.
    • UPLOAD_SIZE_REMAINING es la cantidad de bytes que subes en la solicitud actual. Por ejemplo, la carga del resto de un objeto con un tamaño total de 20,000,000 que se interrumpió después de haber subido los bytes 0-42 tendría un UPLOAD_SIZE_REMAINING de 19999957.
    • NEXT_BYTE es el siguiente número entero después del valor que guardaste en el paso 2. Por ejemplo, si 42 es el valor superior en el paso 2, el valor de NEXT_BYTE es 43.
    • LAST_BYTE es el byte final que contiene esta solicitud PUT. Por ejemplo, para terminar de subir un objeto cuyo tamaño total es 20000000, el valor de LAST_BYTE es 19999999.
    • TOTAL_OBJECT_SIZE es el tamaño total del objeto que deseas subir. Por ejemplo, 20000000.
    • SESSION_URI es el valor que se mostró en el encabezado Location cuando iniciaste la carga reanudable.

API de XML

  1. Verifica el estado de la carga reanudable.

  2. Guarda el valor superior del encabezado Range que se encuentra en la respuesta a tu verificación de estado. Si la respuesta no tiene un encabezado Range, Cloud Storage aún no conservó ningún byte, y debes reanudar la carga desde el principio.

  3. Asegúrate de que los datos del objeto que estás a punto de subir comiencen en el byte que le sigue al valor superior en el encabezado Range.

  4. Usa cURL para llamar a la API de XML con una solicitud de objeto PUT que reanude la carga a partir del byte que le sigue al valor en el encabezado Range:

    curl -i -X PUT --data-binary @PARTIAL_OBJECT_LOCATION \
        -H "Content-Length: UPLOAD_SIZE_REMAINING" \
        -H "Content-Range: bytes NEXT_BYTE-LAST_BYTE/TOTAL_OBJECT_SIZE" \
        "SESSION_URI"

    Donde:

    • PARTIAL_OBJECT_LOCATION es la ruta de acceso local a la parte restante de los datos que deseas subir.
    • UPLOAD_SIZE_REMAINING es la cantidad de bytes que subes en la solicitud actual. Por ejemplo, la carga del resto de un objeto con un tamaño total de 20,000,000 que se interrumpió después de haber subido los bytes 0-42 tendría un UPLOAD_SIZE_REMAINING de 19999957.
    • NEXT_BYTE es el siguiente número entero después del valor que guardaste en el paso 2. Por ejemplo, si 42 es el valor superior en el paso 2, el valor de NEXT_BYTE es 43.
    • LAST_BYTE es el byte final que contiene esta solicitud PUT. Por ejemplo, para terminar de subir un objeto cuyo tamaño total es 20000000, el valor de LAST_BYTE es 19999999.
    • TOTAL_OBJECT_SIZE es el tamaño total del objeto que deseas subir. Por ejemplo, 20000000.
    • SESSION_URI es el valor que se mostró en el encabezado Location cuando iniciaste la carga reanudable.

Puedes reanudar las cargas tantas veces como sea necesario mientras el URI de sesión esté activo. El URI de la sesión vence después de una semana. Cuando los datos se suben de forma correcta, Cloud Storage responde con un código de estado 200 OK o 201 created.

Cancela una carga

Para cancelar una carga reanudable incompleta y evitar que se realicen más acciones, sigue estos pasos:

API de JSON

  1. Usa cURL para llamar a la API de JSON con una solicitud DELETE:

    curl -i -X DELETE -H "Content-Length: 0" \
      "SESSION_URI"

    Donde:

Si la solicitud se completa de forma correcta, la respuesta contendrá un código de estado 499. Los intentos posteriores de consultar o reanudar la carga generarán una respuesta 4xx.

API de XML

  1. Usa cURL para llamar a la API de XML con una solicitud DELETE:

    curl -i -X DELETE -H "Content-Length: 0" \
      "SESSION_URI"

    Donde:

Si se ejecuta de forma correcta, la respuesta contiene un código de estado 204 y los intentos futuros de consultar o reanudar la carga también generan una respuesta 204.

Manejo de fallas

En circunstancias excepcionales, es posible que una solicitud para reanudar una carga interrumpida falle con un error "4xx" que no se puede recuperar porque cambiaron los permisos del bucket o porque la verificación de integridad del objeto subido final detectó una discrepancia. Si esto ocurre, inicia una nueva sesión de carga reanudable para volver a intentar la carga.

¿Qué sigue?