Linux의 ZFS - L2ARC를 읽을 수 없습니다.

Linux의 ZFS - L2ARC를 읽을 수 없습니다.

오늘 저는 Linux 0.7.10에서 최신 ZFS를 사용하여 L2ARC에 대해 몇 가지 테스트를 수행했습니다. L2ARC가 데이터로 채워지는 것을 보았지만 기본 모듈 설정을 사용하면 L2ARC 캐시에 있는 데이터는 절대 건드리지 않습니다. 대신 데이터는 메인 풀의 vdev에서 읽혀집니다. 또한 0.7.9에서도 이 동작을 보았으며 이것이 예상된 동작인지 확실하지 않습니다.
그것이 예상되는 동작이라 하더라도, 결코 읽히지 않는 데이터로 L2ARC를 망치는 것은 이상하다고 생각합니다.


테스트 설치는 VM입니다.

  • 최신 패치가 포함된 CentOS 7.5
  • Linux 0.7.10의 ZFS
  • 2GB RAM

몇 가지 ZFS 설정을 수행했습니다.

  • l2arc_headroom=1024l2arc_headroom=1024L2ARC 인구의 속도를 높이기 위해

수영장이 생성된 방법과 레이아웃은 다음과 같습니다. 실제 설정에서는 다소 이상하다는 것을 알고 있지만 이는 L2ARC 테스트 전용입니다.

[root@host ~]# zpool create tank raidz2 /dev/sda /dev/sdb /dev/sdc cache sdd -f
[root@host ~]# zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  2.95G   333K  2.95G         -     0%     0%  1.00x  ONLINE  -
  raidz2  2.95G   333K  2.95G         -     0%     0%
    sda      -      -      -         -      -      -
    sdb      -      -      -         -      -      -
    sdc      -      -      -         -      -      -
cache      -      -      -         -      -      -
  sdd  1010M    512  1009M         -     0%     0%

이제 파일에 일부 데이터를 쓰고 장치 사용량을 살펴보세요.

[root@host ~]# dd if=/dev/urandom of=/tank/testfile bs=1M count=512
512+0 records in
512+0 records out
536870912 bytes (537 MB) copied, 9.03607 s, 59.4 MB/s

[root@host ~]# zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  2.95G  1.50G  1.45G         -    10%    50%  1.00x  ONLINE  -
  raidz2  2.95G  1.50G  1.45G         -    10%    50%
    sda      -      -      -         -      -      -
    sdb      -      -      -         -      -      -
    sdc      -      -      -         -      -      -
cache      -      -      -         -      -      -
  sdd  1010M   208M   801M         -     0%    20%

좋습니다. 일부 데이터는 이미 L2ARC로 이동되었지만 전부는 아닙니다. 그러니 L2ARC로 완전히 만들려면 몇 번 더 읽어보세요.

