본문 바로가기

리눅스

[linux] 실시간 동기화 lsyncd / rsync / makuosan

 

후.. 리눅스 실시간 동기화..

1. 일단 실시간 동기화
  - NFS : 머라 말할 필요도 없는 그것!
  - DRBD : block 장치 수준에서 동작하며 스토리지 형태의 큰 대용량 파일을 동기화 할때 좋다.
               백업 데이타를 확인하지 못하고, 백업되는 상황만 확인할수 있다는 단점이 있다.
               속도에서 빠르나, 블록단위 백업이라 쓸모없는 것까지 백업되기도 한다.
  - rsync : 실시간이 될수 없다. 파일 개수가 많아질수록 속도가 늦어진다.

2. lsyncd 동기화 툴
 - 리눅스 커널의 inotify 로 파일시스템의 변경사항을 체크한다.
 - 변경사항이 생기자 마자, rsync 를 호출하여 상대 서버로 동기화를 한다.
   (반응 시간은 1초 미만, 전송속도는 네트워크 회선 속도와 파일 용량에 따라 틀림)

 inotify는 리눅스 커널에 포함된 기능으로, 파일 시스템에 변경사항이 발생할 때 이벤트를 통보해준다. 하지만 리눅스 커널
2.6.13 에서부터 기본으로 포함되어 있으므로, centos 5버전 이상에서만 디폴트로 가능하다는것을 알아두자.

3. 작동방식
  - src 서버에 lsyncd 데몬이 동작
  - dst 서버에 rsync 가 동작해야 함.

4. 설치
  - lsyncd 를 컴파일 하기 위해서는 libxml2-devel 패키지가 필요하다고 한다. 나는 그냥 설치되어 있던데 ㅋ
  - 다운로드 후 ./configure && make && make install 로 설치 끝

5. 사용법
  - conf 파일을 만들어 두는것이 편하다. (이거는 기본이다. 옵션이나 그런것은 알아서 조절하자)

 <lsyncd version="1">

<settings>

 <!--uncomment to log all debug messages.-->
 <!--debug/-->

 <!--uncomment to log only errors.-->
 <!--scarce/-->

 <!--uncomment to not detach, log to stdout/stderr.-->
 <!--no-daemon/-->

 <!--uncomment to not call any actions, run dry only.-->
 <!--dryrun/-->

 <!--uncomment to exclude file handled to rsync.-->
 <!--exclude-from filename="/tmp/exclude"/-->

 <logfile      filename="/var/log/lsyncd"/>
 <binary       filename="/usr/bin/rsync"/>
 <!--pidfile      filename="/var/run/lsyncd.pid"/-->

 <callopts>
  <option text="-avvr"/>
  <option text="--delete"/>
  <exclude-file/>
  <source/>
  <destination/>
 </callopts>
</settings>

<directory>
        <source path="/svc/lsyncd_test/"/>
        <target path="xxx.xxx.xxx.xxx::lsyncd/"/>
</directory>

</lsyncd>


  - 실행 방법
  lsyncd --conf 설정파일

  - dst 서버에서 rsync 를 설정해주고 /etc/rsyncd.conf 도 설정해 주자. 당연히 rsync 방화벽도 open !!

=================================================
localhost test
=================================================
1. 반응속도는 빠르다.
2. 데몬이 동작중일때 파일 생성, 수정, 삭제에 대해서 반응한다.
3. 데몬이 중단되었을때 일어나는 이벤트에 대해서는 다시 데몬이 동작하여도 감지 할수 없다.
4. src 와 dst 가 파일 내용이 틀린상황에서 src 에서 변화가 일어나면 dst 로 덮어씌우기가 된다.
  -> 결론은 무조건 src의 내용으로 동기화가 일어난다. (dst 에서의 변경내용은 사라진다)
