ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 파일 싱크 자동화를 위한 incrontab 스크립트 개발(feat. git->s3)
    개발Tip 2022. 12. 26. 21:32
    728x90

     

     

    도입배경

    Airflow에서 실행하는 ETL pyspark 스크립트를 s3 버킷에 저장해두고 사용중이었는데, 

    그러면 매번 수동으로 파일을 upload해야하고, 파일의 히스토리 및 버전 관리의 필요성을 느낌.

    따라서 Git에 파일을 올리고, s3에도 자동으로 업데이트 해주어 싱크를 맞출 수 있는 자동화 시스템을 구현할 수 있는 방법 모색함.

     

    이때 고려했던 점은, 현재 회사에서 bitbucket server를 사용중이므로 GitHub Action를 사용할 수 없었고 

    Jenkins를 사용해보려고 했으나, 이전에 써보지 않았으므로 러닝커브를 고려하여

    구글링을 통해 알게된 incrontab으로 간단하게 스크립트로 짜서 구현하기로함.

     

     

    개발과정

    1. 로컬에서 git에 etl 파일 업도르하면, Airflow 서버에서 crontab으로 1분마다 git pull 땡겨오기

    2. incrontab으로 파일의 변경점 감지하기

    3. 변경된 파일을 s3에 자동 업로드하는 로직

     

    [incrontab으로 예약걸기]

    • incrontab 설치 
    $ sudo apt install incron

     

    $ incrontab -l
    
    user 'ubuntu' is not allowed to use incron
    

     

    유저 권한이 없다고 나오면 권한 추가해주기👇

    $ vi /etc/incron.allow
    
    root
    ubuntu
    

     

    $ incrontab -e
    

    incrontab을 수정(edit)하기 위한 명령어로, 기본 에디터인 vim을 vi 로 변경해준다.

    $ vi /etc/incron.conf
    
    # editor = nano
    
    editor = vi
    

     

     

    upload를 위한 .sh 파일을 생성하고, incrontab으로 자동 실행하게 하려면 파일 실행을 위한 권한을 줘야함.

    $ chmod +x 파일명(xxx.sh)

     

     

    • incrontab 설정
    # incrontab -e
    /home/ubuntu/airflow/git_airflow_dir  IN_MODIFY  /home/ubuntu/airflow/s3_upload.sh $#
    => 꼭 절대경로로 입력하기!!

     

    incrontab edit에 들어가서 1. 어떤 디렉토리 경로에 2. 어떤 변화가 있을 때 3. 어떤 액션을 할 것인지를 정의합니다.

    여기서 중요한 점은 꼭 절대경로로 입력할 것!

     

    즉, git_airflow repo 디렉토리에 파일이 추가되는 것을 IN_MODIFY로 감지한 후

    같은 디렉토리에 있는 s3_upload.sh라는 파일을 자동으로 실행하라는 명령어 입니다.

     

    이 파일은 s3에 방금 새롭게 업데이트 된 파일(신규 or 수정)을 s3에 업로드 해야하므로 정확한 대상 파일명이 필요합니다. 

    따라서 마지막에 $#event-related file name를 뜻하는 wildcard로 변화된 해당 파일의 이름을 인자값으로 전달해줍니다.

     

    • s3_upload.sh 스크립트 작성
    echo "$1 $(date)" >> ~/airflow/print.txt
    aws s3 cp ~/airflow/git_airflow_dir/$1 s3://airflow-emr-load-test/script_file_test/ >> ~/airflow/s3_upload_log.txt

     

    변경된 파일명이 인자값으로 잘 전달 되었는지 print.txt 파일로 print하여 확인하기.

    test용으로 생성한 s3 버킷에 변경된 파일 업로드 하고 s3_upload_log.txt 파일로 로그 확인하기.

     

    • s3_upload_log.txt
    upload: home/ubuntu/airflow/git_airflow_dir/config.py to s3://airflow-emr-load-test/script_file_test/config.py
    upload: home/ubuntu/airflow/git_airflow_dir/abc.py to s3://airflow-emr-load-test/script_file_test/abc.py

     

    s3에 파일이 정상적으로 올라간 로그 확인 완료!

     

    - 이상 개별 파일 변화 감지 후 s3 업로드 방법이었고, 이제 git repo 전체의 변경점을 반영하는 방법을 알아보겠습니다.

     


     

     

    [git repo 전체 변경 반영]

    • incrontab -e
    /home/ubuntu/airflow/git_airflow_dir/ IN_MODIFY,IN_DELETE /home/ubuntu/airflow/s3_update.sh $% $@ $#
    • s3_update.sh
    if [$1 == 'IN_MODIFY'] # 꼭 대괄호로 묶어주기! => 아닐 시 error 발생
    then
      echo "$1 IN_MODIFY YES" >> ~/airflow/print.txt
      aws s3 cp $2/$3 s3://airflow-emr-load-test/script_file_test/ >> ~/airflow/shell_log.txt
    else
      echo "$1 IN_DELETE YES" >> ~/airflow/print.txt
      aws s3 rm s3://airflow-emr-load-test/script_file_test/$3 >> ~/airflow/shell_log.txt
    fi

    success

     

    • git으로 shell script 파일 관리할 때, 실행 권한 준 상태로 push 하기
    git config core.filemode false
    
    git update-index --chmod=+x s3_update.sh
    git commit -am"Executable!"
    
    git ls-files --stage
    

     

     

    각 파일 권한 체크

    git pull => incrontab run 'file write' shell script=> file write => run 's3_upload' shell script => upload run

    1. 각자 파일 탐지 -> 각자 파일 upload
    2. 전체 디렉토리 탐지 -> 전체 디렉토리 upload

     

    s3를 업데이트 할 수 있는 2가지 방법:

    1. 디렉토리 전체 update => 변경 없는 파일들도 계속 append
    2. 개별 파일 update => delete한 파일들은 s3에 남아있음

     

    <file 변경 시 미반영 문제>

    • 파일 변경 시 Delete, Create, Modify event 발생
    • lazy execution(?) 실행으로 Delete event가 제일 마지막에 발생하는 문제 => 파일 추가해 놓고 지워버림.
    • 해결책:
      1. 파일 변경 시, 먼저 삭제 후 새 파일에서 수정 후 push(Delete => Create => Modify 순)
      2. list에 event들 저장 후 마지막 이벤트만 실행 => 10초 sleep?

    https://wiki.encar.io/pages/viewpage.action?pageId=83359786

     


    [최종버전 정리]

    1. incrontab 설정(개별 파일 감지)

    /home/ubuntu/airflow/git_airflow_dir/ IN_MODIFY /home/ubuntu/airflow/s3_upload.sh $#

    1-1. incrontab 설정(추가/삭제)

    /home/ubuntu/airflow/git_airflow_dir/ IN_CREATE,IN_DELETE /home/ubuntu/airflow/s3_update.sh $% $@ $#

     

     

    2. s3_upload.sh(개별 파일 upload)

    aws s3 cp ~/airflow/git_airflow_dir/$1 s3://airflow-emr-load-test/script_file_test/

    2-2. s3_upload.sh(추가/삭제)

    # directory&file delete
    if [ $1 == 'IN_DELETE' ]
    then
    aws s3 rm s3://airflow-emr-load-test/script_file/$3 >> ~/airflow/s3_update.log
    # file add/modify
    elif [ $1 == 'IN_CREATE' ]
    then
     sleep 15s
     aws s3 cp $2/$3s3://airflow-emr-load-test/script_file/ >> ~/airflow/s3_update.log
    
    # directory&file ADD
    elif [ $1 == 'IN_CREATE,IN_ISDIR' ]
    then
     aws s3 sync $2/$3s3://airflow-emr-load-test/script_file/ >> ~/airflow/s3_update.log
    
    fi

     

    * sleep 15s: 파일 변경 시 Delete → Modify → Create 순으로 incrontab event 작동 구현

    => 파일 upload(IN_CREATE) 시 sleep을 걸어서 delete 먼저 실행 후 upload를 실행하게 함.

     

     

    ref.

    https://linux.die.net/man/5/incrontab

     

     

     

    댓글

Designed by Tistory.