MinIO 是一个强大的主 TileDB 后端,因为两者都是为了性能和规模而构建的。 MinIO 是一个单一的 Go 二进制文件,可以在许多不同类型的云和本地环境中启动。它非常轻量级,而且功能丰富,例如
TileDB 用于存储各种应用程序中的数据,例如基因组学、地理空间、生物医学成像、金融、机器学习等。 TileDB 的强大之处在于,任何数据都可以有效地建模为密集或稀疏多维数组,这是大多数数据科学工具内部使用的格式。通过将数据和元数据存储在 TileDB 数组中,您可以抽象化所有数据存储和管理难题,同时通过我们众多的 API 和集成,使用您最喜欢的编程语言或数据科学工具高效地访问数据。
让我们深入研究并使用 TileDB 创建一些测试数据。
安装 TileDB pip
模块,该模块还应安装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
通过运行以下 Python 脚本创建一个测试数组,将其命名为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[:])
运行脚本
% python3 tiledb-demo.py [1. 2. 3.]
这将创建一个名为tiledb_demo
的目录来存储实际数据。
% 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
您可以继续按原样使用它,但如果一切都是本地的,那就不好了,因为如果本地磁盘或节点发生故障,那么您将丢失整个数据。让我们做一些有趣的事情,比如从 MinIO 存储桶中读取相同的数据。
我们首先将 mc 拉入我们的 docker 生态系统,然后使用 play.min.io 创建存储桶。
拉取 mc docker 镜像
% docker pull minio/mc
通过列出所有存储桶来测试 MinIO Play
% docker run minio/mc ls play [LONG TRUNCATED LIST OF BUCKETS]
创建一个存储桶来将本地 TileDB 数据移动到其中,将其命名为tiledb-demo
。
% docker run minio/mc mb play/tiledb-demo Bucket created successfully `play/tiledb-demo`.
将tiledb_demo
数据目录的内容复制到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
列出tiledb-demo
的内容以确保数据已被复制。
% 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/
注意:MinIO 客户端 ( mc
) 或任何 S3 兼容客户端仅复制非空文件夹。原因是在对象存储世界中,数据是根据存储桶前缀组织的,因此不需要非空文件夹。在未来的博客中,我们将更深入地探讨如何使用前缀和文件夹组织数据。因此,您只能看到这 3 个文件夹,而看不到我们在本地文件夹中看到的其余文件夹。
现在,我们尝试使用下面的 Python 代码直接从 MinIO 存储桶读取相同的数据,将文件命名为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[:])
输出应该看起来很熟悉
% python3 tiledb-minio-demo.py [1. 2. 3.]
我们已经从 MinIO 中读取了数据,接下来让我们看看如何将数据直接写入 MinIO 存储桶中,而不是将其从现有源复制到 MinIO。
到目前为止,我们已经向您展示了如何读取本地存储或现有存储桶中已存在的数据。但如果您想从一开始就直接写入 MinIO 来重新开始,那该怎么办呢?让我们来看看。
直接向 MinIO 存储桶写入数据的代码与上面相同,只是更改了两行。
存储 TileDB 数据的 MinIO 存储桶的路径必须更新为tiledb_minio_demo
(而不是tiledb_demo
)。
我们将使用tiledb.from_numpy
函数(就像我们之前对本地存储所做的那样)来创建要存储在 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]
进行这两项更改后,运行脚本,您应该看到下面的输出
% python3 tiledb-minio-demo.py [1. 2. 3.]
如果再次运行该脚本,它将失败并出现以下错误,因为它将尝试再次写入。
tiledb.cc.TileDBError: [TileDB::StorageManager] Error: Cannot create array; Array 's3://tiledb-demo/tiledb_minio_demo/' already exists
只需注释掉以下行即可重新运行多次。
# 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.]
检查 MinIO Play 存储桶以确保数据按预期存储在其中
% 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/
就是这样,将数据导入 MinIO 就是这么简单。您得到与之前相同的结果吗?你应该有,但如果你没有,你可以检查一些事情。
我们将了解您在尝试读/写 MinIO 时可能遇到的一些常见错误。
如果您的访问密钥和秘密密钥不正确,您应该会看到如下错误消息
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.
接下来,您需要确保主机名和端口正确,如果没有正确的端点,这些就是您会遇到的错误。
主机名不正确:
tiledb.cc.TileDBError: [TileDB::S3] Error: … Couldn't resolve host name
端口错误:
tiledb.cc.TileDBError: [TileDB::S3] Error: … Couldn't connect to server
最后但并非最不重要的一点是,我见过的最神秘的错误之一如下
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
经过大量调试后发现,如果您使用 http 连接,但 MinIO 服务器激活了 TLS,那么您将看到上述错误。只需确保连接方案设置为正确的配置,在本例中为 config["vfs.s3.scheme"] = "https"。
有一首说唱歌曲(你可以搜索一下),他们说唱的是一堆一堆的*咳嗽*现金。但有另一首说唱歌曲声称他们有这么多现金,以至于不能再称为“堆栈”,它们现在是“架子”。本质上,当您的现金堆变得又大又高时,您需要架子上的架子来存放成堆的现金。
这是一个恰当的比较,因为你的数据堆对你来说与他们谈论的现金堆一样重要(甚至更多)。如果有像 MinIO 这样的东西来保证所有对象(物理或虚拟)的安全且易于访问就好了。
结合使用 MinIO,您可以轻松地将 TileDB 扩展到
我们已将本博客中使用的代码片段添加到
也出现在这里。