当 MinIO Modern Datalake 部署通过添加新的服务器池进行扩展时,默认情况下它不会重新平衡对象。相反,MinIO 会将新的文件/对象写入具有更多可用空间的池中。手动触发 MinIO 的重新平衡会扫描整个部署,然后对象会在服务器池之间移动(如果需要),以确保所有池在之后都具有几乎相同的可用空间级别。对于 MinIO 部署来说,这是一个代价高昂的操作,应谨慎触发。虽然重新平衡可以在任何时候停止和重新启动。
在独立部署中模拟重新平衡场景并不容易,无论它是基于 Kind 的集群还是使用目录作为驱动器的独立部署。为了实际触发重新平衡,我们需要将现有的池填充到几乎满载,然后在添加新的服务器池后,手动触发重新平衡。出于这个原因,使用虚拟机模拟此场景总是更容易且更好。
为了快速简便地模拟重新平衡的开发者模式,LXD(Linux 容器虚拟机管理程序)是一个不错的选择。本博文将列出所需的设置并描述如何实现模拟重新平衡的过程。
设置基础设施
按照以下步骤模拟 MinIO Modern Datalake 部署中的重新平衡。为此,我们应该使用 Ubuntu 启动总共 8 个 LXD 虚拟机。我们将使用前 4 个虚拟机启动初始 MinIO 实例,然后使用接下来的 4 个虚拟机进行扩展。为了限制可以加载的对象的大小,我们将使用主机上的循环设备向所有虚拟机添加大小为 1GiB 的虚拟磁盘。所以,让我们开始吧!请按照以下步骤操作。
LXD 可作为 snap 包正式提供,因此请先安装 snapd。
$ sudo apt install snapd $ sudo ln -s /var/lib/snapd/snap /snap $ snap version $ sudo systemctl restart snapd.service |
现在安装 lxd。
验证安装并启动 LXD。
$ sudo snap enable lxd $ sudo snap services lxd $ sudo snap start lxd |
将您的用户名添加到 lxd 组。
$ sudo usermod -a -G lxd <USERNAME> $ id <USERNAME> $ newgrp lxd |
初始化 LXD。
这将引导您完成一系列问题,大多数默认问题都可以接受。
您是否要使用 LXD 集群?(yes/no) [default=no] 您是否要配置新的存储池?(yes/no) [default=yes] 新存储池的名称 [default=default] 要使用的存储后端的名称 (btrfs, ceph, dir, lvm) [default=btrfs] 创建新的 BTRFS 池?(yes/no) [default=yes] 您是否要使用现有的块设备?(yes/no) [default=no] 新块设备的大小(以 GB 为单位)(最小 1GB)(默认 30GB) 您是否要连接到 MAAS 服务器?(yes/no) [default=no] 您是否要创建一个新的本地网络桥接?(yes/no) [default=yes] 新桥接的名称是什么?(默认 lxdbr0) 应使用什么 IPv4 地址?(CIDR 子网表示法,“auto”或“none”)[default=auto] 应使用什么 IPv6 地址?(CIDR 子网表示法,“auto”或“none”)[default=auto]: none 您是否希望 LXD 可通过网络访问?(yes/no) [default=no] 您是否希望过时的缓存映像自动更新?(yes/no) [default=yes] 您是否希望打印 YAML "lxd init" 按钮?(yes/no) [default=no] |
使用以下命令创建虚拟机。
$ lxc init images:ubuntu/jammy vm-01 --profile=default -c boot.autostart=true -c security.privileged=true -c security.syscalls.intercept.mount=true -c security.syscalls.intercept.mount.allowed=ext4 -c limits.memory=1024MB -c limits.cpu.allowance=10% $ lxc start vm-01 |
对所有 8 个虚拟机重复这些命令。现在,为了使所有虚拟机的 IPv4 IP 都有序,请执行以下命令重置它们的 IP。
$ lxc stop vm-01 $ lxc network attach lxdbr0 vm-01 eth0 eth0 $ lxc config device set vm-01 eth0 ipv4.address 10.115.111.111 $ lxc start vm-01 |
类似地,对于其他虚拟机,IP 可以设置为 10.115.111.112、10.115.111.113 等。
现在进入虚拟机内部,创建大小为 1GiB 的虚拟磁盘映像,并使用 mkfs.ext4 对其进行格式化。还为主机上的循环设备创建一个挂载路径。
$ lxc exec vm-01 bash $ truncate -s 1GiB /media/disk.img $ mkfs.ext4 /media/disk.img $ mkdir /mnt/virtual-disk |
对所有虚拟机重复此操作。
现在,我们将主机上可用的循环设备附加到虚拟机。这些只是列为 /dev/loop* 的文件,并不一定所有列出的文件都可用。如果在虚拟机内挂载时遇到问题 mount: /mnt/virtual-disk: failed to setup loop device for /media/disk.img.,请在主机上创建一个新的循环设备并尝试使用新的设备。使用命令 sudo losetup -f 获取一个新的可用循环设备。请按照以下步骤在虚拟机内附加和挂载循环设备
$ lxc config device add vm-01 loop-control unix-char path=/dev/loop-control $ lxc config device add vm-01 loop4 unix-block path=/dev/loop4 |
从虚拟机内部挂载它。
$ lxc exec vm-01 bash $ mount -t ext4 -o loop /media/disk.img /mnt/virtual-disk |
对所有虚拟机重复此过程。要验证挂载是否成功,请在虚拟机内运行以下命令。
$ mount | grep virtual-disk /media/disk.img on /mnt/virtual-disk type ext4 (rw,realtime) |
虚拟机现在已准备就绪,我们可以开始 MinIO 部署了
设置 MinIO
我们需要创建许多对象,我们稍后会将其推送到 MinIO 存储桶。在主机节点上执行以下命令以执行此操作
$ mkdir -p $HOME/test-minio-rebal $ cd $HOME/test-minio-rebal $ for index in {1..4500}; do truncate -s 1M file$index; done |
这将创建 4500 个大小均为 1M 的随机文件。
在所有虚拟机上安装 MinIO 二进制文件
$ wget -O https://dl.min.io/server/minio/release/linux-amd64/minio $ chmod +x minio $ mv minio /usr/local/bin |
MinIO 客户端可以安装在主机本身上。
$ wget -O https://dl.min.io/client/mc/release/linux-amd64/mc $ chmod +x mc $ sudo mv mc /usr/local/bin |
启动 MinIO 实例并加载对象。首先获取所有正在运行的 lxc 虚拟机的列表并记下它们的 IPv4 IP。
$ lxc list +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ | vm-01 | RUNNING | 10.49.238.61 (eth0) | fd42:9cd0:6055:a53:216:3eff:fef3:f0f (eth0) | CONTAINER | 0 | +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ | vm-02 | RUNNING | 10.49.238.62 (eth0) | fd42:9cd0:6055:a53:216:3eff:fe16:4d04 (eth0) | CONTAINER | 0 | +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ | vm-03 | 运行中 | 10.49.238.63 (eth0) | fd42:9cd0:6055:a53:216:3eff:fe34:44cd (eth0) | 容器 | 0 | +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ | vm-04 | 运行中 | 10.49.238.64 (eth0) | fd42:9cd0:6055:a53:216:3eff:fef9:4262 (eth0) | 容器 | 0 | +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ | vm-05 | 运行中 | 10.49.238.65 (eth0) | fd42:9cd0:6055:a53:216:3eff:fe16:2e02 (eth0) | 容器 | 0 | +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ | vm-06 | 运行中 | 10.49.238.66 (eth0) | fd42:9cd0:6055:a53:216:3eff:fe94:4610 (eth0) | 容器 | 0 | +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ | vm-07 | 运行中 | 10.49.238.67 (eth0) | fd42:9cd0:6055:a53:216:3eff:fef1:40f3 (eth0) | 容器 | 0 | +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ | vm-08 | 运行中 | 10.49.238.68 (eth0) | fd42:9cd0:6055:a53:216:3eff:fef5:d909 (eth0) | 容器 | 0 | +-------+---------+---------------------+----------------------------------------------+-----------+-----------+ |
现在使用前四台虚拟机启动一个 MinIO 实例,如下所示。此命令应在前面四台虚拟机内部运行。
$ minio server http://10.49.238.{61...64}/mnt/virtual-disk/disk{1...4} |
实例稳定后,为集群创建 mc 别名,如下所示。
mc alias set ALIAS http://10.49.238.61:9000 minioadmin minioadmin |
现在可以将对象加载到集群中了。运行以下命令执行此操作。
$ mc mb ALIAS/test-bucket $ mc cp $HOME/test-minio-rebal/* ALIAS/test-bucket |
您可能会在最后看到磁盘空间不足的错误,这是正常的,因为集群现在已将对象加载到极限。等待几秒钟,然后验证对象是否已加载到池中。
$ mc admin info ALIAS --json | jq -r '.info.pools' { "0": { "0": { "id": 0, "rawUsage": 3785478144, "rawCapacity": 3800956928, "usage": 1155530752, "objectsCount": 1102, "versionsCount": 0, "healDisks": 0 } } } |
现在我们可以用一组新的节点扩展集群了。停止前 4 台虚拟机上的 MinIO 进程,然后从所有 8 台虚拟机运行以下命令。
$ minio server http://10.49.238.{61...64}/mnt/virtual-disk/disk{1...4} http://10.49.238.{65...68}/mnt/virtual-disk/disk{1...4} |
等待集群稳定,并检查是否添加了新的池。
$ mc admin info ALIAS --json | jq -r '.info.pools' { "0" "0": { "id": 0, "rawUsage": 3785478144, "rawCapacity": 3800956928, "usage": 1155530752, "objectsCount": 1102, "versionsCount": 0, "healDisks": 0 } }, "1": { "0": { "id": 0, "rawUsage": 376832, "rawCapacity": 3800956928, "usage": 0, "objectsCount": 0, "versionsCount": 0, "healDisks": 0 } } } |
现在您可以安全地在集群上运行重新平衡操作。
$ mc admin rebalance start ALIAS |
您可以跟踪正在运行的重新平衡状态,如下所示。
$ mc admin rebalance status ALIAS 每个池的使用情况 ┌─────────┬────────┐ │ 池-0 │ 池-1 │ │ 0.85% * │ 0.14% │
└─────────┴────────┘ 摘要 数据: 390 MiB (195 个对象,195 个版本) 时间: 11.40798155s (完成时间 52.794879439s) |
一旦重新平衡完成并且没有更多对象需要移动,您应该能够验证如下内容。
$ mc admin info ALIAS --json | jq -r '.info.pools' { "0": { "0": { "id": 0, "rawUsage": 2029391872, "rawCapacity": 3800956928, "usage": 1394606080, "objectsCount": 1330, "versionsCount": 0, "healDisks": 0 } }, "1": { "0": { "id": 0, "rawUsage": 1756606464, "rawCapacity": 3800956928, "usage": 435159040, "objectsCount": 415, "versionsCount": 0, "healDisks": 0 } } } |
就这么简单。
最终思考
通常,当添加或删除新的存储池时,MinIO 不需要任何手动重新平衡。MinIO 足够智能,可以将新数据添加到有可用空间的位置,同时牢记擦除编码要求。重新平衡是一个非常占用资源的操作,因此不建议在集群使用最频繁的高峰时段运行它。相反,如果需要重新平衡集群,则必须在集群使用最少的非高峰时段进行。
如果您对重新平衡以及如何管理 MinIO 现代数据湖有任何疑问,请务必在Slack上与我们联系!