พฤติกรรมของ rsync กับไฟล์ที่ยังเขียนอยู่?


12

หาก Apache อยู่ระหว่างการเขียนไฟล์ขนาดใหญ่และงาน rsync cron ทำงานบนไฟล์นั้น rsync จะพยายามคัดลอกไฟล์หรือไม่?

ตัวอย่าง

  • Apache-1: /var/wwwมีไฟล์ที่มีขนาดใหญ่เป็นลายลักษณ์อักษรไปยัง
  • Apache-2: Clone of Apache-1 ทุกห้านาทีมี cron รัน rsync เพื่อ/var/wwwซิงค์

คำตอบ:


20

หาก Apache กำลังเขียนไฟล์บางชนิดไปยังที่เดียวและยังเขียนไม่เสร็จและ rsyncเริ่มเล่นใหม่rsyncจะคัดลอกไฟล์ที่อยู่ในนั้น

หมายความว่าหาก Apache กำลังจัดการกับไฟล์ 5MB จะมีเพียง 2MB เท่านั้นที่เขียนและrsyncเริ่มทำงานไฟล์ 2MB บางส่วนจะถูกคัดลอก ดังนั้นไฟล์นั้นจะดูเหมือนว่า“ เสียหาย” บนเซิร์ฟเวอร์ปลายทาง

ขึ้นอยู่กับขนาดของไฟล์ที่คุณใช้คุณสามารถใช้--inplaceตัวเลือกในrsyncการทำสิ่งต่อไปนี้:

ตัวเลือกนี้จะเปลี่ยนวิธีการถ่ายโอนไฟล์ rsync เมื่อข้อมูลของไฟล์จำเป็นต้องได้รับการอัปเดต: แทนที่จะเป็นวิธีการเริ่มต้นในการสร้างสำเนาใหม่ของไฟล์และย้ายไปยังตำแหน่งเมื่อเสร็จสมบูรณ์ rsync จะเขียนข้อมูลที่อัพเดทโดยตรงไปยังปลายทางแทน ไฟล์.

ประโยชน์ของการทำเช่นนี้คือหากไฟล์ 5MB มีการคัดลอกเพียง 2MB ในการเรียกใช้ครั้งแรกการเรียกใช้ครั้งต่อไปจะรับที่ 2MB และทำการคัดลอกไฟล์ต่อไปจนกว่าจะมีการใช้งาน 5MB แบบเต็ม

ข้อเสียคือสามารถสร้างสถานการณ์ที่มีคนกำลังเข้าถึงเว็บเซิร์ฟเวอร์ในขณะที่กำลังคัดลอกไฟล์จากนั้นพวกเขาจะเห็นไฟล์บางส่วน ในความคิดของฉันrsyncทำงานได้ดีที่สุดเพราะเป็นพฤติกรรมเริ่มต้นของการแคชไฟล์ "ที่มองไม่เห็น" จากนั้นย้ายไปไว้ที่เดิม แต่--inplaceจะดีสำหรับสถานการณ์ที่ไฟล์ขนาดใหญ่และข้อ จำกัด แบนด์วิดท์อาจยืนในทางของไฟล์ขนาดใหญ่ที่ถูกคัดลอกได้อย่างง่ายดายจากตารางที่หนึ่ง

ที่กล่าวว่าคุณทำรัฐนี้ เน้นเป็นของฉัน:

ทุกๆห้านาทีมี cron run rsync ...

ดังนั้นฉันคิดว่าคุณมีสคริปต์ทุบตีเพื่อจัดการงาน cron นี้หรือไม่ สิ่งนี้rsyncฉลาดพอที่จะคัดลอกเฉพาะไฟล์ที่จำเป็นต้องคัดลอกเท่านั้น และถ้าคุณมีสคริปต์ที่ทำงานทุก 5 นาทีดูเหมือนว่าคุณกำลังพยายามหลีกเลี่ยงrsyncขั้นตอนซึ่งกันและกันหากสคริปต์ทำงานได้เร็วขึ้น หมายความว่าหากคุณใช้งานทุกนาทีมีความเสี่ยงที่กระบวนการอย่างน้อยหนึ่งrsyncกระบวนการยังคงทำงานเนื่องจากขนาดไฟล์หรือความเร็วเครือข่ายและกระบวนการถัดไปจะเป็นการแข่งขันกับมัน สภาพการแข่งรถ

วิธีหนึ่งในการหลีกเลี่ยงปัญหานี้คือการห่อrsyncคำสั่งทั้งหมดของคุณในสคริปต์ทุบตีที่ตรวจสอบการล็อกไฟล์ ด้านล่างเป็นกรอบสคริปต์ทุบตีสำเร็จรูปที่ฉันใช้สำหรับกรณีเช่นนี้

โปรดทราบว่าบางคนจะแนะนำให้ใช้flockแต่เนื่องจากflockไม่ได้ติดตั้งในบางระบบที่ฉันใช้ - และฉันกระโดดระหว่าง Ubuntu (ซึ่งมี) และ Mac OS X (ซึ่งไม่ได้) มากฉันใช้กรอบง่าย ๆ นี้โดยไม่มีปัญหาจริง:

