암호화된 드라이브 쓰기는 느린 반면, 벤치마크에서는 암호화/원시 디스크 쓰기 속도가 훨씬 더 높은 것으로 나타났습니다.

암호화된 드라이브 쓰기는 느린 반면, 벤치마크에서는 암호화/원시 디스크 쓰기 속도가 훨씬 더 높은 것으로 나타났습니다.

현재 장치에 Ubuntu 18.04 NAS가 설치되어 있습니다 Netgear ReadyNAS 102. 이 기계에는 "CESA"라는 하드웨어 암호화 가속기를 갖춘 Armada Marvell 370/XP SoC가 있습니다. CESA의 커널 드라이버가 실행 중입니다. 다음을 통해 확인할 수 있습니다 cat /proc/crypto.

[...]
name         : cbc(aes)
driver       : mv-cbc-aes
module       : marvell_cesa
priority     : 300
refcnt       : 1
selftest     : passed
internal     : no
type         : skcipher
async        : yes
blocksize    : 16
min keysize  : 16
max keysize  : 32
ivsize       : 16
chunksize    : 16
walksize     : 16
[... other marvel_cesa entries are available too...]

mdadm을 통해 두 개의 디스크(회전 디스크가 있는 일반 HDD)를 RAID1로 설정했습니다. 내가 사용한 최종 RAID 장치는 /dev/md127이었습니다. 쓰기 속도는 약 65MB/s입니다.

# dd if=/dev/zero of=/dev/md127 bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 15.945 s, 65.8 MB/s

cryptsetup 벤치마크에 따르면 "aes-xts"를 사용한 암호화는 약 30MB/s를 달성해야 합니다(cryptsetup은 기본적으로 이 값을 사용합니다. "aes-cbc"는 더 이상 안전하지 않기 때문입니다).

# cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1        72979 iterations per second for 256-bit key
PBKDF2-sha256     125547 iterations per second for 256-bit key
PBKDF2-sha512      49498 iterations per second for 256-bit key
PBKDF2-ripemd160   69497 iterations per second for 256-bit key
PBKDF2-whirlpool   18875 iterations per second for 256-bit key
argon2i       4 iterations, 25926 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id      4 iterations, 26234 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
#     Algorithm |       Key |      Encryption |      Decryption
        aes-cbc        128b        55.8 MiB/s        56.6 MiB/s
    serpent-cbc        128b        17.9 MiB/s        17.7 MiB/s
    twofish-cbc        128b        22.3 MiB/s        25.2 MiB/s
        aes-cbc        256b        53.0 MiB/s        53.4 MiB/s
    serpent-cbc        256b        17.9 MiB/s        17.7 MiB/s
    twofish-cbc        256b        23.0 MiB/s        25.3 MiB/s
        aes-xts        256b        30.7 MiB/s        31.0 MiB/s
    serpent-xts        256b        19.9 MiB/s        18.8 MiB/s
    twofish-xts        256b        28.0 MiB/s        28.3 MiB/s
        aes-xts        512b        29.8 MiB/s        30.1 MiB/s
    serpent-xts        512b        20.6 MiB/s        18.8 MiB/s
    twofish-xts        512b        28.0 MiB/s        28.2 MiB/s

이제 cryptsetup luksFormat /dev/md127이를 사용하여 암호화된 블록 장치를 만듭니다.

   root@ReadyNAS102:~# cryptsetup luksFormat /dev/md127

   WARNING!
   ========
   This will overwrite data on /dev/md127 irrevocably.

   Are you sure? (Type uppercase yes): YES
   Enter passphrase for /dev/md127:
   Verify passphrase:

cryptsetup luksDump그런 다음 실제로 선택한 비밀번호를 확인했습니다 . 제가 아는 한 "aes-xts-plain64"는 데이터 암호화용 키 크기가 512비트이고 AES의 대칭 512비트 키를 암호화하는 데 사용되는 비밀번호를 sha256을 사용하여 해시하는 것입니다.

   root@ReadyNAS102:~# cryptsetup luksDump /dev/md127
   LUKS header information
   Version:        2
   Epoch:          3
   Metadata area:  16384 [bytes]
   Keyslots area:  16744448 [bytes]
   UUID:           1f4917c4-ce8c-48d8-99f6-2c19ccb4ecc9
   Label:          (no label)
   Subsystem:      (no subsystem)
   Flags:          (no flags)

   Data segments:
     0: crypt
           offset: 16777216 [bytes]
           length: (whole device)
           cipher: aes-xts-plain64
           sector: 512 [bytes]

   Keyslots:
     0: luks2
           Key:        512 bits
           Priority:   normal
           Cipher:     aes-xts-plain64
           Cipher key: 512 bits
           PBKDF:      argon2i
           Time cost:  4
           Memory:     26404
           Threads:    1
           Salt:       0a ef ca 34 29 9a 23 a1 78 30 8e d8 d7 15 29 21
                       67 84 02 31 f4 b4 66 11 20 c7 82 ab 98 11 cd 93
           AF stripes: 4000
           AF hash:    sha256
           Area offset:32768 [bytes]
           Area length:258048 [bytes]
           Digest ID:  0
   Tokens:
   Digests:
     0: pbkdf2
           Hash:       sha256
           Iterations: 7953
           Salt:       5d 2d de 4d c3 72 e1 ab 70 d2 ba 8a b3 7e 18 89
                       2e 3a 28 e3 51 c8 80 fe ba 73 ce 5e 53 db 72 99
           Digest:     36 6e 0e b0 b7 8c df 28 8f ec 49 bf 97 15 25 68
                       25 b2 92 35 c6 5e 0d ce f4 44 05 8d 3f 5b 78 93