5. 파일변경시 변경도중은 인식하지 못하고, 변경이 완료되어서 파일의 stat 상태가 변경되어야만 감지한다.
6. localhost 에서의 동기화는 rsync 사용시 rsync 의 특징으로 rsync 데몬이 떠잇거나 port 보안 설정등이 없어도 자연스럽게 된다. (rsync 설정도 필요없다. 근데 localhost 에서 이런거 동기화 할 이유가 있을까나?)
7. conf 파일 만들기 전에 lsyncd 명령어로 시작시 stop/start 스크립트가 먹히지 않는다.  원본글의 스크립트는 버리자

==============================================
target 서버를 지정할때 test
==============================================
백업 서버에 /etc/rsyncd.conf 설정할것

소스 서버에서 lsyncd 데몬 시작할것
conf 파일을 사용시 lsyncd --conf 설정파일  로 실행시킬경우 좋음

rync 옵션에서 기본 예제 옵션은 에러가 나서 avvr 로 로그 남기기로 변경하였음
로그 남기기로 변경하니 /var/log/lsyncd.log 에 rsync 로그가 남게 됨.

반응속도는 거의 순간적인듯 함

중간에 잠시 10초 정도 네트워크 접근이 불가 할경우.. 장애 해소시에 멈춘부분부터 계속 이어서 백업됨
rsync 의 트라이 회수 같은 설정이 있으면 그거의 영향일지도??

30분 정도의 장애를 산정하고 테스트 해봣더니 동기화가 일어나지 않았다. ;; 해결점을 찾아야 겟다
lsyncd 의 데몬이 내려간사이 변화가 있는 파일에 대해서는 감지하지 못한다. ;;
  -> 위에 2가지 상황 때문에 크론으로 일정 시간에 한번 rsync 로 동기화를 따로 해주던가 해야 할거 같다.

==================================================
makuosan
==================================================
특별히 src / dst 서버 구분이 없이 모든 서버에서 makuosan -b /디렉토리  로 데몬이 떠 잇어야 반응한다
host 1 < - > host 2 모두 양방향 반응을 할수 있다.
UDP 5000 포트를 사용하므로 전송속도는 빠르나, 신뢰성은 떠러진다.

파일 전송 명령어는
msync 파일
msync --delete -v -r 디렉토리 
등으로 전송 시작할수 있다.
아직까지 lsyncd 의 설정파일에 makuosan 을 연계할지 확인 못해봣다.
그냥 rsync 가 더 나아 보이기도 한다..  1:1 미러 싸이트의 웹소스 미러링 같은경우는 rsync 가 더 효율적일거 같다.

 아래는 해당 데몬에 대한 자세한 설명이 되어있는 커피닉스 싸이트의 좋은진호님 글이다
http://coffeenix.net/board_view.php?bd_code=1696

 제  목 : lsyncd로 서버간 파일을 실시간으로 동기화해보자.
작성자 : 좋은진호(truefeel, http://coffeenix.net/ )
작성일 : 2009.12.4(금)
수정일 : 2009.12.7(월)  퍼미션까지 동기화 추가
수정일 : 2009.12.13(일) '5. 주의할 점' 추가

- 거의 실시간으로 서버간의 파일 동기화가 필요한 경우라면 어떻게 해야할까?
- 실시간으로 백업을 하고 싶다면?

서버간의 파일 동기화를 위해서는 3가지 방법을 생각해볼 수 있다.

1. NFS를 이용한다.
2. A, B, C서버를 동기화하려고 할 때, 원본 데이터를 D서버(배포용 서버)에 넣어둔다. 그리고 D 서버에서 A, B, C서버로 rsync, makuosan툴 등으로 동기화 한다. (D 서버 -> A, B, C 서버로 동기화)
3. DRBD(Distributed Replicated Block Device)를 구축한다.


1. lsyncd 동기화 툴

위의 방법을 이용하지 않고, 한 서버의 변경사항을 다른 서버로 실시간으로 동기화시키는 흥미로운 툴이 있다. 바로 실시간 싱크 프로그램인 lsyncd이 그 주인공.

lsyncd - Live Syncing (Mirror) Daemon
http://code.google.com/p/lsyncd/

1) lsyncd의 원리는 간단하다.

