Выбор наборов на основе высокого процента посещаемости?
-
06-09-2019 - |
Вопрос
Установка:Веб-сайт с высокой посещаемостью и список URL-адресов изображений, которые мы хотим отобразить.У нас есть одно место для изображения, и каждый элемент в наборе URL-адресов изображений имеет целевой процент отображения за день.Пример:
- Изображение 1 - 10%
- Изображение2 - 30%
- Изображение 3 - 60%
Поскольку объем трафика может меняться изо дня в день, я рассчитываю проценты в пределах блоков от 1000.Изображения также должны выбираться случайным образом, но при этом точно соответствовать распределению.
Вопрос:Я реализовал POC-код для выполнения этого в memcache, но меня не устраивает способ хранения данных (несколько хэш-ключей, сопоставленных "главной записью" с метаданными).Это также должно позволять возвращаться к базе данных, если серверы memcache выходят из строя.Я также обеспокоен проблемами параллелизма для основной записи.
Есть ли более простой способ добиться этого?Возможно, быстрый запрос mysql или лучший способ использовать memcache в этом?
Спасибо
Нет правильного решения
Другие советы
Вы могли бы сделать то, что сказали, предварительно сгенерировать блок из 1000 значений, указывающих на изображения, которые вы вернете:
$distribution = "011022201111202102100120 ..." # exactly evenly distributed
Затем сохраните этот блок в MySQL и memcache и используйте другой ключ (как в MySQL, так и в memcache) для хранения текущего значения индекса для приведенной выше строки.Всякий раз, когда запускается сценарий изображения, увеличивайте значение в memcache.Если memcache выходит из строя, вместо этого перейдите в MySQL (ОБНОВИТЬ, затем ВЫБЕРИТЕ;возможно, есть лучший способ выполнить эту часть).
Чтобы синхронизировать 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, и они будут мгновенно активированы повторно.
Обращение к базе данных, скорее всего, займет больше времени, поэтому я бы предпочел использовать memcache.У вас будет больше проблем с параллелизмом при использовании MySQL, чем memcache.memcache лучше приспособлен для обработки большого количества запросов, и если серверы выйдут из строя, это будет наименьшей из ваших забот на веб-сайте с высоким трафиком.
Возможно, эксперт по MySQL сможет предоставить здесь хорошую структуру запроса, если вы дадите нам больше конкретики.