Nếu Apache đang viết một tệp nào đó đến một nơi và chưa hoàn thành việc viết nó và sau đó rsync khởi động, rsyncsẽ sao chép bất cứ thứ gì đang ngồi ở đó.
Có nghĩa là nếu Apache là đối phó với một file 5MB, chỉ có 2MB được viết và rsyncđá trong, file 2MB một phần sẽ được sao chép. Vì vậy, tập tin đó có vẻ như là lỗi bị hỏng trên máy chủ đích.
Tùy thuộc vào kích thước của tệp bạn đang sử dụng, bạn có thể sử dụng --inplacetùy chọn rsyncđể thực hiện các thao tác sau:
Tùy chọn này thay đổi cách rsync chuyển tệp khi cần cập nhật dữ liệu của tệp: thay vì phương pháp mặc định tạo bản sao mới của tệp và di chuyển tệp vào vị trí khi hoàn tất, thay vào đó, rsync ghi dữ liệu cập nhật trực tiếp vào đích tập tin.
Lợi ích của việc này là nếu một tệp 5 MB chỉ có 2 MB được sao chép trong lần chạy đầu tiên, lần chạy tiếp theo sẽ nhận ở mức 2 MB và tiếp tục sao chép tệp cho đến khi có đủ 5 MB.
Điều tiêu cực là nó có thể tạo ra tình huống ai đó đang truy cập máy chủ web trong khi một tệp đang được sao chép và sau đó họ sẽ thấy một phần tệp. Theo ý kiến của tôi, nó rsynchoạt động tốt nhất trong hành vi mặc định của nó là lưu trữ một tập tin vô hình trên mạng và sau đó di chuyển nó vào vị trí ngay lập tức. Nhưng --inplacetốt cho các tình huống trong đó các tệp lớn và các ràng buộc về băng thông có thể cản trở một tệp lớn dễ dàng được sao chép từ một hình vuông.
Điều đó nói rằng bạn làm điều này; nhấn mạnh là của tôi:
Cứ năm phút lại có cron chạy rsync
Vì vậy, tôi giả sử bạn có một số tập lệnh bash tại chỗ để quản lý công việc định kỳ này? Vâng, điều này rsynclà đủ thông minh để chỉ sao chép các tập tin cần được sao chép. Và nếu bạn có một kịch bản chạy cứ sau 5 phút thì nó xuất hiện, bạn đang cố gắng tránh rsyncbước lên nhau nếu nó diễn ra nhanh hơn. Có nghĩa là, nếu bạn chạy nó mỗi phút, có một rủi ro là một hoặc nhiều rsyncquá trình vẫn sẽ chạy do kích thước tệp hoặc tốc độ mạng và quá trình tiếp theo sẽ cạnh tranh với nó; một điều kiện đua xe.
Một cách để tránh điều này là bọc toàn bộ rsynclệnh của bạn trong tập lệnh bash để kiểm tra khóa tệp; dưới đây là một khung kịch bản bash nồi hơi tôi sử dụng cho các trường hợp như thế này.
Lưu ý rằng một số người sẽ khuyên bạn nên sử dụng flocknhưng vì flockchưa được cài đặt trên một số hệ thống nên tôi sử dụng và tôi nhảy giữa Ubuntu (có nó) và Mac OS X (không có) rất nhiều. Tôi sử dụng khung đơn giản này mà không gặp vấn đề thực sự nào:
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
Ý tưởng là cốt lõi chung, nơi tôi có phần mềm echo "Hello world!", nơi trung tâm của kịch bản của bạn. Phần còn lại của nó về cơ bản là một cơ chế khóa / logic dựa trên mkdir. Một lời giải thích tốt về khái niệm này nằm trong câu trả lời này :
mkdir tạo một thư mục nếu nó chưa tồn tại và nếu có, nó sẽ đặt mã thoát. Quan trọng hơn, nó thực hiện tất cả điều này trong một hành động nguyên tử duy nhất làm cho nó hoàn hảo cho kịch bản này.
Vì vậy, trong trường hợp rsyncquy trình của bạn , tôi khuyên bạn nên sử dụng tập lệnh này bằng cách thay đổi echolệnh thành lệnh của bạn rsync. Ngoài ra, thay đổi LOCK_NAMEthành một cái gì đó như RSYNC_PROCESSvà sau đó bạn là tốt để đi.
Giờ đây, với rsynctập lệnh này, bạn có thể thiết lập công việc định kỳ để chạy mỗi phút mà không có bất kỳ rủi ro nào về điều kiện đua trong đó hai hoặc nhiều rsyncquy trình đang chiến đấu để làm điều tương tự. Điều này sẽ cho phép bạn tăng tốc độ hoặc rsynccập nhật sẽ không loại bỏ được vấn đề của một phần tệp được chuyển, nhưng nó sẽ giúp tăng tốc quá trình tổng thể để toàn bộ tệp có thể được sao chép chính xác tại một số điểm.