- 리눅스 커널의 inotify로 파일시스템의 변경사항을 체크한다.          (판단은 inotify로)
- 변경사항이 생기자마자, rsync를 호출하여 상대 서버로 싱크를 해준다. (동기화는 rsync로)

inotify는 리눅스 커널에 포함된 기능으로, 파일시스템에 변경사항이 발생할 때 이벤트를 통보해준다. 이 inotify를 이용하게 되면, 파일 변경사항을 수시로 파악할 필요없이 가만히 앉아있으면 된다. 파일이 바뀔 때 커널에서 통보해주는 신호를 덥석 받아먹으면 되기 때문이다.

0.5초(0.5초는 그만큼 짧다는 것을 표현하기 위해서 사용했음)도 안되는 아주 짧은 시간 동안의 차이는 생길 수 있지만, 소규모 서버를 운영할 경우에는 무리가 없을 것으로 보인다.

2) 원본 서버와 동기화 대상 서버(target)간의 구조

 

- 원본 데이터가 있는 서버(1대의 서버)에는 lsyncd 데몬(lsyncd 데몬 + rsync 클라이언트)이 동작하게 되고,
- 동기화 대상 서버(다수의 서버)에는 rsync 데몬(rsync 서버)이 띄워져 있어야 한다.

3) lsyncd master서버에서 필요 환경은 다음과 같다. 대상 서버는 rsync만 동작하면 OS종류, 버전에 상관없다.

- Linux Kernel 2.6.13 이상 (inotify를 위해)
- rsync 프로그램
- lsyncd 컴파일을 위해서 libxml2가 필요하다.
  CentOS : libxml2-devel 패키지
  Ubuntu : libxml2-dev   패키지

4) 어떤 경우 유용할까?


소규모 사이트에서 NFS대신하여 동기화를 고민할 때. (단, 파일이 너무 많으면 동기화가 늦어질 수 있음)
실시간 백업이 필요할 때.
대규모 웹사이트에서 메인페이지나 대메뉴의 첫페이지 등 유저 접속이 많다.
이 페이지에서 실시간으로 변경되는 데이터를 매번 DB접속하여 처리하는 것은 좋지 않다.
실시간 데이터를 1분 또는 더 짧은 간격으로 텍스트로 저장하고, 변경이 되자마자 자동 동기화 되도록 처리할 때.
규모가 크면 1차 master -> 2차 여러대의 master -> 상당수의 서비스 서버의 구조가 될 수도 있다.

 

2. lsyncd를 이용한 실시간 동기화

기본 형식은 다음과 같다.

  
lsyncd [SOURCE] [TARGET 1] [TARGET 2] ....
 


다음은 간단한 사용 예이다. lsyncd은 rsync를 사용하여 동기화하므로, TARGET은 rsync처럼 1) 로컬 디렉토리를 지정할 수도 있으며, 2) 원격지의 rsync 경로도 가능하다. TARGET을 다수 지정하게 되면 여러 서버로 실시간 동기화가 이뤄진다.

  
# ./lsyncd /home/cnx/ /data/backup/
# ./lsyncd /home/cnx/ 192.168.123.3::backup/
# ./lsyncd /home/cnx/ 192.168.123.3::backup/ 192.168.123.4::backup/
 


lsyncd는 기본적으로 daemon형태로 실행되며, /var/log/lsyncd 파일에 로그가 저장된다. 다음은 테스트를 위해서 --no-daemon옵션을 넣고 실행했다. 로그를 살펴보면 다음과 같은 사항을 파악할 수 있다.


