Question

La configuration: site à fort trafic et une liste d'URL d'image que nous voulons afficher. Nous avons une tache d'image, et chaque élément dans l'ensemble des URL d'image a un pourcentage d'affichage cible pour la journée. Exemple:

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

Parce que la quantité de trafic peut varier de jour en jour, je fais les pourcentages à l'intérieur des blocs de 1000. Les images doivent également être pris au hasard, mais toujours en forme de la distribution avec précision.

Question: J'ai mis en code POC pour ce faire dans memcache, mais je suis mal à l'aise avec les données sont stockées de manière (plusieurs clés de hachage mis en correspondance par un « enregistrement maître » avec des données méta). Cela doit également être en mesure de revenir à une base de données si les serveurs memcache baissent. Je suis aussi préoccupé par les questions de concurrence pour l'enregistrement maître.

Y at-il d'y arriver de façon plus simple? Peut-être une requête MySQL rapide ou une meilleure façon d'apporter memcache dans tout cela?

Merci

Pas de solution correcte

Autres conseils

Vous pouvez faire ce que vous avez dit, pregenerate un bloc de 1000 valeurs pointant les images que vous allez retour:

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

Ensuite, stocker ce bloc dans MySQL et memcache, et utiliser une autre clé (dans les deux MySQL et memcache) pour maintenir la valeur de l'indice actuel de la chaîne ci-dessus. Chaque fois que le script d'image est frappé incrémenter la valeur memcache. Si memcache descend, allez à MySQL à la place. (UPDATE, puis SELECT, il peut y avoir une meilleure façon de faire cette partie)

Pour garder memcache et MySQL en synchronisation vous pourriez avoir une tâche cron copie la valeur d'index en cours de memcache à MySQL. Vous perdrez une certaine précision, mais qui ne peut être critique dans cette situation.

Vous pouvez stocker plusieurs distributions dans les deux MySQL et memcache et une autre clé qui pointe à la distribution active. De cette façon, vous pouvez pregenerate futurs blocs d'image. Lorsque l'indice est supérieur à la distribution du script incrémenterait la clé et allez à la suivante.

En gros:

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. Les noms de fonction type de puent, mais je pense que vous aurez l'idée. Lorsque le serveur memcache est de retour à nouveau, vous pouvez copier les données de MySQL retour à memcache et il est instantanément réactivés.

Un coup à la base de données est le plus susceptible de prendre plus de temps, je tiendrais donc avec memcache. Vous allez avoir plus de problèmes avec l'aide de MySQL que concurrency memcache. memcache est mieux équipé pour gérer un grand nombre de demandes et si les serveurs baissent, cela va être le moindre de vos soucis sur un site à fort trafic.

Peut-être un expert MySQL peut pipe ici avec une bonne structure de requête si vous nous donner plus de détails.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top