| 免费下载:IBM® DB2® Express-C 10.1 免费版 或者 DB2® 10.1 for Linux®, UNIX®, and Windows® 试用版 |
|---|
| 下载更多的 IBM 软件试用版,并加入 IBM 软件下载与技术交流群组,参与在线交流。 |
RDMA 是一种支持计算机绕过操作系统(内核和 TCP 堆栈)访问其他计算机上内存位置的机制。与传统的基于 TCP 的软硬件架构相比较,RDMA 有几个优势。内核旁路 (Kernel bypass) 意味着缩短了两个应用程序之间的路径,并减少了 CPU 利用率。通过直接在网络适配器和应用程序内存(用户空间)之间传输数据减少了特定于 TCP 的协议开销,无需将数据复制到内核空间并进行缓存。
为了充分利用 RDMA 提供的所有优势,需要使用 RDMA 语义或上层协议,比如 User-Level Direct Access Transport (uDAPL) 或 Message Passing Interface (MPI) 来编写应用程序。然而,对于 RDMA 来说,重写一个 TCP 应用程序可能非常昂贵,因此,针对这种情况开发了一个替代解决方案。该方法称之为 Direct Socket Protocol (SDP),无需重新编码任何应用程序。
SDP 是一个连线协议,在 RDMA 能力的适配器和套接字之间使用。鉴于这个原因,SDP 对应用程序是透明的,而标准流套接字的实现不需要使用另一个 API 替换。DB2 应用程序和 DB2 服务器无需修改就可在 SDP 或 TCP 上运行。用户只需要在执行应用程序之前通过预加载 SDP 共享库来选择要使用的协议即可。所有关于 TCP 的设置,比如主机名、IP 地址和端口,均无需修改。
例如,一个使用 TCP 连接到数据库服务器的 Java 应用程序也可以使用相同 JDBC URL 在 SDP 上运行。该 SDP 库,一旦预加载之后,将根据一组在 /etc/libsdp.conf 中定义的规则,以及服务器接受的协议来决定必需启动哪个协议。默认规则指定 SDP 作为第一个选项,如果连接失败,SDP 库将退回到 TCP。
一个应用程序可以只使用 SDP,或者只使用 TCP,或者同时使用二者。例如,可以将一个应用程序配置为使用 SDP 实现 DB2 数据库连接以及使用 TCP 实现 LDAP 连接。数据库和 LDAP 服务器可以在不同的物理机器上运行,或者运行在相同的机器上但侦听不同的接口。本文稍后将讨论各种场景以及如何应用规则。
RDMA 需要专用的硬件和软件基础架构。本文将讨论 Linux x86 平台上的 SDP。
- 主机适配器
两类主机适配器支持 RDMA:Infiniband 适配器和 RoCE 适配器。前者需要 Infiniband 交换机,而后者需要 Ethernet 交换机。
本例使用 Mellanox RoCE 适配器。本文提供的所有指令均适用于 Infiniband 适配器,只需稍作修改或无需修改。RoCE (RDMA over Converged Ethernet) 是 Infiniband over Ethernet 协议的一个实现。Converged Ethernet 网络允许不同类型的协议共享同一个媒介。定期封装 IP 数据包、Infiniband over Ethernet 和 Fiber Channel over Ethernet 的 LAN Ethernet 框架都可在一个 Ethernet 线路中共存。
- 设备驱动程序
这里有几个关于操作 Mellanox 适配器所需要的设备驱动程序和工具。所有可用的设备驱动程序和工具都是以 OpenFabrics Alliance 维护的 OFED 堆栈为基础。参阅 参考资料 部分,获取 OFED 网站链接。
- 操作系统
Red Hat Linux 6.2,内核版本 2.6.32-220.4.1.el6.x86_64。
- Ethernet 交换机
10Gbps RackSwitch G8264,操作系统版本 6.8.1.0。
-
Mellanox 软件被打包为一个 ISO 映像。从 参考资料 部分提供的链接下载适合您操作系统的映像,对于 Red Hat 6.2,映像名为 MLNX_OFED_LINUX-1.5.3-3.0.0-rhel6.2-x86_64.iso。
除非另有规定,以下所有命令都作为 root 来执行。
在每个计算机上挂载 ISO 映像并启动安装程序,如清单 1 所示。
清单 1. ISO 映像和安装程序bash# mount -o loop MLNX_OFED_LINUX-1.5.3-3.0.0-rhel6.2-x86_64.iso /mnt/iso bash# cd /mnt/iso bash# ./mlnxofedinstall This program will install the MLNX_OFED_LINUX package on your machine. Note that all other Mellanox, OEM, OFED, or Distribution IB packages will be removed.
安装程序将安装所有驱动程序和工具,并将尝试升级每个 Mellanox 卡中的固件,只要它们的版本比 ISO 映像包含的版本低即可。
- 重启计算机以加载所有内核模块。
- SDP 需要 Ethernet 接口配置一个 IP 地址。对于 Infiniband 接口,IPoIB 必须启用,这基本意味着在 ib* 接口上配置 IP 地址以及在
/etc/infiniband/openib.conf上启用IPOIB_LOAD=yes。首先,需要识别新设备。这一命令将列出所有 Mellanox 网络适配器和适配器的当前设置,包括 Link Layer 类型(本例中是 Ethernet)、固件版本和链接状态,如清单 2 所示。
清单 2. Mellanox 网络适配器bash# ibv_devinfo hca_id: mlx4_0 transport: InfiniBand (0) fw_ver: 2.10.300 node_guid: 0002:c903:0005:6aa8 sys_image_guid: 0002:c903:0005:6aab vendor_id: 0x02c9 vendor_part_id: 4099 hw_ver: 0x0 board_id: IBM1020110023 phys_port_cnt: 2 port: 1 state: PORT_ACTIVE (4) max_mtu: 2048 (4) active_mtu: 1024 (3) sm_lid: 0 port_lid: 0 port_lmc: 0x00 link_layer: Ethernet port: 2 state: PORT_DOWN (1) max_mtu: 2048 (4) active_mtu: 1024 (3) sm_lid: 0 port_lid: 0 port_lmc: 0x00 link_layer: Ethernet - 要识别出哪个端口与 eth* 接口相关联,执行以下命令,并将 IP 地址分配给相应接口,如清单 3 所示。
清单 3. 识别端口bash# ibdev2netdev mlx4_0 port 1 ==> eth8 (Up) mlx4_0 port 2 ==> eth9 (Down) bash# ifconfig eth8 10.7.7.1 netmask 255.255.255.0
SDP 不是默认启用的。除了前面提到的 libsdp.so 用户库,部分 SDP 实现为一个需要加载的内核模块。
- 加载 SDP 内核模块 ib_sdp,并编辑
/etc/infiniband/openib.conf来将该参数设置为 yes,如清单 4 所示。
清单 4. 参数设置为 yesSDP_LOAD=yes
- 重新启动系统,或手动加载该模块。然后验证内核模块是否加载,如清单 5 所示。
清单 5. 加载模块bash# modprobe ib_sdp bash# lsmod | grep ib_sdp ib_sdp 130827 0 rdma_cm 35175 2 ib_sdp,rdma_ucm ipv6 322029 89 ib_sdp,ib_addr,ib_ipoib ib_core 69947 14 - 配置应用程序以便加载动态库
/usr/lib64/libsdp.so。有两种方法可用于加载 SDP 库。您可以对创建的每个进程预加载该 SDP 库,或者对整个系统预加载该 SDP 库。这些方法适用于任何使用 glibc 套接字调用的应用程序,包括使用 JDBC 连接到数据库服务器的 Java 应用程序。- 为您创建的每个进程预加载此库,如清单 6 所示。
清单 6. 预加载库bash# LD_PRELOAD=/usr/lib64/libsdp.so myapplication
- 为整个系统预加载此库。系统中的每个进程将预加载该库。在
/etc/ld.so.preload中添加下面一行,如清单 7 所示。
清单 7. 使用 /etc/ld.so.preload 预加载 SDP/usr/lib64/libsdp.so
- 检查一个应用程序是否将在运行时加载 SDP 库,如清单 8 所示。
清单 8. 运行时的 SDP 库bash# ldd my_app | grep sdp /usr/lib64/libsdp.so (0x00007f217170d000)
- 为您创建的每个进程预加载此库,如清单 6 所示。
启动 DB2 服务器和客户端之前,可使用
echo server和telnet来测试 SDP 是否正常运行。通过设置disable = no启用/etc/xinetd.d/echo-stream中的 echo 服务器。- 重启
xinetd守护进程,如清单 9 所示。
清单 9. xinetd 守护进程bash# service xinetd restart Stopping xinetd: [ OK ] Starting xinetd: [ OK ]
- 验证
xinetd进程是否链接到 SDP 库。如清单 10 所示。
清单 10. xinetd 进程bash# lsof -p `pidof xinetd` | grep sdp xinetd 10090 root mem REG 8,5 69128 9339172 /usr/lib64/libsdp.so.1.0.0
- 现在,您可以从另一个配置了 SDP 的计算机连接到端口 7 上的
echo server,如清单 11 所示。
清单 11. Echo 服务器连接bash# LD_PRELOAD=/usr/lib64/libsdp.so telnet 10.7.7.1 7 Trying 10.7.7.1... Connected to 10.7.7.1. Escape character is '^]'. test sdp test sdp
- 此时,
telnet客户端被连接到echo server,输入到telnet的任何行都将由echo server返回。活动的 SDP 连接可使用sdpnetstat命令列出,该命令类似于标准的 Linuxnetstat。如清单 12 所示。
清单 12. 活动的 SDP 连接命令bash# sdpnetstat -Sn Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State sdp 0 0 10.7.7.2:41771 10.7.7.1:7 ESTABLISHED
注意,SDP 连接不能通过标准的
netstat命令显示。
- 重启
启用 SDP for DB2 所需的步骤类似于 echo 服务器示例。确保 SDP 库在 /etc/ld.so.preload 中列出,然后重启 DB2 实例。 DB2 服务器不能通过设置或导出环境变量 LD_PRELOAD 启动,因为 DB2 由许多被分叉的进程构成,而且其中一些进程是作为 root 或 setuid root 运行的。因此,变量将不能传递给所有子进程。
- 以实例所有者的身份登录并重启实例,如清单 13 所示。
清单 13. 重启 DB2 实例db2inst1$ db2stop db2inst1$ db2start
- 要测试正在使用 SDP 的 DB2,使用一个简单命令
db2batch,该命令包含在 DB2 中。在 DB2 客户端机器上,以客户端实例所有者身份登录,并创建一个包含将用于基准测试的 SQL 语句的文件。清单 14 提供了一个样例文件。
清单 14. 样例 update.sql 文件--#SET PERF_DETAIL 0 create table demo (c1 bigint, c2 double, c3 varchar(8)); --#BGBLK 4000 insert into demo values (-9223372036854775808, -0.000000000000005, 'demo'); --#EOBLK --#SET ROWS_OUT 0 select * from demo; drop table demo;
在该示例中有 4 个语句。第一个语句创建一个表,该表将在语句 4 测试结束后删除。第二个语句是INSERT,将执行 4000 次。第 3 个语句将选择表中的所有行(4000 行),但是不会将它们显示到 stdout 中。 - 要启动测试,在客户端机器上以客户端实例所有者身份运行该命令,如清单 15 所示。
清单 15. 客户端实例db2inst1$ LD_PRELOAD=/usr/lib64/libsdp.so db2batch -d sample -f update.sql \ -a db2inst1/password -r result.txt,summary.txt
db2batch 命令生成 2 个结果文件。result.txt包含每个语句的详细度量,summary.txt包含每个块的总时间和平均时间。
尽管这是一个非常简单的测试,但是您可以看到 SDP 对性能的影响。使用 SDP,插入平均耗时 230 微秒,而 TCP 平均耗时 300 微秒。使用 SDP,SELECT语句返回 4000 条记录耗时 4 毫秒,而 TCP 耗时 6 毫秒。这些测试是使用默认 SDP 设置sdp_zcopy_thresh(64K) 和recv_poll(700) 执行的。参阅 性能调优 部分,了解如何调优这些参数的详细信息。 - db2batch over SDP 摘要如清单 16 所示。
清单 16. db2batch over SDP 摘要Type Number Repetitions Total Time (s) Min Time (s) Max Time (s) --------- ----------- ----------- -------------- -------------- -------------- Statement 1 1 0.115556 0.115556 0.115556 Block 1 4000 0.924646 0.000200 0.001328 Statement 3 1 0.004281 0.004281 0.004281 Statement 4 1 0.133243 0.133243 0.133243 Type Number Repetitions Arithmetic Mean Geometric Mean --------- ----------- ----------- --------------- -------------- Statement 1 1 0.115556 0.115556 Block 1 4000 0.000231 0.000229 Statement 3 1 0.004281 0.004281 Statement 4 1 0.133243 0.133243 - db2batch over TCP 摘要如清单 17 所示。
清单 17. db2batch over TCP 摘要Type Number Repetitions Total Time (s) Min Time (s) Max Time (s) --------- ----------- ----------- -------------- -------------- -------------- Statement 1 1 0.115521 0.115521 0.115521 Block 1 4000 1.445863 0.000326 0.001034 Statement 3 1 0.006005 0.006005 0.006005 Statement 4 1 0.137436 0.137436 0.137436 Type Number Repetitions Arithmetic Mean Geometric Mean --------- ----------- ----------- --------------- -------------- Statement 1 1 0.115521 0.115521 Block 1 4000 0.000361 0.000360 Statement 3 1 0.006005 0.006005 Statement 4 1 0.137436 0.137436 - 图 1 和 图 2 中以图形化方式显示了 SDP 和 TCP 之间的比较。
图 1. 每个 INSERT 的平均时间
图 2. 4000 个 INSERT 块的总时间
默认情况下,SDP 库被配置为首先使用 SDP,如果 SDP 连接失败,则尝试使用 TCP。附加规则可在 /etc/libsdp.conf 中定义。
该文件格式是 <address-family> <role> <program name> <address|*>:<port range|*>。
默认值在清单 18 中定义。
清单 18. 默认值
use both server * *:* use both client * *:* |
both关键词意味着如果尝试 TCP 失败,尝试 SDP。server规则适用于侦听一个套接字的应用程序。client规则适用于启动一个连接的应用程序。<program name>指定该规则采用的进程名。<address:port>与本地 IP 和服务器侦听server规则的端口相匹配。<address:port>与远程 IP 和客户端试图连接的端口相匹配。
与应用程序匹配的第一个规则将被应用,其余规则则忽略。
例如,当连接一个 DB2 服务器并使用 TCP 连接 LDAP 服务器时,这些规则将 Java 进程切换到 SDP,如清单 19 所示。
清单 19. DB2 的 SDP 连接、LDAP 的 TCP 连接
use sdp client java 192.168.100.10:50000 use tcp client java *:389 |
这些规则配置一个 DB2 服务器仅接受一个接口上的 SDP 连接,以及另一个服务器上的 TCP 连接,如清单 20 所示。
清单 20. 接受 SDP 和 TCP 连接的服务器
use sdp server db2* 192.168.100.10:50000 use tcp server db2* 192.168.200.10:50000 |
清单 21 中的规则配置 SDP 库以同时接受 SDP 和 TCP 连接,SDP 作为首选。
清单 21. 配置 SDP 库的规则
use both server * 192.168.100.10:50000 |
sdp_zcopy_thresh 和 recv_poll 参数对于 SDP 性能调优是非常重要的,必须根据每个特定工作负载和流量模式进行设置。
SDP 可以通过两种模式拷贝数据包:使用零拷贝(绕过内核,用户缓存直接从用户内存传送),或者缓存拷贝(用户缓存首先拷贝到内核空间)。
ZCopy 对于较大的消息更为有效,而 Bcopy 只一些大小为 KBytes 的消息比较有效。
sdp_zcopy_thresh 参数指定将要使用哪种方法。默认情况下,小于 64 KB 的消息使用 Bcopy 传递,大于 64 KB 的消息使用 Zcopy 传递,如清单 22 所示。
清单 22. sdp_zcopy_thresh 参数
bash# cat /sys/module/ib_sdp/parameters/sdp_zcopy_thresh 65536 |
要修改该阈值,在 sys 文件系统中写入一个不同值,如清单 23 所示。
清单 23. sys 文件系统
bash# echo 32768 > /sys/module/ib_sdp/parameters/sdp_zcopy_thresh |
用一个 0 值来完全禁用 Zcopy,强制所有消息大小使用 Bcopy。
也可以在 modprobe.conf 中对该参数进行设置,如清单 24 所示。
清单 24. modprobe.conf
options ib_sdp sdp_zcopy_thresh=32768 |
最小阈值等于内存页面大小。使用 getconf PAGE_SIZE 显示系统的页面大小。
recv_poll 参数指定接收器轮询输入数据的时间,默认值是 700 微秒,如清单 25 所示。
清单 25. 接收轮询计时器
bash# cat /sys/module/ib_sdp/parameters/recv_poll 700 |
该轮询可以通过将 procfs 参数 recv_poll 设置为零来禁用,如清单 26 所示。与非零值相反,这的 CPU 密集程度更小。但是,使用 recv_poll=0 的消息延迟则比较高。
清单 26. 使用 recv_poll=0
bash# echo 0 > /sys/module/ib_sdp/parameters/recv_poll |
将其添加到 modprobe.conf 中,重启后将被持久化,如清单 27 所示。
清单 27. modprobe.conf
options ib_sdp recv_poll=0 |
- 使用
sdpnetstat列出 SDP 连接,类似于netstat,但是netstat不能显示 SDP 连接,如清单 28 所示。
清单 28. 使用 sdpnetstatbash# sdpnetstat -Sn Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State sdp 0 0 192.168.100.10:4432 192.168.100.11:7 ESTABLISHED sdp 0 0 192.168.100.11:7 192.168.100.10:4432 ESTABLISHED
- SDP 有两个组件,称为内核模块和用户库。它们都可以在调试模式中进行设置,如清单 29 所示。
- 用户空间调试模式由
libsdp.conf控制。
清单 29. 调试的等级在libsdp.conf中进行了描述log min-level 9 destination file libsdp.log
- Kernel-mode 调试模式可在
procfs中启用,如清单 30 所示。
清单 30. Kernel-mode 调试bash# echo 1 > /sys/module/ib_sdp/debug_level
Kernel-mode 调试模式也可在
modprobe.conf中启用,如清单 31 所示。
清单 31. modprob.conf 中的 Kernel-mode 调试options ib_sdp sdp_debug_level=1
- 用户空间调试模式由
本文介绍了如何使 Remote Direct Memory Access (RDMA) 协议比 TCP 更高效,并提供了一个经济高效的方法,使得可以在 DB2 客户端服务器环境启用 RDMA 功能,而不需要对现有应用程序进行重新编码或重新编译。本文也讨论了如何安装 Mellanox 驱动程序和工具、在内核和用户空间中启用 SDP,以及性能调优和 SDP 调试。
学习
- 了解有关 Mellanox 和 RDMA 的更多信息。
- 随时关注 OpenFabrics Alliance 的最新开发。
- 在 DAT Collaborative 中查看 uDAPL,在 Ohio State University 中查看 MPI。
- 了解有关 DB2 最佳实践 的更多信息。
- 访问 developerWorks 中国网站 Information Management 专区:查找面向 DB2 开发人员和管理员的更多资源。
- 随时关注 developerWorks 技术活动 和 网络广播,包括各种 IBM 产品和 IT 行业主题。
- 参加 免费的 developerWorks Live! 简报,快速了解 IBM 产品和工具,以及 IT 行业趋势。
- 在 Twitter 上关注 developerWorks。
- 观看 developerWorks 演示中心,包括面向初学者的产品安装和设置演示,以及为经验丰富的开发人员提供的高级功能。
获得产品和技术
- 下载 Mellanox OpenFabrics Enterprise Distribution for Linux (MLNX_OFED)。
- 使用 IBM 产品评估试用版软件 构建您的下一个开发项目,可直接从 developerWorks 下载。
- 以最适合您的方式 IBM 产品评估试用版软件:下载产品试用版、在线试用产品、在云环境中使用产品,或者在 IBM SOA 人员沙箱 中花费几个小时来了解如何高效实现面向服务架构。
讨论
- 加入 developerWorks 中文社区。查看开发人员推动的博客、论坛、讨论组和维基,并与其他 developerWorks 用户交流。
