Cómo funcionan los subdirectorios

Descripción general

En esta sección, se brindan detalles sobre cómo funcionan los subdirectorios en gsutil. Es probable que la mayoría de los usuarios no necesiten saber estos detalles y solo usen los comandos (como cp -r) que funcionan con los subdirectorios. Proporcionamos esta documentación adicional para ayudar a que los usuarios comprendan cómo gsutil controla los subdirectorios de manera diferente a la mayoría de las herramientas basadas en la Web o en la GUI y, también, para explicar las implicaciones de costos y rendimiento del enfoque de gsutil para esas personas. interesados en obtener detalles.

gsutil proporciona la ilusión de un árbol jerárquico de archivos arriba del espacio de nombres “fijo” que admite el servicio de Cloud Storage. Para el servicio, el objeto gs://your-bucket/abc/def.txt es solo un objeto que tiene caracteres “/” en su nombre. No hay un directorio “abc”; solo un objeto único con el nombre determinado. En el siguiente diagrama, se ilustra cómo gsutil proporciona una vista jerárquica de objetos en un depósito:

https://cloud.google.com/storage/images/gsutil-subdirectories.svg

Gsutil logra esta ilusión de árbol jerárquico de archivos mediante la aplicación de varias reglas para intentar que la asignación de nombres funcione como el usuario espera. Por ejemplo, con el fin de determinar si tratar a una URL de destino como un nombre de objeto o la raíz de un directorio bajo el cual los objetos se deben copiar, gsutil usa estas reglas:

  1. Si el objeto de destino termina en “/”, gsutil lo trata como un directorio. Por ejemplo, ejecuta el siguiente comando:

    gsutil cp your-file gs://your-bucket/abc/
    

    Gsutil crea el objeto gs://your-bucket/abc/your-file.

  2. Si intentas copiar varios archivos de origen en una URL de destino, gsutil tratará la URL de destino como un directorio. Por ejemplo, ejecuta el siguiente comando:

    gsutil cp -r your-dir gs://your-bucket/abc
    

    Gsutil crea objetos como gs://your-bucket/abc/your-dir/file1, etc., suponiendo que file1 es un archivo en el directorio de origen your-dir.

  3. Si no se aplica ninguna de las reglas anteriores, gsutil crea una lista de depósitos para determinar si el objetivo de la operación es una coincidencia de prefijo con la string especificada. Por ejemplo, ejecuta el siguiente comando:

    gsutil cp your-file gs://your-bucket/abc
    

    Gsutil realiza una solicitud de enumeración de depósitos para el depósito con nombre mediante delimiter="/" y prefix="abc". Luego, examina los resultados de la lista del depósito y determina si hay objetos en el depósito cuya ruta de acceso comienza con gs://your-bucket/abc/. Si es así, gsutil trata el destino como un nombre de directorio. A su vez, esto afecta el nombre del objeto que creas: si la verificación anterior indica que hay un directorio abc, tendrás el objeto gs://your-bucket/abc/your-file, de lo contrario, tendrás el objeto gs://your-bucket/abc. Consulta “Cómo se crean los nombres” en gsutil help cp para obtener más detalles.

Este enfoque basado en reglas se diferencia de la forma en que funcionan muchas herramientas, que crean objetos de 0 bytes para marcar la existencia de carpetas. gsutil entiende varias convenciones que usan esas herramientas, como la convención de agregar _$folder$ al final del nombre del objeto 0 bytes, pero gsutil no requiere que esos objetos de marcador implementen un comportamiento coherente de nombres con los comandos de UNIX.

Una desventaja de este enfoque de asignación de nombres de subdirectorios de gsutil es que se necesita una lista de depósitos adicional antes de ejecutar el comando cp o mv necesario. Sin embargo, generar esas listas es bastante económico, ya que se usan parámetros de prefijos y delimitadores para limitar los datos del resultado. Además, gsutil genera solo una solicitud de lista de depósitos por cada comando cp o mv, lo que amortiza los costos de la lista de depósitos en todos los objetos transferidos (p. ej., cuando se realiza una copia recurrente de un directorio en la nube).

Posibles sorpresas cuando se nombran los subdirectorios de destino

El enfoque anterior basado en reglas para determinar cómo se construyen las rutas de destino puede generar la siguiente sorpresa: supongamos que comienzas por subir todo lo de un directorio local a un “subdirectorio” de depósitos que aún no existe.

gsutil cp -r ./your-dir/* gs://your-bucket/new

En el ejemplo anterior, existen directorios en your-dir (por ejemplo, dir1 y dir2). La primera vez que ejecutes este comando, se crearán los objetos:

gs://your-bucket/new/dir1/abc
gs://your-bucket/new/dir2/abc

Se crearán porque gs://your-bucket/new aún no existe. Si vuelves a ejecutar el mismo comando, porque gs://your-bucket/new ahora existe, se crearán los objetos adicionales:

gs://your-bucket/new/your-dir/dir1/abc
gs://your-bucket/new/your-dir/dir2/abc

Más allá del hecho de que este comportamiento de nombres puede sorprender a los usuarios, un caso particular que debes tener en cuenta es la ejecución de secuencias de comandos de gsutil con un bucle de reintento. Si haces esto y el primer intento copia algunos archivos, pero no todos, el segundo intento encontrará un subdirectorio de origen existente y dará como resultado el problema de nomenclatura descrito antes.

Hay dos formas de evitar este problema:

1. Usa gsutil rsync. Dado que rsync no usa las reglas de nombres de directorio definidas por cp de Unix, funcionará con coherencia si el subdirectorio de destino existe o no.

2. Si el uso de rsync no funciona, puedes comenzar a crear un objeto “marcador de posición” para establecer que el destino es un subdirectorio mediante la ejecución de un comando como el siguiente:

gsutil cp some-file gs://your-bucket/new/placeholder

En este punto, cuando se ejecuta el comando gsutil cp -r mencionado antes, se tratará de forma coherente a gs://your-bucket/new como un subdirectorio. Una vez que tengas al menos un objeto en ese subdirectorio, puedes borrar el objeto de marcador de posición, y las cargas posteriores en ese subdirectorio continuarán funcionando con los nombres que funcionan como se espera.