마지막으로 luks 장치를 열고 쓰기 속도를 다시 확인했습니다.

   root@ReadyNAS102:~# cryptsetup luksOpen /dev/md127 md127-decrypt
   Enter passphrase for /dev/md127:
   root@ReadyNAS102:~# dd if=/dev/zero of=/dev/mapper/md127-decrypt bs=1M count=1000
   1000+0 records in
   1000+0 records out
   1048576000 bytes (1.0 GB, 1000 MiB) copied, 120.121 s, 8.7 MB/s

보시다시피 약 8.7MB/s만 달성되었습니다. 약 30MB/s 또는 최소한 20MB/s 이상이어야 하지 않나요? (디스크/CPU가 단순히 바쁜 것은 아닌지 확인하기 위해 속도 테스트를 여러 번 반복했습니다.)

왜 그렇게 느린가요? 어떻게 속도를 높일 수 있나요?

편집 #1: top 및 iostat에서 통계 요청

여기에서 요청한 대로 top/dev/mapper/md127-decrypt에 쓸 때 나타나는 내용은 다음과 같습니다.

   top - 15:30:52 up 1 day, 11:07,  1 user,  load average: 3.33, 1.09, 0.39
   Tasks:  80 total,   2 running,  78 sleeping,   0 stopped,   0 zombie
   %Cpu(s):  1.6 us, 98.4 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
   MiB Mem :    492.5 total,     14.9 free,     58.0 used,    419.6 buff/cache
   MiB Swap:    511.4 total,    510.2 free,      1.3 used.    422.2 avail Mem

     PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
     245 root     -51   0       0      0      0 S  40.5   0.0   3:20.16 irq/38-d0090000
   10791 root       0 -20       0      0      0 I  34.1   0.0   2:24.71 kworker/u3:1-kcryptd
   30143 root      20   0       0      0      0 S   7.9   0.0   0:15.33 dmcrypt_write
   29939 root      20   0       0      0      0 R   7.1   0.0   0:15.21 kworker/u2:1+flush-253:0
   28396 root      20   0    7064   2272   1236 D   6.3   0.5   0:05.60 dd
      28 root      20   0       0      0      0 S   1.6   0.0   0:08.80 kswapd0
     648 sdwarfs   20   0   10468   3560   2756 S   1.6   0.7   0:08.58 sshd
   28398 root      20   0    9360   2632   2124 R   1.6   0.5   0:01.20 top
   28397 root      20   0       0      0      0 I   0.8   0.0   0:00.12 kworker/u2:2-events_unbound
       1 root      20   0   29916   4416   3172 S   0.0   0.9   0:07.86 systemd
       2 root      20   0       0      0      0 S   0.0   0.0   0:00.06 kthreadd
       3 root       0 -20       0      0      0 I   0.0   0.0   0:00.00 rcu_gp

iostat -kx 5표시되는 내용 은 다음과 같습니다 .

   avg-cpu:  %user   %nice %system %iowait  %steal   %idle
              0.20    0.00   99.80    0.00    0.00    0.00

   Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
   sda              0.00  410.40      0.00   8494.10     0.00  1713.60   0.00  80.68    0.00    0.56   0.18     0.00    20.70   0.42  17.04
   sdb              0.00  401.80      0.00   8494.10     0.00  1722.20   0.00  81.08    0.00    0.49   0.14     0.00    21.14   0.30  11.92
   md127            0.00 2123.60      0.00   8494.40     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     4.00   0.00   0.00
   md0              0.00    0.60      0.00      2.40     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     4.00   0.00   0.00
   md1              0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
   dm-0             0.00 2123.60      0.00   8494.40     0.00     0.00   0.00   0.00    0.00    2.42   5.13     0.00     4.00   0.47 100.00

   avg-cpu:  %user   %nice %system %iowait  %steal   %idle
              0.00    0.00  100.00    0.00    0.00    0.00

   Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
   sda              0.00  415.80      0.00   8436.30     0.00  1693.40   0.00  80.29    0.00    0.49   0.18     0.00    20.29   0.43  18.08
   sdb              0.00  415.80      0.00   8436.30     0.00  1693.40   0.00  80.29    0.00    0.30   0.10     0.00    20.29   0.24  10.00
   md127            0.00 2108.20      0.00   8432.80     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     4.00   0.00   0.00
   md0              0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
   md1              0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
   dm-0             0.00 2107.80      0.00   8431.20     0.00     0.00   0.00   0.00    0.00    2.16   4.55     0.00     4.00   0.47 100.00

