LUKS (Abysmal General dm-crypt) 쓰기 성능


21

블록 장치를 암호화 하면 성능 저하 가 발생하는 문제를 조사 중 입니다. 몇 시간의 인터넷 읽기 및 실험으로 해결책은 물론 적절한 이해도를 얻지 못했습니다.

간단히 말해 : btrfs를 블록 장치 (~ 170MB / s)에 넣을 때 쓰기 속도가 완벽하게 빠른 이유는 무엇입니까? 시스템이 충분히 높은 암호화 처리량을 유지할 수 있지만 파일 시스템과 블록 장치는 무엇입니까?

대본

/home/schlimmchen/random/dev/urandom이전의 데이터로 채워진 4.0GB 파일 입니다.

dd if=/dev/urandom of=/home/schlimmchen/Documents/random bs=1M count=4096

그것을 읽는 것은 매우 빠릅니다.

$ dd if=/home/schlimmchen/Documents/random of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 6.58036 s, 648 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 0.786102 s, 5.4 GB/s

(두 번째로, 파일은 분명히 캐시에서 읽혔습니다).

암호화되지 않은 btrfs

장치는 btrfs로 직접 형식화됩니다 (블록 장치에 파티션 테이블 없음).

$ sudo mkfs.btrfs /dev/sdf
$ sudo mount /dev/sdf /mnt
$ sudo chmod 777 /mnt

쓰기 속도는 ~ 170MB / s에 달합니다.

$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 27.1564 s, 157 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test2 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 25.1882 s, 169 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test3 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 29.8419 s, 143 MB/s

읽기 속도가 200MB / s보다 훨씬 높습니다.

$ dd if=/mnt/dd-test1 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.8265 s, 215 MB/s
$ dd if=/mnt/dd-test2 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.9821 s, 213 MB/s
$ dd if=/mnt/dd-test3 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 19.8561 s, 215 MB/s

블록 장치의 암호화 된 BTRFS

장치는 LUKS로 형식화되고 결과 장치는 btrfs로 형식화됩니다.

$ sudo cryptsetup luksFormat /dev/sdf
$ sudo cryptsetup luksOpen /dev/sdf crypt
$ sudo mkfs.btrfs /dev/mapper/crypt
$ sudo mount /dev/mapper/crypt /mnt
$ sudo chmod 777 /mnt
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 210.42 s, 20.3 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test2 bs=1M 
4265841146 bytes (4.3 GB) copied, 207.402 s, 20.6 MB/s

읽기 속도는 약간만 저하됩니다 (왜 전혀 그렇지 않습니까).

$ dd if=/mnt/dd-test1 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 22.2002 s, 192 MB/s
$ dd if=/mnt/dd-test2 of=/dev/null bs=1M
4265841146 bytes (4.3 GB) copied, 22.0794 s, 193 MB/s

luksDump : http://pastebin.com/i9VYRR0p

블록 장치의 btrfs에있는 파일의 암호화 된 btrfs

쓰기 속도는 암호화 된 파일에 쓸 때 150MB / s 이상으로 "하늘 로켓"입니다. 블록 장치에 btrfs를 넣고 16GB 파일을 할당하여 파일을 lukfsFormat마운트했습니다.

$ sudo mkfs.btrfs /dev/sdf -f
$ sudo mount /dev/sdf /mnt
$ sudo chmod 777 /mnt
$ dd if=/dev/zero of=/mnt/crypted-file bs=1M count=16384 conv=fsync
17179869184 bytes (17 GB) copied, 100.534 s, 171 MB/s
$ sudo cryptsetup luksFormat /mnt/crypted-file
$ sudo cryptsetup luksOpen /mnt/crypted-file crypt
$ sudo mkfs.btrfs /dev/mapper/crypt
$ sudo mount /dev/mapper/crypt /tmp/nested/
$ dd if=/home/schlimmchen/Documents/random of=/tmp/nested/dd-test1 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 26.4524 s, 161 MB/s
$ dd if=/home/schlimmchen/Documents/random of=/tmp/nested/dd-test2 bs=1M conv=fsync
4265841146 bytes (4.3 GB) copied, 27.5601 s, 155 MB/s

왜 이렇게 쓰기 성능이 향상됩니까? 파일 시스템 및 블록 장치의 이러한 특정 중첩은 높은 쓰기 속도를 지원하기 위해 무엇을 달성합니까?

