高トラフィックのパーセンテージに基づいたセットの選択?
-
06-09-2019 - |
質問
セットアップ:トラフィックの多い Web サイトと表示したい画像 URL のリスト。画像スポットが 1 つあり、画像 URL セットの各項目にはその日の目標表示率が設定されています。例:
- 画像1 - 10%
- 画像2 - 30%
- 画像3 - 60%
トラフィック量は日によって異なる可能性があるため、1000 ブロック内のパーセンテージを計算しています。画像もランダムに選択する必要がありますが、それでも分布に正確に適合します。
質問:これを行うためのPOCコードをmemcacheに実装しましたが、データの保存方法(メタデータを含む「マスターレコード」によってマップされた複数のハッシュキー)に不快感を感じています。また、memcache サーバーがダウンした場合にデータベースにフォールバックできる必要もあります。マスターレコードの同時実行性の問題も懸念しています。
これを実現するもっと簡単な方法はありますか?おそらく、高速な mysql クエリ、またはこれに memcache を組み込むより良い方法でしょうか?
ありがとう
正しい解決策はありません
他のヒント
あなたは、あなたが言った何をあなたが戻ります画像を指して1000の値のブロックを事前に生成できます:
$distribution = "011022201111202102100120 ..." # exactly evenly distributed
次に、MySQLとメモリキャッシュ内のそのブロックを格納し、上記文字列の現在のインデックスの値を保持する(MySQLとmemcacheの両方で)別のキーを使用しています。画像スクリプトがヒットするたびにmemcacheで値をインクリメント。 memcacheのがダウンした場合、(UPDATEは、[選択];この部分を行うには良い方法があるかもしれない)の代わりに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のサーバーが再び帰ってきたときに、あなたが戻っmemcacheのにMySQLのデータをコピーすることができますし、それが即座にアクティブ化されます。
データベースへのヒットが最も可能性が高いので、私はmemcacheのに固執するだろう時間がかかるとしています。あなたはmemcacheのよりMySQLを使用して並行処理でより多くの問題を持ってしようとしています。 memcacheのは良く要求の多くを処理するために装備されており、サーバがダウンした場合、これは高トラフィックのウェブサイト上でお悩みの最低になるだろうされます。
たぶん、MySQLの専門家は、パイプはここで良いクエリ構造として、あなたは私たちに多くの詳細を与えることができるかどうか。