어디에서 어디로 동기화가 되는지 확인할 수 있다. ( syncing /home/cnx/ -> 192.168.123.3::backup/ )
16개 디렉토리( /home/cnx/ + 15개의 서브디렉토리 )를 모니터링한다. ( [16] monitored directories )
truefeel.txt 파일이 생성되자마자 rsync를 호출하여 동기화된다.
서브 디렉토리( /home/cnx/docs/ ) 내의 파일이 변경된 경우 그 디렉토리만 동기화한다. ( rsyncing /home/cnx/docs/ --> 192.168.123.3::backup/docs/ ) 전체 디렉토리를 동기화하지 않기 때문에 그 만큼 동기화 시간이 빨라진다.


  
# ./lsyncd --no-daemon /home/cnx/ 192.168.123.3::backup/
Fri Dec  4 18:13:13 2009: command line options: syncing /home/cnx/ -> 192.168.123.3::backup/

Fri Dec  4 18:13:13 2009: Starting up
Fri Dec  4 18:13:13 2009: watching /home/cnx/
Fri Dec  4 18:13:13 2009: found new directory: ?????? in /home/cnx/ -- added on tosync stack.
Fri Dec  4 18:13:13 2009: found new directory: ?????? in /home/cnx/ -- added on tosync stack.
... 생략 ...
Fri Dec  4 18:13:13 2009: --- Entering normal operation with [16] monitored directories ---
Fri Dec  4 18:14:40 2009: event CREATE:truefeel.txt triggered.
Fri Dec  4 18:14:40 2009: rsyncing /home/cnx/ --> 192.168.123.3::backup/
Fri Dec  4 18:14:40 2009: event CLOSE_WRITE:truefeel.txt triggered.
Fri Dec  4 18:14:40 2009: rsyncing /home/cnx/ --> 192.168.123.3::backup/
Fri Dec  4 18:16:22 2009: event CREATE:vimcheatsheet.pdf triggered.
Fri Dec  4 18:16:22 2009: rsyncing /home/cnx/docs/ --> 192.168.123.3::backup/docs/
Fri Dec  4 18:16:22 2009: event CLOSE_WRITE:vimcheatsheet.pdf triggered.
Fri Dec  4 18:16:22 2009: rsyncing /home/cnx/docs/ --> 192.168.123.3::backup/docs/
 


다음은 TARGET을 2곳으로 지정했을 때 동기화 결과이다.

  
Fri Dec  4 19:04:37 2009: event CREATE:cnx.txt triggered.
Fri Dec  4 19:04:37 2009: rsyncing /home/cnx/ --> 192.168.123.3::backup/
Fri Dec  4 19:04:37 2009: rsyncing /home/cnx/ --> 192.168.123.4::backup/
Fri Dec  4 19:04:37 2009: event CLOSE_WRITE:cnx.txt triggered.
Fri Dec  4 19:04:37 2009: rsyncing /home/cnx/ --> 192.168.123.3::backup/
Fri Dec  4 19:04:37 2009: rsyncing /home/cnx/ --> 192.168.123.4::backup/
 

 

3. lsyncd config 파일

lsyncd.conf 샘플 설정 파일이다.

* lsyncd.conf 샘플 내려받기
  
<lsyncd version="1">

<settings>
   <!--uncomment to log all debug messages.-->
   <!--debug/-->
   
   <!--uncomment to log only errors.-->
   <!--scarce/-->
   
   <!--uncomment to not detach, log to stdout/stderr.-->
   <!--no-daemon/-->

   <!--uncomment to not call any actions, run dry only.-->
   <!--dryrun/-->

   <!--uncomment to exclude file handled to rsync.-->
   <!--exclude-from filename="/tmp/exclude"/-->

   <logfile      filename="/var/log/lsyncd"/>
   <binary       filename="/usr/bin/rsync"/>
   <!--pidfile      filename="/var/run/lsyncd.pid"/-->

   <callopts>
      <option text="-ltogp%r"/>
      <option text="--delete"/>
      <exclude-file/>
      <source/>
      <destination/>
   </callopts>
</settings>

<directory>
   <source path="/home/cnx/"/>
   <target path="192.168.123.3::backup/"/>
   <target path="192.168.123.4::backup/"/>
</directory>

</lsyncd>
 