편집 #2: 암호화에 더 큰 섹터 크기(512 대신 4096)를 사용해 보십시오...

상단에는 IRQ 핸들러가 대부분의 CPU 리소스를 사용한다는 것을 보여주므로 이를 줄이기 위해서는 더 큰 암호화 블록 크기가 필요할 것으로 예상됩니다. 테스트를 위해 디스크를 다시 포맷했습니다 cryptsetup --sector-size=4096 luksFormat /dev/md127. cryptsetup의 luksDump 명령은 현재 암호화 섹터 크기 4096을 사용하고 있음을 확인합니다.

   root@ReadyNAS102:~# cryptsetup luksDump /dev/md127

   [...]

   Data segments:
     0: crypt
           offset: 16777216 [bytes]
           length: (whole device)
           cipher: aes-xts-plain64
           sector: 4096 [bytes]

   [...]

그런 다음 적용 luksOpen하고 또 다른 측정을 수행했습니다.

root@ReadyNAS102:~# cryptsetup luksOpen /dev/md127 md127-decrypt
Enter passphrase for /dev/md127:

root@ReadyNAS102:~# dd if=/dev/zero of=/dev/mapper/md127-decrypt bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 73.9352 s, 14.2 MB/s

IRQ의 CPU 로드가 약간 감소한 것 같습니다.

     PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   10791 root       0 -20       0      0      0 I  31.7   0.0   3:32.92 kworker/u3:1-kcryptd
     245 root     -51   0       0      0      0 S  22.9   0.0   4:38.98 irq/38-d0090000
   29296 root      20   0       0      0      0 R  15.9   0.0   0:04.14 kworker/u2:0+flush-253:0
   29356 root      20   0       0      0      0 R  15.9   0.0   0:04.09 dmcrypt_write
   29538 root      20   0    7064   2280   1252 D   9.2   0.5   0:02.83 dd

iostat -kx 5가 보여주는 내용은 다음과 같습니다.

   Device            r/s     w/s     rkB/s     wkB/s   rrqm/s   wrqm/s  %rrqm  %wrqm r_await w_await aqu-sz rareq-sz wareq-sz  svctm  %util
   sda              0.00 1030.00      0.00  14018.70     0.00  2474.80   0.00  70.61    0.00    0.56   0.54     0.00    13.61   0.44  45.44
   sdb              0.00 1029.80      0.00  14018.70     0.00  2475.00   0.00  70.62    0.00    0.34   0.32     0.00    13.61   0.28  28.72
   md127            0.00 3504.40      0.00  14017.60     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     4.00   0.00   0.00
   md0              0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
   md1              0.00    0.00      0.00      0.00     0.00     0.00   0.00   0.00    0.00    0.00   0.00     0.00     0.00   0.00   0.00
   dm-0             0.00 3504.20      0.00  14016.80     0.00     0.00   0.00   0.00    0.00    2.91  10.18     0.00     4.00   0.28  99.44

더 큰 섹터 크기는 데이터 속도를 높이는 데 도움이 되는 것으로 보입니다! 이제 다양한 섹터 크기에 대해 이것을 시도해 보겠습니다. 하지만 작은 파일의 성능 저하를 초래하지 않고 섹터 크기를 너무 많이 늘릴 수는 없다고 생각합니다. md127-decrypt 외에 btrfs를 사용하고 싶기 때문에 섹터 크기 4096은 문제가 되지 않습니다. Btrfs는 기본적으로 16kB 노드 크기를 사용하는데, 이는 아마도 합리적인 상한일 것입니다.

편집 #3: 데이터 속도와 암호화된 섹터 크기

다양한 섹터 크기를 확인하는 자동화된 테스트(bash 스크립트)를 작성했습니다. 그러나 cryptsetup은 섹터 크기 8192 사용을 지원하지 않습니다(메시지: "cryptsetup: 지원되지 않는 암호화 섹터 크기."). 따라서 4096바이트를 사용하겠습니다.

   Sector Size   Speed
     512 bytes    8.7 MB/s
    1024 bytes   11.8 MB/s
    2048 bytes   13.8 MB/s
    4096 bytes   14.4 MB/s

관련 정보