1. 项目概述一个面向边缘计算的轻量级存储编排器最近在折腾边缘计算环境下的存储方案发现了一个挺有意思的项目叫Atum246/rook。这名字乍一看有点怪但如果你熟悉云原生存储编排可能会联想到大名鼎鼎的rook/rook。没错这个项目正是基于 Rook 的一个深度定制分支但它瞄准了一个更具体、也更“接地气”的场景在资源受限的边缘节点上实现一个极度轻量、易于部署且功能聚焦的分布式存储系统。传统的 Rook 功能强大是一个完整的云原生存储编排器能管理 Ceph、EdgeFS、Cassandra 等多种存储后端。但它的“重”也带来了挑战复杂的 Operator 逻辑、相对庞大的资源消耗以及对稳定 Kubernetes 控制平面的强依赖。这在资源充沛的数据中心里不是问题但到了边缘——那些可能只有几个节点、CPU和内存都捉襟见肘网络还不稳定的环境中就显得有些“水土不服”了。Atum246/rook的核心思路就是做减法。它没有试图去支持所有存储后端而是专注于一个最经典、最可靠的选项Ceph。更准确地说它聚焦于 Ceph 的 RADOS 块设备RBD和 Ceph 文件系统CephFS这两种最常用的存储类型并针对边缘环境的特点对部署、配置和运维流程进行了大刀阔斧的精简和优化。它的目标不是成为一个通用的存储平台而是成为一个“开箱即用”的边缘存储底座让开发者能像在云端一样在边缘轻松地为有状态应用提供持久化存储。如果你正在为物联网网关、工厂产线、零售门店或者车载计算单元这类边缘场景寻找存储解决方案既希望获得类似云上 Persistent Volume 的便利性又受限于边缘硬件的苛刻条件那么这个项目值得你花时间深入了解。接下来我会从设计思路、实操部署到排错优化完整拆解一遍。2. 核心设计思路与架构取舍为什么要在边缘重新造一个 Rook 的轮子这背后是对边缘计算存储需求的深刻理解。边缘存储面临几个核心矛盾有限的算力与存储服务开销的矛盾、波动的网络与存储一致性的矛盾以及简易运维需求与复杂存储系统之间的矛盾。Atum246/rook的每一个设计选择几乎都是围绕解决这些矛盾展开的。2.1 极简化架构只保留核心路径原版 Rook 的架构包含了多个组件Rook Operator、Ceph Operator、多个 CRD自定义资源定义控制器、以及各种辅助 Pod。Atum246/rook首先做的就是架构瘦身。它大幅合并了功能通常只保留一个高度集成的 Operator Pod。这个 Operator 负责监听少数几个关键的 CRD比如CephCluster、CephBlockPool和CephFilesystem并直接驱动 Ceph 集群的部署和管理。注意这种高度集成化设计带来了部署上的便利但也意味着定制化能力的降低。如果你需要修改 Ceph 的某个非常底层的参数或者集成特定的监控插件可能需要直接修改这个 Operator 的代码或配置映射而不是通过丰富的 CRD 字段来配置。在 Ceph 集群的构成上它也做了针对性优化。考虑到边缘节点数量少常见3节点它默认推荐使用bluestore作为 OSD对象存储守护进程的后端存储引擎因为bluestore在性能和空间利用率上通常优于旧的filestore。同时为了节省资源它可能会默认禁用一些在边缘场景下非必需的功能比如 Ceph Dashboard 的 Grafana 模块或者精简监控指标的输出。2.2 部署模式革新拥抱 Helm 和单清单文件原版 Rook 虽然也支持 Helm但其部署过程依然涉及多个步骤和 YAML 文件。Atum246/rook则极力推崇“一键部署”体验。它通常提供一个高度优化的 Helm Chart或者甚至是一个包含了所有必要资源的单一 Kubernetes 清单文件。这个 Helm Chart 的values.yaml会预设好针对边缘场景的优化参数。例如资源请求与限制为 Ceph Monitor、Manager 和 OSD 设置更保守的 CPU 和内存请求防止在资源紧张的节点上因调度失败而导致部署卡住。存储设备发现简化设备筛选逻辑。在边缘我们通常使用直接附加的 SSD 或 NVMe 盘而不是复杂的 RAID 阵列。因此部署工具可以更直接地使用/dev/sdb、/dev/nvme0n1这样的原始设备路径避免复杂的过滤器配置。网络配置明确指定集群网络和公共网络在边缘环境中两者往往是同一个网络段。同时可能会禁用主机网络hostNetwork的默认使用以减少对节点网络的侵入性除非在特定网络隔离场景下才开启。2.3 存储策略聚焦RBD 和 CephFS 的黄金组合项目明确聚焦于 Ceph RBD 和 CephFS这是经过深思熟虑的。RBD 提供了块存储兼容性极佳几乎所有支持 Persistent Volume 的应用都可以使用性能也相对直接。CephFS 则提供了文件系统接口适合需要共享存储、多 Pod 同时读写的场景比如 CI/CD 流水线共享工作区、日志聚合目录等。在边缘我们很少需要 Ceph 对象网关RGW提供的 S3 兼容接口因为对象存储的负载通常会上传到云端。因此砍掉 RGW 组件能显著减少内存占用和复杂度。对于存储池Pool的配置项目可能会预设创建两个池一个用于 RBD如rbd池副本数设置为与节点数匹配如3副本另一个用于 CephFS 的元数据和数据池。副本策略通常采用经典的“副本池”Replicated Pool而非纠删码池因为纠删码虽然节省空间但计算开销更大在边缘小集群中恢复数据的效率可能反而更低。3. 实战部署从零搭建一个边缘 Ceph 集群理论说得再多不如动手跑一遍。假设我们有一个由三台 x86 机器组成的边缘集群每个节点有一块额外的 500GB SSD 用于存储已经安装好了 Kubernetes例如使用 K3s 或 MicroK8s 这类轻量发行版。下面我们一步步来部署Atum246/rook。3.1 前置条件与节点准备首先确保你的 Kubernetes 集群是健康的并且具备网络互通能力。每个节点都需要满足一些基本要求内核版本建议 Linux 内核 4.17 或更高以支持最新的 Ceph 功能和更好的性能。使用uname -r检查。存储设备用于 OSD 的裸设备如/dev/sdb必须没有文件系统或分区表。可以使用lsblk -f命令确认。重要操作前务必确认设备无误否则可能导致数据丢失。LVM2 工具Ceph OSD 通常依赖 LVM 来管理物理设备。确保节点上安装了lvm2包。在 Ubuntu/Debian 上sudo apt-get install -y lvm2。时间同步Ceph 对节点间时间同步非常敏感。务必使用 NTP 或 Chrony 确保所有节点时间一致偏差最好在毫秒级以内。实操心得在资源极其受限的边缘节点我曾遇到过因为lvm2包缺失导致 OSD 部署失败但错误信息却非常隐晦只提示“无法创建物理卷”。所以把这几个依赖项作为部署检查清单的第一步能省去很多排查时间。3.2 使用 Helm 部署 Rook Operator假设项目提供了 Helm Chart。我们首先添加仓库并安装 Operator。# 添加 Helm 仓库这里用假设的仓库地址实际请参考项目文档 helm repo add atum-rook https://atum246.github.io/rook-charts helm repo update # 创建一个命名空间 kubectl create ns rook-ceph-edge # 安装 Rook Operator helm install rook-ceph-edge atum-rook/rook-ceph \ --namespace rook-ceph-edge \ --set operator.resources.requests.cpu100m \ --set operator.resources.requests.memory256Mi这里的关键参数是设置了 Operator 的资源请求。在边缘我们主动限制它的资源用量避免它抢占应用负载的资源。安装后使用kubectl get pods -n rook-ceph-edge -w观察直到 Operator Pod 状态变为Running。3.3 配置并创建 Ceph 集群接下来是核心步骤定义 Ceph 集群。我们需要创建一个CephCluster自定义资源。项目通常会提供一个优化过的示例文件cluster-edge.yaml。apiVersion: ceph.rook.io/v1 kind: CephCluster metadata: name: rook-ceph-edge namespace: rook-ceph-edge spec: dataDirHostPath: /var/lib/rook # 元数据主机路径 cephVersion: image: ceph/ceph:v17.2.6-quincy # 使用一个稳定且较新的 Ceph 版本 mon: count: 3 # 三个 Monitor与节点数一致实现高可用 allowMultiplePerNode: false # 每个节点只运行一个 Mon避免单点资源过载 mgr: count: 2 # 两个 Manager 实现高可用 storage: useAllNodes: false # 不自动使用所有节点精确控制 useAllDevices: false # 不自动使用所有设备 nodes: - name: edge-node-1 devices: - name: sdb # 指定设备名确保是裸盘 - name: edge-node-2 devices: - name: sdb - name: edge-node-3 devices: - name: sdb network: provider: host # 在边缘通常使用主机网络以获得最佳性能 resources: # 为各个组件设置严格的资源限制防止在边缘节点上失控 mgr: limits: cpu: 500m memory: 512Mi requests: cpu: 200m memory: 256Mi mon: limits: cpu: 500m memory: 1Gi requests: cpu: 200m memory: 512Mi osd: limits: cpu: 1 memory: 2Gi requests: cpu: 500m memory: 1Gi healthCheck: daemonHealth: mon: interval: 45s # 拉长健康检查间隔减少网络开销 osd: interval: 45s应用这个配置kubectl apply -f cluster-edge.yaml。创建过程可能需要几分钟。你可以通过以下命令观察进度# 查看集群状态 kubectl get cephcluster -n rook-ceph-edge # 当状态显示为 Ready 和 Healthy 时表示集群就绪 # 查看所有 Ceph Pod kubectl get pods -n rook-ceph-edge # 等待所有 Pod 都进入 Running 状态特别是 osd-prepare-* 任务完成osd-* Pod 正常运行。3.4 创建存储池与存储类集群就绪后我们需要创建存储池Pool和对应的 Kubernetes StorageClass。创建块设备池 (RBD Pool):apiVersion: ceph.rook.io/v1 kind: CephBlockPool metadata: name: rbd-edge-pool namespace: rook-ceph-edge spec: failureDomain: host # 副本分布在不同的主机上 replicated: size: 3 # 3副本与节点数一致 requireSafeReplicaSize: true # 确保在副本数不足时不提供IO保证数据安全创建文件系统 (CephFS):apiVersion: ceph.rook.io/v1 kind: CephFilesystem metadata: name: cephfs-edge namespace: rook-ceph-edge spec: metadataPool: failureDomain: host replicated: size: 3 dataPools: - failureDomain: host replicated: size: 3 preserveFilesystemOnDelete: true # 删除 CR 时保留底层数据防止误操作 metadataServer: activeCount: 2 # 两个 MDS 实例实现高可用 activeStandby: true resources: limits: memory: 1Gi cpu: 500m应用以上两个 YAML 文件后就可以创建 StorageClass 了。Rook Operator 通常会自动创建一些默认的 StorageClass但为了更贴合边缘场景我们手动创建RBD StorageClass:apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: rook-ceph-block-edge provisioner: rook-ceph.rbd.csi.ceph.com parameters: clusterID: rook-ceph-edge pool: rbd-edge-pool imageFormat: 2 imageFeatures: layering csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph-edge csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph-edge csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph-edge reclaimPolicy: Delete allowVolumeExpansion: true mountOptions: - discard # 启用 TRIM/UNMAP 支持有助于 SSD 长期性能CephFS StorageClass:apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: rook-cephfs-edge provisioner: rook-ceph.cephfs.csi.ceph.com parameters: clusterID: rook-ceph-edge fsName: cephfs-edge pool: cephfs-edge-data0 csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph-edge csi.storage.k8s.io/controller-expand-secret-name: rook-csi-cephfs-provisioner csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph-edge csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph-edge reclaimPolicy: Delete allowVolumeExpansion: true创建完成后使用kubectl get sc就能看到这两个存储类了。现在你的边缘 Kubernetes 集群就已经具备了动态供给持久化卷的能力。4. 关键配置解析与边缘场景调优部署成功只是第一步要让存储系统在边缘稳定高效运行还需要理解并调整一些关键配置。这些配置往往在通用教程里一笔带过但在边缘环境下却是稳定性的生命线。4.1 网络配置性能与稳定的平衡在CephClusterCR 中我们设置了network.provider: host。这意味着 Ceph 的各个守护进程Mon、OSD、MDS将直接使用宿主机的网络命名空间和 IP 地址。优势是网络路径最短性能最好延迟最低。劣势是端口管理需要更小心Ceph 会固定使用一些端口如 Mon 的 6789。在边缘我们通常追求极简和性能所以主机网络是首选。但你必须确保这些端口在集群所有节点间的防火墙如 firewalld, iptables都是开放的。一个常见的坑是节点重启后防火墙规则丢失导致 Ceph 集群网络分区。我的建议是要么在系统层面永久开放这些端口要么直接禁用防火墙仅在可控的内网环境中考虑。如果因为策略必须使用 Pod 网络provider: multus或默认的 CNI则需要关注网络插件的性能和稳定性。一些轻量级 CNI如 Flannel 的 VXLAN可能会引入额外的开销。务必进行网络性能测试确保存储流量不会成为瓶颈。4.2 资源限制防止存储服务“饿死”业务应用上面 YAML 中的resources部分至关重要。在边缘节点上CPU 和内存是黄金资源。如果不加限制Ceph OSD 在后台进行数据均衡、恢复或清理scrubbing时可能会消耗大量 CPU导致同节点上的业务应用响应延迟飙升。OSD 内存Ceph Bluestore 会利用内存进行缓存。1Gi的请求和2Gi的限制是一个比较安全的起点。如果节点内存非常紧张比如只有 4GiB你可能需要将这个值压到requests: 512Mi, limits: 1Gi。但这会显著影响缓存命中率和性能需要权衡。Monitor 内存Mon 存储集群的 CRUSH Map 和 OSD Map 等元数据。对于百台以下的小集群512Mi请求通常足够。CPU将limits设置为requests的 2 倍左右允许 Ceph 在需要时如恢复数据短暂爆发但又不至于长期霸占 CPU。实操心得不要只看 Pod 的请求和限制还要关注节点的实际资源利用率。使用kubectl top node和kubectl top pod -n rook-ceph-edge持续监控。我曾遇到一个案例OSD 的limits.cpu设置过高导致节点整体 CPU 使用率看似不高但业务 Pod 的 CPU 节流Throttling非常严重因为 Linux CFS 调度器在竞争激烈时限制高的进程会获得更多时间片。后来通过适当调低 OSD 的 CPU 限制并设置合理的 CPU 亲和性问题才得以解决。4.3 存储设备与 OSD 调优对于边缘常用的消费级或工控级 SSD需要进行一些调优以延长寿命并保证性能。调度器Scheduler将 SSD 的 I/O 调度器设置为none即 noop或kyber/mq-deadline多队列设备。这可以减少内核 I/O 调度层的开销对于闪存设备更高效。# 检查当前调度器 cat /sys/block/sdb/queue/scheduler # 临时修改 echo kyber /sys/block/sdb/queue/scheduler # 永久修改需修改 grub 或 udev 规则Discard/TRIM在 StorageClass 的mountOptions中我们已经添加了discard。对于 Ceph Bluestore还需要确保在部署时启用了自动 trimming。这需要检查 Ceph 的配置通常可以通过在CephClusterCR 的spec.storage部分添加config字段来设置全局参数或者在 OSD 启动后通过ceph config set命令设置osd_bluestore_use_trim等参数。OSD 内存目标可以通过 Ceph 配置调整 Bluestore 的缓存大小。如果内存限制设置得较低可以适当调低缓存目标避免 OSD 因内存压力而崩溃。# 进入 toolbox pod kubectl exec -it -n rook-ceph-edge deploy/rook-ceph-tools -- bash # 设置所有 OSD 的 BlueStore 缓存大小目标为 1GB ceph config set osd bluestore_cache_size_hdd 1073741824 ceph config set osd bluestore_cache_size_ssd 1073741824注意这里的值是以字节为单位的。对于混合部署或全闪存部署需要根据实际情况调整。5. 运维、监控与故障排查实录系统上线后日常运维和问题排查才是真正的挑战。下面分享几个在边缘环境中特别容易遇到的问题和解决思路。5.1 基础监控与健康检查首先你需要进入 Rook 提供的工具箱 Pod 来执行 Ceph 命令。kubectl exec -it -n rook-ceph-edge deploy/rook-ceph-tools -- bash进入后常用命令如下ceph status: 查看集群整体健康状态。HEALTH_OK是目标。ceph osd status: 查看所有 OSD 的状态、权重和上下线情况。ceph df: 查看集群存储空间使用详情。ceph pg stat: 查看归置组PG状态。重点关注activeclean的比例。对于集成到 Prometheus 的监控Rook 默认会暴露 metrics。你可以使用 ServiceMonitor 或直接 scrape Ceph Manager 的 HTTP 端点默认端口 9283来收集指标。在边缘你可能需要一个更轻量的监控方案比如将关键指标如集群状态、OSD 状态、存储使用率通过 sidecar 容器输出到日志或者集成轻量级的监控代理。5.2 常见问题与排查技巧问题一集群健康状态为HEALTH_WARN提示 “too few PGs per OSD”这是小集群的典型问题。PG归置组是 Ceph 数据分布的单位。PG 数量太少会导致数据分布不均影响性能和恢复能力太多则会增加管理开销。对于一个小型边缘集群计算合适的 PG 数很重要。解决进入 toolbox使用命令调整存储池的 PG 数量。一个经验公式是每个 OSD 的 PG 数目标在 50-100 左右。假设我们有 3 个 OSD副本数为 3那么总 PG 数约为3 OSDs * 100 / 3 副本 ≈ 100。我们可以为rbd-edge-pool设置 PG_NUM 为 128必须是2的幂。ceph osd pool set rbd-edge-pool pg_num 128 ceph osd pool set rbd-edge-pool pgp_num 128 # pgp_num 通常与 pg_num 保持一致调整后集群会开始数据迁移期间可能会有性能影响应在业务低峰期进行。问题二一个节点宕机后集群健康状态变为HEALTH_ERRIO 暂停这是由requireSafeReplicaSize: true设置导致的。当副本数不足时例如3副本缺了1个为了保证数据一致性Ceph 会停止对该 PG 的写入甚至拒绝读取。这是为了数据安全但在边缘高可用场景下我们可能希望牺牲一点安全性来换取可用性。解决根据业务容忍度有两种选择等待节点恢复如果节点能快速恢复如网络闪断这是最佳选择。临时降低安全要求如果业务不能中断可以临时调整最小副本数。这是一个有数据丢失风险的操作务必谨慎# 将池的 min_size 从默认的2调整为1。这意味着只要有一个副本存活IO 就可以继续。 ceph osd pool set rbd-edge-pool min_size 1节点恢复后务必记得改回来ceph osd pool set rbd-edge-pool min_size 2。问题三OSD Pod 不断重启日志显示 “bluestore has too few free extents” 或类似空间错误这可能是因为消费级 SSD 的过度配置Over-Provisioning空间不足或者 Bluestore 的元数据空间RockDB被占满。在频繁写入删除的场景下容易发生。解决检查 OSD 的使用率ceph osd df。如果某个 OSD 使用率接近 100%需要扩容或进行数据均衡。如果是因为 Bluestore 的元数据空间问题可以尝试在工具箱中对该 OSD 进行压缩但线上操作有风险ceph tell osd.osd_id compact例如osd.0。 3.根本预防在部署时不要将 OSD 的占用比例设得太高。Ceph 默认会在使用率达到 85% 时发出警告95% 时停止写入。对于小容量 SSD建议通过ceph osd set-full-ratio 0.90和ceph osd set-backfillfull-ratio 0.85设置更保守的阈值。问题四Pod 挂载 CephFS 卷失败提示 “mount error(112): Host is down”这通常是 CephFS 的元数据服务器MDS问题或网络问题。排查步骤检查 MDS Pod 状态kubectl get pods -n rook-ceph-edge -l approok-ceph-mds。确保它们处于Running状态。进入 toolbox检查 MDS 状态ceph mds stat。应该显示active状态。检查客户端即你的业务 Pod 所在节点到 Ceph 集群网络的连通性特别是到 MDS 服务端口的连通性默认 6789 用于 Mon但 MDS 有动态端口。一个常见边缘场景的坑是业务 Pod 使用了hostNetwork: true但 Ceph 集群使用的是 Pod 网络或反之导致网络无法直接互通。确保存储网络和业务网络策略兼容。5.3 备份与灾难恢复简易方案对于边缘场景完整的异地备份可能不现实但必须有基本的容灾计划。配置快照利用 RBD 的快照功能为重要卷定期创建快照。这可以快速回滚到某个时间点。# 在 toolbox 中为某个 RBD 镜像创建快照 rbd snap create rbd-edge-pool/image_namesnap_name # 例如rbd snap create rbd-edge-pool/pvc-abc123backup-20231027导出/导入镜像定期将关键卷导出到边缘节点的本地磁盘或另一个存储节点。# 导出 rbd export rbd-edge-pool/pvc-abc123 /mnt/backup/pvc-abc123.img # 导入恢复 rbd import /mnt/backup/pvc-abc123.img rbd-edge-pool/pvc-restored --image-format 2然后你可以基于导入的镜像创建一个新的 PVC。集群级容灾对于极端情况你可以备份关键的 Ceph 配置文件、密钥环和 CRUSH Map。使用ceph mon getmap、ceph osd getmap和ceph auth list等命令导出信息。但请注意这种方法复杂恢复成功率依赖于集群状态的一致性仅作为最后手段。6. 性能测试与基准评估部署调优后如何知道存储性能是否符合预期你需要进行基准测试。在边缘环境下测试应更贴近实际业务场景即混合读写、随机 IO 为主。可以使用fio工具在 Pod 内进行测试。首先创建一个使用rook-ceph-block-edgeStorageClass 的 PVC 和测试 Pod。测试 Pod YAML (fio-tester.yaml):apiVersion: v1 kind: Pod metadata: name: fio-tester spec: containers: - name: fio image: registry.hub.docker.com/axboe/fio:latest command: [sleep, infinity] volumeMounts: - name: test-volume mountPath: /data volumes: - name: test-volume persistentVolumeClaim: claimName: fio-test-pvc # 需要提前创建这个PVC进入 Pod 执行测试kubectl exec -it fio-tester -- bash # 安装 fio如果镜像里没有 apt-get update apt-get install -y fio # 测试 4K 随机写 (模拟日志写入) fio --namerandwrite --ioenginelibaio --rwrandwrite --bs4k --direct1 --size1G --numjobs1 --runtime60 --time_based --group_reporting --filename/data/testfile # 测试 4K 随机读 (模拟数据库查询) fio --namerandread --ioenginelibaio --rwrandread --bs4k --direct1 --size1G --numjobs1 --runtime60 --time_based --group_reporting --filename/data/testfile # 测试混合读写 (模拟应用负载) fio --namemixed --ioenginelibaio --rwrandrw --bs4k --direct1 --size1G --numjobs1 --runtime60 --time_based --group_reporting --rwmixread70 --filename/data/testfile重点关注输出中的iops(每秒读写操作数) 和lat(延迟包括 clat 百分位数如 99.00%、99.99%)。在边缘的机械硬盘或 SATA SSD 上4K 随机写的 iops 可能在几百到几千延迟在几毫秒到十几毫秒。NVMe SSD 会好很多。将测试结果与你的应用需求对比如果延迟过高可能需要回头检查网络配置、OSD 资源限制或底层磁盘的健康状态。最后别忘了清理测试资源kubectl delete pod fio-tester和对应的 PVC。通过以上从设计、部署、配置到运维、排错和测试的完整流程你应该能在边缘环境中驾驭这个轻量化的Atum246/rook存储方案了。它的价值在于把复杂的东西变简单把通用的东西变专注让存储这个基础设施在资源受限的边缘也能可靠地跑起来为你的有状态应用铺平道路。在实际操作中最深的体会就是“因地制宜”没有放之四海而皆准的配置只有不断观察、测试和调整才能让存储系统与边缘业务负载达成最佳平衡。