<settings> 의 설정에는 다음 항목들이 있다.


debug     : debug mode로 실행한다. 상세한 로그가 남는다. 적용하려면 <debug/> 처럼 설정한다.
scarce    : debug와는 반대되는 개념. 에러만 로그에 남긴다.
no-daemon : 데몬형태로 실행하지 않으며, 로그는 화면에 바로 출력된다.
dryrun    : 실제 적용하지는 않는다 어떻게 동작하는지 로그에만 남기고, 동기화(rsync)는 실행하지 않는다.
exclude-from : 제외할 목록이 들어있는 파일명을 지정한다.
logfile   : 로그 파일명
binary    : rsync의 경로
pidfile   : PID 파일명
callopts  : rsync 호출할 때 사용할 옵션을 지정한다.


<directory> 은 따로 설명하지 않아도 바로 이해가 될 것이다. 대상 서버가 많으면 쭈욱 나열해주면 된다.

  
# ./lsyncd --conf lsyncd.conf
 

 

4. lsyncd 깊이 알기

1) 특정 서브 디렉토리나 파일을 제외(exclude)하려면?

lsyncd는 동기화에서 제외할 디렉토리 목록을 '--exclude-from FILE' 옵션으로 지정할 수 있다. lsyncd_exclude.lst 파일에 아래 내용을 넣으면 2개 디렉토리를 제외하게 된다. 특정 파일만 제외할 수는 없다. 디렉토리만 지정이 가능하다. 제외한 디렉토리는 rsync할 때 제외되는 것이 아니라, inotify의 모니터링 대상 자체에서 빠진다. 빠진 디렉토리수(서브디렉토리도 있다면 그 것도 포함)만큼 'Entering normal operation with [??] monitored directories' 로그에 남으니, 계산해보면 확인이 될 것이다.

  
doc/
photo/
 


config파일에서 설정하려면 다음과 같이 한다.

  
<exclude-from filename="/etc/lsyncd_exclude.lst"/>
 


디렉토리가 아닌 파일을 동기화 대상에서 제외하려면 어떻게 해야할까? rsync 옵션을 활용해야 한다. rsync의 --exclude-from=FILE 옵션이 있다. 파일(예. lsyncd_file_exclude.lst) 에 제외할 파일목록을 넣는다. 그리고, config 파일의  rsync옵션부분에 다음을 추가하면 된다.

  
<option text="--exclude-from=/etc/lsyncd_file_exclude.lst"/>
 


파일 제외할 때 주의할 것은 서브 디렉토리에 같은 파일명이 있을 때도 제외될 수 있다. 만약 lsyncd_file_exclude.lst에 cnx.doc 을 지정했다고 하자. 그러나 우연찮게 lib/cnx.doc 파일이 실제 존재할 때 lib/cnx.doc 파일이 변경되어도 동기화 안될 수 있다.

2) 퍼미션, 소유자까지 변경하려면?

lsyncd는 퍼미션과 소유자의 변경은 무시하도록 되어 있다. debug 모드로 살펴보면 로그에 다음과 같이 남는다.

  
Fri Dec  4 19:13:18 2009: inotfy event: ATTRIB:cnx.txt
Fri Dec  4 19:13:18 2009: ... ignored this event.
Fri Dec  4 19:13:18 2009: Processing through tosync stack.
Fri Dec  4 19:13:18 2009: being done with tosync stack
 


파일 속성 변경까지 동기화하기 위해서는 lsyncd.c 소스 수정이 필요하다. 1131번째줄에서 IN_ATTRIB를 추가해주면 파일속성 변경시 동기화된다.

  
        if ((IN_CREATE | IN_CLOSE_WRITE | IN_DELETE |
             IN_MOVED_TO | IN_MOVED_FROM | IN_ATTRIB ) & event->mask
 


그리고, config파일에서 rsync 옵션 변경이 필요하다. <callopts> 에서 <option text="-lt%r"/> 대신 <option text="-ltogp%r"/>로 변경한다. o는 소유자 유지, g는 소유그룹 유지, p는 퍼미션 유지.

3) lsyncd가 rsync를 어떻게 호출하는지 궁금하다?