LOCK_NAME="MY_GREAT_BASH_SCRIPT"
LOCK_DIR='/tmp/'${LOCK_NAME}.lock
PID_FILE=${LOCK_DIR}'/'${LOCK_NAME}'.pid'

if mkdir ${LOCK_DIR} 2>/dev/null; then
  # If the ${LOCK_DIR} doesn't exist, then start working & store the ${PID_FILE}
  echo $$ > ${PID_FILE}

  echo "Hello world!"

  rm -rf ${LOCK_DIR}
  exit
else
  if [ -f ${PID_FILE} ] && kill -0 $(cat ${PID_FILE}) 2>/dev/null; then
    # Confirm that the process file exists & a process
    # with that PID is truly running.
    echo "Running [PID "$(cat ${PID_FILE})"]" >&2
    exit
  else
    # If the process is not running, yet there is a PID file--like in the case
    # of a crash or sudden reboot--then get rid of the ${LOCK_DIR}
    rm -rf ${LOCK_DIR}
    exit
  fi
fi

ความคิดคือแกนกลางทั่วไป - ที่ฉันมีecho "Hello world!"- เป็นหัวใจของสคริปต์ของคุณ ส่วนที่เหลือของมันนั้นเป็นกลไกการล็อค / mkdirตรรกะขึ้นอยู่กับ คำอธิบายที่ดีของแนวคิดอยู่ในคำตอบนี้ :

mkdirสร้างไดเรกทอรีถ้ามันยังไม่มีอยู่และถ้ามันทำมันจะตั้งรหัสทางออก ที่สำคัญมันทำสิ่งนี้ทั้งหมดในการกระทำปรมาณูเดียวทำให้มันสมบูรณ์แบบสำหรับสถานการณ์นี้

ดังนั้นในกรณีของคุณrsyncขั้นตอนที่ผมจะแนะนำให้ใช้สคริปต์นี้โดยเพียงแค่การเปลี่ยนechoคำสั่งที่คุณrsyncสั่ง นอกจากนี้เปลี่ยนLOCK_NAMEสิ่งที่ชอบRSYNC_PROCESSแล้วคุณก็ไปดี

ขณะนี้ด้วยrsyncสคริปต์ของคุณในตอนนี้คุณสามารถตั้งค่า cron job ให้ทำงานทุก ๆ นาทีโดยไม่ต้องเสี่ยงกับสภาพการแข่งขันที่rsyncกระบวนการสองอย่างหรือมากกว่านั้นกำลังต่อสู้เพื่อทำสิ่งเดียวกัน วิธีนี้จะช่วยให้คุณเพิ่มความเร็วหรือrsyncอัปเดตซึ่งจะไม่ขจัดปัญหาของไฟล์บางส่วนที่ถูกถ่ายโอน แต่มันจะช่วยเร่งความเร็วกระบวนการโดยรวมเพื่อให้สามารถคัดลอกไฟล์เต็มรูปแบบได้อย่างถูกต้องในบางจุด


1
ขอบคุณสำหรับการชี้ให้เห็นความเป็นไปได้ของการทำงานหลาย rsyncs ไม่คิดอย่างนั้น สคริปต์ฟังดูยอดเยี่ยม ฉันแค่พยายามที่จะเข้าใจ gotchas ของการซิงค์ไซต์ที่มีความสมดุลกับ rsync และดูเหมือนว่ามันจะช่วยบรรเทาพวกเขาได้ โบนัสที่ยอดเยี่ยม ยังคงรู้สึกเหมือนอาจจะเป็นวิธีการที่ไม่ถูกต้อง ... แต่เรามาดู :)
Louis Waweru

@Louis ยินดีต้อนรับ! lsyncdนอกจากนี้ถ้าคุณต้องการที่จะเก็บโฟลเดอร์ในการซิงค์ตามการเปลี่ยนแปลงไฟล์ทันทีผมจะขอแนะนำให้มองในการใช้ / การปรับตัว ช่วยให้คุณมี "โฟลเดอร์ยอดนิยม" ที่ให้ความสนใจกับกิจกรรมในพวกเขาอย่างแท้จริงจากนั้นดำเนินการกับไฟล์เหล่านั้นเมื่อมีการเปลี่ยนแปลง ฉันใช้rsyncมากตามที่ระบุไว้ในคำตอบของฉัน แต่ฉันใช้lsyncdสำหรับกรณีที่ต้องใช้รูปแบบการกระทำที่ไม่ใช่ cron / มากกว่าทันที
JakeGould

3

ใช่ - และไฟล์อาจเสียหายหาก rsync กำลังอ่านไฟล์ในเวลาเดียวกันกับไฟล์ที่กำลังถูกเขียนไป

คุณสามารถลองทำสิ่งนี้: /unix//a/2558

คุณสามารถเขียนสคริปต์ด้วย lsof:

lsof /path/to file

รหัสทางออก 0 หมายถึงไฟล์นั้นถูกใช้งานและรหัสทางออก 1 หมายถึงไม่มีกิจกรรมในไฟล์นั้น


ฉันไม่เห็นว่าทำไมไฟล์จะเสียหายหาก rsync เพิ่งอ่านมัน
orestisf
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.