net.java.ao.cache.CacheLayerの概要(javadocの日本語訳)

https://activeobjects.dev.java.net/api/net/java/ao/cache/CacheLayer.htmlのクラスの概要を翻訳しました。

本文

エンティティのキャッシュの値セマンティクス*1を管理するクラスの上位インタフェースです。このインタフェースの実装は、対応するキャッシュ(Cache)の実装に割り当てられたリソースを使用することで、実際のキャッシュ操作を行います。

Superinterface for classes which manage the cache semantics for specific entity values. Implementations of this interface are what actually handle the meat of the cache operation, using resources allocated within the corresponding Cache implementation.

基本的なキャッシュモデルは、Mapインタフェースのモデルと同じです(ActiveObjectsは単純にHashMapでキャッシュしているため)。値は文字列のキーに基づいてキャッシュ中に記憶されます。これらの値はObjectにアップキャストされますが、正しい型で取得できるように型情報を保持する必要があります。AOでは、キャッシュを使用するコードが値を適切な型にキャストできることを想定しているため、このことは非常に重要です。したがって、すべてのキャッシュの実装は値の型を内部に記憶する必要があります。

The basic cache model is that of the Map interface (which is logical as ActiveObjects was originally cached with a conventional HashMap). Values are stored in the cache based on String keys. These values must be typed within the cache and returned in their proper type, up-cast to Object. This is extremely important since AO will assume that values can be cast to their appropriate types within code which uses the cache. Thus, any cache implementation must also store value types in its implementation. It is also critical that any cache implementation be able to store null values. Technically, null values may be dropped for non-dirty fields, but this will lead to decreased performance in the entity accessor algorithm. Null keys need not be accepted.

キャッシュは値を永久に保持し続ける必要はありません。たとえば、分散されたバックエンド実装においては、値の有効期限を実装することが強く推奨されています。同様に、ローカルキャッシュにおいても、(メモリのような)有限なリソースへの配慮することがあります。ActiveObjectsの中心となる実装は、値を保持する期間が一定でないことを想定しており、問題はありません。実際のところ、キャッシュ層の実装は呼び出しに対して適切に応じれさえすればよいので、キャッシュを全く行わないことも技術的には可能です。このようなことができるのは確かですが、パフォーマンスは非常に不利になるでしょう。キーと値をできるだけ長く保持し続けられるよう、実装は最大限の努力をすべきです。AOの複数のインスタンスがキャッシュへアクセスしなければ、値自体は決して陳腐化(DBと一致しない状態になること)しません。

Cache bindings themselves need not be persistent. For example, it is strongly encouraged to implement value expiry on implementations with a distributed backend. Likewise, local caches may take into account finite resources (such as memory). There is nothing in the ActiveObjects core implementation which assumes that bindings will be persistent for any length of time. In fact, it is technically permissible to implement a cache layer which does not cache at all, but simply responds appropriately when invoked. Note that while this is certainly possible, it would be quite detrimental to performance. Implementations should make the utmost effort to ensure that key,value bindings persist for as long as possible. The values themselves will never become stale (out of sync with the DB) unless the cache is being accessed by multiple instnaces of AO.

ActiveObjectsが正しく動作するために、このインタフェースのすべてのメソッドを実装する必要があるということは、重要です。いくつかのメソッドの実装を省いても動作に重大な影響ないかもしれませんが、そうなると仮定すべきではありません。このことは、(memcachedような)キャッシュが有限なバックエンドを使用する場合、特に重要です。契約は必ず満たさなければなりません。

It is important to note that all of the methods in the interface must be implemented for ActiveObjects to function properly. A few of the methods may be omitted without affecting critical functionality, but this should not be assumed. This fact is especially important to keep in mind when working with limitted cache backends (such as memcached). By whatever means necessary, the contract must be fullfilled.

すべての実装、特に分散されたバックエンドにおいては、並行性を考慮する必要があります。ActiveObjectsはキャッシュへの呼び出しの同期を行わず、同期の動作はキャッシュの実装自体に任せされています。ActiveObjectsでは、キャッシュのコードブロック全体をロックしないため、分散キャッシュを行うと本質的に競合状態になりやすく、データは陳腐化しやすくなります。この設計上の判断は将来的には変更するかもしれませんが、今のところパフォーマンスの安定性を重視しているためこのままにしています。そのため、(memcachedのような)分散バックエンドを使用したキャッシュでは、無効なデータが自然と有効期限切れになるよう、十分に短いデフォルトタイムアウトを使用することを推奨しています。

Concurrency must be considered for all implementations, but especially those with a distributed backend. ActiveObjects does not synchronize calls to the cache, that task is left up to the cache implementation itself. Due to the fact that entire code blocks are not locked against the cache, ActiveObjects is inherantly prone to race conditions and stale data in distributed caches. This is a design decision which may change in future, but for now it remains due to performance and stability concerns. For this reason, caches with distributed backends (such as memcached) are encouraged to set a sufficiently short default timeout to allow invalid data to simply expire naturally.

特殊な場合を除いて、CacheLayerの実装は揮発性の高いリソースを管理すべきではありません。これらは対応するValueCacheの実装で扱うべきです。値キャッシュが「何」を扱い、キャッシュ層が「どのように」を管理するというのが、一般的な経験則です。

Except in odd cases, CacheLayer implementations should not manage volatile resources themselves. All of this work should be handled within the corresponding ValueCache implementation. The general rule of thumb is that the value cache handles the "what" while the cache layer manages the "how".

*1:値セマンティクスは、割当てで参照またはアドレス(ポインタなど)ではなく値がコピーされることを示します。http://otndnld.oracle.co.jp/document/products/oracle11g/111/windows/E06104-01/glossary.htmより