キャッシュを無効—ある一般的な溶液とはなんですか?
-
19-09-2019 - |
質問
"が困難な問題のコンピュータ科学キャッシュを無効化およびネーミングを思い出すのもいいでしょう。
フィルKarlton
が一般的解法を覆し、キャッシュ;い場合には陳腐などの保証は常に新鮮なデータはもらえますか?
たとえば、次の機能 getData()
取得するデータからのファイルです。でキャッシュでの最終更新日時のファイルをチェックするだけであるため毎時間で呼び出されます。
その後を追加した第二の機能 transformData()
を変化させるデータキャッシュその結果、次の機能が呼び出されます。Itに関する知識が全くないファイルのどん追加に依存した場合には、ファイルを変更し、このキャッシュが無効になり?
き getData()
毎回 transformData()
と呼ばれと比較してみることをしたときの値を用い、キャッシュになれない多額のコストがかかります。
解決
うお話をしているが寿命の依存関係のチェーンうすることで、そのひとつのことに依存した変更可能な外ではとてもうまくいっています。
とした場合に例外:機能から a
, b
へ c
の場合 a
や b
同じものを c
は同じですが、コストの確認 b
が高いときのいずれかの
- 受け入れる時には操作の日付情報としない必ず確認してください
b
- いレベルをチェック
b
このときの
できない場合もありますのでごケーキを食べ---
できれば層の追加のキャッシュに基づく a
以上のその影響を最初に問題ないます。を選択した場合に1になければなら何でも自由にやりくりは夫婦で別にされていま自分自身でこのようにキャッシュよりも決して忘れてはいけないと思うの妥当性、キャッシュに格納された値 b
.を選択した場合2だチェック b
毎時間がかかることができ、キャッシュ a
の場合 b
チェック。
場合層キャッシュが必要と考えているかどうか取得します侵害の規則のシステムを組み合わせ活動しています。
い a
常に有効の場合 b
はその費用を節約することができキャッシュのような(擬似コード):
private map<b,map<a,c>> cache //
private func realFunction // (a,b) -> c
get(a, b)
{
c result;
map<a,c> endCache;
if (cache[b] expired or not present)
{
remove all b -> * entries in cache;
endCache = new map<a,c>();
add to cache b -> endCache;
}
else
{
endCache = cache[b];
}
if (endCache[a] not present) // important line
{
result = realFunction(a,b);
endCache[a] = result;
}
else
{
result = endCache[a];
}
return result;
}
明らかに連続すね(言 x
はないとして、各段階での有効性は、新たに追加された入力にマッチし a
:b
関係 x
:b
や x
:a
.
しかしあるものと思いますので、う三つの入力が有効でしたら完全に独立て(循環式)、積層することが可能である。この意味を示されているライン//重要な考えを変更へ
if(endCache[a] 期間の満了日または 存在しない)
他のヒント
キャッシュの無効化の問題点は、私たちはそれについて知らなくても、その原料の変化です。それについて知っているんや私たちを通知することができ、いくつかの他の事があるのであれば、いくつかのケースでは、解決策が可能です。与えられた例では、のgetData関数は関係なく、どのようなプロセスのファイルを変更し、ひいてはこのコンポーネントがデータを変換コンポーネントに通知することもでき、ファイルへのすべての変更について知っているんれ、ファイルシステムにフックすることができます。
私はこの問題は、離れて行くようにする任意の一般的な魔法の修正はないと思います。しかし、多くの実用的な例では非常によく、「中断」の問題は、単に離れて行くことができますいずれかをベースに「ポーリング」ベースのアプローチを変革する機会があるかもしれません。
、その後、あなたはキャッシュの全体の利益を排除しました。
あなたの例では、それはまた、データから生成されたファイルのファイル名と最終更新日時を保存するために、あなたが変換されたデータを生成するときのためになる解決策のように思える(すでに返されたどんなデータ構造でこれを保存しますgetData()によって、あなただけコピーしてそのtransformData()によって返されたデータ構造に記録)、あなたは再びtransformData()を呼び出すときに、ファイルの最終更新時間をチェックします。
IMHO、官能性反応プログラミング(FRP)意味でのキャッシュの無効化を解決するための一般的な方法です。
FRPの用語では、古いデータはグリッチに呼び出されます。ここではその理由です。 FRPの目標の一つは、グリッチのないことを保証することです。
FRPはトークの「FRPのエッセンス」こので詳しく説明されており、このにSO に答えます。
Cells のhref="https://m.youtube.com/watch?v=CjEDmJMLEGE" rel="nofollow noreferrer">話は、キャッシュされたオブジェクト/エンティティを表し、Cell
ですそれの依存関係の一つが更新される場合にリフレッシュ。
FRPは、依存関係グラフに関連した配管コードを隠し、何の古いCell
sがないことを確認します。
別の方法はb
(Haskellの表記)に変更可能な値のすべての識別子が含まれているライターモナドのWriter (Set (uuid)) b
のいくつかの種類に(タイプSet (uuid)
の)計算された値をラップされます計算された値のb
は依存しています。だから、uuid
は可変値/変数を識別する一意の識別子のいくつかの種類がある(例えば、データベース内の列)を計算b
が依存している。
作家モナドのこの種で動作し、あなただけの新しいb
を計算するためにこれらのコンビネータを使用する場合には、一般的なキャッシュ無効化ソリューションのいくつかの種類につながる可能性コンビネータでこのアイデアを組み合わせます。そのようなコンビネータは、ライターモナドとfilter
によって識別(uuid, a)
が可変データ/可変入力、などa
-Sを取る(uuid
の特別バージョンを言います)。
だから、毎回あなたがタイプ(uuid, a)
の計算値が、その後、あなたがいずれかを変異させる場合b
が含まれているキャッシュを無効にすることができます依存している(b
が計算された、データベース内の正規化されたデータを言う)「オリジナル」のデータb
を変更しますWriterのa
に基づいているため、この問題が発生したときに、計算b
値が依存する値Set (uuid)
は、モナドあなたが言うことができます。
だから、いつでもあなたが与えられたuuid
で何かを変異させ、b
uuid
が包まれているライターモナドができるので、言った、あなたはすべてのキャッシュ-Sにこの変異をブロードキャストし、彼らがで識別可変値に依存する値のb
を無効にそのb
が言っuuid
に依存かどう伝えます。
もちろん、これはのみオフに支払っています。
<時間>第三の、実用的なアプローチは、データベース内のビュー-Sをマテリアライズド使用してキャッシュ-ESとしてそれらを使用することです。私の知る限り、彼らはまた、無効化の問題を解決することを目指しています。もちろんこれは、導出されたデータに可変データを接続する動作を制限します。
ようにアプローチ現に基づく PostSharp や memoizing機能.思いで過去に私のアカデミック-メンター、そうでな実施のキャッシュでコンテンツ-agnosticます。
各機能が付属性を指定する期限ます。各機能マでは、このmemoizedの結果が格納されるキャッシュ、ハッシュ関数の呼びパラメータとして使用しています。を使用してい 速度 のバックエンドが取り扱っている分布のキャッシュデータです。
エントリが古くなっているときは、常に新鮮なデータを取得することが保証されているので、知っている?、キャッシュを作成するための一般的な解決策や方法があります。
いいえ、すべてのデータが異なるため。一部のデータは、いくつかの時間後に、分後に「古い」とすることができ、いくつかは数日または数ヶ月のために細かいかもしれません。
あなたの具体的な例については、最も簡単な解決策は、あなたがgetData
とtransformData
の両方から呼び出すファイルのための機能「をチェックキャッシュ」を持つことです。
ありません一般的な溶液が
すキャッシュにとってはプロキシュ).想定キャッシュ知の起源の変化のタイムスタンプ、誰かに電話
getData()
, のキャッシュの原点での最終変更のタイムスタンプの場合と同じでを返しますキャッシュ、それ以外の場合、更新コンテンツのソースを一つ戻りすることを決定しました。(バリエーションがクライアントに直接送信のタイムスタンプに要求、ソースが返すコンテンツの場合、そのタイムスタンプが異なります。)はそのままご利用いただけ通知プロセス(プッシュ)、キャッシュのソースの場合、ソースの変更が送信される通知のキャッシュして<日本語仮抄訳>欧州連としての"汚染".れば通話
getData()
キャッシュの最初の更新のソースを取り外しての"汚染"の旗;その後戻りすることを決定しました。
は一般的に依存す:
- 周波数:多くの呼びかけ
getData()
ことを望でを避けるために源泉をも水没する恐れがあるgetTimestamp機能 - お客様のアクセスにはソース:ご所有のソースモデルかどうかを示します。ない場合はチャンスを追加することはできませんの他の通知です。
注意:使用タイムスタンプは従来のhttpプロキシは、別のアプローチが共有ハッシュコンテンツの格納されています。みんなのために2つの事業体に更新とは呼びます(引き)またはお電話に---(プッシュ)まることはありません。
キャッシュは難しいです。 1)キャッシュは複数のノードで、彼らのためにコンセンサスを必要とします 2)無効化時間 3)競合状態multple取得/設定が発生したとき
これは良い読書です。 https://www.confluent.io /ブログ/ターニング・データベース・インサイドアウト-と-のapache-samza / の
おそらくキャッシュ忘れアルゴリズムは、最も一般的な(依存あるいは、少なくとも、以下のハードウェア構成)になります。ここではその上にMITの講義です:キャッシュ紛失アルゴリズム