전체 zfs 풀을 다른 zfs 풀로 단방향 미러링하는 방법

전체 zfs 풀을 다른 zfs 풀로 단방향 미러링하는 방법

여러 개의 zvol과 데이터 세트가 포함된 하나의 zfs 풀이 있는데 그 중 일부도 중첩되어 있습니다. 모든 데이터세트와 zvol은 zfs-auto-snapshot에 의해 주기적으로 스냅샷이 생성됩니다. 모든 데이터세트와 zvol에는 수동으로 생성된 스냅샷도 있습니다.

시간 부족으로 인해 zfs send -R을 통한 로컬 고속 네트워크를 통한 초기 복사가 완료되지 않은 원격 풀을 설정했습니다(일부 데이터 세트가 누락되었거나 일부 데이터 세트에 오래되었거나 스냅샷이 누락됨).

이제 풀은 저속 연결을 통해 물리적으로 원격이며 원격 풀을 로컬 풀과 주기적으로 동기화해야 합니다. 즉, 로컬 풀에 있는 데이터를 원격 풀에 복사해야 하고, 로컬 풀에서 사라진 데이터를 원격 풀에서 삭제해야 합니다. 원격 풀에는 있지만 로컬 풀에는 없는 데이터는 'zvols', 'datasets' 또는 'snapshots'을 의미하는 데이터로 원격 풀에서 삭제되어야 합니다.

rsync를 사용하여 두 개의 일반 파일 시스템 간에 이 작업을 수행하는 경우 "-axPHAX --delete"가 됩니다(일부 시스템을 백업하기 위해 실제로 수행하는 작업입니다).

원격 풀 zvol 및 데이터 세트(스냅샷 포함)가 로컬 zvol, 데이터 세트 및 스냅샷과 동기화될 수 있도록 동기화 작업을 어떻게 설정합니까?

SSH의 처리 성능이 낮기 때문에 SSH를 통한 전송을 피하고 싶습니다. 대신 mbbuffer 또는 iscsi를 선호합니다.

답변1

고지 사항: 저는 zvol을 사용해 본 적이 없기 때문에 일반 파일 시스템이나 스냅샷과 복제가 다른지 여부를 말할 수 없습니다. 나는 그럴 것이라고 생각하지만 내 말을 받아들이지 마십시오.


귀하의 질문은 실제로 여러 질문이므로 개별적으로 답변하려고 합니다.

전체 풀을 원격 위치에 복제/미러링하는 방법

작업을 두 부분으로 나누어야 합니다. 먼저 초기 복제가 완료되어야 하고 이후 증분 복제가 가능해야 합니다.복제 스냅샷을 망치지 않는 한. 증분 복제를 활성화하려면 마지막 복제 스냅샷을 보존해야 하며 그 이전의 모든 것은 삭제될 수 있습니다. 이전 스냅샷을 삭제하면 에서 zfs recv불만을 표시하고 복제를 중단합니다. 이런 경우에는 처음부터 다시 시작해야 하므로 이렇게 하지 마세요.

올바른 옵션이 필요한 경우 다음과 같습니다.

  • zfs send:
    • -R: 지정된 풀 또는 데이터 세트 아래의 모든 항목을 보냅니다(항상 필요한 재귀 복제에는 가 포함됨 -p). 또한, 수신 시 삭제된 소스 스냅샷은 모두 대상에서 삭제됩니다.
    • -I: 마지막 복제 스냅샷과 현재 복제 스냅샷 사이의 모든 중간 스냅샷을 포함합니다(증분 전송에만 필요함)
  • zfs recv:
    • -F: 소스에서 삭제된 기존 데이터 세트 삭제를 포함하여 대상 풀을 확장합니다.
    • -d: 소스 풀의 이름을 버리고 대상 풀 이름으로 바꿉니다. (나머지 파일 시스템 경로는 보존되며 필요한 경우 생성됩니다.)
    • -u: 대상에 파일 시스템을 마운트하지 않습니다

완전한 예를 원한다면 다음과 같은 작은 스크립트가 있습니다.

#!/bin/sh

# Setup/variables:

# Each snapshot name must be unique, timestamp is a good choice.
# You can also use Solaris date, but I don't know the correct syntax.
snapshot_string=DO_NOT_DELETE_remote_replication_
timestamp=$(/usr/gnu/bin/date '+%Y%m%d%H%M%S')
source_pool=tank
destination_pool=tank
new_snap="$source_pool"@"$snapshot_string""$timestamp"
destination_host=remotehostname

# Initial send:

# Create first recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Initial replication via SSH.
zfs send -R "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"

# Incremental sends:

# Get old snapshot name.
old_snap=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$source_pool"@"$snapshot_string" | tail --lines=1)
# Create new recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Incremental replication via SSH.
zfs send -R -I "$old_snap" "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"
# Delete older snaps on the local source (grep -v inverts the selection)
delete_from=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$snapshot_string" | grep -v "$timestamp")
for snap in $delete_from; do
    zfs destroy "$snap"
done

SSH보다 빠른 것을 사용하십시오

IPSec 또는 OpenVPN 터널과 같이 충분히 보안된 연결이 있고 발신자와 수신자 사이에만 존재하는 별도의 VLAN이 있는 경우 SSH에서 mbuffer와 같은 암호화되지 않은 대안으로 전환할 수 있습니다.여기에 설명된 대로또는 암호화가 약하거나 암호화되지 않고 압축이 비활성화된 SSH를 사용할 수 있습니다.여기에 자세히 설명되어 있습니다. 훨씬 더 빠르게 SSH를 다시 ​​컴파일하는 방법에 대한 웹사이트도 있었지만 안타깝게도 URL이 기억나지 않습니다. 나중에 찾으면 편집하겠습니다.

