2011-07-05 6 views
1

この質問のタイトルは混乱するかもしれませんが、問題は簡単です。Zend_cacheをmemcachedで分散して使用するには?

memcachedをバックエンドとしてZend_Cacheを使用しています。私は「最後の記事」と「人気のある記事」という2つのモジュールを持っています。このモジュールはすべてのページにあり、次のような類似のクエリを使用します。

Select * from table where status = 'published' and category = '' order by dateCreated|/popularity\ 

私のテーブルには今までに150万行もあります。前のクエリで使用しているすべてのフィールドにインデックスがあります。 私は最近の記事を1時間キャッシュし、人気は4時間キャッシュします。私は4つのWebサーバー(php5/apache2)と1つのデータベースサーバー(mysql)を持っています。テーブルエンジンはinnoDBです。

重大な負荷の途中でキャッシュの有効期限が切れてしまい、それらのモジュールが再びキャッシュされるまで私のWebサイトを使用できなくなることがあります。私は新しいMYSQLサーバーを持っていた可能性があります。

しかし、スマートな方法でキャッシングを処理する方法はありますか?たとえば、server1とserver2はキャッシュから同じ値を引き続き使用しますが、server1はキャッシュをリフレッシュしようとします。

私はそれを行うためのコードを書くことができますが、Zend_Cacheで直接行う方法があるのだろうかと思っていましたか?私の問題に適用できるデザインパターンがあれば?

[EDIT]私は100台のサーバー

答えて

0

私は最後にZend_Cache_Backend_Libmemcachedから継承するクラスを実装しました load()メソッドをオーバーライドしています。

各サーバーには、serv01、serv02、serv03、serv04などの一連の番号で仕上げられたホスト名があります。 主な考え方は、各サーバーは、キャッシュが異なる時期に期限切れになったと考えます。例えば、serv01は、キャッシュが実際に期限切れになる前にキャッシュが満了したと考え、serv02は15分、serv03は10分、serv04は5分になります。

これを行うと、各サーバーでキャッシュが同時にリフレッシュされることはなく、あるサーバーがダウンしていると、キャッシュは別のサーバーによって更新されます。

1

代わりの期限切れ、その後、(複数の同時要求時に、または、それ以上という問題)HTTPリクエスト時に再作成されたキャッシュに頼ることにスケールアップ可能性が何かをしたい、なぜキャッシュが期限切れになることはありませんか?

次に、あなたの高価なクエリを(一度だけ!)実行し、バックグラウンドでキャッシュを更新するようにいくつかのuntilityスクリプトをスケジュールします。

+0

問題はクエリが「カテゴリ」であり、数十万のカテゴリがあり、カテゴリごとに2つのクエリがあります。+毎日訪問していないカテゴリを更新するという事実です。 – zzarbi

1

すべてが可能です:)

分散メモリキャッシュ(serv1,2,3,4)。

Serv4はReCache専用です。

は、「内部のみ」のwebSite(ユーザーには表示されません)を設定します。

「一部のカテゴリを更新する」部分を削除します。

"ほとんどの記事を読む" - > Apacheのアクセスログを解析する。

を入力し、server4にURLを再送信してください。

アクセス時間があるため、必要な部分、つまり2〜6時間前に取得することができます。

分散memcacheは、値をserv1,2,3に自動的に設定します。

+0

私はすでに忘れていることは、私はすでにサーバー1,2,3,4でmemcachedを使用しています。また、ログが解析されないサービスがあれば、私のモジュールはリフレッシュされません。サーバー4が動作していなければ、 。 4つのWebサーバーを持つという考えは、負荷に対応することですが、同時に4つのサーバーに冗長性を持たせることです。もし私がそれを解決するまで、私はそれを扱うことができます。あなたのソリューションでは、1つのサーバーが私のモジュールを壊す可能性があります。私は似たようなものが必要ですが、サーバー4が死んでいるときは、サーバー2がその場所を取るでしょう... – zzarbi

1

実行している実際のクエリですか?

Select * from table where status = 'published' and category = '' order by dateCreated|/popularity\ 

多分代わりの高​​度なキャッシュ・ソリューションを探して、このクエリは、データベース・サーバを強調する理由を参照してください。 1.5m行のテーブルは珍しいものではありません。

あなたはLIMIT句を追加してみたり、必要な列のみを選択しました:

Select col1, col2 from table where status = 'published' and category = '' order by dateCreated LIMIT 5 

それはかなりのデータベースとWebサーバ間のトラフィックを削減します。

+0

いいえ、実際のクエリではありません。実際のクエリは既に最適化されており、Select * from(Select field1、field2 where category = '')のようになります。クエリの前には、クエリー自体はかなり軽いですが、すべてのキャッシュが同時に期限切れになるという事実は、mysqlに指数関数的にストレスを与えます。 – zzarbi