Pergunta

A configuração: Site alta tráfego e uma lista de URLs de imagem que deseja exibir. Temos um ponto de imagem, e cada item no conjunto de URLs de imagem tem uma porcentagem de exibição de destino para o dia. Exemplo:

  • Image1 - 10%
  • Image2 - 30%
  • Image3 - 60%

Porque a quantidade de tráfego pode variar de dia para dia, eu estou fazendo as percentagens dentro de blocos de 1000. As imagens também precisam ser escolhido aleatoriamente, mas ainda caber a distribuição de precisão.

Pergunta: Eu tenho implementado código de POC para fazer isso no memcache, mas estou desconfortável com a maneira como os dados são armazenados (várias chaves de hash mapeados por um "registro mestre" com dados de meta). Isso também precisa ser capaz de cair de volta para um banco de dados se os servidores memchache ir para baixo. Eu também estou preocupado com problemas de simultaneidade para o registro mestre.

Existe uma maneira mais simples de fazer isso? Talvez uma consulta mysql rápido ou uma melhor maneira de trazer memcache para isso?

Graças

Nenhuma solução correta

Outras dicas

Você poderia fazer o que você disse, pregenerate um bloco de 1000 valores apontando para as imagens que você vai voltar:

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

Em seguida, armazenar esse bloco no MySQL e memcache, e usar outra chave (tanto em MySQL e memcache) para manter o valor do índice atual para a seqüência acima. Sempre que o script de imagem é atingido incremento do valor em memcache. Se memcache vai para baixo, vá para o MySQL em seu lugar. (UPDATE, então SELECT, pode haver uma maneira melhor de fazer esta parte)

Para manter memcache e MySQL em sincronia você poderia ter um trabalho cron copiar o valor do índice atual de memcache para MySQL. Você vai perder alguma precisão, mas que pode não ser crítica nesta situação.

Você pode armazenar várias distribuições em ambos MySQL e memcache e ter outra chave que aponta para a distribuição actualmente activa. Dessa forma, você pode pregenerate futuros blocos de imagens. Quando o índice ultrapassa a distribuição do script seria incrementar a chave e ir para a próxima.

Cerca de:

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;
}

.. etc. Os nomes das funções tipo de fedor, mas eu acho que você vai ficar com a ideia. Quando o servidor memcache está de volta novamente, você pode copiar os dados do MySQL volta para memcache e é instantaneamente reativado.

A bater para o banco de dados é muito provavelmente vai demorar mais tempo para que eu iria ficar com memcache. Você vai ter mais problemas com a simultaneidade usando MySQL que memcache. memcache está melhor equipado para lidar com um monte de pedidos e se os servidores vão para baixo, isso vai ser a menor das suas preocupações em um site de alto tráfego.

Talvez um especialista MySQL pode canalizar aqui com uma boa estrutura de consulta se você nos dar mais detalhes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top