MinIO é um back-end primário poderoso do TileDB porque ambos são desenvolvidos para desempenho e escalabilidade. MinIO é um binário Go único que pode ser lançado em muitos tipos diferentes de ambientes de nuvem e locais. É muito leve, mas também repleto de recursos como
O TileDB é usado para armazenar dados em uma variedade de aplicações, como genômica, geoespacial, imagens biomédicas, finanças, aprendizado de máquina e muito mais. O poder do TileDB decorre do fato de que qualquer dado pode ser modelado eficientemente como um array multidimensional denso ou esparso, que é o formato usado internamente pela maioria das ferramentas de ciência de dados. Ao armazenar seus dados e metadados em arrays TileDB, você abstrai todas as dificuldades de armazenamento e gerenciamento de dados, ao mesmo tempo que acessa os dados de forma eficiente com sua linguagem de programação favorita ou ferramenta de ciência de dados por meio de nossas inúmeras APIs e integrações.
Vamos nos aprofundar e criar alguns dados de teste usando o TileDB.
Instale o módulo pip
TileDB, que também deve instalar a dependência numpy
.
% pip3 install tiledb Collecting tiledb Downloading tiledb-0.25.0-cp311-cp311-macosx_11_0_arm64.whl (10.4 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 10.4/10.4 MB 2.7 MB/s eta 0:00:00 Collecting packaging Downloading packaging-23.2-py3-none-any.whl (53 kB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 53.0/53.0 kB 643.1 kB/s eta 0:00:00 Collecting numpy>=1.23.2 Downloading numpy-1.26.3-cp311-cp311-macosx_11_0_arm64.whl (14.0 MB) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 14.0/14.0 MB 2.5 MB/s eta 0:00:00 Installing collected packages: packaging, numpy, tiledb Successfully installed numpy-1.26.3 packaging-23.2 tiledb-0.25.0
Crie uma matriz de teste executando o script Python abaixo, chame-o de tiledb-demo.py
.
import tiledb import numpy as np import os, shutil # Local path array_local = os.path.expanduser("./tiledb_demo") # Create a simple 1D array tiledb.from_numpy(array_local, np.array([1.0, 2.0, 3.0])) # Read the array with tiledb.open(array_local) as A: print(A[:])
Execute o script
% python3 tiledb-demo.py [1. 2. 3.]
Isto criará um diretório chamado tiledb_demo
para armazenar os dados reais.
% ls -l tiledb_demo/ total 0 drwxr-xr-x 3 aj staff 96 Jan 31 05:27 __commits drwxr-xr-x 2 aj staff 64 Jan 31 05:27 __fragment_meta drwxr-xr-x 3 aj staff 96 Jan 31 05:27 __fragments drwxr-xr-x 2 aj staff 64 Jan 31 05:27 __labels drwxr-xr-x 2 aj staff 64 Jan 31 05:27 __meta drwxr-xr-x 4 aj staff 128 Jan 31 05:27 __schema
Você pode continuar usando-o como está, mas não há problema se tudo for local, porque se o disco ou nó local falhar, você perderá todos os seus dados. Vamos fazer algo divertido, como ler os mesmos dados de um bucket MinIO.
Começaremos puxando mc em nosso ecossistema docker e depois usando play.min.io para criar o bucket.
Extrair imagem do mc docker
% docker pull minio/mc
Teste com MinIO Play listando todos os buckets
% docker run minio/mc ls play [LONG TRUNCATED LIST OF BUCKETS]
Crie um bucket para mover nossos dados locais do TileDB, chame-o de tiledb-demo
.
% docker run minio/mc mb play/tiledb-demo Bucket created successfully `play/tiledb-demo`.
Copie o conteúdo do diretório de dados tiledb_demo
para o bucket MinIO tiledb-demo
% docker run -v $(pwd)/tiledb_demo:/tiledb_demo minio/mc cp --recursive /tiledb_demo play/tiledb-demo `/tiledb_demo/__commits/__1706696859767_1706696859767_777455531063403b811b2a2bf79d40e7_21.wrt` -> `play/tiledb-demo/tiledb_demo/__commits/__1706696859767_1706696859767_777455531063403b811b2a2bf79d40e7_21.wrt` `/tiledb_demo/__fragments/__1706696859767_1706696859767_777455531063403b811b2a2bf79d40e7_21/a0.tdb` -> `play/tiledb-demo/tiledb_demo/__fragments/__1706696859767_1706696859767_777455531063403b811b2a2bf79d40e7_21/a0.tdb` `/tiledb_demo/__fragments/__1706696859767_1706696859767_777455531063403b811b2a2bf79d40e7_21/__fragment_metadata.tdb` -> `play/tiledb-demo/tiledb_demo/__fragments/__1706696859767_1706696859767_777455531063403b811b2a2bf79d40e7_21/__fragment_metadata.tdb` `/tiledb_demo/__schema/__1706696859758_1706696859758_74e7040e138a4cca93e34aca1c587108` -> `play/tiledb-demo/tiledb_demo/__schema/__1706696859758_1706696859758_74e7040e138a4cca93e34aca1c587108` Total: 3.24 KiB, Transferred: 3.24 KiB, Speed: 1.10 KiB/s
Liste o conteúdo do tiledb-demo
para garantir que os dados foram copiados.
% docker run minio/mc ls play/tiledb-demo/tiledb_demo [2024-01-15 14:15:57 UTC] 0B __commits/ [2024-01-15 14:15:57 UTC] 0B __fragments/ [2024-01-15 14:15:57 UTC] 0B __schema/
Nota: O MinIO Client ( mc
), ou qualquer cliente compatível com S3, copia apenas pastas não vazias. A razão para isso é que no mundo do armazenamento de objetos os dados são organizados com base em prefixos de bucket, portanto, pastas não vazias não são necessárias. Em um blog futuro, nos aprofundaremos em como os dados são organizados com prefixos e pastas. Portanto, você vê apenas essas 3 pastas e não o resto que vimos na pasta local.
Agora vamos tentar ler os mesmos dados diretamente do bucket MinIO usando o código Python abaixo, nomeie o arquivo tiledb-minio-demo.py
.
import tiledb import numpy as np # MinIO keys minio_key = "minioadmin" minio_secret = "minioadmin" # The configuration object with MinIO keys config = tiledb.Config() config["vfs.s3.aws_access_key_id"] = minio_key config["vfs.s3.aws_secret_access_key"] = minio_secret config["vfs.s3.scheme"] = "https" config["vfs.s3.region"] = "" config["vfs.s3.endpoint_override"] = "play.min.io:9000" config["vfs.s3.use_virtual_addressing"] = "false" # Create TileDB config context ctx = tiledb.Ctx(config) # The MinIO bucket URI path of tiledb demo array_minio = "s3://tiledb-demo/tiledb_demo/" with tiledb.open(array_minio, ctx=tiledb.Ctx(config)) as A: print(A[:])
A saída deve parecer familiar
% python3 tiledb-minio-demo.py [1. 2. 3.]
Lemos o MinIO, a seguir vamos ver como podemos escrever os dados diretamente em um bucket do MinIO, em vez de copiá-los para o MinIO de uma fonte existente.
Até agora, mostramos como ler dados que já existem, seja no armazenamento local ou em um bucket existente. Mas se você quisesse começar do zero escrevendo diretamente para o MinIO desde o início, como isso funcionaria? Vamos dar uma olhada.
O código para gravar dados diretamente no bucket MinIO é o mesmo acima, exceto com duas alterações de linha.
O caminho para o bucket MinIO onde os dados do TileDB são armazenados deve ser atualizado para tiledb_minio_demo
(em vez de tiledb_demo
).
Usaremos a função tiledb.from_numpy
, como fizemos anteriormente com o armazenamento local, para criar o array a ser armazenado no bucket MinIO.
[TRUNCATED] # The MinIO bucket URI path of tiledb demo array_minio = "s3://tiledb-demo/tiledb_minio_demo/" tiledb.from_numpy(array_minio, np.array([1.0, 2.0, 3.0]), ctx=tiledb.Ctx(config)) [TRUNCATED]
Depois de fazer essas 2 alterações, execute o script e você verá a saída abaixo
% python3 tiledb-minio-demo.py [1. 2. 3.]
Se você executar o script novamente, ele falhará com o erro abaixo porque tentará gravar novamente.
tiledb.cc.TileDBError: [TileDB::StorageManager] Error: Cannot create array; Array 's3://tiledb-demo/tiledb_minio_demo/' already exists
Basta comentar a linha a seguir e você poderá executá-la novamente várias vezes.
# tiledb.from_numpy(array_minio, np.array([1.0, 2.0, 3.0]), ctx=tiledb.Ctx(config))
% python3 tiledb-minio-demo.py [1. 2. 3.] % python3 tiledb-minio-demo.py [1. 2. 3.]
Verifique o intervalo do MinIO Play para ter certeza de que os dados estão lá conforme o esperado
% docker run minio/mc ls play/tiledb-demo/tiledb_minio_demo/ [2024-01-15 16:45:04 UTC] 0B __commits/ [2024-01-15 16:45:04 UTC] 0B __fragments/ [2024-01-15 16:45:04 UTC] 0B __schema/
Pronto, colocar dados no MinIO é simples assim. Você obteve os mesmos resultados de antes? Você deveria ter feito isso, mas se não o fez, há algumas coisas que você pode verificar.
Veremos alguns erros comuns que você pode encontrar ao tentar ler/gravar no MinIO.
Se sua chave de acesso e chave secreta estiverem incorretas, você verá uma mensagem de erro como abaixo
tiledb.cc.TileDBError: [TileDB::S3] Error: Error while listing with prefix 's3://tiledb-demo/tiledb_minio_demo/__schema/'... The request signature we calculated does not match the signature you provided. Check your key and signing method.
Em seguida, você precisa garantir que o nome do host e a porta estejam corretos; sem um endpoint adequado, esses são os erros que você encontrará.
Nome de host incorreto:
tiledb.cc.TileDBError: [TileDB::S3] Error: … Couldn't resolve host name
Porta incorreta:
tiledb.cc.TileDBError: [TileDB::S3] Error: … Couldn't connect to server
Por último, mas não menos importante, um dos erros mais enigmáticos que já vi é o seguinte
tiledb.cc.TileDBError: [TileDB::S3] Error: … [HTTP Response Code: -1] [Remote IP: 98.44.32.5] : curlCode: 56, Failure when receiving data from the peer
Depois de muita depuração, acontece que se você estiver se conectando usando http, mas o servidor MinIO tiver o TLS ativado, você verá o erro acima. Apenas certifique-se de que o esquema de conexão esteja definido com a configuração correta, neste caso, config["vfs.s3.scheme"] = "https".
Há uma música rap (você pode pesquisá-la) onde eles cantam sobre ter pilhas e mais pilhas de dinheiro * tosse* . Mas há outra música rap onde eles afirmam que têm tantas pilhas de dinheiro que não podem mais ser chamadas de “pilhas”, agora são “racks”. Essencialmente, quando suas pilhas ficam tão grandes e altas, você precisa de prateleiras em prateleiras para armazenar suas pilhas de dinheiro.
Esta é uma comparação adequada porque suas pilhas de dados significam tanto (ou mais) para você quanto as pilhas de dinheiro sobre as quais eles estão fazendo rap. Se ao menos houvesse algo como o MinIO para manter todos os seus objetos – físicos ou virtuais – seguros e prontamente acessíveis.
Com MinIO no mix, você pode facilmente dimensionar o TileDB para
Adicionamos os trechos de código usados neste blog a um
Também aparece aqui .