매우 큰 데이터 세트와 느린 연결의 경우 하드 디스크를 통한 첫 번째 전송에 유용할 수도 있습니다(암호화된 디스크를 사용하여 zpool을 저장하고 택배, 우편 또는 직접을 통해 밀봉된 패키지로 전송). send/recv에서는 전송 방법이 중요하지 않으므로 모든 것을 디스크로 파이프하고, 풀을 내보내고, 디스크를 대상으로 보내고, 풀을 가져온 다음 SSH를 통해 모든 증분 전송을 전송할 수 있습니다.

엉망인 스냅샷 문제

앞서 설명한 대로 복제 스냅샷을 삭제/수정하면 오류 메시지가 표시됩니다.

cannot send 'pool/fs@name': not an earlier snapshot from the same fs

이는 명령이 잘못되었거나 스냅샷을 제거하고 처음부터 다시 시작해야 하는 일관성 없는 상태에 있음을 의미합니다.

이는 다음과 같은 몇 가지 부정적인 의미를 갖습니다.

  1. 새 복제 스냅샷이 성공적으로 전송될 때까지 복제 스냅샷을 삭제할 수 없습니다. 이러한 복제 스냅샷에는 다른 모든(이전) 스냅샷의 상태가 포함되므로 삭제된 파일과 스냅샷의 빈 공간은 복제가 완료된 경우에만 회수됩니다. 이로 인해 풀에 임시 또는 영구적인 공간 문제가 발생할 수 있으며 전체 복제 절차를 다시 시작하거나 완료해야만 해결할 수 있습니다.
  2. 추가 스냅샷이 많아지면 list 명령 속도가 느려집니다(이 문제가 수정된 Oracle Solaris 11 제외).
  3. 스크립트 자체를 제외하고 (우발적인) 제거로부터 스냅샷을 보호해야 할 수도 있습니다.

이러한 문제에 대한 가능한 해결책이 있지만 직접 시도하지는 않았습니다. zfs bookmark이 작업을 위해 특별히 만들어진 OpenSolaris/illumos의 새로운 기능인 를 사용할 수 있습니다 . 이렇게 하면 스냅샷 관리가 필요 없습니다. 유일한 단점은 현재 재귀적으로 작동하지 않고 단일 데이터 세트에서만 작동한다는 것입니다. 이전 데이터세트와 새 데이터세트 모두의 목록을 저장한 다음 반복해서 북마크하고 보내고 받은 다음 목록(또는 원하는 경우 소규모 데이터베이스)을 업데이트해야 합니다.

북마크 경로를 시도해 보시면 결과가 어떻게 되었는지 듣고 싶습니다!

답변2

개인적으로 저는 원격 서버에 zvol, 데이터 세트 등의 목록을 만들어서~하지 않다zfs send시간이 많이 걸리고 대역폭을 많이 사용하더라도 최신 스냅샷을 가지고 있는 경우 를 사용하여 해당 스냅샷을 최신 상태로 유지하십시오 .

그러면 그때부터 계속 사용할 수 zfs send있고 자체 동기화 코드를 작성하여 바퀴를 다시 만들 필요가 없습니다. rsync오래된 파일 시스템에는 좋지만zfs send zfs에는 훨씬 좋습니다.정확히스냅샷에서 어떤 블록이 변경되어 전송되는지오직반면 rsync는 로컬 서버와 원격 서버 간의 개별 파일 및/또는 타임스탬프를 비교해야 합니다. btrfs sendbtrfs 풀 에도 동일하게 적용됩니다 .

최신 상태로 가져와야 하는 스냅샷 수가 적은 경우 수동으로 수행할 수 있습니다. 그렇지 않고 자동으로 수행하려면 최신 로컬 스냅샷과 원격 스냅샷의 목록, 그리고 버전을 비교한 다음 zfs sendrmeote 서버에서 오래된 로컬 스냅샷을 비교하는 스크립트가 필요합니다.

각 데이터세트의 최신 스냅샷에만 관심이 있다면 이것으로 충분합니다. 이전의 모든 스냅샷에 관심이 있다면 분명히 스크립트도 스냅샷을 처리해야 할 것입니다....그리고 이는 훨씬 더 복잡해집니다. 경우에 따라 중간/누락된 스냅샷을 다시 보낼 수 있도록 원격 서버에서 롤백해야 할 수도 있습니다.

ssh원격 서버에 대한 보안 연결을 원한다면 를 사용하거나 를 사용하여 터널을 설정하고 openvpn사용하는 것 외에는 선택의 여지가 거의 없습니다 netcat.

답변3

FreeBSD의 `zrepl'을 살펴보십시오. 이것은 당신의 삶을 훨씬 더 쉽게 만들어 줄 것이며, 모든 사람의 삶을 훨씬 더 쉽게 만들어줄 것입니다. 며칠 전 오타와에서 열린 BSDCan2018에서 발표되었습니다. 유망해 보이고 문제에 대한 해결책이 될 수도 있습니다.

답변4

zrep은 훌륭한 올인원 솔루션이며 일반 SSH 전송보다 더 빠른 전송을 얻는 방법에 대한 문서와 후크가 있습니다.

https://github.com/bolthole/zrep

또한 크로스 플랫폼이기도 합니다. Linux, freebsd 및 Solaris/illumos에서 지원됩니다.

관련 정보