[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512 # until L2ARC is populated with the 512MB testfile

[root@host ~]# zpool list -v
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  2.95G  1.50G  1.45G         -    11%    50%  1.00x  ONLINE  -
  raidz2  2.95G  1.50G  1.45G         -    11%    50%
    sda      -      -      -         -      -      -
    sdb      -      -      -         -      -      -
    sdc      -      -      -         -      -      -
cache      -      -      -         -      -      -
  sdd  1010M   512M   498M         -     0%    50%

좋아요, L2ARC가 채워졌고 읽을 준비가 되었습니다. 하지만 먼저 L1ARC를 제거해야 합니다. 나는 다음을 수행했는데 효과가 있는 것 같았습니다.

[root@host ~]# echo $((64*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; echo $((1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; arc_summary.py -p1

------------------------------------------------------------------------
ZFS Subsystem Report                        Sun Sep 09 17:03:55 2018
ARC Summary: (HEALTHY)
    Memory Throttle Count:                  0

ARC Misc:
    Deleted:                                20
    Mutex Misses:                           0
    Evict Skips:                            1

ARC Size:                           0.17%   1.75    MiB
    Target Size: (Adaptive)         100.00% 1.00    GiB
    Min Size (Hard Limit):          6.10%   62.48   MiB
    Max Size (High Water):          16:1    1.00    GiB

ARC Size Breakdown:
    Recently Used Cache Size:       96.06%  1.32    MiB
    Frequently Used Cache Size:     3.94%   55.50   KiB

ARC Hash Breakdown:
    Elements Max:                           48
    Elements Current:               100.00% 48
    Collisions:                             0
    Chain Max:                              0
    Chains:                                 0

자, 이제 L2ARC를 읽을 준비가 되었습니다(서문이 길어서 죄송하지만 중요하다고 생각했습니다).
그래서 명령을 다시 실행하면서 두 번째 터미널에서 dd if=/tank/testfile of=/dev/null bs=512지켜보고 있었습니다 .zpool iostat -v 5

놀랍게도 파일은 L2ARC에 있지만 L2ARC 대신 일반 vdev에서 파일을 읽었습니다. 이것은 파일 시스템의 유일한 파일이며 테스트 중에는 다른 활동이 활성화되지 않습니다.

              capacity     operations     bandwidth 
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.50G  1.45G    736     55  91.9M  96.0K
  raidz2    1.50G  1.45G    736     55  91.9M  96.0K
    sda         -      -    247     18  30.9M  32.0K
    sdb         -      -    238     18  29.8M  32.0K
    sdc         -      -    250     18  31.2M  32.0K
cache           -      -      -      -      -      -
  sdd        512M   498M      0      1  85.2K  1.10K
----------  -----  -----  -----  -----  -----  -----

zfetch_array_rd_sz그런 다음 , zfetch_max_distance, 및 와 zfetch_max_streams같은 일부 설정을 조작하여 홀수 높은 숫자로 설정했습니다. 그러나 아무것도 변하지 않았습니다. l2arc_write_boostl2arc_write_max

변경 후

  • l2arc_noprefetch=0(기본값은 1)
  • 또는 zfs_prefetch_disable=1(기본값은 0)
  • 둘 다 기본값에서 전환

읽기는 L2ARC에서 제공됩니다. 두 번째 터미널에서 다시 실행 dd if=/tank/testfile of=/dev/null bs=512하고 시청하며 zpool iostat -v 5L1ARC를 제거합니다.

[root@host ~]# echo 0 > /sys/module/zfs/parameters/l2arc_noprefetch 
[root@host ~]# echo $((64*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; echo $((1024*1024*1024)) > /sys/module/zfs/parameters/zfs_arc_max; sleep 5s; arc_summary.py -p1
...
[root@host ~]# dd if=/tank/testfile of=/dev/null bs=512 

결과는 다음과 같습니다.

              capacity     operations     bandwidth 
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
tank        1.50G  1.45G      0     57    921   102K
  raidz2    1.50G  1.45G      0     57    921   102K
    sda         -      -      0     18      0  34.1K
    sdb         -      -      0     18      0  34.1K
    sdc         -      -      0     19    921  34.1K
cache           -      -      -      -      -      -
  sdd        512M   497M    736      0  91.9M   1023
----------  -----  -----  -----  -----  -----  -----

이제 L2ARC에서 데이터를 읽지만 위에서 언급한 모듈 매개변수를 전환한 후에만 가능합니다.

나는 또한 L2ARC의 크기가 너무 클 수 있다는 것을 읽었습니다. 그러나 해당 주제에 대해 내가 찾은 스레드는 성능 문제 또는 L1ARC를 망치는 L2ARC의 공간 맵을 언급하고 있었습니다.
여기서 성능은 내 문제가 아니며, 내가 알 수 있는 한 L2ARC의 공간 맵도 그다지 크지 않습니다.

[root@host ~]# grep hdr /proc/spl/kstat/zfs/arcstats 
hdr_size                        4    279712
l2_hdr_size                     4    319488

이미 언급했듯이 이것이 의도한 동작인지 아니면 뭔가 빠졌는지 확실하지 않습니다.

답변1

따라서 이 주제를 읽은 후 주로이 게시물, 이것이 ZFS의 기본 동작인 것 같습니다.

파일을 읽은 후 L1ARC로 들어가고 블록에 액세스하면 L2ARC에 있는 것으로 간주됩니다.
이제 두 번째 파일 읽기에서 ZFS는 파일 블록이 L2ARC에 저장되어 있더라도 L2ARC를 우회하는 파일 프리페치를 수행합니다.

를 사용하여 프리페치를 완전히 비활성화하거나 zfs_prefetch_disable=1ZFS에 를 사용하여 L2ARC에서 프리페치를 수행하도록 지시하면 l2arc_noprefetch=0읽기 시 L2ARC에 있는 파일 블록을 사용하게 됩니다.
L2ARC가 읽고 있는 파일 크기에 비해 충분히 큰 경우 이는 바람직할 수 있습니다.
그러나 metadata. zfs set secondarycache=metadata tank​이렇게 하면 큰 파일이 L2ARC에 들어가 읽혀지지 않는 것을 방지할 수 있습니다. 왜냐하면 이것은약탈L2ARC를 제거하고 프리패치되지 않은 작은 파일 블록과 L2ARC에 보관하려는 메타데이터 블록을 제거할 수 있습니다.

ZFS에 넣으라고 지시하는 방법을 찾지 못했습니다.작은 파일만L2ARC에 추가하고 프리페치 후보를 L2ARC에 병합하지 않습니다. 따라서 지금은 파일 크기와 L2ARC 크기에 따라 절충을 해야 합니다.
ZoL 0.8.0 릴리스에서는 다른 접근 방식을 사용할 수 있는 것으로 보입니다.할당 분류예를 들어 데이터 블록은 그대로 두고 빠른 SSD에 메타데이터를 넣을 수 있어야 합니다.느린회전 디스크. 이것은 여전히 ​​​​경합을 남길 것입니다작은 파일큰 파일L2ARC의 경우 메타데이터에 대한 빠른 액세스 문제를 해결합니다.

답변2

이 경우 ZFS는 임의/비스트리밍 읽기에 대해 L2ARC 대역폭을 보존하려고 시도하며, 물리적 디스크에 충격을 가하면 성능이 저하될 수 있습니다. 스트리밍 읽기는 기계식 HDD에서 매우 잘 제공되며 6/8개 이상의 디스크가 있는 풀은 순차 읽기에 대해 SATA L2ARC 장치보다 성능이 뛰어납니다. 그리고 중간 크기의 zpool(예: 24/48+ 디스크)은 다음을 제공합니다.풍부한순차 실제 대역폭.

찾은 대로 L2ARC를 변경하여 피해자 캐시와 더 유사하게 작동하도록 할 수 있습니다(예: ARC에서 제거된 모든 항목을 저장합니다. L2ARC에서 블록이 발견되면 메인 풀에 액세스하려고 시도하지도 마세요). 일부 특정 설정에서는 이것이 좋은 것일 수 있습니다. 그러나 ZFS는 더 빠른 무작위 읽기 성능을 위해 실제로 사용된 블록을 캐시하는 등 매우 유리할 수 있는 L2ARC 마모/사용을 보존하도록 (올바르게) 설계되었습니다.

관련 정보