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, rsync
sẽ 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 --inplace
tù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ó rsync
hoạ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 --inplace
tố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 rsync
là đủ 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 rsync
bướ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 rsync
quá 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ộ rsync
lệ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 flock
nhưng vì flock
chư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 rsync
quy 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 echo
lệnh thành lệnh của bạn rsync
. Ngoài ra, thay đổi LOCK_NAME
thành một cái gì đó như RSYNC_PROCESS
và sau đó bạn là tốt để đi.
Giờ đây, với rsync
tậ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 rsync
quy 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 rsync
cậ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.