lsyncd가 실행되는 서버에서 다음 스크립트를 실행한다. 파일변경시 즉시 실행되는 rsync 명령을 확인할 수 있다.

  
#!/bin/bash

while [ 1 ]
do
   date +'%H:%M:%S'
   ps auxww|grep [r]sync
   sleep 0.05
done
 


rsync가 호출되는 순간에 다음과 같이 화면에 출력될 것이다.

  
19:19:46
19:19:46
root      4076  0.0  0.0   5812  1036 ?        S    19:19   0:00 /usr/bin/rsync -ltogpd --delete /home/cnx/docs/ 192.168.123.3::backup/docs/
 


4) rsync 대신 다른 동기화 프로그램 호출

lsyncd는 rsync의 경로를 --binary 옵션이나 config에서 설정할 수 있다. 따라서 이 경로를 수정하게 되면 rsync를 직접 호출하지 않고, 스크립트를 통해 호출할 수가 있다. 그래서 동기화할 때 ① 원하는 명령을 실행할 수도 있고, ③ rsync 대신 다른 동기화 프로그램도 사용할 수가 있게 된다.

일본 KLAB에서 만든 동기화 툴인 Makuosan( http://lab.klab.org/wiki/Makuosan )이 있다. 이 툴은 동기화 서버가 1대이든 몇십대이든 속도 저하없이 거의 동시에 동기화된다. 이 툴을 이용하여 스크립트를 만든다면 재밌는 조합( lsyncd + Makuosan )이 될 것이다. 실시간 파일 변경 판단은 lsyncd로 하고, 동기화는 빠른 Makuosan로 이뤄지는 것이다.

참고로 rsync를 스크립트로 만든 경우는 http://code.google.com/p/lsyncd/wiki/HowToExecAfter 를 읽어보기 바란다.


5. 주의할 점

DB 파일, log 파일처럼 파일이 계속 active된 상태로 변경되는 디렉토리에는 사용하지 않는다.
파일 변화가 상당히 잦을 디렉토리에는 사용하지 않는다.
한 개의 디렉토리 내에 파일이 너무 많으면 동기화가 느려질 수 있다.
파일이 큰 파일(몇 백메가 또는 몇 기가)이 변경될 경우 동기화가 느려질 수 있다. 또한 이렇게 큰 파일의 변경이 잦으면 제외해주는 것이 좋다.
lsyncd가 파일 변화를 모니터링할 수 있는 디렉토리 갯수는 최대 8192개이다.


lsyncd는 기본적으로 소유자와 퍼미션 변경은 동기화하지 않는다. 속성 변경까지 동기화하기 위해서는 '4. lsyncd 깊이 알기'의 '2) 퍼미션, 소유자까지 변경하려면?'를 살펴보기 바란다.


※ '범냉이'의 제안으로 '주의할 점' 추가함.

6. 참고 자료

* lsyncd wiki
  http://code.google.com/p/lsyncd/w/list

* inotify로 파일 시스템 활동 감시하기
  http://www.ibm.com/developerworks/kr/library/l-ubuntu-inotify/index.html
* inotify
  http://ko.wikipedia.org/wiki/Inotify

* Rsync를 이용한 데이터 미러링 구축  (2004.1, 글 굿스피드)
  http://coffeenix.net/board_view.php?bd_code=166
* rsync의 write only 기능(쓰기만 가능한 설정) (2004.12, 글 좋은진호)
  http://coffeenix.net/board_view.php?bd_code=616
* 자료를 다른 파티션으로 그대로 백업(rsync이용) (2003.10, 글 좋은진호)
  http://coffeenix.net/board_view.php?bd_code=88
* rsync 활용(대역폭제한, 날짜별sync 등)  (2006.6, 글 좋은진호)
  http://coffeenix.net/board_view.php?bd_code=1418