요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
두 계층과 bitmap
switch.rst:41-90Upper dm-switch가 member를 선택하고 lower multipath가 direct·failover path를 관리합니다.
Message와 예제
switch.rst:91-141Hex region/path token, 반복 pattern과 세 volume을 사용한 64 KiB region table을 설명합니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=========
dm-switch
=========
The device-mapper switch target creates a device that supports an
arbitrary mapping of fixed-size regions of I/O across a fixed set of
paths. The path used for any specific region can be switched
dynamically by sending the target a message.
It maps I/O to underlying block devices efficiently when there is a large
number of fixed-sized address regions but there is no simple pattern
that would allow for a compact representation of the mapping such as
dm-stripe.
Background
----------
Dell EqualLogic and some other iSCSI storage arrays use a distributed
frameless architecture. In this architecture, the storage group
consists of a number of distinct storage arrays ("members") each having
independent controllers, disk storage and network adapters. When a LUN
is created it is spread across multiple members. The details of the
spreading are hidden from initiators connected to this storage system.
The storage group exposes a single target discovery portal, no matter
how many members are being used. When iSCSI sessions are created, each
session is connected to an eth port on a single member. Data to a LUN
can be sent on any iSCSI session, and if the blocks being accessed are
stored on another member the I/O will be forwarded as required. This
forwarding is invisible to the initiator. The storage layout is also
dynamic, and the blocks stored on disk may be moved from member to
member as needed to balance the load.
This architecture simplifies the management and configuration of both
the storage group and initiators. In a multipathing configuration, it
is possible to set up multiple iSCSI sessions to use multiple network
interfaces on both the host and target to take advantage of the
increased network bandwidth. An initiator could use a simple round
robin algorithm to send I/O across all paths and let the storage array
members forward it as necessary, but there is a performance advantage to
sending data directly to the correct member.
A device-mapper table already lets you map different regions of a
device onto different targets. However in this architecture the LUN is
spread with an address region size on the order of 10s of MBs, which
means the resulting table could have more than a million entries and
consume far too much memory.
Using this device-mapper switch target we can now build a two-layer
device hierarchy:
Upper Tier - Determine which array member the I/O should be sent to.
Lower Tier - Load balance amongst paths to a particular member.
The lower tier consists of a single dm multipath device for each member.
Each of these multipath devices contains the set of paths directly to
the array member in one priority group, and leverages existing path
selectors to load balance amongst these paths. We also build a
non-preferred priority group containing paths to other array members for
failover reasons.
The upper tier consists of a single dm-switch device. This device uses
a bitmap to look up the location of the I/O and choose the appropriate
lower tier device to route the I/O. By using a bitmap we are able to
use 4 bits for each address range in a 16 member group (which is very
large for us). This is a much denser representation than the dm table
b-tree can achieve.
Construction Parameters
=======================
<num_paths> <region_size> <num_optional_args> [<optional_args>...] [<dev_path> <offset>]+
<num_paths>
The number of paths across which to distribute the I/O.
<region_size>
The number of 512-byte sectors in a region. Each region can be redirected
to any of the available paths.
<num_optional_args>
The number of optional arguments. Currently, no optional arguments
are supported and so this must be zero.
<dev_path>
The block device that represents a specific path to the device.
<offset>
The offset of the start of data on the specific <dev_path> (in units
of 512-byte sectors). This number is added to the sector number when
forwarding the request to the specific path. Typically it is zero.
Messages
========
set_region_mappings <index>:<path_nr> [<index>]:<path_nr> [<index>]:<path_nr>...
Modify the region table by specifying which regions are redirected to
which paths.
<index>
The region number (region size was specified in constructor parameters).
If index is omitted, the next region (previous index + 1) is used.
Expressed in hexadecimal (WITHOUT any prefix like 0x).
<path_nr>
The path number in the range 0 ... (<num_paths> - 1).
Expressed in hexadecimal (WITHOUT any prefix like 0x).
R<n>,<m>
This parameter allows repetitive patterns to be loaded quickly. <n> and <m>
are hexadecimal numbers. The last <n> mappings are repeated in the next <m>
slots.
Status
======
No status line is reported.
Example
=======
Assume that you have volumes vg1/switch0 vg1/switch1 vg1/switch2 with
the same size.
Create a switch device with 64kB region size::
dmsetup create switch --table "0 `blockdev --getsz /dev/vg1/switch0`
switch 3 128 0 /dev/vg1/switch0 0 /dev/vg1/switch1 0 /dev/vg1/switch2 0"
Set mappings for the first 7 entries to point to devices switch0, switch1,
switch2, switch0, switch1, switch2, switch1::
dmsetup message switch 0 set_region_mappings 0:0 :1 :2 :0 :1 :2 :1
Set repetitive mapping. This command::
dmsetup message switch 0 set_region_mappings 1000:1 :2 R2,10
is equivalent to::
dmsetup message switch 0 set_region_mappings 1000:1 :2 :1 :2 :1 :2 :1 :2 \
:1 :2 :1 :2 :1 :2 :1 :2 :1 :2
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
고정 region을 path에 동적으로 mapping
1-14Device Mapper의 `switch` target은 고정 크기 I/O region을 고정된 path 집합에 임의로 mapping하는 device를 만듭니다. 특정 region이 사용할 path는 target에 message를 보내 동적으로 바꿀 수 있습니다.
고정 크기 address region 수가 매우 많고 `dm-stripe`처럼 mapping을 간결하게 표현할 단순 pattern이 없을 때 underlying block device로 I/O를 효율적으로 mapping합니다.
Region table lookup으로 path를 선택하고 control message로 개별 mapping을 갱신합니다.
정규 stripe pattern 대신 큰 임의 mapping table이 필요한 경우에 적합합니다.
Distributed frameless iSCSI storage
15-40Dell EqualLogic과 일부 iSCSI storage array는 distributed frameless architecture를 사용합니다. Storage group은 서로 독립적인 controller, disk storage와 network adapter를 가진 여러 storage array, 즉 'member'로 구성됩니다.
LUN을 만들면 여러 member에 분산하지만 initiator에는 세부 배치를 숨깁니다. 사용 중인 member 수와 관계없이 storage group은 하나의 target discovery portal을 노출합니다. 각 iSCSI session은 한 member의 ethernet port에 연결됩니다.
LUN data는 어느 iSCSI session으로 보내도 됩니다. 접근 block이 다른 member에 있으면 필요한 곳으로 I/O를 forwarding하며 initiator에는 보이지 않습니다. Storage layout도 동적이므로 부하를 균형 있게 맞추기 위해 disk block을 member 사이에서 이동할 수 있습니다.
Initiator는 어느 session으로든 I/O를 보낼 수 있고 array group이 실제 block owner로 전달합니다.
이 구조는 storage group과 initiator의 관리·구성을 단순화합니다. Multipathing에서는 host와 target의 여러 network interface를 쓰는 여러 iSCSI session을 구성해 network bandwidth를 늘릴 수 있습니다.
Initiator가 모든 path에 단순 round-robin으로 I/O를 보내고 array member가 필요한 forwarding을 수행하게 할 수도 있지만, data가 실제로 있는 올바른 member로 직접 보내면 성능상 이점이 있습니다.
두 방식 모두 동작하지만 member 내부 forwarding을 피하는 직접 경로가 더 효율적입니다.
Bitmap upper tier와 member별 multipath lower tier
41-67Device Mapper table은 device의 서로 다른 region을 서로 다른 target에 mapping할 수 있습니다. 하지만 이 architecture에서 LUN은 수십 MB 정도의 address region으로 분산되므로 table entry가 백만 개를 넘고 지나치게 많은 memory를 소비할 수 있습니다.
`dm-switch`를 사용하면 두 계층 device hierarchy를 만들 수 있습니다. Upper tier는 I/O를 보낼 array member를 결정하고, lower tier는 특정 member로 가는 path 사이에서 load balance합니다.
Region ownership 선택과 network path load balancing을 서로 다른 Device Mapper 계층이 담당합니다.
Lower tier에는 member마다 `dm-multipath` device 하나가 있습니다. 각 device는 해당 array member로 직접 가는 path 집합을 하나의 preferred priority group에 넣고 기존 path selector로 load balance합니다. Failover를 위해 다른 member로 가는 path를 담은 non-preferred priority group도 구성합니다.
Upper tier는 `dm-switch` device 하나입니다. Bitmap으로 I/O 위치를 lookup해 적절한 lower-tier device를 선택합니다. 16-member group이면 address range마다 4-bit만 사용하므로 dm table B-tree보다 훨씬 조밀하게 표현할 수 있습니다.
Path 수를 표현하는 데 필요한 bit 수만 region마다 사용합니다.
Path 수, region 크기와 device offset
68-90Constructor 형식은 다음과 같습니다.
<num_paths> <region_size> <num_optional_args> [<optional_args>...] [<dev_path> <offset>]+
Region geometry를 정의하고 사용할 각 block-device path를 나열합니다.
각 region은 사용 가능한 어느 path로든 redirect할 수 있습니다. 현재 지원하는 optional argument가 없으므로 `<num_optional_args>`는 0이어야 합니다.
Request를 특정 path로 전달할 때 logical sector number에 `<offset>`을 더합니다. Offset은 보통 0입니다.
Region table이 선택한 path의 고유 시작 offset을 logical sector에 더합니다.
Region mapping과 반복 pattern message
91-112`set_region_mappings` message로 region table을 수정해 각 region을 어느 path로 redirect할지 지정합니다.
set_region_mappings <index>:<path_nr> [<index>]:<path_nr> [<index>]:<path_nr>...
`<index>`는 constructor의 region size로 정한 region 번호입니다. Index를 생략하면 이전 index에 1을 더한 다음 region을 사용합니다. 값은 `0x` 같은 prefix 없이 hexadecimal로 씁니다.
`<path_nr>`는 0부터 `<num_paths> - 1`까지의 path 번호이며 이것도 prefix 없는 hexadecimal입니다.
R<n>,<m>
`R<n>,<m>`은 반복 pattern을 빠르게 load합니다. `<n>`과 `<m>`은 hexadecimal이며, 마지막 `<n>`개 mapping을 이어지는 `<m>`개 slot에 반복합니다.
명시적 index, 연속 index 생략과 반복 압축을 함께 사용할 수 있습니다.
Hex token을 순서대로 해석해 bitmap region entry를 갱신합니다.
Status line 없음
113-117`dm-switch` target은 status line을 보고하지 않습니다.
Runtime region mapping은 status 출력이 아니라 message로 관리합니다.
세 path와 첫 일곱 region mapping
118-133같은 크기의 `vg1/switch0`, `vg1/switch1`, `vg1/switch2` volume이 있다고 가정합니다. 다음 table은 64 KiB region 크기의 switch device를 만듭니다. 512-byte sector 128개가 64 KiB입니다.
dmsetup create switch --table "0 `blockdev --getsz /dev/vg1/switch0`
switch 3 128 0 /dev/vg1/switch0 0 /dev/vg1/switch1 0 /dev/vg1/switch2 0"
세 같은 크기 volume을 path 0, 1, 2로 등록하고 region마다 선택합니다.
첫 7개 region을 차례로 `switch0`, `switch1`, `switch2`, `switch0`, `switch1`, `switch2`, `switch1`에 mapping합니다. 첫 token `0:0` 뒤에는 index를 생략하므로 region 번호가 자동 증가합니다.
dmsetup message switch 0 set_region_mappings 0:0 :1 :2 :0 :1 :2 :1
Message token과 선택 path를 펼쳐 표시합니다.
Hexadecimal R2,10 pattern 확장
134-141다음 명령은 hexadecimal region `1000`에서 path 1, 다음 region에서 path 2를 설정한 뒤 마지막 두 mapping을 다음 hexadecimal `10`, 즉 16개 slot에 반복합니다.
dmsetup message switch 0 set_region_mappings 1000:1 :2 R2,10
따라서 path 1과 2가 번갈아 나오는 16개 token을 직접 나열한 다음 명령과 같습니다.
dmsetup message switch 0 set_region_mappings 1000:1 :2 :1 :2 :1 :2 :1 :2 \
:1 :2 :1 :2 :1 :2 :1 :2 :1 :2
마지막 두 mapping `:1 :2`를 8회 반복해 다음 16개 region slot을 채웁니다.
Prefix 없이 쓰지만 모든 숫자는 16진수로 해석합니다.
임의 region routing
switch.rst:1-40Distributed iSCSI array에서 실제 block owner로 직접 I/O를 보내 forwarding을 줄입니다.