Неслучайное взвешенное распределение

Я не выполняю перспективу, но virtualbox должен сделать большую часть установки для Вас - все, что необходимо сделать, присваивают IP-адрес, маску подсети, и (дополнительно) шлюз по умолчанию гостю ОС, и это должно просто работать.

не беспокоятся ни одним из расширенных параметров сети в опциях для VM - они полезны в некоторых ситуациях, но я никогда не должен был использовать их, и я использовал virtualbox в течение нескольких лет теперь.

при регистрации определенной проблемы Вы имеете, возможно, я могу помочь больше. Но Ваш вопрос довольно неопределенен...

5
задан duckworth 20 November 2009 в 18:04
поделиться

5 ответов

Разбейте проблему на две части: (1) определите, какой дистрибутив вы хотите иметь для каждого набора клиентов; и (2) детерминированное назначение времени повторного подключения, которое соответствует этому распределению.

Для задачи (1) рассмотрим двумерный массив чисел, очень похожий на диаграмму, которую вы нарисовали: каждая строка представляет часовой пояс, а каждый столбец представляет равный промежуток времени (возможно, час) в течение дня. Проблема, которую вы должны решить, состоит в том, чтобы заполнить сетку такими числами, чтобы

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

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

Для задачи (2) вам нужна функция, которая принимает десятизначный идентификатор и желаемое распределение (то есть одну строку матрицы из задачи 1 выше) и детерминированно производит время повторного подключения. Это легко сделать с помощью линейной интерполяции. Предположим, желаемое распределение:

12:00    1:00   2:00   3:00   4:00   5:00   6:00 ...
  +------+------+------+------+------+------+----
  |    0 |    0 |  100 |   70 |   30 |    0 |   ...
  +------+------+------+------+------+------+----

Сначала найдите сумму всей строки и масштабируйте числа до диапазона идентификаторов. То есть разделите на сумму и умножьте на 10 10 .

12:00    1:00   2:00        3:00       4:00        5:00   6:00 ...
  +------+------+-----------+-----------+-----------+------+----
  |    0 |   0  | 500000000 | 350000000 | 150000000 |    0 |   ...
  +------+------+-----------+-----------+-----------+------+----

Теперь пусть x = десятизначный идентификатор, и прочтите строку слева направо. В каждой коробке вычтите значение в этом поле из x. Продолжайте, пока число в поле не станет больше, чем осталось в x. Возврат времени

(start time for this box) + (duration of this box) * x / (number in box)

Обратите внимание, что после вычисления решения проблемы (1) время повторного подключения будет детерминированным до , когда вы в следующий раз пересчитаете матрицу. Тогда время повторного подключения у всех немного изменится - но ненамного, если только матрица не изменится кардинально.

5
ответ дан 14 December 2019 в 01:10
поделиться

Вы можете принять во внимание часовой пояс пользователя в дополнение к его идентификатору.

Одним из примеров решения, которое использует это, может быть следующее:

Существует 24 часовых пояса. Рассчитайте относительную нагрузку для каждого часового пояса. Вы можете сделать это, суммируя общее количество клиентов из каждого часового пояса из ваших статических данных. Теперь у вас есть «взвешенные часовые пояса». Каждый часовой пояс получит долю времени, пропорциональную его весу.

Например, если у вас есть следующие данные (для простоты предположим, что существует только три часовых пояса):

Time Zone | Clients num
------------------------
    0     |     20
    1     |     30
    2     |     10

Затем вы должны разделить размер временного интервала на 60 и дать каждому из часовых поясов его долю времени: первый часовой пояс получит (20/60 * # время), второй получит следующее (30/60 * # время) и т. д.

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

Примечания:

  1. Очевидно, вам понадобится некоторый минимум число клиентов для часовых поясов с очень низким трафиком, но это просто - вы просто редактируете исходную таблицу.
  2. Это один из примеров «временного разделения», вы можете изменить этот пример по своему усмотрению, например, вы могут иметь общие временные рамки для нескольких часовых поясов.

РЕДАКТИРОВАТЬ:

Учитывая пример, который вы добавили в свой вопрос, вы можете применить этот метод следующим образом:

Если я правильно вас понял, у вас есть 10 часов в который ваш сервер активен, и вы хотите, чтобы нагрузка была более или менее одинаковой в каждый из этих часов. Смысл: Используя описанную выше идею, можно неравномерно разделить пользователей, так что для каждого часового пояса есть часы с «большей вероятностью» и часы с «меньшей вероятностью». В вашем примере в группе GMT-4 10% / 40% клиентов получат доступ к серверу в первый час: 12 AM-01AM GMT. Можно рассчитать нагрузку для каждого часового пояса, так что общая нагрузка на сервер за каждый час составляет 10%. Для этого есть много способов - подойдет и самый жадный. Получив это, вы узнаете веса для каждого часового пояса, и вам станет понятнее, как использовать метод разделения времени, описанный выше.

3
ответ дан 14 December 2019 в 01:10
поделиться

Why not generate your reconnect-window times in GMT on the server and convert to client local time before you send the time to the client?

0
ответ дан 14 December 2019 в 01:10
поделиться

How about this for something simple:

  • If the load on the server is OK, send the client the same number of seconds you sent last time.

  • If the load on the server is too high, instead send the client some other random number in the time window.

Over a few days things should sort themselves out.

(This assumes you have some way of measuring the quantity you're trying to optimize, which doesn't seem too unreasonable.)

0
ответ дан 14 December 2019 в 01:10
поделиться

Я бы определил вспомогательный класс для каждого часового пояса, на который вы смотрите:

class Timezone
{
  DateTime start;
  int hourlyWeights[6]; //assuming you have 6 hour long timeslot for every timezone

  DateTime GetStartTime(long clientId)
  {
    long allTicks = 3600*sum(hourlyWeights);
    long clientTicks = clientId%allTicks;
    int i = 0;
    while(clientTicks>hourlyWeights[i])
    {
      clientTicks -= hourlyWeights[i]*3600;
      i++;
    }
    long seconds = clientTicks/hourlyWeights[i];
    return start.AddHours(i).AddSeconds(seconds);
  }
}

Теперь вы используете метод GetStartTime, чтобы получить время начала для клиента из этого часового пояса. Идея здесь в том, что у нас есть эта таблица hourlyWeights с распределением, которое вы хотите получить для данного часового пояса, например, [40, 20, 0, 0, 0, 0] будет означать, что эти клиенты будут обслуживаться только в течение первых 2 часов. , и мы хотим вдвое больше клиентов в течение первого часа. Примечание: я предполагаю, что идентификаторы равномерно распределяются между клиентами из данного часового пояса.

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

1
ответ дан 14 December 2019 в 01:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: