Skip to content

Instantly share code, notes, and snippets.

@lionants02
Last active October 27, 2024 08:43
Show Gist options
  • Save lionants02/32071dc0ce2f509593411d32e4c1510b to your computer and use it in GitHub Desktop.
Save lionants02/32071dc0ce2f509593411d32e4c1510b to your computer and use it in GitHub Desktop.
แนวทางการใช้ rsync กับไฟล์ปริมาณมาก

script

ตัวอย่างงาน
ผมต้องการ Bakcup ไฟล์จาก โฟเดอร์ uploads ที่มีไฟล์จำนวนมาก หลายล้านไฟล์ ไปยังปลายทางที่เป็นสื่อบันทึกความเร็วต่ำ

สิ่งที่ต้องรู้

  • สื่อบันทึกความเร็วต่ำที่ผมใช้เป็น HDD จานหมุน ถ้านำไฟล์หลายล้านไฟล์ไปรวมกันอยู่โฟเดอร์เดียว เครื่องน่าจะไม่ไหวต้องใช้วิธีแบ่งแยกย่อย
  • ต้องการมีบันทึกว่า ส่วนไหนย้ายสำเร็จแล้ว เพื่อที่จะได้เช็คตามหลัง หรือ รันซ้ำเฉพาะกลุ่มที่ไม่สำเร็จได้
  • ไม่เอาไฟล์ที่เป็น thumbnail
  1. สร้างรายการไฟล์โดยแบ่งเป็นช่วง ในที่นี้แบ่งทีละ 3000 ไฟล์ หรือตามที่ต้องการ
  • สร้างรายการไฟล์ทั้งหมด และไม่เอาชื่อไฟล์ที่มีคำว่า thumbnail
    mkdir filelist_upload
    cd uploads
    find ./ -type f | awk '!/thumbnail/'  > ../fulllist.txt
    cd ..
  • ก่อนใช้คำสั่งแบ่งรายการไฟล์ สามารถเอา fulllist.txt ไปเช็คกับอันที่เคยทำไปก่อนหน้าได้ เพื่อเอาเฉพาะไฟล์ที่เพิ่มเข้ามาใหม่ได้
  • แบ่งรายการชื่อไฟล์ เป็นไฟล์ละ 3000 รายชื่อไว้ที่ filelist_upload/filelist_xxx โดยที่ xxx ระบบจะเติ่มให้เองอัตโนมัติเป็นรูปแบบ aa to zzzzzzzzz
    split -l 3000 fulllist.txt filelist_upload/filelist_
  1. สร้างคำสั่ง sync.sh ด้วย command ด้านล่าง
    ระวังหาก run command นี้ซ้ำอาจมีไฟล์ sync.sh หลงเข้ามาใน sync.sh ก็ต้องลบออกด้วยไม่งั้นสริปจะติด loop ไปเรียกตัวเองซ้ำเรือยๆ
    cd filelist_upload
    ls -1 |awk -F: '{printf "./bp3 %s\n",$1}' > sync.sh
  • อย่าลืมเก็บไฟล์ fulllist.txt ที่สร้างในตอนแรกไว้ด้วย สามารถเอาไปทำ ETL เพื่อคัดไม่ให้ backup ไฟล์ซ้ำได้ในอนาคต หรือ นำไปเช็คได้ว่าไฟล์ไหนเคยทำการ backup ไปแล้ว
    mv ../fulllist.txt ./
  1. เตรียมไฟล์สำหรับช่วยในการทำสริปย่อย ในที่นี้จะใช้ชื่อว่า bp3
    อธิบาย ตัวอย่างไรไฟล์ bp3 ตัวนี้จะถูกปรับ rsync ให้ทำงานได้เร็วและไม่ต้องสนใจอะไรมาก และมีการเก็บ log ของชุดไฟล์ที่ rsync ทำสำเร็จไว้ใน log3.txt
    จำเป็นต้องใช้คำสั่ง rsync เป็นเพราะว่า ต้องแก้ไขปลายทาง และต้นทาง
  • bp3
    echo "command ./bp3.sh $1"
    date
    time rsync -r --size-only --no-perms --no-owner --no-group -e 'ssh -p 22 -i /home/xxx/.ssh/no-p' --files-from=$1 --info=progress2 --stats --human-readable source@source_ip_domain:/home/xxx/app/uploads/ /mnt/h/uploads-$1/ && echo "$1 done" >> log3.txt
    date
  1. อย่าลืมย้ายโฟเดอร์ filelist_upload ที่มีคำสั่งและ config ต่างๆ มายังเครื่องปลายทาง หรือ ปรับแต่งตามสะดวก
  2. อย่าลืม
    chmod +x bp3 sync.sh
  3. รันคำสั่ง ./sync.sh

sync.sh

ไฟล์คำสั่งที่จะให้ทำงาน สำหรับการรันซ้ำในเวลาอื่น เช่น VPN หลุดแล้วจะรันซ้ำ อันไหนสำเร็จแล้วก็ ลบๆไปบ้างก็ได้ จะได้เริ่มทำงานใหม่ได้เร็วๆ ไม่ต้องเสียเวลาไปเช็คกลุ่มที่สำเร็จแล้วซ้ำ

log3.txt

สำหรับไฟล์ log3.txt จะถูกสร้างขึ้นอัตโนมัติ ตามตัวอย่างไฟล์ที่แนบมา เรียกไปเรื่อยๆ ด้วย a - z วนไฟเรื่อยๆ หากอันไหนไม่สำเร็จจะไม่มีอยู่ในนี้ ก็ไป run ตัวนั้นซ้ำตามหลังได้ เทคนิคที่ผมใช้คือ หา z อันสุดท้าย หารด้วย 26 ถ้าไม่มีเศษก็ถือว่าครบ บลาๆๆๆๆ

filelist_aa done
filelist_ab done
filelist_ac done
filelist_ad done
filelist_ae done
filelist_af done
filelist_ag done
filelist_ah done
filelist_ai done
filelist_aj done
filelist_ak done
filelist_al done
filelist_am done
filelist_an done
filelist_ao done
filelist_ap done
filelist_aq done
filelist_ar done
filelist_as done
filelist_at done
filelist_au done
filelist_av done
filelist_aw done
filelist_ax done
filelist_ay done
filelist_az done
filelist_ba done
filelist_bb done
filelist_bc done
filelist_bd done
filelist_be done
filelist_bf done
filelist_bg done
filelist_bh done
filelist_bi done
filelist_bj done
filelist_bk done
trap "exit 1" SIGINT ERR
./bp3 filelist_se
./bp3 filelist_sf
./bp3 filelist_sg
./bp3 filelist_sh
./bp3 filelist_si
./bp3 filelist_sj
./bp3 filelist_sk
./bp3 filelist_sl
./bp3 filelist_sm
./bp3 filelist_sn
./bp3 filelist_so
./bp3 filelist_sp
./bp3 filelist_sq
./bp3 filelist_sr
./bp3 filelist_ss
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment