Наборы с высоким процентом трафика на основе набора? - PullRequest
0 голосов
/ 30 мая 2009

Настройка: веб-сайт с высоким трафиком и список URL-адресов изображений, которые мы хотим отобразить. У нас есть одна область изображения, и каждый элемент в наборе URL-адресов изображений имеет целевой процент отображения для дня. Пример:

  • Изображение 1 - 10%
  • Изображение 2 - 30%
  • Изображение 3 - 60%

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

Вопрос: Я реализовал POC-код для выполнения этого в memcache, но мне неудобно, как хранятся данные (несколько хеш-ключей отображаются в «основной записи» с метаданными). Это также должно быть в состоянии вернуться к базе данных, если серверы memcache выйдут из строя. Я также обеспокоен проблемами параллелизма для основной записи.

Есть ли более простой способ сделать это? Может быть, быстрый запрос MySQL или лучший способ внести в нее memcache?

Спасибо

Ответы [ 2 ]

1 голос
/ 09 августа 2009

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

$distribution = "011022201111202102100120 ..." # exactly evenly distributed

Затем сохраните этот блок в MySQL и memcache и используйте другой ключ (как в MySQL, так и в memcache) для хранения текущего значения индекса для приведенной выше строки. При каждом нажатии на скрипт изображения увеличивается значение в memcache. Если memcache не работает, вместо этого перейдите в MySQL (UPDATE, затем SELECT; возможно, есть лучший способ выполнить эту часть).

Чтобы синхронизировать memcache и MySQL, у вас может быть задание cron скопировать текущее значение индекса из memcache в MySQL. Вы потеряете некоторую точность, но это может быть не критично в этой ситуации.

Вы можете хранить несколько дистрибутивов как в MySQL, так и в memcache, и иметь другой ключ, который указывает на текущий активный дистрибутив. Таким образом, вы можете предварительно генерировать будущие блоки изображений. Когда индекс превышает распределение, скрипт увеличивает ключ и переходит к следующему.

Грубо:

function FetchImageFname( )
{
  $images = array( 0 => 'image1.jpg', 1 => 'image2.jpg', 2 => 'image3.jpg' );
  $distribution = FetchDistribution( );
  $currentindex = FetchCurrentIndex( );

  $x = 0;
  while( $distribution[$currentindex] == '' && $x < 10 );
  {
    IncrementCurrentDistribKey( );
    $distribution = FetchDistribution( );
    $currentindex = FetchCurrentIndex( );
    $x++;
  }

  if( $distribution[$currentindex] == '' )
  {
    // XXX Tried and failed. Send error to central logs.
    return( $images[0] );
  }

  return( $distribution[$currentindex] );
}

function FetchDistribution( )
{
  $current_distib_key = FetchCurrentDistribKey( );
  $distribution = FetchFromMemcache( $current_distrib_key );
  if( !$distribution )
    $distribution = FetchFromMySQL( $current_distrib_key );
  return $distribution;
}

function FetchCurrentIndex( )
{
  $current_index = MemcacheIncrement( 'foo' );
  if( $current_index === false )
    $current_index = MySQLIncrement( 'foo' );
  return $current_index;
}

.. и т. Д. Названия функций вроде воняют, но я думаю, вы поймете эту идею. Когда сервер memcache снова работает, вы можете скопировать данные из MySQL обратно в memcache, и они сразу же активируются.

0 голосов
/ 31 мая 2009

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

Может быть, эксперт MySQL может передать здесь хорошую структуру запроса, если вы дадите нам больше подробностей.

...