2012-01-23 7 views
1

私は、クエリによって高価なグループを避けるために、特定の情報をmembaseにロールアップしたいアプリケーションがあります。たとえば、クリックコンバージョンがMySQLに記録され、特定のユーザーのmemcacheキーでの稼働時間の合計を時間単位で管理したいとします。 私は必要な値で配列をun/serializeすることができます。mysqlとmemcached/membaseを同期させる

MCとMysqlが同期していることを保証する何らかの「トランザクション」を作成するにはどうすればよいでしょうか?私は基本的なMySQLストアに基づいてキーストアをいつも再構築することができましたが、私は2つの製品間の良好な並行性を維持したいと考えています。

答えて

0

ハイレベルで、MemBase値/ memcacheのを使用するためには/ etc MySQL用のキャッシュとして、次のような何かをしたいと思うが:

public Object readMethod(String key) { 
    value = membaseDriver->get(key); 
    if(value != null) { 
     return value; 
    } 
    value = getFromMysql(key); 
    membaseDriver->put(key, value, TTL); 
} 

public Object writeMethod(String key, String value) { 
    writeToMysql(key, value); 
    membaseDriver->delete(key); 
    //next call to get will get the value that we just wrote to db 
} 

これはあなたのDBは、の主なソースのままであることを保証しますデータとmembaseとmysqlはとほぼ一致するようにします。が同期しています。 (プロセスがwriteメソッドを実行している間、mysqlに書き込んだ後に、そしてそれがmembaseからキーを削除する前に、ではありません)。

本当に同期したい場合は、プロセスがwriteMethodを実行しているときに、readMethodを実行できるプロセスがないことを確認する必要があります。 addメソッドを使用すると、memcache/membaseで単純なグローバルロックを行うことができます。基本的には、ロックの後に名前のついたユニークなキーを追加します(例: "MY_LOCK")。あなたの書き込みを完了したら、ロックのキー名でdeleteを呼び出すことによってロックを解除します。その "ロック"で両方のメソッドを起動し、両方のメソッドを "アンロック"で終えると、一度に1つのプロセスだけがどちらかを実行していることが保証されます。また、別の読み書きロックを構築することもできますが、99.999%の最新のものではなく、100%の最新のものにする必要がなければ、ロックを本当にしたいとは思わないと思います。

クリック1時間あたりのケースでは、現在の時間(つまり、変更する唯一の時間)を前のすべての時間の配列とは別に保持して別のクリックをカウントするたびにクエリを再実行する必要がなくなります(これは決して変わることはないでしょうか?)

クリックを追加するたびに、現時点のカウンタでmemcacheインクリメントを使用してください。次に、読み込み要求を受け取ったら、前のすべての時間、現在の時間、および前のすべての時間と、最後に現在の時間を追加した配列を検索します。無料のボーナスとして、インクリメントがアトミックであるという事実は実際に同期された値を提供するので、ロックをスキップすることができます。

関連する問題