Add the missing BRPC_WITH_UBRING Bazel configuration, wire it through the library and example targets, and document the supported build commands. Enable RDMA and UBRING in CI jobs whose all-options configurations did not exercise those features. Run both feature suites in the existing Bazel unit-test jobs and enable RDMA in the Make unit-test job. Use unsigned literals for UBRING atomic counter operations to match the counter type and avoid template deduction failures on stricter compilers. Signed-off-by: Zhengwei Zhu <141622927+ZhengweiZhu@users.noreply.github.com>
6.2 KiB
UBRing: 高性能共享内存 RPC
UBRing 是 brpc 中的高性能 RPC 实现,它利用共享内存进行进程间通信(IPC)。它支持本地共享内存(POSIX IPC)和远端共享内存(ubs-mem)两种模式,提供微秒到纳秒级的进程间通信延迟。
技术背景
传统的 RPC 框架通常使用网络套接字进行通信,由于内核参与、上下文切换和数据拷贝等原因,会引入显著的开销。UBRing 通过使用共享内存作为通信介质来解决这个问题,允许进程之间直接内存访问,最小化内核干预。
UBRing 的主要优势:
- 超低延迟:微秒级 RPC 延迟
- 高吞吐量:每秒数百万次 RPC 调用
- 减少数据拷贝:进程间直接内存访问
- 跨平台支持:支持 Linux 和 macOS
支持的共享内存后端
UBRing 支持两种共享内存后端,通过 ub_shm_type 参数控制:
1. POSIX IPC 共享内存 (ub_shm_type = 1)
这是默认模式,使用标准 POSIX 共享内存进行本地 IPC。同一机器上的进程可以通过共享内存区域直接通信。
2. UBS-Mem 远端共享内存 (ub_shm_type = 2)
此模式使用 ubs-mem(Unified Block Storage Memory),这是来自 openEuler 的开源远端共享内存框架。它支持机架内节点之间的共享内存通信,类似于 RDMA 但部署要求更简单。
UBS-Mem 开源地址: https://atomgit.com/openeuler/ubs-mem
所需库文件:
libubsm_sdk.so- UBS-Mem SDK 库(安装路径:/usr/local/ubs_mem/lib/libubsm_sdk.so)- UBS-Mem 通过
dlopen()动态加载该库,并使用ubsmem_initialize()、ubsmem_create_region()、ubsmem_shmem_allocate()、ubsmem_shmem_map()等函数
UBS-Mem 关键函数:
ubsmem_init_attributes()- 初始化 UBS-Mem 属性ubsmem_initialize()- 初始化 UBS-Mem 库ubsmem_finalize()- 释放 UBS-Mem 库ubsmem_create_region()- 创建共享内存区域ubsmem_shmem_allocate()- 分配共享内存ubsmem_shmem_map()- 将共享内存映射到本地地址空间ubsmem_shmem_unmap()- 解除共享内存映射ubsmem_shmem_deallocate()- 释放共享内存ubsmem_destroy_region()- 销毁共享内存区域
未来扩展
该架构设计支持未来扩展 CXL(Compute Express Link)基于的远端共享内存,实现更灵活的分布式内存共享。
构建配置
使用 CMake 构建
要构建带有 UBRing 支持的 brpc,请使用以下命令:
# 构建 brpc 并启用 UBRing 支持
cd /path/to/brpc
cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DWITH_UBRING:BOOL=ON
cmake --build build -j 8
# 构建 ubring_performance 示例
cd /path/to/brpc/example/ubring_performance
cmake -B build
cmake --build build -j 8
使用 Bazel 构建
使用 Bazel 构建带有 UBRing 支持的 brpc:
# 构建 brpc 并启用 UBRing 支持
cd /path/to/brpc
bazel build //:brpc --define=BRPC_WITH_UBRING=true
# 构建 ubring_performance 示例
bazel build \
//example:ubring_performance_server \
//example:ubring_performance_client \
--define=BRPC_WITH_UBRING=true
选择共享内存后端
共享内存后端通过 --ub_shm_type 参数控制:
# 使用 POSIX IPC(默认)
./your_program --ub_shm_type=1
# 使用 UBS-Mem
./your_program --ub_shm_type=2
性能测试
示例: ubring_performance
brpc 在 example/ubring_performance/ 目录提供了性能测试示例。
构建示例
cd example/ubring_performance
mkdir -p build && cd build
cmake ..
make
运行服务端
# 使用 POSIX IPC
./ubring_performance_server --ub_shm_type=1
# 使用 UBS-Mem
./ubring_performance_server --ub_shm_type=2
运行客户端
# 使用 POSIX IPC
./ubring_performance_client --ub_shm_type=1 --server=127.0.0.1:8000
# 使用 UBS-Mem
./ubring_performance_client --ub_shm_type=2 --server=<remote_ip>:8000
测试选项
| 选项 | 描述 | 默认值 |
|---|---|---|
--ub_shm_type |
共享内存类型 (1=IPC, 2=UBS-Mem) | 1 |
--server |
服务端地址 | 127.0.0.1:8000 |
--thread_num |
客户端线程数 | 1 |
--request_num |
每线程请求总数 | 1000000 |
--timeout_ms |
请求超时时间(毫秒) | 1000 |
架构概述
graph TD
subgraph 客户端进程
A[Client]
end
subgraph 服务端进程
B[Server]
end
subgraph 共享内存层
C[SHM Manager]
D[IPC Backend]
E[UBS-Mem Backend]
end
A -->|直接内存访问| C
B -->|直接内存访问| C
C --> D
C --> E
style A fill:#636,color:#fff,stroke:#333,stroke-width:2px
style B fill:#369,color:#fff,stroke:#333,stroke-width:2px
style C fill:#396,color:#fff,stroke:#333,stroke-width:2px
架构细节
UBRing 架构包含以下组件:
- 客户端/服务端进程: 通过共享内存通信的应用进程
- SHM Manager: 共享内存操作的中央管理器 (
shm_mgr.cpp) - IPC Backend: 用于本地通信的 POSIX 共享内存实现
- UBS-Mem Backend: 用于跨节点通信的远端共享内存实现
实现细节
共享内存管理
共享内存管理器 (shm_mgr.cpp) 为不同的共享内存后端提供统一接口:
- 初始化:
ShmMgrInit()- 初始化共享内存子系统 - 本地分配:
ShmLocalMalloc()- 分配本地共享内存 - 远端分配:
ShmRemoteMalloc()- 分配远程节点可访问的共享内存 - 释放:
ShmFree()- 释放共享内存资源
定时器管理
UBRing 使用高精度定时器系统 (timer_mgr.cpp) 进行连接管理和超时处理,支持 epoll(Linux)和 kqueue(macOS)。