Каков наилучший способ реализации взвешенного случайного выбора на основе переменных 2 типов (в php)?
В основном моя дилемма заключается в следующем. У меня есть список х серверов, на которых размещены файлы. Существует еще один сервер, на котором размещены база данных и приложение mysql. Когда файл загружен (на внешний сервер), приложение проверяет, на каком сервере больше всего свободного места, и перемещает файл туда. Это прекрасно работает, если вы начали с 2+ пустых серверов с одинаковым количеством свободного места. Если вы добавите другой сервер в микшер на более позднем этапе... на котором будет больше свободного места, чем на текущих серверах, этот метод не будет таким эффективным, потому что все новые файлы будут выгружены на новый сервер, что приведет к перегрузке. так как он будет обрабатывать большую часть нового трафика, пока не догонит остальные блоки с точки зрения свободного места.
Поэтому я подумал ввести систему взвешивания, которая поможет нормализовать распределение файлов. Таким образом, если для каждого из 3 серверов установлено значение 33%, а на 1 сервере будет значительно больше свободного места, он все равно получит больше загрузок, чем другие серверы (даже если он имеет одинаковый вес), но нагрузка будет распределена по всем серверы.
Кто-нибудь может предложить хорошую реализацию этого только для php?
4 ответа
Один из подходов заключается в суммировании всего доступного пространства на всех серверах, на которых есть место для хранения файла (поэтому сервер с доступным пространством, но недостаточным для хранения файла, очевидно, будет исключен). Затем определите процентную долю этого пространства, на которую приходится каждый сервер (так что новый сервер будет иметь пропорционально больший процент). Используйте случайное число и выровняйте его по процентам, чтобы определить, какой сервер выбрать.
Например, рассмотрим пять серверов со следующими уровнями свободного пространства:
Server 1: 2048MB
Server 2: 51400MB
Server 3: 1134MB
Server 4: 140555MB
Вам нужно хранить 1500 МБ файла. Это выбивает Сервер 3 из строя, оставляя нам 194003 МБ свободного места.
Server 1: 1.0%
Server 2: 26.5%
Server 4: 72.5%
Затем вы выбираете случайное число от 0 до 100: 40
Numbers between 0 and 1 (inclusive) would go to Server 1
Numbers > 1 and <= 26.5 would go to Server 2
Numbers > 26.5 and <= 100 would go to Server 4
Таким образом, в этом случае 40 означает, что он хранится на сервере 4.
Балансировка трафика обычно очень важна. Вы можете добавить какую-то систему взвешивания, чтобы уравновесить ее (хотя, как вы говорите, новый сервер все равно будет перегружен больше, чем другие), или какой-то другой альтернативный метод, когда один сервер никогда не получает удар дважды подряд, просто как пример.
Но я думаю, что я бы, вероятно, искусственно сбалансировал данные серверов так, чтобы они были почти равны друг другу, переместив контент с одного на другой, а затем позволил бы исходному или взвешенному / чередующемуся алгоритму нормально выполнять свою работу.
Это не только реализация php, но и некоторые идеи для рассмотрения.
Вы вошли в мир распределенных файловых систем - проблема больше, чем вы ожидали.
Много работы / исследований было сделано в этой области. Вы должны рассмотреть возможность использования доступного решения, такого как MogileFS, или, по крайней мере, провести некоторое исследование того, как они решали проблемы, с которыми вы столкнулись (а также проблемы, с которыми вы еще не сталкивались)
Для примера того, что я подразумеваю под "проблемами, с которыми вы еще не сталкивались": разве вы не должны хранить как минимум 2 копии каждого файла, чтобы, если вы потеряете один сервер, вы не потеряли все файлы на Это? Конечно, как только вы начнете это делать, разве вы не сможете читать части одного файла с нескольких серверов одновременно для повышения производительности? И, конечно же, теперь вам нужно выяснить, как распределяются файлы, как они перераспределяются при сбое сервера, при подключении нового сервера и т. Д. И т. Д...
Делать это правильно сложно. Не изобретайте велосипед, если можете его избежать. И если вам придется изобретать велосипед, по крайней мере, потратьте некоторое время на изучение того, как его построили другие люди.
Способ его реализации заключается в следующем:
- Создайте массив всего пустого пространства, как дробь, в вашем случае { 0.5, 0.5, 1.0 }
- Создайте второй массив весов - объем пространства на сервере, деленный на общий объем пространства, как он представлен в первом массиве - { 0.25, 0.25, 0.5 }
- Получить случайное число, нормализованное до (0.0,1.0), путем вызова 1.0*mt_rand()/mt_getmaxrand()
запустите следующий цикл:
$total_weight = 0.0; for ( $i = 10; $i <= sizeof($weights); $i++) { $total_weight += #weights[$i]; if($rand <= $total_weight) { return $i; } }
Возвращаемое значение является индексом сервера