mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #790] 关于多RDMA卡场景下的性能测试疑问 #243
Labels
No labels
ascend
auto-closed
bug
bug
CI/Build
Common
documentation
enhancement
feature request
good first issue
help wanted
high priority
MetaX
nightly-failure
pull-request
PyTorch Backend
question
RFC
Roadmap
stale
Store
Tests
Transfer Engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/Mooncake#243
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @XQZ1120 on GitHub (Aug 28, 2025).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/790
我想验证多RDMA卡聚合的吞吐性能,但测试过程中发现不符合预期,下面是我的实验过程:
两台实验机器,每个节点含8个400Gbps的NIC设备。
我首先使用 transfer_engine_bench 测试了多RDMA卡的吞吐性能,是符合预期的:单RDMA卡约为47GB/s,双RDMA卡约为90GB/s。
然后我创建了两个.py脚本,模拟客户端和服务端:
client.py
import time
import uuid
import numpy as np
from mooncake.store import MooncakeDistributedStore
def random_uuid() -> str:
return str(uuid.uuid4().hex)
store = MooncakeDistributedStore()
store.setup(
"xx.xx.xx.85",
"http://xx.xx.xx.85:9101/metadata",
0, # global 设置为0,作为纯客户端
5368709120,
"rdma",
"mlx5_0",
#"mlx5_0,mlx5_1",
#"mlx5_0,mlx5_1,mlx5_2,mlx5_4",
"xx.xx.xx.85:50051"
)
original_data = np.random.randn(512*1204, 1024).astype(np.uint8)
buffer_ptr = original_data.ctypes.data
size = original_data.nbytes
result = store.register_buffer(buffer_ptr, size)
if result != 0:
raise RuntimeError(f"Failed to register buffer: {result}")
key = "large_tensor" + random_uuid()
t1 = time.perf_counter()
result = store.put_from(key, buffer_ptr, size)
t2 = time.perf_counter()
if result == 0:
print(f"Successfully stored {int(size/1024/1024)} MB with zero-copy")
print(f"store.put_from cost {int(1000 * (t2 - t1))} msec")
else:
raise RuntimeError(f"Store failed with code: {result}")
retrieved_data = np.empty((512*1204, 1024), dtype=np.uint8)
recv_buffer_ptr = retrieved_data.ctypes.data
recv_size = retrieved_data.nbytes
result = store.register_buffer(recv_buffer_ptr, recv_size)
if result != 0:
raise RuntimeError(f"Failed to register receive buffer: {result}")
t1 = time.perf_counter()
bytes_read = store.get_into(key, recv_buffer_ptr, recv_size)
t2 = time.perf_counter()
if bytes_read > 0:
print(f"Successfully retrieved {int(bytes_read/1024/1024)} MB with zero-copy")
print(f"store.get_into cost {int(1000 * (t2 - t1))} msec")
# Verify the data
print(f"Data matches: {np.array_equal(original_data, retrieved_data)}")
else:
raise RuntimeError(f"Retrieval failed with code: {bytes_read}")
store.unregister_buffer(buffer_ptr)
store.unregister_buffer(recv_buffer_ptr)
store.close()
====================================================================
server.py
import time
from mooncake.store import MooncakeDistributedStore
store = MooncakeDistributedStore()
store.setup(
"xx.xx.xx.3","http://xx.xx.xx.85:9101/metadata",
5368709120, # MB global
5368709120, # MB local
"rdma",
"mlx5_0",
#"mlx5_0,mlx5_1",
#"mlx5_0,mlx5_1,mlx5_2,mlx5_4",
"xx.xx.xx.xx:50051" # master
)
print(f"store start......")
time.sleep(3600 * 24 *30)
====================================================================
先在xx.xx.xx.85节点上启动master和metadata_server:
mooncake_master
mooncake_http_metadata_server --port 9101
再在xx.xx.xx.3节点上启动server.py:
python3 server.py
最后在xx.xx.xx.85节点上执行client.py
python3 client.py
会打印如下结果:
I0828 09:27:47.769611 56710 client.cpp:189] transport_type=rdma
I0828 09:27:47.791265 56710 rdma_context.cpp:423] Find best gid index: 0 on mlx5_0/
I0828 09:27:47.793476 56710 rdma_context.cpp:125] RDMA device: mlx5_0, LID: 9449, GID: (GID_Index 0) fe:80:00:00:00:00:00:00:58:a2:e1:03:00:0c:38:72
Successfully stored 602 MB with zero-copy
store.put_from cost 26 msec
Successfully retrieved 602 MB with zero-copy
store.get_into cost 16 msec
Data matches: True
这是一张RDMA卡(mlx5_0)的读写耗时。
然后我将 client.py 和 server.py 的RDMA设备改为2张(mlx5_0,mlx5_1),运行结果为:
I0828 09:32:39.452854 57941 rdma_context.cpp:423] Find best gid index: 0 on mlx5_0/
I0828 09:32:39.454994 57941 rdma_context.cpp:125] RDMA device: mlx5_0, LID: 9449, GID: (GID_Index 0) fe:80:00:00:00:00:00:00:58:a2:e1:03:00:0c:38:72
I0828 09:32:39.461373 57941 rdma_context.cpp:423] Find best gid index: 0 on mlx5_1/
I0828 09:32:39.462862 57941 rdma_context.cpp:125] RDMA device: mlx5_1, LID: 9456, GID: (GID_Index 0) fe:80:00:00:00:00:00:00:58:a2:e1:03:00:0b:d5:ba
Successfully stored 602 MB with zero-copy
store.put_from cost 27 msec
Successfully retrieved 602 MB with zero-copy
store.get_into cost 11 msec
Data matches: True
再改为4张(mlx5_0,mlx5_1,mlx5_2,mlx5_4),运行结果为:
I0828 09:29:33.809651 57026 client.cpp:189] transport_type=rdma
I0828 09:29:33.831156 57026 rdma_context.cpp:423] Find best gid index: 0 on mlx5_0/
I0828 09:29:33.832779 57026 rdma_context.cpp:125] RDMA device: mlx5_0, LID: 9449, GID: (GID_Index 0) fe:80:00:00:00:00:00:00:58:a2:e1:03:00:0c:38:72
I0828 09:29:33.850885 57026 rdma_context.cpp:423] Find best gid index: 0 on mlx5_1/
I0828 09:29:33.852046 57026 rdma_context.cpp:125] RDMA device: mlx5_1, LID: 9456, GID: (GID_Index 0) fe:80:00:00:00:00:00:00:58:a2:e1:03:00:0b:d5:ba
I0828 09:29:33.868894 57026 rdma_context.cpp:423] Find best gid index: 0 on mlx5_2/
I0828 09:29:33.870131 57026 rdma_context.cpp:125] RDMA device: mlx5_2, LID: 9457, GID: (GID_Index 0) fe:80:00:00:00:00:00:00:58:a2:e1:03:00:09:e5:d4
I0828 09:29:33.888024 57026 rdma_context.cpp:423] Find best gid index: 0 on mlx5_4/
I0828 09:29:33.889616 57026 rdma_context.cpp:125] RDMA device: mlx5_4, LID: 9454, GID: (GID_Index 0) fe:80:00:00:00:00:00:00:58:a2:e1:03:00:09:e9:9c
Successfully stored 602 MB with zero-copy
store.put_from cost 46 msec
Successfully retrieved 602 MB with zero-copy
store.get_into cost 10 msec
Data matches: True
我疑惑的是,随着RDMA设备的成倍增加,读写性能并没有体现出明显的线性提升。这种现象是否正常?
但前面我也提到,使用 transfer_engine_bench 测试时,增加RDMA设备却能体现出线性的吞吐提升。
所以我自己的.py脚本测试是否有问题?
@alogfans commented on GitHub (Aug 29, 2025):
这是因为测试方式不同所致的,transfer_engine_bench 会使用多个线程及 Batch 提交方式并发执行传输任务,因此可观测到带宽随网卡的加入而提升。而你的测试中只有单线程参与,单次传输 1K- 512K,此时为 latency 主导,网卡大多数时候负载不足,因此体现不出线性提升的效果。
@XQZ1120 commented on GitHub (Aug 29, 2025):
@alogfans 那我能够通过设置环境变量的方式来改善吗?您有一些推荐值吗?
文档里给出了很多环境变量,但我不太清楚哪些变量对当前测试场景有提升?
@xiaguan commented on GitHub (Aug 29, 2025):
调大
MC_SLICE_SIZE,2MB, 4MB... 1024MB@xiaguan commented on GitHub (Aug 29, 2025):
在200gbps的测试效果如下,沿用提供的压测脚本
@XQZ1120 commented on GitHub (Aug 29, 2025):
@xiaguan 您好,我调整了 MC_SLICE_SIZE 变量,从 2MB 到 1024MB,有一定改善,但还是没达到预期......
下面是使用了4块RDMA卡的性能测试结果:
export MC_SLICE_SIZE=2097152
执行python3 client.py后输出:
Successfully stored 602 MB with zero-copy
store.put_from cost 32 msec
Successfully retrieved 602 MB with zero-copy
store.get_into cost 7 msec
Data matches: True
export MC_SLICE_SIZE=4194304
执行python3 client.py后输出:
Successfully stored 602 MB with zero-copy
store.put_from cost 28 msec
Successfully retrieved 602 MB with zero-copy
store.get_into cost 7 msec
Data matches: True
export MC_SLICE_SIZE=8388608
store.put_from cost 27 msec
store.get_into cost 7 msec
export MC_SLICE_SIZE=16777216
store.put_from cost 26 msec
store.get_into cost 7 msec
export MC_SLICE_SIZE=33554432
store.put_from cost 30 msec
store.get_into cost 7 msec
export MC_SLICE_SIZE=67108864
store.put_from cost 27 msec
store.get_into cost 7 msec
export MC_SLICE_SIZE=134217728
store.put_from cost 32 msec
store.get_into cost 7 msec
export MC_SLICE_SIZE=1073741824
store.put_from cost 29 msec
store.get_into cost 7 msec
此外,我也使用单张RDMA设备做了测试,调整 MC_SLICE_SIZE 从 2MB 到 1024MB,也没什么效果。
@XQZ1120 commented on GitHub (Aug 29, 2025):
@xiaguan 这个是使用我提供的 client.py 和 server.py 测试的吗?
我复现不出类似您的结果,我这里测试的put时间总是比get时间长很多,比如:
store.put_from cost 29 msec
store.get_into cost 7 msec
@xiaguan commented on GitHub (Aug 29, 2025):
是issue里的脚本,我加了一些warmup避免冷启动 根据经验来看,似乎RDMA write 带宽比read 带宽高更符合预期?(https://enterprise-support.nvidia.com/s/article/MLNX2-117-2974kn, https://github.com/NVIDIA/nccl/issues/609)
也可以排除一下是否是RPC latency的问题,一般来说同机在200us左右.
如果需要打满带宽,建议您增加并发线程数等.
@xiaguan commented on GitHub (Sep 9, 2025):
可能和numa问题有关, https://github.com/kvcache-ai/Mooncake/pull/817
@github-actions[bot] commented on GitHub (Jun 27, 2026):
This issue has had no activity for 90 days and will be closed in 7 days if there is no further activity. Please comment or react if it should stay open.
@github-actions[bot] commented on GitHub (Jul 5, 2026):
Closing due to 3 months of inactivity. If this is still relevant, please comment and we can reopen.