Семафоры и Замки в Ubuntu - PullRequest
3 голосов
/ 30 ноября 2010

У меня есть резервный сервер, который получает много rsync соединений каждый час. Поскольку слишком большое количество открытых rsync экземпляров может привести к сбою, я хочу ограничить число одновременных экземпляров, используя Семафор . Я имею в виду что-то вроде:

ssh root@backup_server "get_semaphore"     #Will hold until semaphore released
rsync -avzrL --super --delete local_directory root@backup_server:`localhost`

Есть идеи?

1 Ответ

12 голосов
/ 05 декабря 2010

По моему мнению, вам следует ограничить число одновременных подключений непосредственно на стороне сервера, чтобы вам не приходилось делать что-то экстремальное на стороне клиента:

(1) Если вы запускаете rsync в режиме демона, для rsyncd.conf есть опция max connections.

(2) В Linux вы можете использовать iptables и его модуль connlimit, чтобы ограничить количество одновременных подключений к порту с одного или нескольких удаленных хостов. Возможно, вам придется заставить любые клиенты rsync использовать порт, отличный от обычных пользователей ssh, и экземпляр sshd должен их прослушивать.

(3) Замените ваш двоичный файл rsync на сервере сценарием-оберткой, который перехватит параметр --server, который используется внутри rsync, и остановится, пока не освободится слот. Упомянутый скрипт-обертка должен убедиться, что одновременно выполняется не более N его экземпляров. Э.Г.

#!/bin/bash

N=5

mutex_hold() {
    while ! mkdir /var/lock/rsync/mutex 2>/dev/null; do
       sleep 1
    done
}

mutex_release() {
    rmdir /var/lock/rsync/mutex
}

if [[ "$1" = "--server" ]]; then
    shopt -s nullglob

    while mutex_hold && A=(/var/lock/rsync/[0-9]*) && [[ "${#A[@]}" -ge "$N" ]] && mutex_release; do
       sleep 1
    done

    touch /var/lock/rsync/$$

    mutex_release

    rsync.bin "$@"

    rm -f /var/lock/rsync/$$
else
    rsync.bin "$@"
fi

Обратите внимание, что этот сценарий в основном не проверен и в нем отсутствует необходимый код прерывания для удаления файла блокировки, даже если он прерван. Он также не заботится ни о каких устаревших файлах блокировки и т. Д., Ни о создании каталога блокировки.

Если вы настроены на создание собственной реализации семафора, вас может заинтересовать мьютекс , который я использовал выше, чтобы избежать условия гонки между подсчетом количества файлов блокировки и созданием нового файла блокировки, что может позволить двум (или более) экземплярам работать в одном слоте.

Во всех этих случаях вы должны убедиться, что ваши клиенты могут корректно обрабатывать таймауты или отклоненные соединения.

Если вы действительно хотите использовать систему в стиле семафоров, как вы предложили, приведенный выше скрипт может быть несколько модифицирован.

...