설정

동일한 배포판과 커널을 실행하는 두 시스템에서 문제를 재현 할 수 있습니다. 그러나 System2의 커널 3.19.0에서 쓰기 속도가 느리다는 것도 관찰했습니다.

  • 장치 : SanDisk Extreme 64GB USB3.0 USB 스틱
  • 시스템 1 : Intel NUC 5i5RYH, i5-5250U (Broadwell), 8GB RAM, Samsung 840 EVO 250GB SSD
  • 시스템 2 : Lenovo T440p, i5-4300M (Haswell), 16GB RAM, Samsung 850 PRO 256GB SSD
  • 배포판 / 커널 : 데비안 제시, 3.16.7
  • cryptsetup : 1.6.6
  • /proc/cryptoSystem1의 경우 : http://pastebin.com/QUSGMfiS
  • cryptsetup benchmarkSystem1의 경우 : http://pastebin.com/4RxzPFeT
  • btrfs (-tools)는 버전 3.17입니다.
  • lsblk -t /dev/sdf: http://pastebin.com/nv49tYWc

생각

  • 내가 볼 수있는 한 정렬은 원인 이 아닙니다 . 스틱의 페이지 크기가 16KiB 인 경우에도 cryptsetup 페이로드 시작은 어쨌든 2MiB로 정렬됩니다.
  • --allow-discards (cryptsetup의 luksOpen의 경우) 예상대로 도움이되지 않았습니다.
  • 그것으로 실험을하는 동안 USB3.0 어댑터를 통해 연결된 외장 하드 드라이브와 매우 유사한 동작을 관찰했습니다.
  • 시스템이 64KiB 블록을 쓰고있는 것 같습니다. systemtrap 스크립트 내가 시도는 적어도 것을 나타냅니다. /sys/block/sdf/stat많은 쓰기가 병합되므로이 가설을 뒷받침합니다. 그래서 내 생각 엔 너무 작은 블록으로 쓰는 것이 원인이 아니라는 것입니다.
  • 블록 장치 큐 스케줄러를 NOOP로 변경하면 운이 없습니다.
  • 암호를 LVM 볼륨에 넣는 것은 도움이되지 않았습니다.

각 테스트 전에 디스크 캐시를 지우면 가능한 속도로 인해 디스크 캐시를 제거 할 수 있습니다 (현재는 램 외부에서 648MB / s의 사운드를 얻을 수 없음)
Xen2050

답변:


18

대답은 (지금 내가 아는 바와 같이) 동시성 입니다.

요컨대 : 파일을 사용 하거나 복사 할 때 (매일 사용하는 것과 같은) 내 순차적 쓰기 는 4 개의 스레드가 동시에 암호화 된 데이터를 블록 장치에 쓰는 작업을 동시에 수행하기 때문에 의사 랜덤 쓰기 (나쁜)가됩니다. 암호화 (양호).dd

완화 ( "이전"커널의 경우)

다음과 같이 IO 스케줄러 큐에서 대기중인 요청의 양을 늘리면 부정적인 영향을 완화 할 수 있습니다.

echo 4096 | sudo tee /sys/block/sdc/queue/nr_requests

필자의 경우 이것은 내 질문에 설명 된 4GB 임의 데이터 테스트의 처리량을 거의 세 배 (~ 56MB / s)로 처리합니다. 물론, 암호화되지 않은 IO에 비해 성능은 여전히 ​​100MB / s로 떨어집니다.

조사

멀티 코어 blktrace

또한 btrfs가 LUKS 암호화 블록 장치 위에 배치되는 문제가있는 시나리오를 조사했습니다. 실제 블록 장치에 발행되는 쓰기 명령을 보여주기 위해 다음 blktrace과 같이 사용 했습니다.

sudo blktrace -a write -d /dev/sdc -o - | blkparse -b 1 -i - | grep -w D

이 작업은 (필자가 이해할 수있는 한) /dev/sdc" 쓰기 " 유형의 IO 요청을 추적 한 다음이를 사람이 읽을 수있는 출력으로 구문 분석하지만 출력을 조치 " D " 로 제한합니다 (에 따라 man blkparse). " IO가 드라이버에 발행되었습니다 ".

