当通过添加新的服务器池来扩展 MinIO Modern Datalake 部署时,默认情况下它不会重新平衡对象。相反,MinIO 会将新文件/对象写入具有更多可用空间的池中。MinIO 的手动重新平衡触发器会扫描整个部署,然后在服务器池周围移动对象(如果需要),以确保所有池之后几乎处于相似的可用空间级别。对于 MinIO 部署来说,这是一项代价高昂的操作,应明智地触发。尽管可以随时停止和重新启动再平衡。
在独立部署中模拟重新平衡方案并不容易,无论是基于种类的集群还是使用目录作为驱动器的独立部署。为了真正触发重新平衡,我们需要将现有池填充到几乎满,然后在添加新的服务器池后,手动触发重新平衡。因此,使用虚拟机模拟此方案总是更容易、更好。
对于快速简便的开发人员模式来模拟再平衡,LXD(Linux 容器虚拟机管理程序)是一个不错的选择。本博客将列出所需的设置,并描述如何实现模拟再平衡的过程。
设置基础结构
按照以下步骤模拟 MinIO 现代数据湖部署中的再平衡。为此,我们应该使用 ubuntu 旋转总共 8 个 LXD VM。我们将使用前 4 个 VM 启动初始 MinIO 实例,然后使用接下来的 4 个 VM 进行扩展。为了限制可加载的对象的大小,我们将使用主机中的环回设备将大小为 1GiB 的虚拟磁盘添加到所有 VM。那么,让我们开始吧!!请按照以下步骤操作。
LXD 作为 snap 包正式提供,因此请先安装 snapd。
$ sudo apt install snapd
$ sudo ln -s /var/lib/snapd/snap /snap
$ snap version
$ sudo systemctl restart snapd.service
现在安装 lxd。
$ sudo snap install 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 init
这将带您完成一组问题,并且大多数默认问题都可以被接受。
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, ceph, dir, lvm) [default=btrfs]:
Create a new BTRFS pool? (yes/no) [default=yes]:
Would you like to use an existing block device (yes/no) [default=no]:
Size in GB of the new block device (1GB minimum) (default=30GB):
Would you like to connect to a MAAS server (yes/no) [default=no]:
Would you like to create a new local network bridge (yes/no) [default=yes]:
What should new bridge be called (default=lxdbr0):
What IPv4 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]: none
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:
Would you like a YAML "lxd init" pressed to be printed? (yes/no) [default=no]:
使用以下命令创建 VM。
$ 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 个 VM 重复这些命令。现在,要使所有 IPv4 IP 都符合 VM 的要求,请执行以下命令来重置其 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
同样,对于其他 VM,IP 可以设置为 10.115.111.112、10.115.111.113 和 …。
立即进入 VM 内部,创建 1GiB 大小的虚拟磁盘映像,并使用 mkfs.ext4 对其进行格式化。此外,还要从主机为环回设备创建挂载路径。
$ lxc exec vm-01 bash
$ truncate -s 1GiB /media/disk.img
$ mkfs.ext4 /media/disk.img
$ mkdir /mnt/virtual-disk
对所有 VM 重复此操作。
现在,我们将可用的环回设备从主机附加到 VM。这些只是以 /dev/loop* 形式列出的文件,不一定所有列出的文件都可以使用。如果在 VM 中挂载时遇到问题 mount: /mnt/virtual-disk: failed to setup loop device for /media/disk.img., create a new loopback device on host and try with the new one.使用命令 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
从 VM 内部 ,立即挂载。
$ lxc exec vm-01 bash
$ mount -t ext4 -o loop /media/disk.img /mnt/virtual-disk
对所有 VM 重复此过程。若要验证装载是否成功,请在 VM 中运行以下命令。
$ mount | grep virtual-disk
/media/disk.img on /mnt/virtual-disk type ext4 (rw,realtime)
VM 现在已准备就绪,我们可以开始 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。
在所有 VM 上安装 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 VM 的列表,并记下其 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 | RUNNING | 10.49.238.63 (eth0) | fd42:9cd0:6055:a53:216:3eff:fe34:44cd (eth0) | CONTAINER | 0 |
+-------+---------+---------------------+----------------------------------------------+-----------+-----------+
| vm-04 | RUNNING | 10.49.238.64 (eth0) | fd42:9cd0:6055:a53:216:3eff:fef9:4262 (eth0) | CONTAINER | 0 |
+-------+---------+---------------------+----------------------------------------------+-----------+-----------+
| vm-05 | RUNNING | 10.49.238.65 (eth0) | fd42:9cd0:6055:a53:216:3eff:fe16:2e02 (eth0) | CONTAINER | 0 |
+-------+---------+---------------------+----------------------------------------------+-----------+-----------+
| vm-06 | RUNNING | 10.49.238.66 (eth0) | fd42:9cd0:6055:a53:216:3eff:fe94:4610 (eth0) | CONTAINER | 0 |
+-------+---------+---------------------+----------------------------------------------+-----------+-----------+
| vm-07 | RUNNING | 10.49.238.67 (eth0) | fd42:9cd0:6055:a53:216:3eff:fef1:40f3 (eth0) | CONTAINER | 0 |
+-------+---------+---------------------+----------------------------------------------+-----------+-----------+
| vm-08 | RUNNING | 10.49.238.68 (eth0) | fd42:9cd0:6055:a53:216:3eff:fef5:d909 (eth0) | CONTAINER | 0 |
+-------+---------+---------------------+----------------------------------------------+-----------+-----------+
现在使用前四个 VM 启动 MinIO 实例,如下所示。此命令应从前 4 个 VM 内部运行。
$ 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 个 VM 上的 MiniIO 进程,现在从所有 8 个 VM 运行以下命令。
$ 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
Per-pool usage:
┌─────────┬────────┐
│ Pool-0 │ Pool-1 │
│ 0.85% * │ 0.14% │
└─────────┴────────┘
Summary:
Data: 390 MiB (195 objects, 195 versions)
Time: 11.40798155s (52.794879439s to completion)
一旦重新平衡完成并且不再有对象要移动,您应该能够验证如下所示。
$ 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 足够智能,可以在空间可用时添加新数据,同时牢记纠删码要求。重新平衡是一项非常耗费资源的操作,因此不建议在集群使用最多的高峰时段运行它。相反,如果需要重新平衡集群,则必须在集群使用最少的下班时间完成。