E/S de datos y cifrado
El tamaño de objeto puede tener un impacto significativo en el rendimiento de IBM Cloud® Object Storage. Elija el enfoque adecuado para su carga de trabajo.
Transferencias de varias partes
En condiciones típicas, las cargas y descargas de varias partes son un método muy eficiente para dividir las transferencias en muchas transacciones paralelas. En función del tamaño del objeto, generalmente se recomienda un tamaño de parte de 100MB. En cualquier caso, es más eficiente establecer el tamaño de parte en un múltiplo de 4MiB para optimizar la ingesta de datos y la salida de COS.
Al igual que con AWS S3, el uso de transferencias de varias partes proporciona las ventajas siguientes:
- Rendimiento mejorado: puede cargar partes en paralelo para mejorar el rendimiento.
- Recuperación rápida de cualquier problema de red-El tamaño de parte más pequeño minimiza el impacto de reiniciar una carga fallida debido a un error de red.
- Pausar y reanudar cargas de objetos-Cargar partes de objetos a lo largo del tiempo. Una vez que se inicia una carga de varias partes, no hay caducidad; debe completarse explícitamente o la carga de varias partes debe terminarse anormalmente.
- Iniciar una carga antes de que se conozca el tamaño final del objeto: se puede cargar un objeto a medida que se crea.
Debido a la complejidad adicional de las transferencias de varias partes, se recomienda utilizar las bibliotecas, herramientas o SDK S3 adecuados que ofrecen soporte para las transferencias de varias partes gestionadas:
- IBM COS SDK para Java
- IBM COS SDK para Python
- IBM COS SDK for Javascript(Node.js)
- IBM COS SDK for Go
- CLI deIBM COS Plug-in for IBM Cloud
- S3FS-FUSE
Aunque no hay ninguna API dedicada para una descarga de varias partes, es posible utilizar una cabecera Range en una solicitud GET para leer sólo una parte específica de un objeto, y se pueden emitir muchas lecturas
de rango en paralelo, al igual que cuando se cargan partes. Después de que se hayan descargado todas las partes, se pueden concatenar y se puede comprobar la integridad del objeto completo. Como se ha mencionado anteriormente, se recomienda
el uso de SDK u otras herramientas para evitar las complejidades de la gestión manual de estas transferencias.
Los flujos de trabajo que necesitan almacenar un gran número de objetos muy pequeños se pueden servir mejor agregando los archivos pequeños en una estructura de datos más grande, como por ejemplo [Parquet].
Para objetos de tamaño superior a 200mb, especialmente en redes menos estables o en distancias muy largas en las que la pérdida de paquetes es un problema, Aspera High-Speed Transfer puede ofrecer un rendimiento excelente. Las transferencias de Aspera también pueden cargar estructuras de directorios anidadas de forma eficiente dentro de una única solicitud.
Regulación de supresiones de lotes
La API S3 proporciona un mecanismo para suprimir hasta 1.000 objetos con una única solicitud de supresión por lotes. Se recomienda regular estas solicitudes del lado del cliente para minimizar las posibilidades de rendimiento despectivo dentro del sistema COS. Cuando el número de supresiones emitidas es demasiado alto para el sistema, el cliente recibirá errores HTTP 503 con un mensaje de error que indica "ralentización".
Impactos de coherencia
IBM Cloud Object Storage System garantiza la coherencia inmediata para todas las operaciones de objetos, que incluyen escrituras de objetos, sobrescrituras, supresiones, operaciones de varias partes y modificaciones de ACL. La creación de grupos también es inmediatamente coherente. Los metadatos de grupo y la configuración son finalmente coherentes, como es el caso de otros sistemas de almacenamiento de objetos, lo que significa que los cambios en un sistema altamente distribuido pueden no estar sincronizados durante un breve periodo de tiempo. Esto se produce debido a que el almacenamiento en memoria caché de metadatos proporciona importantes ventajas de rendimiento y también protege contra la posibilidad de ataques de denegación de servicio.
Algunas aplicaciones sobrescribirán el mismo objeto, o suprimirán y reescribirán el mismo objeto repetidamente durante un breve periodo de tiempo. Esto puede provocar contención en los índices dentro del sistema COS y debe evitarse. En los casos excepcionales en los que la sobrescritura de datos con la misma clave de objeto (nombre) con una frecuencia muy alta y durante largos periodos de tiempo es un aspecto crítico de un diseño de aplicación, una plataforma de almacenamiento diferente (archivo, bloque, noSQL, etc.) puede ser una mejor opción.
Comprobaciones de existencia
Es posible que las aplicaciones deseen comprobar si existe un objeto o si se ha modificado antes de escribirlo. A menudo, esto conduce a una lógica de aplicación ineficiente que enviará una solicitud HEAD seguida de una solicitud PUT o GET. Este anti-patrón da como resultado una red desperdiciada y recursos de servidor, y debe desaconsejarse.
En lugar de utilizar una solicitud HEAD como comprobación de existencia dentro de alguna función, utilice una cabecera de solicitud condicional. Estas cabeceras HTTP estándar compararán los hashes MD5 o las indicaciones de fecha y hora para determinar si la operación de datos debe continuar o no. Para obtener más información, consulte Solicitudes condicionales.
Utilización de solicitudes condicionales
Al realizar una solicitud para leer o escribir datos, es posible establecer condiciones en esa solicitud para evitar operaciones innecesarias. Esto se consigue utilizando las siguientes cabeceras HTTP precondicionales: If-Match,
If-None-Match, If-Modified-Since y If-Unmodified-Since.
Generalmente es preferible utilizar If-Match porque la granularidad del valor Last-Modified sólo es en segundos y puede que no sea suficiente para evitar condiciones de carrera en algunas aplicaciones.
Utilización de If-Match
En una solicitud de objeto PUT, HEAD o GET, la cabecera If-Match comprobará si un Etag proporcionado (MD5 hash del contenido del objeto) coincide con el valor Etag proporcionado. Si este valor coincide, la operación continuará. Si la coincidencia falla, el sistema devolverá un error 412 Precondition Failed.
If-Match se utiliza con más frecuencia con métodos de cambio de estado (por ejemplo, POST, PUT, DELETE) para evitar sobreescrituras accidentales cuando varios agentes de usuario pueden estar actuando en paralelo en el mismo recurso (es decir, para evitar el problema de "actualización perdida").
Utilización de If-None-Match
En una solicitud de objeto PUT, HEAD o GET, la cabecera If-None-Match comprobará si un Etag proporcionado (MD5 hash del contenido del objeto) coincide con el valor Etag proporcionado. Si este valor no coincide, la operación continuará. Si la coincidencia es satisfactoria, el sistema devolverá un error 412 Precondition Failed en un PUT y un 304 Not Modified en GET o HEAD.
If-None-Match se utiliza principalmente en solicitudes GET condicionales para habilitar actualizaciones eficaces de la información almacenada en memoria caché con una cantidad mínima de sobrecarga de transacciones. Cuando un cliente desea actualizar una o más respuestas almacenadas que tienen etiquetas de entidad, el cliente DEBE generar un campo de cabecera If-None-Match que contenga una lista de dichas etiquetas de entidad al realizar una solicitud GET; esto permite a los servidores destinatarios enviar una respuesta 304 (No modificada) para indicar cuándo una de esas respuestas almacenadas coincide con la representación seleccionada.
Utilización de If-Modified-Since
En una solicitud HEAD o GET de objeto, la cabecera If-Modified-Since comprobará si el valor Last-Modified del objeto (por ejemplo, Sat, 14 March 2020 19:43:31 GMT) es más reciente
que un valor proporcionado. Si el objeto se ha modificado, la operación continuará. Si el objeto no se ha modificado, el sistema devolverá un 304 Not Modified.
If-Modified-Since se utiliza normalmente para dos fines distintos: permitir actualizaciones eficaces de una representación en memoria caché que no tiene un
Etagy limitar el ámbito de un cruce web a los recursos que han cambiado recientemente.
Utilización de If-Unmodified-Since
En una solicitud de objeto PUT, HEAD o GET, la cabecera If-Unmodified-Since comprobará si el valor Last-Modified del objeto (por ejemplo, Sat, 14 March 2020 19:43:31 GMT)
es igual o anterior a un valor proporcionado. Si el objeto no se ha modificado, la operación continuará. Si el valor Last-Modified es más reciente, el sistema devolverá un error 412 Precondition Failed en un PUT y un 304 Not Modified en GET o HEAD.
If-Unmodified-Since se utiliza con más frecuencia con métodos de cambio de estado (por ejemplo, POST, PUT, DELETE) para evitar sobregrabaciones accidentales cuando varios agentes de usuario pueden estar actuando en paralelo en un recurso que no proporciona etiquetas de entidad con sus representaciones (es decir, para evitar el problema de "actualización perdida"). También se puede utilizar con métodos seguros para abortar una solicitud si la representación seleccionada no coincide con una ya almacenada (o parcialmente almacenada) de una solicitud anterior.
Estrategia de reintento
Aunque la mayoría de las bibliotecas y los SDK manejarán automáticamente la lógica de reintentos, se debe tener cuidado al escribir software que utilice la API directamente para manejar correctamente los errores transitorios. Lo más importante es que es fundamental proporcionar una lógica de reintento adecuada que implemente una interrupción exponencial al recibir 503 errores.
Ajuste de cifrado
IBM COS da soporte a diversos valores de cifrado para cifrar datos en tránsito. No todos los valores de cifrado producen el mismo nivel de rendimiento y el uso de TLS en general conduce a una pequeña degradación del rendimiento. Se recomiendan los siguientes valores de cifrado (en orden descendente de prioridad):
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256TLS_ECDHE_RSA_WITH_AES_256_CBC_SHATLS_ECDHE_RSA_WITH_AES_128_CBC_SHATLS_RSA_WITH_AES_256_CBC_SHA256TLS_RSA_WITH_AES_128_CBC_SHA256TLS_RSA_WITH_AES_256_CBC_SHATLS_RSA_WITH_AES_128_CBC_SHA