Настройка: веб-сайт с высокой посещаемостью и список URL-адресов изображений, которые мы хотим отобразить. У нас есть одно место для изображения, и каждый элемент в наборе URL-адресов изображений имеет целевой процент отображения в течение дня. Пример:
- Изображение 1 – 10 %
- Изображение2 – 30 %
- Изображение3 – 60 %
Поскольку объем трафика может меняться изо дня в день, я делаю проценты в блоках по 1000. Изображения также должны выбираться случайным образом, но при этом точно соответствовать распределению.
Вопрос. Я внедрил POC-код для этого в memcache, но меня не устраивает способ хранения данных (множество хеш-ключей, сопоставленных «основной записью» с метаданными). Это также должно иметь возможность вернуться к базе данных, если серверы memcache перестанут работать. Меня также беспокоят проблемы параллелизма для основной записи.
Есть ли более простой способ сделать это? Возможно, быстрый запрос mysql или лучший способ добавить в это memcache?
Благодарность
2 ответа
Вы можете сделать то, что сказали, предварительно сгенерировав блок из 1000 значений, указывающих на изображения, которые вы вернете:
$distribution = "011022201111202102100120 ..." # exactly evenly distributed
Затем сохраните этот блок в MySQL и в кэше памяти и используйте другой ключ (как в MySQL, так и в кэше памяти) для хранения текущего значения индекса для указанной выше строки. Всякий раз, когда выполняется скрипт изображения, увеличивайте значение в memcache. Если memcache выходит из строя, вместо этого перейдите к MySQL (UPDATE, затем SELECT; возможно, есть лучший способ выполнить эту часть).
Чтобы синхронизировать memcache и MySQL, вы можете выполнить задание cron, скопировав текущее значение индекса из memcache в MySQL. Вы потеряете некоторую точность, но это может быть не критично в этой ситуации.
Вы можете хранить несколько дистрибутивов как в MySQL, так и в кэше памяти и иметь еще один ключ, указывающий на текущий активный дистрибутив. Таким образом, вы можете предварительно сгенерировать будущие блоки изображений. Когда индекс превышает распределение, скрипт увеличивает ключ и переходит к следующему.
Грубо говоря :
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 сможет добавить сюда хорошую структуру запроса, если вы дадите нам больше деталей.
Похожие вопросы
Новые вопросы
php
PHP — это широко используемый язык сценариев общего назначения с открытым исходным кодом, мультипарадигмальный, динамически типизированный и интерпретируемый, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.