xref: /spdk/doc/nvmf_multipath_howto.md (revision 29784f35cdce03eb4b33a4d462b25f42bb4a6b60)
1e745bb65STheo Jepsen# NVMe-oF Multipath HOWTO {#nvmf_multipath_howto}
2e745bb65STheo Jepsen
3e745bb65STheo JepsenThis HOWTO provides step-by-step instructions for setting-up a simple SPDK deployment and testing multipath.
4e745bb65STheo JepsenIt demonstrates configuring path preferences with Asymmetric Namespace Access (ANA), as well as round-robin
5e745bb65STheo Jepsenpath load balancing.
6e745bb65STheo Jepsen
7e745bb65STheo Jepsen## Build SPDK on both the initiator and target servers
8e745bb65STheo Jepsen
9e745bb65STheo JepsenClone the repo:
10e745bb65STheo Jepsen~~~{.sh}
1101a88849Spaul lusegit clone https://github.com/spdk/spdk --recursive
12e745bb65STheo Jepsen~~~
13e745bb65STheo Jepsen
14e745bb65STheo JepsenConfigure and build SPDK:
15e745bb65STheo Jepsen~~~{.sh}
16e745bb65STheo Jepsencd spdk/
17e745bb65STheo Jepsen./configure
18e745bb65STheo Jepsenmake -j16
19e745bb65STheo Jepsen~~~
20e745bb65STheo Jepsen
21e745bb65STheo Jepsen## Setup hugepages
22e745bb65STheo Jepsen
23e745bb65STheo JepsenThis should be run once on each server (and after reboots):
24e745bb65STheo Jepsen~~~{.sh}
25e745bb65STheo Jepsencd spdk/
26e745bb65STheo Jepsen./scripts/setup.sh
27e745bb65STheo Jepsen~~~
28e745bb65STheo Jepsen
29e745bb65STheo Jepsen## On target: start and configure SPDK
30e745bb65STheo Jepsen
31e745bb65STheo JepsenStart the target in the background and configure it:
32e745bb65STheo Jepsen~~~{.sh}
33e745bb65STheo Jepsencd spdk/
34e745bb65STheo Jepsen./build/bin/nvmf_tgt -m 0x3 &
35e745bb65STheo Jepsen./scripts/rpc.py nvmf_create_transport -t tcp -o -u 8192
36e745bb65STheo Jepsen~~~
37e745bb65STheo Jepsen
38e745bb65STheo JepsenCreate a subsystem, with `-r` to enable ANA reporting feature:
39e745bb65STheo Jepsen~~~{.sh}
40e745bb65STheo Jepsen./scripts/rpc.py nvmf_create_subsystem nqn.2022-02.io.spdk:cnode0 -a -s SPDK00000000000001 -r
41e745bb65STheo Jepsen~~~
42e745bb65STheo Jepsen
43e745bb65STheo JepsenCreate and add a malloc block device:
44e745bb65STheo Jepsen~~~{.sh}
45e745bb65STheo Jepsen./scripts/rpc.py bdev_malloc_create 64 512 -b Malloc0
46e745bb65STheo Jepsen./scripts/rpc.py nvmf_subsystem_add_ns nqn.2022-02.io.spdk:cnode0 Malloc0
47e745bb65STheo Jepsen~~~
48e745bb65STheo Jepsen
49e745bb65STheo JepsenAdd two listeners, each with a different `IP:port` pair:
50e745bb65STheo Jepsen~~~{.sh}
51e745bb65STheo Jepsen./scripts/rpc.py nvmf_subsystem_add_listener -t tcp -a 172.17.1.13 -s 4420 nqn.2022-02.io.spdk:cnode0
52e745bb65STheo Jepsen./scripts/rpc.py nvmf_subsystem_add_listener -t tcp -a 172.18.1.13 -s 5520 nqn.2022-02.io.spdk:cnode0
53e745bb65STheo Jepsen~~~
54e745bb65STheo Jepsen
55e745bb65STheo Jepsen## On initiator: start and configure bdevperf
56e745bb65STheo Jepsen
57e745bb65STheo JepsenLaunch the bdevperf process in the background:
58e745bb65STheo Jepsen~~~{.sh}
59e745bb65STheo Jepsencd spdk/
60*29784f35SKrzysztof Karas./build/examples/bdevperf -m 0x4 -z -r /tmp/bdevperf.sock -q 128 -o 4096 -w verify -t 90 &> bdevperf.log &
61e745bb65STheo Jepsen~~~
62e745bb65STheo Jepsen
63e745bb65STheo JepsenConfigure bdevperf and add two paths:
64e745bb65STheo Jepsen~~~{.sh}
65e745bb65STheo Jepsen./scripts/rpc.py -s /tmp/bdevperf.sock bdev_nvme_set_options -r -1
66e745bb65STheo Jepsen./scripts/rpc.py -s /tmp/bdevperf.sock bdev_nvme_attach_controller -b Nvme0 -t tcp -a 172.17.1.13 -s 4420 -f ipv4 -n nqn.2022-02.io.spdk:cnode0 -l -1 -o 10
67e745bb65STheo Jepsen./scripts/rpc.py -s /tmp/bdevperf.sock bdev_nvme_attach_controller -b Nvme0 -t tcp -a 172.18.1.13 -s 5520 -f ipv4 -n nqn.2022-02.io.spdk:cnode0 -x multipath -l -1 -o 10
68e745bb65STheo Jepsen~~~
69e745bb65STheo Jepsen
70e745bb65STheo Jepsen## Launch a bdevperf test
71e745bb65STheo Jepsen
72e745bb65STheo JepsenConnect to the RPC socket of the bdevperf process and start the test:
73e745bb65STheo Jepsen~~~{.sh}
74*29784f35SKrzysztof KarasPYTHONPATH=$PYTHONPATH:/root/src/spdk/python ./examples/bdev/bdevperf/bdevperf.py -t 1 -s /tmp/bdevperf.sock perform_tests
75e745bb65STheo Jepsen~~~
76e745bb65STheo Jepsen
77e745bb65STheo JepsenThe RPC command will return, leaving the test to run for 90 seconds in the background. On the target server,
78e745bb65STheo Jepsenobserve that only the first path (port) is receiving packets by checking the queues with `ss -t`.
79e745bb65STheo Jepsen
80e745bb65STheo JepsenYou can view the paths available to the initiator with:
81e745bb65STheo Jepsen~~~{.sh}
82e745bb65STheo Jepsen./scripts/rpc.py -s /tmp/bdevperf.sock bdev_nvme_get_io_paths -n Nvme0n1
83e745bb65STheo Jepsen~~~
84e745bb65STheo Jepsen
85e745bb65STheo Jepsen## Switching paths
86e745bb65STheo Jepsen
87e745bb65STheo JepsenThis can be done on the target server by setting the first path's ANA to `non_optimized`:
88e745bb65STheo Jepsen~~~{.sh}
89e745bb65STheo Jepsen./scripts/rpc.py nvmf_subsystem_listener_set_ana_state nqn.2022-02.io.spdk:cnode0 -t tcp -a 172.17.1.13 -s 4420 -n non_optimized
90e745bb65STheo Jepsen~~~
91e745bb65STheo Jepsen
92e745bb65STheo JepsenUse `ss -t`  to verify that the traffic has switched to the second path.
93e745bb65STheo Jepsen
94e745bb65STheo Jepsen## Use round-robin (active_active) path load balancing
95e745bb65STheo Jepsen
96e745bb65STheo JepsenFirst, ensure the ANA for both paths is configured as `optimized` on the target. Then, change the
97e745bb65STheo Jepsenmultipath policy on the initiator to `active_active` (multipath policy is per bdev, so
98e745bb65STheo Jepsen`bdev_nvme_set_multipath_policy` must be called after `bdev_nvme_attach_controller`):
99e745bb65STheo Jepsen~~~{.sh}
100e745bb65STheo Jepsen./scripts/rpc.py -s /tmp/bdevperf.sock bdev_nvme_set_multipath_policy -b Nvme0n1 -p active_active
101e745bb65STheo Jepsen~~~
102e745bb65STheo Jepsen
103e745bb65STheo JepsenObserve with `ss -t` that both connections are receiving traffic (queues build up).
104