결과는 다음과 같습니다 ( 멀티 코어 로그의 약 5000 줄 출력 참조 ).

8,32   0    32732   127.148240056     3  D   W 38036976 + 240 [ksoftirqd/0]
8,32   0    32734   127.149958221     3  D   W 38038176 + 240 [ksoftirqd/0]
8,32   0    32736   127.160257521     3  D   W 38038416 + 240 [ksoftirqd/0]
8,32   1    30264   127.186905632    13  D   W 35712032 + 240 [ksoftirqd/1]
8,32   1    30266   127.196561599    13  D   W 35712272 + 240 [ksoftirqd/1]
8,32   1    30268   127.209431760    13  D   W 35713872 + 240 [ksoftirqd/1]
  • 열 1 : 주요, 블록 장치의 부
  • 열 2 : CPU ID
  • 열 3 : 시퀀스 번호
  • 열 4 : 타임 스탬프
  • 열 5 : 프로세스 ID
  • 열 6 : 행동
  • 열 7 : RWBS 데이터 (유형, 섹터, 길이)

이것은 dd4GB의 랜덤 데이터를 마운트 된 파일 시스템으로 가져 오는 동안 생성 된 출력을 조금씩 줄여 줍니다. 적어도 두 가지 프로세스가 관련되어 있음이 분명합니다. 나머지 로그는 4 개의 프로세서가 모두 실제로 작업 중임을 나타냅니다. 안타깝게도 쓰기 요청은 더 이상 주문되지 않습니다. CPU0이 38038416 번째 섹터 주위에 쓰는 동안 나중에 예약 된 CPU1은 35713872 번째 섹터 주위에 쓰는 중입니다. 그 나쁜.

단일 코어 blktrace

멀티 스레딩을 비활성화하고 CPU의 두 번째 코어를 비활성화 한 후에도 동일한 실험을 수행했습니다. 물론, 하나의 프로세서 만이 스틱 쓰기에 관여합니다. 그러나 더 중요한 것은 쓰기 요청이 올바르게 순차적이기 때문에 동일한 설정에서 ~ 170MB / s의 전체 쓰기 성능이 달성되는 것입니다.

싱글 코어 로그 에서 약 5000 줄의 출력을 살펴보십시오 .

토론

이제 원인과 올바른 Google 검색어를 알았으므로이 문제에 대한 정보가 떠오르고 있습니다. 결과적으로, 나는 가장 먼저 눈치 채지 못했습니다.

현재 커널에서 수정되었습니다 (> = 4.0.2)

나는 (나중에) 이 정확한 문제를 겨냥한 커널 커밋을 발견했기 때문에 업데이트 된 커널을 시도하고 싶었습니다. [컴파일 한 후 이미 발견했다 debian/sid] 문제가 실제로 해결 된 것으로 밝혀졌다. 수정 사항이 나타난 정확한 커널 릴리스를 모르지만 원래 커밋 은 관심있는 사람에게 실마리를 줄 것입니다.

기록을 위해 :

$ uname -a
Linux t440p 4.0.0-1-amd64 #1 SMP Debian 4.0.2-1 (2015-05-11) x86_64 GNU/Linux
$ dd if=/home/schlimmchen/Documents/random of=/mnt/dd-test bs=1M conv=fsync
4294967296 bytes (4.3 GB) copied, 29.7559 s, 144 MB/s

커밋을 작성한 Mikulas Patocka의 모자 팁.


1
커널 4.12.12와 함께 luks에서 btrfs를 사용하고 있으며 속도 저하가 여전히 있습니다!
brauliobo

왜 둔화가 여전히 존재 한다고 말 합니까? 어떤 참조를 사용하여 속도 저하가 발생하지 않았습니까? 당신의 설정은 무엇입니까? LUKS 만 제거 할 때 드라이브 성능을 확인 했습니까?
schlimmchen


1
이제도 여전히 "느린 속도"에 대해 글을 쓰는 이유를 이해합니다. 그러나 문제는 단순히이 문제와 관련이 있으며 반드시 같은 문제는 아닙니다 (지연 대 성능 저하). 나는이 성가신 hickups도 경험하므로 여기서 문제를 지적 해 주셔서 대단히 감사합니다! LUKS를 사용하지 않는 것은 옵션이 아니지만 원인과 관련이있는 것 같습니다.
schlimmchen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.