Каков наилучший способ реализации взвешенного случайного выбора на основе переменных 2 типов (в php)? - PullRequest
3 голосов
/ 17 июня 2009

В основном моя дилемма заключается в следующем. У меня есть список х серверов, на которых размещены файлы. Есть еще один сервер, на котором размещены база данных и приложение mysql. Когда файл загружен (на внешний сервер), приложение проверяет, на каком сервере больше всего свободного места, и перемещает файл туда. Это прекрасно работает, если вы начали с 2+ пустых серверов с одинаковым количеством свободного места. Если вы добавите другой сервер в микшер на более позднем этапе ... на котором будет больше свободного места, чем на текущих серверах, этот метод не будет таким эффективным, потому что все новые файлы будут выгружены на новый сервер, что приведет к перегрузке. так как он будет обрабатывать большую часть нового трафика, пока не догонит остальные блоки с точки зрения свободного места.

Поэтому я подумал также о введении системы взвешивания, которая поможет нормализовать распределение файлов. Таким образом, если для каждого из 3 серверов установлено значение 33%, а на 1 сервере будет значительно больше свободного места, он все равно получит больше загрузок, чем другие серверы (даже если он имеет одинаковый вес), но нагрузка будет распределена по всем серверы.

Может кто-нибудь предложить хорошую реализацию этого только для php?

Ответы [ 4 ]

4 голосов
/ 17 июня 2009

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

Например, рассмотрим пять серверов со следующими уровнями свободного пространства:

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.

1 голос
/ 18 июня 2009

Вы попали в мир распределенных файловых систем - проблема больше, чем вы ожидали.

В этой области было проделано много работы / исследований. Вам следует рассмотреть возможность использования доступного решения, такого как MogileFS , или, по крайней мере, провести некоторое исследование того, как они решали проблемы, с которыми вы столкнулись (а также проблемы, с которыми вы еще не сталкивались)

В качестве примера того, что я подразумеваю под «проблемами, с которыми вы еще не сталкивались»: разве вы не должны хранить по крайней мере 2 копии каждого файла, чтобы, если вы потеряете один сервер, вы не потеряли все файлы на нем? Конечно, как только вы начнете это делать, разве вы не сможете прочитать части одного файла с нескольких серверов одновременно для повышения производительности? И, конечно же, теперь вам нужно выяснить, как распределяются файлы, как они распределяются re при сбое сервера, при подключении нового сервера и т. Д. И т. Д ...

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

1 голос
/ 17 июня 2009

Способ его реализации заключается в следующем:

  1. Создайте массив всего пустого пространства, как дробь, в вашем случае {0.5, 0.5, 1.0}
  2. Создайте второй массив весов - количество пространства на сервере, деленное на общее количество пространства, как оно представлено в первом массиве - {0.25, 0.25, 0.5}
  3. Получить случайное число, нормализованное до (0.0,1.0), вызвав 1.0 * mt_rand () / mt_getmaxrand ()
  4. запустить следующий цикл:

    $total_weight = 0.0;
    for ( $i = 10; $i <= sizeof($weights); $i++) {
      $total_weight += #weights[$i];
      if($rand <= $total_weight) {
    return $i;
      }
    }
    

Возвращаемым значением является индекс сервера

1 голос
/ 17 июня 2009

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

Но я думаю, что я бы, вероятно, искусственно сбалансировал данные серверов так, чтобы они были почти равны друг другу, переместив контент с одного на другой, а затем позволил бы исходному или взвешенному / чередующемуся алгоритму нормально выполнять свою работу.

Это не только реализация php, но и некоторые идеи для рассмотрения.

...