Apache Traffic Server 6.2 - en to ja translation catalogue (211 entries)

en: Cache Architecture
ja: キャッシュアーキテクチャ

en: Introduction
ja: 導入

en: In addition to being an HTTP proxy, |ATS| is also an HTTP cache. |TS| can cache any octet stream, although it currently supports only those octet streams delivered by the HTTP protocol. When such a stream is cached (along with the HTTP protocol headers) it is termed an :term:`object <cache object>` in the cache. Each object is identified by a globally unique value called a :term:`cache key`.
ja: |ATS| は HTTP プロキシーであると同時に HTTP キャッシュでもあります。 |TS| はどんなオクテットストリームもキャッシュできますが、現状サポートしているのは HTTP プロトコルで配信されたオクテットストリームのみです。そういがストリームが (HTTP プロトコルヘッダーと共に) キャッシュされたとき、それはキャッシュ内の :term:`オブジェクト <キャッシュ オブジェクト>` と呼ばれます。それぞれのオブジェクトは :term:`キャッシュキー` と呼ばれるグローバルにユニークな値によって識別されます。

en: Unfortunately, the internal terminology is not particularly consistent, so this document will frequently use terms in different ways than they are used in the code in an attempt to create some consistency.
ja: 不幸なことに、内部用語は一貫していません。そのためこのドキュメントにおいては一貫性を得るためにコード内で使われるものとは違った方法で頻繁に用語を使用します。

en: Cache Layout
ja: キャッシュレイアウト

en: The following sections describe how persistent cache data is structured. |TS| treats its persisent storage as an undifferentiated collection of bytes, assuming no other structure to it. In particular, it does not use the file system of the host operating system. If a file is used it is used only to mark out the set of bytes to be used.
ja: 次節では永続的キャッシュデータがどのような構造を持つかを説明します。 |TS| は永続的ストレージを区別されてないバイト列の集合として扱い、それ以外の構造を仮定しません。特に、ホストオペレーティングシステムのファイルシステムは使用しません。ファイルが使われるとすればそれは使用される一組のバイト列を区切るために使われます。

en: Cache storage
ja: キャッシュストレージ

en: The raw storage for the |TS| cache is configured in :file:`storage.config`. Each line in the file defines a :term:`cache span` which is treated as a uniform persistent store.
ja: |TS| キャッシュ用の生のストレージは :file:`storage.config` で設定されます。ファイルの各行は :term:`キャッシュスパン` を定義し、それが一律の永続ストアとして扱われます。

en: Two cache spans
ja: 二つのキャッシュスパン

en: This storage organized into a set of :term:`cache volumes <cache volume>` which are defined in :file:`volume.config`. These are the units that are used for all other administator level configuration.
ja: このストレージは一組の :term:`キャッシュボリューム` で構成されます。 :term:`キャッシュボリューム` は :file:`volume.config` で定義されます。これらは全ての他の管理レベルの設定に使われる単位となります。

en: Cache volumes can be defined by a percentage of the total storage or as an absolute amount of storage. By default, each cache volume is spread across all of the cache spans for robustness. The intersection of a cache volume and a cache span is a :term:`cache stripe`. Each cache span is divided into cache stripes and each cache volume is a collection of those stripes.
ja: キャッシュボリュームは全体のストレージのパーセンテージかあるいはストレージの絶対的な量で定義できます。デフォルトでは、それぞれのキャッシュボリュームは堅牢性のため全てのキャッシュスパンに散在されます。キャッシュボリュームとキャッシュスパンの共通部分が :term:`キャッシュストライプ` です。それぞれのキャッシュスパンは複数のキャッシュストライプに分割されますし、それぞれのキャッシュボリュームはこれらのストライプの集合です。

en: If the cache volumes for the example cache spans were defined as:
ja: もし、例としてキャッシュスパンのキャッシュボリュームが以下のように定義されていたら

en: Then the actual layout would look like:
ja: 実際のレイアウトはこのようになるでしょう。

en: Cache stripes are the fundamental unit of cache for the implementation. A cached object is stored entirely in a single stripe, and therefore in a single cache span. Objects are never split across cache spans or volumes. Objects are assigned to a stripe (and in turn to a cache volume) automatically based on a hash of the URI used to retrieve the object from the :term:`origin server`. It is possible to configure this to a limited extent in :file:`hosting.config`, which supports content from specific hosts or domain to be stored on specific cache volumes. As of version 4.0.1 it is also possible to control which cache spans (and hence, which cache stripes) are contained in a specific cache volume.
ja: キャッシュストライプはキャッシュを実装するための基本的な単位です。キャッシュされたオブジェクトは全体が単一のストライプひいては単一のキャッシュスパンに保存されます。オブジェクトが複数のキャッシュスパンやボリュームに分割されることは決してありません。オブジェクトは :term:`オリジンサーバー` からオブジェクトを取得するために使われた URI。 のハッシュに基いて自動的にストライプに割り当てられ (そして同様にキャッシュボリュームにも割り当てられ) ます。これは :file:`hosting.config` である程度までは制御することが出来、特定のホストやドメインからのコンテンツを特定のキャッシュボリュームに保存することをサポートしています。バージョン 4.0.1 以降では特定のキャッシュボリュームの中のどのキャッシュスパン (そしてその結果どのキャッシュストライプ) にするかも制御することができます。

en: The layout and structure of the cache spans, the cache volumes, and the cache stripes that compose them are derived entirely from :file:`storage.config` and :file:`cache.config` and is recomputed from scratch when the :program:`traffic_server` is started. Therefore, any change to those files can (and almost always will) invalidate the existing cache in its entirety.
ja: キャッシュスパン、キャッシュボリューム、そしてそれらを構成するキャッシュストライプのレイアウトと構造は、全て :file:`storage.config` と:file:`cache.config` から取得され、 :process:`traffic_server` が開始された時にはじめから再計算されます。従って、これらのファイルへの任意の変更は(ほとんど常に)それら全ての既存のキャッシュを無効化します。

en: Stripe Structure
ja: ストライプ構造

en: |TS| treats the storage associated with a cache stripe as an undifferentiated span of bytes. Internally each stripe is treated almost entirely independently. The data structures described in this section are duplicated for each stripe. Internally the term *volume* is used for these stripes and implemented primarily in :cpp:class:`Vol`. What a user thinks of as a volume (and what this document calls a *cache volume*) is represented by :cpp:class:`CacheVol`.
ja: TS| は、キャッシュストライプと結び付けられたストレージを区別されないバイト列のスパンとして扱います。内部的に各ストライプはほぼ完全に独立して扱われます。この節で記述されるデータ構造は、各ストライプに複製されます。内部的に *ボリューム* という単語はこれらのストライプに使用され、主に :cpp:class:`Vol` で実装されています。ユーザが思うボリューム (このドキュメントでは *キャッシュボリューム* ) は、 :cpp:class:`CacheVol` で表現されます。

en: Stripe assignment must be done before working with an object because the directory is local to the stripe. Any cached objects for which the stripe assignment is changed are effectively lost as their directory data will not be found in the new stripe.
ja: ディレクトリはストライプに配置されるため、ストライプ割当はオブジェクトを扱うような動作をする前に行われなければなりません。ストライプ割当が変更されたキャッシュオブジェクトは、新しいストライプ上で発見されないであろうディレクトリデータとして事実上消失します。

en: Cache Directory
ja: キャッシュディレクトリ

en: Content in a stripe is tracked via a directory. Each element of the directory is a :term:`directory entry` and is represented by :cpp:class:`Dir`. Each entry refers to a chunk of contiguous storage in the cache. These are referred to variously as *fragments*, *segments*, *docs*, *documents*, and a few other things. This document will use the term *fragment* as that is the most common reference in the code. The term *Doc* (for :cpp:class:`Doc`) will be used to refer to the header data for a fragment. Overall, the directory is treated as a hash with the :term:`cache ID` as the key. See :ref:`directory probing <cache-directory-probe>` for how the cache ID is used to locate a directory entry. The cache ID is in turn computed from a :term:`cache key` which by default is the URL of the content.
ja: コンテンツはディレクトリを使って追跡されます。ディレクトリの各要素は :term:`ディレクトリエントリ` と呼ばれ :cpp:class:`Dir` で表されます。各エントリはキャッシュ内の連続したストレージのチャンクを参照します。これらは *フラグメント* 、 *セグメント* 、 *docs* 、 *ドキュメント* 、その他いくつかのものとしてさまざまな呼ばれ方をします。コード内で最もよく参照されているのでこのドキュメントでは *フラグメント* という用語を使います。(:cpp:class:`Doc` に対応する) *Doc* はフラグメントへのヘッダーデータに言及するときに使用します。概してディレクトリは :term:`キャッシュ ID` をキーとしたハッシュとして扱われます。キャッシュ ID がディレクトリエントリを発見するためにどのように使われるかについては :ref:`ディレクトリ検索 <cache-directory-probe>` を参照してください。次にキャッシュ ID は :term:`キャッシュキー` から計算されます。  :term:`キャッシュキー` はデフォルトではコンテンツの URL です。

en: The directory is used as a memory resident structure, which means a directory entry is as small as possible (currently 10 bytes). This forces some compromises on the data that can be stored there. On the other hand this means that most cache misses do not require disk I/O, which has a large performance benefit.
ja: ディレクトリはメモリに常駐する構成で使用されるので、ディレクトリエントリは可能な限り小さくなっています。（現在は 10 バイト）このことは、そこに保存できるデータに幾つかの制約を強要します。一方でほとんどのキャッシュミスはディスク I/O を要求せず、大きな性能面の恩恵を得ることになります。

en: The directory is always fully sized; once a stripe is initialized the directory size is fixed and never changed. This size is related (roughly linearly) to the size of the stripe. It is for this reason the memory footprint of |TS| depends strongly on the size of the disk cache. Because the directory size does not change, neither does this memory requirement, so |TS| does not consume more memory as more content is stored in the cache. If there is enough memory to run |TS| with an empty cache there is enough to run it with a full cache.
ja: ディレクトリは常に最大のサイズになります。ストライプが一旦初期化されると、ディレクトリサイズは固定されて二度と変更されません。このサイズは、ストライプのサイズに（大雑把に、線形に）関係します。この理由により |TS| のメモリ使用量は、ディスクキャッシュのサイズに強く依存します。ディレクトリサイズは変わらずメモリ要件もまた変わらないため、 |TS| がキャッシュに保存されたコンテンツが増えてもメモリ消費量が増えることはありません。キャッシュが空の状態で |TS| を動作させるのに十分なメモリがあるなら、キャッシュが満ちた状態で動作するのに十分です。

en: Each entry stores an offset in the stripe and a size. The size stored in the directory entry is an :ref:`approximate size <dir-size>` which is at least as big as the actual data in the fragment. Exact size data is stored in the fragment header on disk.
ja: それぞれのエントリはストライプ内でのオフセットとサイズを保存します。ディレクトリエントリに保存されるサイズは  :ref:`おおよそのサイズ <dir-size>` でありフラグメント内の実際のデータと最低でも同じになります。正確なサイズデータはディスク上のフラグメントヘッダーに保存されます。

en: Data in HTTP headers cannot be examined without disk I/O. This includes the original URL for the object. The cache key is not stored explicitly and therefore cannot be reliably retrieved.
ja: HTTP ヘッダー内のデータはディスク I/O 無しに調べることは出来ません。これにはオブジェクトの元の URL を含みます。キャッシュキーは明示的には保存されていないので、その結果確実に取得することは出来ません。

en: The directory is a hash table that uses `chaining <http://en.wikibooks.org/wiki/Data_Structures/Hash_Tables#Collision_resolution>`_ for collision resolution. Because each entry is small they are used directly as the list header of the hash bucket.
ja: ディレクトリは衝突解決に `チェイン法 <http://en.wikibooks.org/wiki/Data_Structures/Hash_Tables#Collision_resolution>`_ を使うハッシュテーブルです。各エントリは小さいのでハッシュバケットのリストヘッダーとして直接使用されます。

en: Chaining is implemented by imposing grouping structures on the entries in a directory. The first level grouping is a :term:`directory bucket`. This is a fixed number (currently 4, defined as ``DIR_DEPTH``) of entries. This serves to define the basic hash buckets with the first entry in each cache bucket serving as the root of the hash bucket.
ja: チェイン法はグループ化する構造をディレクトリ内のエントリに課すことで実装されています。第一レベルのグルーピングは :term:`ディレクトリバケット` です。これは固定の数 (現在は 4 、``DIR_DEPTH`` で定義されています)のエントリです。これはそれぞれのキャッシュバケット内に最初のエントリを持つ基本的なハッシュバケットを定義するのに役立ちます。キャッシュバケットはハッシュバケットのルートの役目を果たします。

en: The term *bucket* is used in the code to mean both the conceptual bucket for hashing and for a structural grouping mechanism in the directory. These will be qualified as needed to distinguish them. The unqualified term *bucket* is almost always used to mean the structural grouping in the directory.
ja: *バケット* という用語はハッシングのための概念的なバケットとディレクトリ内の構造をグループ化するメカニズムの両方を意味するコードで使われています。これらを区別する必要に応じてこれらは修飾されます。修飾無しの *バケット* という用語はほぼ常にディレクトリ内の構造をグループ化することを意味するのに使われます。

en: Directory buckets are grouped in to :term:`segments <directory segment>`. All segments in a stripe have the same number of buckets. The number of segments in a stripe is chosen so that each segment has as many buckets as possible without exceeding 65,535 (2\ :sup:`16`\ -1) entries in a segment.
ja: ディレクトリバケットは :term:`セグメント <ディレクトリセグメント>` の中にグループ化されます。ストライプの中の全てのセグメントは同じ数のバケットを持ちます。ストライプ内のセグメントの数は 1 つのセグメント内のエントリの数が 65,535 (2\ :sup:`16`\ -1 を超えない範囲で各セグメントがなるべく多くのバケットを持つように選ばれます。

en: Each directory entry has a previous and next index value which is used to link entries in the same segment. Because no segment has more than 65,535 entries, 16 bits suffices for storing the index values. The stripe header contains an array of entry indices which are used as the roots of entry free lists, one for each segment. Active entries are stored via the bucket structure. When a stripe is initialized the first entry in each bucket is zeroed (marked unused) and all other entries are put in the corresponding segment free list in the stripe header. This means the first entry of each :term:`directory bucket` is used as the root of a hash bucket and is therefore marked unused rather than being put a free list. The other entries in the directory bucket are preferred for adding to the corresponding hash bucket but this is not required. The segment free lists are initialized such that the extra bucket entries are added in order; all the seconds, then the thirds, then the fourths. Because the free lists are FIFOs, this means extra entries will be selected from the fourth entries across all the buckets first, then the thirds, etc. When allocating a new directory entry in a bucket the entries are searched from first to last, which maximizes bucket locality (that is, :term:`cache IDs <cache ID>` that map to the same hash bucket will also tend to use the same directory bucket).
ja: 各ディレクトリエントリは前と次のインデックス値を持ちそれは同一セグメント内のエントリを結びつけるために使われます。 65,535 エントリより多くを持つセグメントは存在しないので、インデックス値を保存するには 16 ビットあれば十分です。ストライプヘッダーはエントリインデックスの配列を格納し、エントリインデックスはエントリのフリーリストのルートとして使われます。ルートそれぞれのセグメントに 1 つ存在します。アクティブなエントリはバケット構造を使って保存されます。ストライプが初期化されるとき、それぞれのバケットの最初のエントリはゼロクリア (未使用とマーク) され、他のエントリはストライプヘッダー内の対応するセグメントのフリーリストに置かれます。これはそれぞれの :term:`ディレクトリバケット` の最初のエントリはハッシュバケットのルートとして使われ、そのためフリーリスト内に置かれるよりは未使用としてマークされることを意味します。ディレクトリバケット内の他のエントリは対応するハッシュバケットに追加されることが望ましいですが、必須ではありません。セグメントのフリーリストは予備のバケットエントリが順番に追加されるように初期化され、全ての第 2 ディレクトリバケット、第 3 ディレクトリバケット、そして第 4 ディレクトリバケットが続きます。フリーリストは FIFO なので、これは予備のエントリはまず全ての第 4 ディレクトリバケットから選択され、次に第 3 ディレクトリバケットから選択され、などとなることを意味します。バケット内に新しいディレクトリエントリを割り当てるときはエントリは先頭から最後に検索され、バケットの局所性 (つまり、同じハッシュバケットにマッピングする :term:`キャッシュ ID` は同じディレクトリバケットを使う傾向が強くなるように) を最大化します。

en: Storage Layout
ja: ストレージレイアウト

en: The storage layout is the stripe metadata followed by cached content. The metadata consists of three parts: the stripe header, the directory, and the stripe footer. The metadata is stored twice. The header and the footer are instances of :cpp:class:`VolHeaderFooter`. This is a stub structure which can have a trailing variable sized array. This array is used as the segment free list roots in the directory. Each contains the segment index of the first element of the free list for the segment. The footer is a copy of the header without the segment free lists. This makes the size of the header dependent on the directory but not that of the footer.
ja: ストレージレイアウトは、ストライプメタデータの後ろにキャッシュされたコンテンツが続きます。メタデータは三つの要素、ストライプヘッダ、ディレクトリ、ストライプフッタで構成されます。メタデータは二度保存されます。ヘッダとフッタは :cpp:class:`VolHeaderFooter` のインスタンスです。これは可変長配列を末尾に持つことができるスタブ構造体です。この配列はディレクトリのルートのセグメントフリーリストとして使用されます。各要素はセグメントのフリーリストの、最初の要素のセグメントインデックスを持ちます。フッタは、セグメントフリーリストを伴わないヘッダのコピーです。ヘッダのサイズはディレクトリに依存しますが、フッタは依存しません。

en: Each stripe has several values that describe its basic layout:
ja: 各ストライプは、基本的なレイアウトを表現する幾つかの値を持ちます。

en: The start of stripe data. This represents either space reserved at the start of a physical device to avoid problems with the host operating system, or an offset representing use of space in the cache span by other stripes.
ja: ストライプデータの開始地点です。これはホストオペレーティングシステムによる問題を回避するために物理デバイスの始点に予約されたスペース、もしくは他のストライプにキャッシュスパンのスペースが使用されていることを表すオフセットのどちらかを表します。

en: The offset for the start of the content, after the stripe metadata.
ja: ストライプメタデータの後からの、コンテンツの開始地点を示すオフセット

en: Total number of bytes in the stripe. :cpp:member:`Vol::len`.
ja: ストライプのバイトの合計値。 :cpp:member:`Vol::len`

en: Total number of blocks in the stripe available for content storage. :cpp:member:`Vol::data_blocks`.
ja: コンテンツストレージとして使用可能なストライプのブロックの合計値。:cpp:member:`Vol::data_blocks`

en: Great care must be taken with sizes and lengths in the cache code because there are at least three different metrics (bytes, cache blocks, store blocks) used in various places.
ja: キャッシュコードの size や length を扱う場合、特に注意しなければなりません。これらは様々な箇所で、少なくとも三つの違うメトリクス(バイト、キャッシュブロック、ストアブロック)が使われているからです。

en: The total size of the directory (the number of :term:`entries <directory entry>`) is computed by taking the size of the :term:`cache stripe` and dividing by the average object size. The directory always consumes this amount of memory which has the effect that if cache size is increased so is the memory requirement for |TS|. The average object size defaults to 8000 bytes but can be configured using :ts:cv:`proxy.config.cache.min_average_object_size`. Increasing the average object size will reduce the memory footprint of the directory at the expense of reducing the number of distinct objects that can be stored in the cache.
ja: ディレクトリの合計サイズ (:term:`エントリ <ディレクトリエントリ>` 数) は、 :term:`キャッシュストライプ` のサイズを取得して平均オブジェクトサイズで割ることで計算されます。ディレクトリは常にメモリ量を消費し、それはもしキャッシュサイズが増加するなら |TS| のメモリ要件も増加するという効果を引き起こします。平均オブジェクトサイズはデフォルトでは 8000 バイトですが、 :ts:cv:`proxy.config.cache.min_average_object_size` で設定できます。平均オブジェクトサイズを増加させることにより、キャッシュに保存するオブジェクト数を減らすことと引き換えに、ディレクトリのメモリ使用量を減らすことができます。

en: The content area stores the actual objects and is used as a circular buffer where new objects overwrite the least recently cached objects. The location in a stripe where new cache data is written is called the *write cursor*. This means that objects can be de facto evicted from cache even if they have not expired if the data is overwritten by the write cursor. If an object is overwritten this is not detected at that time and the directory is not updated. Instead it will be noted if the object is accessed in the future and the disk read of the fragment fails.
ja: コンテンツエリアは実際のオブジェクトを保存し、最もキャッシュされてから時間が経過したオブジェクトを新たなドキュメントで上書きする循環バッファとして使用されます。ストライプの新たなキャッシュデータの位置は、 *書込みカーソル* と呼ばれます。これはデータが書込みカーソルによって上書きされる場合、たとえ失効していなくても、オブジェクトは事実上キャッシュから立ち退かせられることを意味します。もしオブジェクトが上書きされる場合、検出されずディレクトリは更新されません。代わりに、もしオブジェクトが将来アクセスされてフラグメントのディスク読込みが失敗する場合、警告されます。

en: The write cursor and documents in the cache.
ja: 書込みカーソルとキャッシュ内のドキュメント

en: Cache data on disk is never updated.
ja: ディスク上のキャッシュデータは永遠に更新されません。

en: This is a key thing to keep in mind. What appear to be updates (such as doing a refresh on :term:`stale` content and getting back a 304) are actually new copies of data being written at the write cursor. The originals are left as "dead" space which will be consumed when the write cursor arrives at that disk location. Once the stripe directory is updated (in memory) the original fragment in the cache is effectively destroyed. This is the general space management technique used in other cases as well. If an object needs to removed from cache, only the directory needs to be changed. No other work (and particularly, no disk I/O) needs to be done.
ja: これは、心に留めておくべき重要な事です。更新されるように見えるもの ( :term:`新鮮ではない` コンテンツをリフレッシュし、 304 を返すような) は、実際には書込みカーソルで書き込まれているデータの新しいコピーです。オリジナルは書込みカーソルがディスクのその位置に到着する時に消去される、 "死んだ" スペースとして残されます。一旦ストライプディレクトリが (メモリ内で) 更新されると、キャッシュ上のオリジナルのフラグメントは事実上破棄されます。これは他のケースでも同様に用いられる、一般的なスペース管理技術です。もしオブジェクトをキャッシュから削除する必要がある場合、ディレクトリだけ変更する必要があります。他の動作行う必要はありません (特にディスク I/O は必要ありません)。

en: Object Structure
ja: オブジェクトの構造

en: Objects are stored as two types of data: metadata and content data. Metadata is all the data about the object and the content and includes the HTTP headers. The content data is the content of the object, the octet stream delivered to the client as the object.
ja: オブジェクトは二つのデータのタイプ、メタデータとコンテンツデータとして保存されます。メタデータは、 HTTP ヘッダを含むオブジェクトとコンテンツに関する全てのデータです。コンテンツデータはオブジェクトのコンテンツで、オブジェクトとしてクライアントに配信されるオクテットストリームです。

en: Objects are rooted in a :cpp:class:`Doc` structure stored in the cache. :cpp:class:`Doc` serves as the header data for a :term:`cache fragment` and is contained at the start of every fragment. The first fragment for an object is termed the *first Doc* and always contains the object metadata. Any operation on the object will read this fragment first. The fragment is located by converting the :term:`cache key` for the object to a :term:`cache ID` and then doing a lookup for a :term:`directory entry` with that key. The directory entry has the offset and approximate size of the first fragment which is then read from the disk. This fragment will contain the request header and response along with overall object properties (such as content length).
ja: オブジェクトは、キャッシュに格納される :cpp:class:`Doc` 構造体をルートとします。:cpp:class:`Doc` は :term:`キャッシュフラグメント` のヘッダデータとして提供し、各フラグメントの先頭に置かれます。オブジェクトの最初のフラグメントは *先頭の Doc* と呼ばれ、常にオブジェクトメタデータを含んでいます。オブジェクトの任意の操作は、最初にこのフラグメントを読み込みます。そのフラグメントはオブジェクトの :term:`キャッシュキー` を :term:`キャッシュ ID` に変換することにより発見され、その後そのキーを使って :term:`ディレクトリエントリ` が検索されます。ディレクトリエントリは、その時ディスクから読み込まれる先頭のフラグメントのオフセットとおおよそのサイズを持ちます。このフラグメントは、全てのオブジェクトのプロパティ (コンテンツ長のような) に加えて、リクエストヘッダとレスポンスを持ちます。

en: |TS| supports `varying content <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44>`_ for objects. These are called :term:`alternates <alternate>`. All metadata for all alternates is stored in the first fragment including the set of alternates and the HTTP headers for them. This enables `alternate selection <http://trafficserver.apache.org/docs/trunk/sdk/http-hooks-and-transactions/http-alternate-selection.en.html>`_ to be done after the *first Doc* is read from disk. An object that has more than one alternate will have the alternate content stored separately from the first fragment. For objects with only one alternate the content may or may not be in the same (first) fragment as the metadata. Each separate alternate content is allocated a directory entry and the key for that entry is stored in the first fragment metadata.
ja: |TS| はオブジェクト用に `コンテンツ変換 <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44>`_ をサポートします。これらを :term:`代替` と呼びます。全ての代替の全メタデータは、代替のセットとそれらの HTTP ヘッダを含む先頭のフラグメントに格納されます。これは、 *先頭の Doc* がディスクから読込まれた後に、 `代替セクション <http://trafficserver.apache.org/docs/trunk/sdk/http-hooks-and-transactions/http-alternate-selection.en.html>`_  が実行されることを有効にします。複数の代替を持つオブジェクトは、先頭のフラグメントとは別に保存された代替コンテンツを持ちます。一つの代替のみ持つオブジェクトは、コンテンツはメタデータと同じ (先頭の) フラグメントに置かれるかもしれないし、そうでもないかもしれません。個々の分離された代替コンテンツはディレクトリエントリを割り当てられ、エントリのキーは先頭のフラグメントのメタデータに保存されます。

en: Prior to version 4.0.1, the header data was stored in the :cpp:class:`CacheHTTPInfoVector` class which was marshaled to a variable length area of the on disk image, followed by information about additional fragments if needed to store the object.
ja: バージョン 4.0.1 以前は、ヘッダデータはディスクイメージの可変長領域に整列される :cpp:class:`CacheHTTPInfoVector` クラス内に保存され、オブジェクトを保存する必要がある場合、追加フラグメント情報がその後ろに続きます。

en: ``Doc`` layout 3.2.0
ja: 3.2.0 の ``Doc`` レイアウト

en: This had the problem that with only one fragment table it could not be reliable for objects with more than one alternate[#multiple-alternates]_. Therefore, the fragment data was moved from being a separate variable length section of the metadata to being directly incorporated in to the :cpp:class:`CacheHTTPInfoVector`, yielding a layout of the following form.
ja: この方法では、一つのフラグメントテーブルのみでは複数の 代替[#multiple-alternates]_ を持つオブジェクトに対しては信頼性を確保できない問題がありました。したがって、フラグメントデータはメタデータ用に分離された可変長領域から :cpp:class:`CacheHTTPInfoVector` へ直接統合されるよう移動し、以下の形式のレイアウトに生まれ変わりました。

en: ``Doc`` layout 4.0.1
ja: 4.0.1 の ``Doc`` レイアウト

en: Each element in the vector contains for each alternate, in addition to the HTTP headers and the fragment table (if any), a :term:`cache key`. This cache key identifies a :term:`directory entry` that is referred to as the *earliest Doc*. This is the location where the content for the alternate begins.
ja: ベクターの各要素は、各代替に加えて (もしあれば) HTTP ヘッダとフラグメントテーブル、 :term:`キャッシュキー` を含みます。このキャッシュキーは *最古の Doc* として参照される :term:`ディレクトリエントリ` を特定します。これは代替のコンテンツの開始位置です。

en: When the object is first cached, it will have a single alternate and that will be stored (if not too large) in first ``Doc``. This is termed a *resident alternate* in the code. This can only happen on the initial store of the object. If the metadata is updated (such as a ``304`` response to an ``If-Modified-Since`` request) then unless the object is small, the object data will be left in the original fragment and a new fragment written as the first fragment, making the alternate non-resident. *Small* is defined as a length smaller than :ts:cv:`proxy.config.cache.alt_rewrite_max_size`.
ja: オブジェクトが最初にキャッシュされる際、それは単一の代替を持ち、 (大きすぎない場合は)  先頭の ``Doc`` に格納されます。これはコード中で *常駐代替* と呼ばれます。この処理はオブジェクトの最初の保存時にのみ発生し得ます。メタデータが更新される場合 (``If-Modified-Since`` リクエストに対し、 ``304`` を返すなど) 、オブジェクトが小さくなければ、オブジェクトデータはオリジナルのフラグメントに取り残され、新しいフラグメントが先頭のフラグメントとして書き込まれ、非常駐の代替を作成します。 :ts:cv:`proxy.config.cache.alt_rewrite_max_size` より小さい長さを、 *小さい* と定義します。

en: The :cpp:class:`CacheHTTPInfoVector` is stored only in the first ``Doc``. Subsequent ``Doc`` instances for the object, including the earliest ``Doc``, should have an ``hlen`` of zero and if not, it is ignored.
ja: :cpp:class:`CacheHTTPInfoVector` は first ``Doc`` にのみ保存されます。earliest ``Doc`` を含む、 first ``Doc`` に続くオブジェクトの ``Doc`` インスタンスはゼロの ``hlen`` を持つはずであり、もしそうでないものは無視されます。

en: Large objects are split in to multiple fragments when written to the cache. This is indicated by a total document length that is longer than the content in first ``Doc`` or an earliest ``Doc``. In such a case a fragment offset table is stored. This contains the byte offset in the object content of the first byte of content data for each fragment past the first (as the offset for the first is always zero). This allows range requests to be serviced much more efficiently for large objects, as intermediate fragments that do not contain data in the range can be skipped. The last fragment in the sequence is detected by the fragment size and offset reaching the end of the total size of the object, there is no explicit end mark. Each fragment is computationally chained from the previous in that the cache key for fragment N is computed by::
ja: 巨大なオブジェクトは、キャッシュに書き込まれる時に複数のフラグメントに分割されます。これは、ドキュメント長の合計が first ``Doc`` もしくは earliest ``Doc`` のコンテンツより長いことを示します。このような場合には、フラグメントオフセットテーブルが保存されます。このテーブルは（オフセットが常にゼロであるような）先頭のフラグメントの次以降の各フラグメントのコンテンツデータの先頭バイトを指し示す、オブジェクトコンテンツ全体の中でのバイトオフセットを含みます。これは範囲内のデータを含まない、中間にあるフラグメントをスキップ可能にすることで、巨大なオブジェクトを非常に効率的に提供するためのレンジリクエストを可能にします。シーケンスの最後のフラグメントは、明示的なエンドマーク無しにフラグメントサイズとオフセットがオブジェクトの合計サイズの最後に到達することにより検出されます。各フラグメントは、計算的に前のものと繋がっています。フラグメント N のキャッシュキーは、以下により計算されます::

en: Where ``next_key`` is a global function that deterministically computes a new cache key from an existing cache key.
ja: ここで ``next_key`` は既存のキャッシュキーから新しいキャッシュキーを決定論的に計算するグローバル関数です。

en: Objects with multiple fragments are laid out such that the data fragments (including the earliest ``Doc``) are written first and the first ``Doc`` is written last. When read from disk, both the first and earliest ``Doc`` are validated (tested to ensure that they haven't been overwritten by the write cursor) to verify that the entire document is present on disk (as they bookend the other fragments - the write cursor cannot overwrite them without overwriting at least one of the verified ``Doc`` instances). Note that while the fragments of a single object are ordered they are not necessarily contiguous, as data from different objects are interleaved as the data arrives in |TS|.
ja: 複数のフラグメントを伴うオブジェクトは、 (最古の ``Doc`` を含む) データフラグメントが先頭に書き込まれ、 先頭の ``Doc`` が末尾に書き込まれる形でレイアウトされます。ディスクから読み込まれる時、先頭と最古の ``Doc`` の両方は、ドキュメント全部がディスクに存在することを確認するため検証されます。 (それらが書込みカーソルにより上書きされていないことを確認することで試験されます)   (これらの ``Doc`` は他のフラグメントのブックエンドとなります。書込みカーソルは、検証された ``Doc`` インスタンスの少なくとも一つの上書き無しに、ドキュメントを上書き出来ません) 単一のオブジェクトのフラグメントは、 |TS| に届いたデータとして異なるオブジェクトのデータが挟み込められてしまうため、必ずしも隣接しないように並べられていることに注意してください。

en: Multi-alternate and multi-fragment object storage
ja: オブジェクトストレージの、複数の代替と複数のフラグメント

en: Documents which are pinned into the cache must not be overwritten so they are evacuated from in front of the write cursor. Each fragment is read and rewritten. There is a special lookup mechanism for objects that are being evacuated so that they can be found in memory rather than the potentially unreliable disk regions. The cache scans ahead of the write cursor to discover pinned objects as there is a dead zone immediately before the write cursor from which data cannot be evacuated. Evacuated data is read from disk and placed in the write queue and written as its turn comes up.
ja: キャッシュへピン留めされたドキュメントは上書きされてはならず、そのためそれらは書込みカーソルの前に退避させられます。各フラグメントは読み込まれ、再書込みされます。潜在的に信頼性の低いディスク領域ではなくメモリ上で検出できるよう、退避されるオブジェクトの特殊な検出メカニズムが存在します。データを退避させることができない書込みカーソル直前のデットゾーンがあるため、ピン留めされたオブジェクトを発見するためにキャッシュは書込みカーソルより先にスキャンします。退避されたデータはディスクから読み込まれて書込みキューに置かれ、出番が来ると書き込まれます。

en: Objects can only be pinned via :file:`cache.config` and while :ts:cv:`proxy.config.cache.permit.pinning` is set to non-zero (it is zero by default). Objects which are in use when the write cursor is near use the same underlying evacuation mechanism but are handled automatically and not via the explicit ``pinned`` bit in :cpp:class:`Dir`.
ja: オブジェクトは :file:`cache.config` ファイルと、 :ts:cv:`proxy.config.cache.permit.pinning` にゼロでない値 (デフォルトではゼロ) を設定した場合のみピン留めできます。書込みカーソルが接近している際に使用中のオブジェクトは、基本的な退避メカニズムを同様に使用しますが、 :cpp:class:`Dir` の明示的な ``ピン留め`` 無しに自動的に扱われます。

en: It could, under certain circumstances, be accurate for none of the alternates.
ja: それは、ある状況下では代替が正確になりません。

en: Additional Notes
ja: 追加情報

en: Some general observations on the data structures.
ja: データ構造のいくつかの概説。

en: Cyclone buffer
ja: 循環バッファ

en: Because the cache is a *cyclone cache*, objects are not preserved for an indefinite time. Even if the object is not :term:`stale` it can be overwritten as the cache cycles through its volume. Marking an object as *pinned* preserves the object through the passage of the write cursor but this is done by copying the object across the gap, in effect re-storing it in the cache. Pinning large objects or a large number objects can lead to excessive disk activity. The original purpose of pinning was for small, frequently used objects explicitly marked by the administrator.
ja: キャッシュは *循環キャッシュ* であるため、キャッシュオブジェクトは無期限の保存はされません。たとえオブジェクトが :term:`新鮮でない` わけではなくても、ボリュームのキャッシュサイクルとして上書きする可能性があります。 *ピン留め* してオブジェクトをマーキングすることにより書込みカーソルの通過をやり過ごしてオブジェクトを保護することができますが、これは書込みカーソルを跨いでオブジェクトをコピーすること、実際にはキャッシュ内に再保存を行うことによって処理されます。巨大なオブジェクトや大量のオブジェクトのピン留めは、過度のディスク動作を引き起こす場合があります。ピン留めの元々の目的は、管理者によって明示的にマークされた小さく頻繁に使用されるオブジェクトのためのものでした。

en: This means the purpose of expiration data on objects is simply to prevent them from being served to clients. They are not in the standard sense deleted or cleaned up. The space can't be immediately reclaimed in any event, because writing only happens at the write cursor. Deleting an object consists only of removing the directory entries in the volume directory which suffices to (eventually) free the space and render the document inaccessible.
ja: 循環バッファの目的は、単純にオブジェクトの失効データがクライアントに提供されるのを防ぐことです。失効データは一般的な意味での削除やクリーンアップはされません。書込み処理は書込みカーソルでのみ発生するので、どんなイベントにおいてもスペースは直ちには取り戻せません。オブジェクトの削除は (最終的には) スペースを解放してかつドキュメントをアクセス不可能にするのに十分な処理である、ボリュームディレクトリのディレクトリエントリの削除のみで成り立ちます。

en: Historically, the cache was designed this way because web content was relatively small and not particularly consistent. The design also provided high performance and low consistency requirements. There are no fragmentation issues for the storage, and both cache misses and object deletions require no disk I/O. It does not deal particularly well with long term storage of large objects. See the :ref:`volume tagging` appendix for details on some work in this area.
ja: ウェブコンテンツは比較的小さく特に一貫もしていなかったので、歴史的にキャッシュはこの方法の通りに設計されています。この設計は高性能でかつ低い一貫性の要件となります。ストレージのフラグメンテーション問題は発生せず、またキャッシュミスやオブジェクトの削除がディスク I/O を要求することもありません。巨大なオブジェクトの長期間保存は特別うまくは扱いません。この部分の動作の詳細については :ref:`ボリュームタグ付け` の付録を見てください。

en: Disk Failure
ja: ディスク障害

en: The cache is designed to be relatively resistant to disk failures. Because each :term:`storage unit` in each :term:`cache volume` is mostly independent, the loss of a disk simply means that the corresponding :cpp:class:`Vol` instances (one per cache volume that uses the storage unit) becomes unusable. The primary issue is updating the volume assignment table to both preserve assignments for objects on still operational volumes while distributing the assignments from the failed disk to those operational volumes. This mostly done in::
ja: キャッシュはディスク障害に比較的強いように設計されます。各 :term:`キャッシュボリューム` の各 :term:`ストレージユニット` はほぼ独立しているので、ディスクの損失は対応する :cpp:class:`Vol` インスタンス (ストレージユニットを使うキャッシュボリュームにつき 1 つ) が使えなくなることを単に意味します。主な課題は故障したディスクから運用中のボリュームへの割当の配布中に、まだ運用中のボリューム上のオブジェクトの割当を両方保存するためのボリューム割当テーブルの更新処理です。これはほとんどが以下の中で処理されます::

en: Restoring a disk to active duty is a more difficult task. Changing the volume assignment of a :term:`cache key` renders any currently cached data inaccessible. This is not a problem when a disk has failed, but is a bit trickier to decide which cached objects are to be de facto evicted if a new storage unit is added to a running system. The mechanism for this, if any, is still under investigation.
ja: ディスクを稼働状態に戻すのは非常に困難な作業です。 :term:`キャッシュキー` のボリューム割当の変更は、全ての現在キャッシュされているデータへのアクセスを不可能にします。ディスクが故障した際にこれは当然ながら問題にはなりませんが、新しいストレージユニットが動作中のシステムに追加された場合、どのキャッシュされたオブジェクトが事実上追い出されるか決定するのが少々扱いにくい処理です。このためのメカニズムは何かないか、まだ調査中です。

en: Implementation Details
ja: 実装の詳細

en: Stripe Directory
ja: ストライプディレクトリ

en: The in memory volume directory entries are described below.
ja: メモリ上のボリュームディレクトリエントリは、以下の通りに定義されます。

en: Defined in |P-CacheDir.h|_.
ja: |P-CacheDir.h|_ で定義される。

en: Name
ja: 名前

en: Type
ja: 型

en: Use
ja: 用途

en: Offset of first byte of metadata (volume relative)
ja: （ボリュームに関連した）メタデータの先頭バイトのオフセット

en: Size multiplier
ja: サイズの乗数

en: Size
ja: サイズ

en: Partial key (fast collision check)
ja: （高速な衝突チェックの為の）キーの一部

en: Flag: first fragment in an object
ja: オブジェクトの先頭のフラグメントを示すフラグ

en: Flag: document is pinned
ja: ドキュメントがピン留めされていることを示すフラグ

en: Flag: Unknown
ja: 不明なフラグ

en: Segment local index of next entry.
ja: 次エントリへのセグメントローカルインデックス

en: High order offset bits
ja: 上位オフセットビット

en: The stripe directory is an array of ``Dir`` instances. Each entry refers to a span in the volume which contains a cached object. Because every object in the cache has at least one directory entry this data has been made as small as possible.
ja: ストライプディレクトリは ``Dir`` インスタンスの配列です。各エントリはキャッシュされたオブジェクトを持つボリュームのスパンを参照します。キャッシュ内の各オブジェクトは少なくとも一つのディレクトリエントリを持つため、このデータは可能な限り小さくなるよう設計されました。

en: The offset value is the starting byte of the object in the volume. It is 40 bits long, split between the *offset* (lower 24 bits) and *offset_high* (upper 16 bits) members. Note that since there is a directory for every storage unit in a cache volume, this is the offset in to the slice of a storage unit attached to that volume.
ja: オフセット値はボリューム内におけるオブジェクトの開始バイトです。それは *offset* （下位 24 ビット） と *offset_high* （上位 16 ビット） メンバに渡って分割された 40 ビット長です。キャッシュボリュームの各ストレージユニット毎にディレクトリは存在するため、この値はボリュームに接続されたストレージユニットの一部分へのオフセットであることに注意してください。

en: The *size* and *big* values are used to calculate the approximate size of the fragment which contains the object. This value is used as the number of bytes to read from storage at the offset value. The exact size is contained in the object metadata in :cpp:class:`Doc` which is consulted once the read has completed. For this reason, the approximate size needs to be at least as large as the actual size but can be larger, at the cost of reading the extraneous bytes.
ja: *size* と *big* 値はオブジェクトを持つスパンの大まかなサイズを計算する為に使用されます。この値はストレージのオフセット値から読込み処理を行うためのバイト数として使用されます。正確なサイズは:cpp:class:`Doc` のオブジェクトメタデータに含まれており、一旦読込みが完了した後に参照されます。この理由により、おおよそのサイズは少なくとも実サイズと同じである必要がありますが、外部からのバイト列の読み込みというコストを費やして読み込んだ結果、より大きくなることがあります。

en: The computation of the approximate size of the fragment is defined as::
ja: フラグメントの大まかなサイズの計算は以下のように定義されます。::

en: Where ``CACHE_BLOCK_SHIFT`` is the bit width of the size of a basic cache block (9, corresponding to a sector size of 512). Therefore the value with current defines is::
ja: ここで ``CACHE_BLOCK_SHIFT`` は基本的なキャッシュブロックのサイズのビット幅（9 であり、 512 のセクタサイズに対応している） です。したがって現在の定義にその値を使った値は以下のようになります。::

en: Because *big* is 2 bits, the values for the multiplier of *size* are:
ja: *big* は 2 ビットであるため、*size* の乗数の値は、

en: Multiplier
ja: 乗数

en: Maximum Size
ja: 最大サイズ

en: Note also that *size* is effectively offset by one, so a value of 0 indicates a single unit of the multiplier.
ja: *size* は実際上は 1 だけずれており、そのため 0 が乗数の単一のユニットを示すことに注意してください (訳注: *size* は 0 から始まりますが、 0 が単一のユニット、 1 が 2 つのユニットを示します)。

en: The target fragment size can set with the :file:`records.config` value :ts:cv:`proxy.config.cache.target_fragment_size`.
ja: ターゲットフラグメントサイズは :file:`records.config` の値 :ts:cv:`proxy.config.cache.target_fragment_size` で設定できます。

en: This value should be chosen so that it is a multiple of a :ref:`cache entry multiplier <big-mult>`. It is not necessary to make it a power of two[#cache-mult-value]_. Larger fragments increase I/O efficiency but lead to more wasted space. The default size (1M, 2^20) is a reasonable choice in most circumstances, although in very specific cases there can be benefit from tuning this parameter. |TS| imposes an internal maximum of a 4,194,232 bytes, which is 4M (2^22), less the size of a struct :cpp:class:`Doc`. In practice, the largest reasonable target fragment size is 4M - 262,144 = 3,932,160.
ja: この値は :ref:`キャッシュエントリ乗数 <big-mult>` の倍数になるように選択するべきです。 2 の冪乗にする必要はありません。 [#cache-mult-value]_ より大きなフラグメントは I/O の効率を向上しますが、無駄なスペースが増加します。デフォルトサイズ（1M, 2^20）はほとんどの環境において合理的な選択です。ただし、非常に特殊なケースではこのパラメータをチューニングすることにより恩恵が得られる場合があります。 |TS| は :cpp:class:`Doc` 構造のサイズより少ない 4M（2^22） である 4,194,232 バイトの内部的な最大値を強制します。事実上、最大の合理的なターゲットフラグメントサイズは 4M - 262,144 = 3,932,160 です。

en: When a fragment is stored to disk, the size data in the cache index entry is set to the finest granularity permitted by the size of the fragment. To determine this, consult the :ref:`cache entry multipler <big-mult>` table and find the smallest maximum size that is at least as large as the fragment. That will indicate the value of *big* selected and therefore the granularity of the approximate size. That represents the largest possible amount of wasted disk I/O when the fragment is read from disk.
ja: フラグメントがディスクへ保存される際、キャッシュインデックスエントリのサイズデータはフラグメントのサイズにより許容される最小粒度で設定されます。これを決定するには :ref:`キャッシュエントリ乗数 <big-mult>` テーブルを参照し、少なくともフラグメントと同じくらい大きな、最大サイズの最も小さい値を検索します。それは選択された *big* の値であり、従っておおよそのサイズの粒度を示すでしょう。それはフラグメントがディスクから読み込まれる際に発生しうる最大の余分なディスク I/O の量を表します。

en: The set of index entries for a volume are grouped in to :term:`segments <directory segment>`. The number of segments for an index is selected so that there are as few segments as possible such that no segment has more than 2^16 entries. Intra-segment references can therefore use a 16 bit value to refer to any other entry in the segment.
ja: ボリュームのインデックスエントリのセットは *セグメント* へグループ化されます。インデックスのセグメントの数は、 2^16 エントリを超えるセグメント数にならないように可能な限り少ないセグメントになるよう選択されます。内部セグメントの参照はそのため、セグメントの任意の他のエントリを参照する為に 16 ビット値を使用します。

en: Index entries in a segment are grouped :term:`buckets <directory bucket>`, each of ``DIR_DEPTH`` (currently 4) entries. These are handled in the standard hash table manner, giving somewhat less than 2^14 buckets per segment.
ja: セグメントのインデックスエントリは ``DIR_DEPTH`` （現在は 4）エントリ毎に :term:`バケット <ディレクトリバケット>` へグループ化されます。これらはセグメント毎に 2^14 未満のバケットを割り当てる標準的なハッシュテーブルの手法で処理されます。

en: The comment in earlier versions of the :file:`records.config` documentation which indicated that this value must be a power of two were, unfortunately, mistaken and have been corrected.
ja: :file:`records.config` のドキュメントの以前の版のコメントでこの値が 2 の冪乗でなければならないと述べていましたが、それは間違いだったため修正されました。

en: Directory Probing
ja: ディレクトリ検索

en: Directory probing is the locating of a specific :term:`directory entry` in the stripe directory based on a :term:`cache ID`. This is handled primarily by the function :cpp:func:`dir_probe()`. This is passed the cache ID (:arg:`key`), a stripe (:arg:`d`), and a last collision (:arg:`last_collision`). The last of these is an in and out parameter, updated as useful during the probe.
ja: ディレクトリ検索は :term:`キャッシュ ID` に基づくストライプディレクトリの特定の :term:`ディレクトリエントリ` を検索します。これは主に :cpp:func:`dir_probe()` 関数によって処理されます。この関数にはキャッシュ ID（:arg:`key`） 、ストライプ（:arg:`d`）、そして最後の衝突（:arg:`last_collision`）が渡されます。これらのうち最後のパラメータは入出力パラメータであり、検索の間に役立つよう更新されます。

en: Given an ID, the top half (64 bits) is used as a :ref:`segment <dir-segment>` index, taken modulo the number of segments in the directory. The bottom half is used as a :ref:`bucket <dir-bucket>` index, taken modulo the number of buckets per segment. The :arg:`last_collision` value is used to mark the last matching entry returned by :cpp:func:`dir_probe`.
ja: ID を考えると、上位半分（64 ビット）は :ref:`セグメント <dir-segment>` インデックスとして使用され、ディレクトリのセグメント数の剰余として扱われます。下位半分は :ref:`バケット <dir-bucket>` インデックスとして使用され、セグメント毎のバケット数の剰余として扱われます。:arg:`last_collision` の値は `dir_probe` の戻り値となる最後にマッチするエントリをマークするために使用されます。

en: After computing the appropriate bucket, the entries in that bucket are searched to find a match. In this case a match is detected by comparison of the bottom 12 bits of the :term:`cache ID` (the *cache tag*). The search starts at the base entry for the bucket and then proceeds via the linked list of entries from that first entry. If a tag match is found and there is no :arg:`collision` then that entry is returned and :arg:`last_collision` is updated to that entry. If :arg:`collision` is set and if it isn't the current match, the search continues down the linked list, otherwise :arg:`collision` is cleared and the search continues.
ja: 適切なバケットを算出した後、バケットのエントリはマッチするものを探すために検索されます。この場合、マッチするかが :term:`キャッシュ ID` ( *キャッシュタグ* ) の下位 12 ビットの比較によって検出されます。検索はバケットのベースエントリから開始して、その後先頭のエントリからのエントリ連結リストを使って進んでいkます。タグのマッチが発見されていてかつ :arg:`collision` が無い場合、エントリは返されて :arg:`last_collision` はそのエントリを指すように更新されます。 :arg:`collision` がセットされていて現在のマッチではない場合、検索は連結リストの次へ続きます。そうで無い場合 (訳注: :arg:`collision` がセットされていて現在のマッチである場合) :arg:`collision` をクリアし、検索を継続します。

en: The effect of this is that matches are skipped until the last returned match (:arg:`last_collision`) is found, after which the next match (if any) is returned. If the search falls off the end of the linked list, then a miss result is returned (if no last collision), otherwise the probe is restarted after clearing the collision on the presumption that the entry for the collision has been removed from the bucket. This can lead to repeats among the returned values but guarantees that no valid entry will be skipped.
ja: これにより最後に返されたマッチしたもの (:arg:`last_collision`) が見つかるまでマッチングがスキップされ、その後に次のマッチするものが (もしあるなら) 返されます。検索が連結リストの最後まで到達した場合、失敗した結果が返される (もし最後の衝突がないなら)、あるいは衝突したエントリがバケットから削除されているとの想定の上で、衝突を解消した後に検索が再開されます。この処理は値が返されるまで繰り返すことができますが、正常なエントリがスキップされることがないことを保証します。

en: Last collision can therefore be used to restart a probe at a later time. This is important because the match returned may not be the actual object. Although the hashing of the :term:`cache ID` to a :term:`bucket <directory bucket>` and the tag matching is unlikely to create false positives, it is possible. When a fragment is read the full cache ID is available and checked and if wrong, that read can be discarded and the next possible match from the directory found because the cache virtual connection tracks the last collision value.
ja: したがって最後の衝突は後で検索を再開するのに使用できます。返されたマッチしたものが実際のオブジェクトではないかも知れないため、これは重要です。 :term:`バケット <ディレクトリバケット>` への :term:`キャッシュ ID` のハッシュ化とタグマッチングが偽陽性を発生しそうに無くても、それは使用可能です。フラグメントが読み込まれる際、キャッシュ ID の全てが使用可能でありチェックされた結果誤りがある場合、その読込みは破棄が可能でありキャッシュ仮想接続は最後の衝突値を追跡するためディレクトリから次のマッチする可能性があるものが検索されます。

en: Cache Operations
ja: キャッシュ操作

en: Cache activity starts after the HTTP request header has been parsed and remapped. Tunneled transactions do not interact with the cache because the headers are never parsed.
ja: キャッシュアクティビティは HTTP リクエストヘッダがパースされ、リマップされてから開始します。トンネルされたトランザクションはヘッダがパースされることがないためキャッシュに影響しません。

en: To understand the logic we must introduce the term *cache valid* which means something that is directly related to an object that is valid to be put in the cache (e.g. a ``DELETE`` which refers to a URL that is cache valid but cannot be cached itself). This is important because |TS| computes cache validity several times during a transaction and only performs cache operations for cache valid results. The criteria used changes during the course of the transaction as well. This is done to avoid the cost of cache activity for objects that cannot be in the cache.
ja: ロジックを理解するため、 *キャッシュバリッド* という用語を紹介しなければなりません。これはキャッシュされるのに有効なオブジェクトに直接関係するものを意味します。 (例えばキャッシュバリッドな URL を参照する ``DELETE`` はそれ自身はキャッシュできません) |TS| はトランザクション中に何度かキャッシュの正当性を計算してキャッシュバリッドの結果によってのみキャッシュ操作を行うため、この用語は重要です。正当性の基準は同様にトランザクション中の変更を使用しました。この処理はキャッシュできないオブジェクトの為のキャッシュアクティビティによるコストを避けるために実行されます。

en: The three basic cache operations are: lookup, read, and write. We will take deleting entries as a special case of writing where only the volume directory is updated.
ja: 3 つの基本的なキャッシュ操作は検索、読込み、そして書込みです。エントリの削除はボリュームディレクトリが更新されるだけという書込みの特殊なケースとして扱います。

en: After the client request header is parsed and is determined to be potentially cacheable, a `cache lookup`_ is done. If successful, a `cache read`_ is attempted. If either the lookup or the read fails and the content is considered cacheable then a `cache write`_ is attempted.
ja: クライアントリクエストヘッダがパースされてキャッシュできると決定された後、 `キャッシュ検索`_  が行われます。成功した場合 `キャッシュ読込み`_ が試みられます。検索か読込みのいずれかが失敗してかつコンテンツがキャッシュできると判断される場合、 `キャッシュ書込み`_  が試みられます。

en: Cacheability
ja: キャッシャビリティ

en: The first thing done with a request with respect to cache is to determine whether it is potentially a valid object for the cache. After initial parsing and remapping, this check is done primarily to detect a negative result, as it allows further cache processing to be skipped. It will not be put in to the cache, nor will a cache lookup be performed. There are a number of prerequisites along with configuration options to change them. Additional cacheability checks are done later in the process, when more is known about the transaction (such as plugin operations and the origin server response). Those checks are described as appropriate in the sections on the relevant operations.
ja: キャッシュに関するリクエストで最初に行われるのは、キャッシュするのに潜在的に有効なオブジェクトであるかどうかを決定することです。最初のパースとリマップの後、このチェックは主にネガティブな結果を検出するために行われます。これはもしネガティブな結果が出た場合は全ての後のキャッシュ処理がスキップされる、すなわちキャッシュに配置されずキャッシュ検索も実行されなくなるためです。それらを変更する設定オプションに加え、必要条件が数多く存在します。追加のキャッシャビリティチェックは、トランザクションについてより多くのことが分かった際の処理 (プラグイン操作やオリジンサーバレスポンスのような) 以降に実行されます。それらのチェックについては関連する操作のセクションで適切に説明します。

en: The set of things which can affect cacheability are:
ja: キャッシャビリティに影響できる項目のセットは:

en: Built in constraints.
ja: 組込みの制約。

en: Settings in :file:`records.config`.
ja: :file:`records.config` の設定。

en: Settings in :file:`cache.config`.
ja: :file:`cache.config` の設定。

en: Plugin operations.
ja: プラグインの操作。

en: The initial internal checks, along with their :file:`records.config` overrides[#cacheability-overrides]_, are done in ``HttpTransact::is_request_cache_lookupable``.
ja: 初期の内部チェック、それらの :file:`records.config` を伴った オーバーライド[#cacheability-overrides]_ は ``HttpTransact::is_request_cache_lookupable`` 内で処理されます。

en: The checks that are done are:
ja: 実行されるチェックは以下の通りです。

en: Cacheable Method
ja: キャッシュ可能なメソッド

en: The request must be one of ``GET``, ``HEAD``, ``POST``, ``DELETE``, ``PUT``.
ja: リクエストは ``GET``, ``HEAD``, ``POST``, ``DELETE``, ``PUT`` のいずれかでなければなりません。

en: See ``HttpTransact::is_method_cache_lookupable()``.
ja: ``HttpTransact::is_method_cache_lookupable()`` を確認してください。

en: Dynamic URL
ja: 動的 URL

en: |TS| tries to avoid caching dynamic content because it's dynamic. A URL is considered dynamic if:
ja: URL が動的であるため |TS| は動的コンテンツのキャッシングを避けようとします。もし以下の条件に当てはまるなら URL は動的であると考えられます。

en: It is not ``HTTP`` or ``HTTPS``,
ja: ``HTTP`` や ``HTTPS`` ではない

en: Has query parameters,
ja: クエリパラメータを含む

en: Ends in ``asp``,
ja: ``asp`` で終わる

en: Has ``cgi`` in the path.
ja: パスに ``cgi`` を含む

en: This check can be disabled by setting a non-zero value for :ts:cv:`proxy.config.http.cache.cache_urls_that_look_dynamic`.
ja: このチェックは :ts:cv:`proxy.config.http.cache.cache_urls_that_look_dynamic` にゼロでない値を設定することで無効にできます。

en: In addition if a TTL is set for rule that matches in :file:`cache.config` then this check is not done.
ja: 加えて、 :file:`cache.config` にマッチするルールに TTL が設定されていたらこのチェックは行われません。

en: Range Request
ja: レンジリクエスト

en: Cache valid only if :ts:cv:`proxy.config.http.cache.range.lookup` in :file:`records.config` is non-zero. This does not mean the range request can be cached, only that it might be satisfiable from the cache. In addition, :ts:cv:`proxy.config.http.cache.range.write` can be set to try to force a write on a range request. This probably has little value at the moment, but if for example the origin server ignores the ``Range:`` header, this option can allow for the response to be cached. It is disabled by default, for best performance.
ja: :file:`records.config` の :ts:cv:`proxy.config.http.cache.range.lookup` がゼロでない値である場合に限りキャッシュバリッドです。これはレンジリクエストがキャッシュ可能であることを意味しません。キャッシュから満たされるかもしれないというだけです。加えて、 :ts:cv:`proxy.config.http.cache.range.write` をレンジリクエストでキャッシュ書込みを強制を試みるように設定することが出来ます。これは今はあまり価値が無いかもしれませんが、例えばオリジンサーバーが ``Range:`` ヘッダーを無視するなら、このオプションはレスポンスをキャッシュすることを許すことが出来ます。ベストのパフォーマンスのため、デフォルトでは  :ts:cv:`proxy.config.http.cache.range.write` は無効になっています。

en: A plugin can call :c:func:`TSHttpTxnReqCacheableSet()` to force the request to be viewed as cache valid.
ja: プラグインはリクエストがキャッシュバリッドと見なされる事を強制するため :c:func:`TSHttpTxnReqCacheableSet()` を呼び出せます。

en: The code appears to check :file:`cache.config` in this logic by setting the ``does_config_permit_lookup`` in the ``cache_info.directives`` of the state machine instance but I can find no place where the value is used. The directive ``does_config_permit_storing`` is set and later checked so the directive (from the administrator point of view) is effective in preventing caching of the object.
ja: コード上ではこのロジックにおいてステートマシンインスタンスの ``cache_info.directives`` の中の ``does_config_permit_lookup`` の値を設定することにより :file:`cache.config` をチェックするように見えますが、その値が使用されている箇所は発見できません。 ``does_config_permit_storing`` ディレクティブが設定されてその後にチェックされるので、このディレクティブは（管理者の観点から）オブジェクトのキャッシュすることを妨げるのに効果的です。

en: Cache Lookup
ja: キャッシュ検索

en: If the initial request is not determined to be cache invalid then a lookup is done. Cache lookup determines if an object is in the cache and if so, where it is located. In some cases the lookup proceeds to read the first ``Doc`` from disk to verify the object is still present in the cache.
ja: 最初のリクエストがキャッシュ無効と判定されなければルックアップが実行されます。キャッシュルックアップはオブジェクトがキャッシュ内にあるか、キャッシュ内にある場合はどこに位置するかを判定します。時には、ルックアップは続けてディスクから最初の ``Doc`` を読み、オブジェクトがまだキャッシュに存在するかを確認します。

en: The basic steps to a cache lookup are:
ja: キャッシュルックアップの基本的なステップは :

en: The cache key is computed.
ja: キャッシュキーが計算されます。

en: This is normally computed using the request URL but it can be overridden :ref:`by a plugin <cache-key>` . The cache index string is not stored, as it is presumed computable from the client request headers.
ja: これは通常はリクエストの URL を用いて計算されますが、 :ref:`<cache-key> プラグインによって` オーバーライド出来ます。キャッシュのインデックス文字列は保存されません。それはクライアントのリクエストヘッダーから計算可能という前提だからです。

en: The cache stripe is determined (based on the cache key).
ja: キャッシュストライプが (キャッシュキーに基いて) 判定されます。

en: The :term:`cache key` is used as a hash key in to an array of :cpp:class:`Vol` instances. The construction and arrangement of this array is the essence of how volumes are assigned.
ja: :term:`キャッシュキー` は :cpp:class:`Vol` インスタンスの配列へのキャッシュキーとして使用されます。この配列の生成と整列はボリュームがどのように割り当てられるかの本質です。

en: The cache stripe directory :ref:`is probed <cache-directory-probe>` using the index key computed from the cache key.
ja: キャッシュキーから計算されたインデックスキーを用いてキャッシュストライプディレクトリーが :ref:`調べられます <cache-directory-probe>` 。

en: Various other lookaside directories are checked as well, such as the :ref:`aggregation buffer <aggregation-buffer>`.
ja: :ref:`集約バッファー <aggregation-buffer>` などさまざまな他の索引ディレクトリもチェックされます。

en: If the directory entry is found the first ``Doc`` is read from disk and checked for validity.
ja: ディレクトリエントリが見つかったら最初の ``Doc`` がディスクから読まれ有効性が検証されます。

en: This is done in :cpp:func:`CacheVC::openReadStartHead()` or :cpp:func:`CacheVC::openReadStartEarliest()` which are tightly coupled methods.
ja: これは :cpp:func:`CacheVC::openReadStartHead()` か :cpp:func:`CacheVC::openReadStartEarliest()` によって行われます。これらは密結合したメソッドです。

en: If the lookup succeeds, then a more detailed directory entry (struct :cpp:class:`OpenDir`) is created. Note that the directory probe includes a check for an already extant ``OpenDir`` which, if found, is returned without additional work.
ja: ルックアップが成功したらより詳細なディレクトリエントリ (:cpp:class:`OpenDir` 構造体) が生成されます。ディレクトリ検索は既に現存する ``OpenDir`` のチェックも含み、もし見つかったら追加作業無しに返されることに注意してください。

en: Cache Read
ja: キャッシュ読込み

en: Cache read starts after a successful `cache lookup`_. At this point the first ``Doc`` has been loaded in to memory and can be consulted for additional information. This will always contain the HTTP headers for all :term:`alternates <alternate>` of the object.
ja: キャッシュ読込みは `キャッシュ検索`_ が成功した後に開始されます。この時点で最初の ``Doc`` がメモリに読み込まれ、追加情報が参照可能になります。これはオブジェクトの全ての :term:`代替 <alternate>` の HTTP ヘッダーを常に含みます。

en: Read while write
ja: 書込みながら読込み

en: There is provision in the code to support *read while write*, that is, serving an object from cache in one transaction while it is being written in another. Several settings are needed for it to be used. See :ref:`admin-configuration-reducing-origin-requests`. It must specifically enabled in :file:`records.config` and if not, a cache read will fail if the object is currently be written or updated.
ja: コード内には *書込みながら読込み* をサポートするための条件があります。  *書込みながら読込み* とはあるトランザクションでオブジェクトをキャッシュに書き込みながら別のトランザクションでキャッシュからオブジェクトを配信することです。使用するためにはいくつかの設定が必要になります。 :ref:`admin-configuration-reducing-origin-requests` を参照してください。 :file:`records.config` で明示的に有効にする必要があります。そうしなければ、オブジェクトが現在書込まれているか更新されている場合はキャッシュ読込みは失敗するでしょう。

en: At this point an alternate for the object is selected. This is done by comparing the client request to the stored response headers, but it can be controlled by a plugin using ``TS_HTTP_ALT_SELECT_HOOK``.
ja: この時点でオブジェクトの代替が選択されます。これはクライアントのリクエストを保存されたレスポンスヘッダーと比較することで実行されますが、 ``TS_HTTP_ALT_SELECT_HOOK`` を用いたプラグインで制御することも出来ます。

en: The content can now be checked to see if it is :term:`stale` by calculating the *freshness* of the object. This is essentially checking how old the object is by looking at the headers and possibly other metadata (note that the headers can't be checked until we've selected an alternate).
ja: この時点でコンテンツはオブジェクトの *新鮮さ* を計算することで :term:`新鮮でない` かどうかをチェックすることが可能になります。これは基本的にはヘッダーと場合によって他のメタデータを見ることによりオブジェクトがどれぐらい古いかをチェックすることになります (ヘッダーは代替を選択する前にはチェックできないことに注意してください) 。

en: Most of this work is done in ``HttpTransact::what_is_document_freshness``.
ja: この作業のほとんどは ``HttpTransact::what_is_document_freshness`` 内で行われます。

en: First, the TTL (time to live) value, which can be set in :file:`cache.config`, is checked if the request matches the configuration file line. This is done based on when the object was placed in the cache, not on any data in the headers.
ja: まず、 TTL (time to live) の値、これは :file:`cache.config` で設定可能です、を見てリクエストが設定ファイルの行にマッチするかチェックされます。これはヘッダー内の日付ではなくオブジェクトがいつキャッシュに収納されたかに基いて行われます。

en: Next, an internal flag (``needs-revalidate-once``) is checked if the :file:`cache.config` value ``revalidate-after`` is not set, and if set the object is marked *stale*.
ja: 次に、内部フラグ (``needs-revalidate-once``) を見て :file:`cache.config` の ``revalidate-after`` の値がセットされていないかをチェックします。セットされていればオブジェクトは *新鮮でない* と印を付けられます。

en: After these checks the object age is calculated by ``HttpTransactHeaders::calculate_document_age``. and then any configured fuzzing is applied. The limits to this age based on available data is calculated by ``HttpTransact::calculate_document_freshness_limit``.
ja: これらのチェックの後オブジェクトの経過時間が ``HttpTransactHeaders::calculate_document_age`` で計算されます。その後設定された曖昧さ (fuzzing) が適用されます。利用可能なデータに基づくこの経過時間の限界は ``HttpTransact::calculate_document_freshness_limit`` によって計算されます。

en: How this age is used is determined by the :file:`records.config` setting for :ts:cv:`proxy.config.http.cache.when_to_revalidate`. If this is ``0`` then the built calculations are used which compare the freshness limits with document age, modified by any of the client supplied cache control values (``max-age``, ``min-fresh``, ``max-stale``) unless explicitly overridden in :file:`cache.config`.
ja: この経過時間がどのように利用されるかは :file:`records.config` の :ts:cv:`proxy.config.http.cache.when_to_revalidate` によって決定されます。これが ``0`` なら組み立てられた計算を使って新鮮さの限界とドキュメントの経過時間を比較します。ドキュメントの経過時間は :file:`cache.config` で明示的に上書きされない限りクライアントが提供したキャッシュ制御の値 (``max-age``, ``min-fresh``, ``max-stale``) のいずれかで調整されます。

en: If the object is not stale then it is served to the client. If it is stale, the client request may be changed to an ``If Modified Since`` request to :term:`revalidate <revalidation>`.
ja: オブジェクトが新鮮であればクリアントに配信されます。新鮮でなければクライアントのリクエストは :term:`再確認 <revalidation>` のために ``If Modified Since`` に変更されるかもしれません。

en: The request is served using a standard virtual connection tunnel (``HttpTunnel``) with the :cpp:class:`CacheVC` acting as the producer and the client ``NetVC`` acting as the sink. If the request is a range request this can be modified with a transform to select the appropriate parts of the object or, if the request contains a single range, it can use the range acceleration.
ja: リクエストは :cpp:class:`CacheVC` を生産者 (producer) としクライアントの ``NetVC`` をシンク (sink) とする標準の仮想接続トンネル (``HttpTunnel``) を用いて処理されます。もしリクエストがレンジリクエストであれば、これはオブジェクトの適切な部分を選択するために変換で調整されるか、リクエストが単一のレンジを含む場合はレンジ加速を使用可能です。

en: Range acceleration is done by consulting a fragment offset table attached to the earliest ``Doc`` which contains offsets for all fragments past the first. This allows loading the fragment containing the first requested byte immediately rather than performing reads on the intermediate fragments.
ja: レンジ加速は全てのフラグメントのオフセットを含む最古の ``Doc`` に添付されたフラグメントオフセットテーブルが最初のレンジを過ぎたかを調べることによって行われます。これにより中間のフラグメントの読込みを実行するのではなくリクエストされた最初のバイトを含むフラグメントを直ちにロードすることを可能にします。

en: Cache Write
ja: キャッシュ書込み

en: Writing to the cache is handled by an instance of the class :cpp:class:`CacheVC`. This is a virtual connection which receives data and writes it to cache, acting as a sink. For a standard transaction data transfers between virtual connections (*VConns*) are handled by :cpp:class:`HttpTunnel`. Writing to the cache is done by attaching a ``CacheVC`` instance as a tunnel consumer. It therefore operates in parallel with the virtual connection that transfers data to the client. The data does not flow to the cache and then to the client, it is split and goes both directions in parallel. This avoids any data synchronization issues between the two.
ja: キャッシュへの書込みは :cpp:class:`CacheVC` クラスのインスタンスによって処理されます。これはデータを受信しシンクとして振る舞うキャッシュに書き込む仮想接続です。標準トランザクションに対する仮想接続 (*VConns*) 間のデータ転送は :cpp:class:`HttpTunnel` によって処理されます。キャッシュへの書込みは ``CacheVC`` のインスタンスをトンネル消費者として取り付けることによって行われます。そのためデータをクライントへ転送する仮想接続と並列に実行されます。データはキャッシュに流れてそれからクライアントに流れるのではなく、分割されて両方の向きに同時に流れます。これにより 2 つの間のデータ排他制御の問題を回避しています。

en: Writing to disk
ja: ディスクへの書込み

en: The actual write to disk is handled in a separate thread dedicated to I/O operations, the AIO threads. The cache logic marshals the data and then hands the operation off to the AIO thread which signals back once the operation completes.
ja: ディスクへの実際の書込みは I/O 処理に専念する別のスレッド、 AIO スレッドで処理されます。キャッシュロジックはデータをバイト列に変換 (marshal) し AIO スレッドに処理を引き渡します。 AIO スレッドは処理が完了したらシグナルを送り返します。

en: While each ``CacheVC`` handles its transactions independently, they do interact at the :term:`volume <cache volume>` level as each ``CacheVC`` makes calls to the volume object to write its data to the volume content. The ``CacheVC`` accumulates data internally until either the transaction is complete or the amount of data to write exceeds the target fragment size. In the former case the entire object is submitted to the volume to be written. In the latter case, a target fragment size amount of data is submitted and the ``CacheVC`` continues to operate on subsequent data. The volume in turn places these write requests in an holding area called the `aggregation buffer`_.
ja: それぞれの ``CacheVC`` はトランザクションを独立に処理しますが、 :term:`volume <cache volume>` のレベルで相互作用します。それぞれの ``CacheVC`` はデータをボリュームコンテンツに書き込むようにボリュームオブジェクトを呼び出すからです。 ``CacheVC`` はトランザクションが完了するかデータ量がターゲットフラグメントサイズを超えて書き込むまではデータを内部に蓄積します。前者の場合はオブジェクト全体がボリュームに提供され書き込まれます。後者の場合はターゲットフラグメントサイズのデータが提供され ``CacheVC`` は後続のデータを処理し続けます。今度はボリュームがこれらの書込みリクエストを `集約バッファー`_ と呼ばれる保留領域に配置します。

en: For objects under the target fragment size, there is no consideration of order, the object is simply written to the volume content. For larger objects, the earliest ``Doc`` is written first and the first ``Doc`` written last. This provides some detection ability should the object be overwritten. Because of the nature of the write cursor no fragment after the first fragment (in the earliest ``Doc``) can be overwritten without also overwriting that first fragment (since we know at the time the object was finalized in the cache the write cursor was at the position of the first ``Doc``).
ja: ターゲットフラグメントサイズ以下のオブジェクトについては順序の考慮はなく、オブジェクトはボリュームコンテンツに単に書き込まれます。より大きなオブジェクトについては最古の ``Doc`` が最初に書き込まれ最初の ``Doc`` が最後に書き込まれます。これがオブジェクトが上書きされるべきかを判定するためのちょっとした能力を提供します。書込みカーソルの性質により (最古の ``Doc`` 内の)、最初のフラグメントが上書きされることなしに最初のフラグメントの後のフラグメントが上書きされることはありません (オブジェクトがキャッシュに書き込み済みになった時点で書込みカーソルは最初の ``Doc`` に位置していることを私達は知っているからです) 。

en: It is the responsibility of the ``CacheVC`` to not submit writes that exceed the target fragment size.
ja: ターゲットフラグメントサイズを超えたデータを提供しないことは ``CacheVC`` の責任です。

en: Update
ja: 更新

en: Cache write also covers the case where an existing object in the cache is modified. This occurs when:
ja: キャッシュ書込みはキャッシュ内の既存のオブジェクトが修正されるケースもカバーします。これは以下の場合に発生します :

en: A conditional request is made to the origin server and a ``304 - Not Modified`` response is received.
ja: 条件付きリクエストがオリジンサーバーに送られて ``304 - Not Modified`` レスポンスを受信した。

en: An alternate of the object is retrieved from an :term:`origin server` and added to the object.
ja: オブジェクトの代替が :term:`オリジンサーバー` から取得されてオブジェクトに追加された。

en: An alternate of the object is removed (e.g., due to a ``DELETE`` request).
ja: (例えば ``DELETE`` リクエストのために) オブジェクトの代替が削除された。

en: In every case the metadata for the object must be modified. Because |TS| never updates data already in the cache this means the first ``Doc`` will be written to the cache again and the volume directory entry updated. Because a client request has already been processed the first ``Doc`` has been read from cache and is in memory. The alternate vector is updated as appropriate (an entry added or removed, or changed to contain the new HTTP headers), and then written to disk. It is possible for multiple alternates to be updated by different ``CacheVC`` instances at the same time. The only contention is the first ``Doc``; the rest of the data for each alternate is completely independent.
ja: どんな場合にもオブジェクトのメタデータは修正されなければなりません。 |TS| は既にキャッシュ内にあるデータは決して更新しないのでこれは最初の ``Doc`` がキャッシュに再度書き込まれるとボリュームディレクトリエントリが更新されることを意味します。クライアントリクエストは既に処理されているので最初の ``Doc`` はキャッシュから読まれてメモリ城にあります。代替ベクターは適切に (エントリが追加、削除、あるいは新しい HTTP ヘッダを含むように変更される) 更新され、その後ディスクに書き込まれます。複数の代替が異なる ``CacheVC`` インスタンスにより同時に更新されます。唯一の制約は最初の ``Doc`` です。それぞれの代替の残りのデータは完全に独立です。

en: Aggregation Buffer
ja: 集約バッファー

en: Disk writes to cache are handled through an *aggregation buffer*. There is one for each :cpp:class:`Vol` instance. To minimize the number of system calls data is written to disk in units of roughly :ref:`target fragment size <target-fragment-size>` bytes. The algorithm used is simple: data is piled up in the aggregation buffer until no more will fit without going over the target fragment size, at which point the buffer is written to disk and the volume directory entries for objects with data in the buffer are updated with the actual disk locations for those objects (which are determined by the write to disk action). After the buffer is written it is cleared and process repeats. There is a special lookup table for the aggregation buffer so that object lookup can find cache data in that memory.
ja: キャッシュへのディスク書込みは *集約バッファー* を通して処理されます。 :cpp:class:`Vol` インスタンスのそれぞれに対して 1 つ存在します。システムコールの回数を最小化するためデータはディスクにおよそ :ref:`ターゲットフラグメントサイズ <target-fragment-size>` バイトの単位で書き込まれます。使用されるアルゴリズムは単純です。データはこれ以上追加するとターゲットフラグメントサイズを超えてしまうようになるまで集約バッファーに集積され、その時点でバッファーはディスクに書き込まれ、バッファ内のデータとオブジェクトに対するボリュームディレクトリエントリがそれらのオブジェクトの実際のディスク上の位置 (それらはディスクに書き込む行為によって決定されます) で更新されます。バッファーが書き出された後にそれはクリアーされて上記の手順が繰り返されます。集約バッファーのための特別なルックアップテーブルがあり、オブジェクトのルックアップはキャッシュデータをそのメモリ上で見つけることが出来ます。

en: Because data in the aggregation buffer is visible to other parts of the cache, particularly `cache lookup`_, there is no need to push a partially filled aggregation buffer to disk. In effect, any such data is memory cached until enough additional cache content arrives to fill the buffer.
ja: 集約バッファー内のデータはキャッシュの他の部分、特に `キャッシュルックアップ`_ にも見えるので、部分的に満たされた集約バッファーをディスクに書き出す必要はありません。実際に、そういったデータはバッファーを満たす追加のキャッシュコンテンツが届くまでメモリ上にキャッシュされています。

en: The target fragment size has little effect on small objects because the fragment size is used only to parcel out disk write operations. For larger objects the effect very significant as it causes those objects to be broken up in to fragments at different locations on in the volume. Each fragment write has its own entry in the volume directory which are computationally chained (each :term:`cache key` is computed from the previous one). If possible, a fragment table is accumulated in the earliest ``Doc`` which has the offsets of the first byte for each fragment.
ja: フラグメントサイズはディスク書込みの操作を分配することにしか使われないため、ターゲットフラグメントサイズは小さなオブジェクトにはあまり影響を及ぼしません。より大きなオブジェクトに対してはそれらのオブジェクトをフラグメントに分割してボリューム内の異なる位置に配置することになるので非常に大きな影響を及ぼします。各フラグメントの書出しはボリューム内の自身のエントリを持っていて、それらは計算によって繋がれています (各 :term:`キャッシュキー` は 1 つ前の値から計算されます)。もし可能なら、フラグメントテーブルは最古の ``Doc`` 内に蓄積されます。最古の ``Doc`` は各フラグメントの最初のバイトのオフセットを持っています。

en: Evacuation Mechanics
ja: 退避メカニズム

en: By default, the write cursor will overwrite (de facto evict from cache) objects as it proceeds once it has gone around the :term:`cache stripe` at least once. In some cases this is not acceptable and the object is *evacuated* by reading it from the cache and then writing it back to cache which moves the physical storage of the object from in front of the write cursor to behind the write cursor. Objects that are evacuated are handled in this way based on data in stripe data structures (attached to the :cpp:class:`Vol` instance).
ja: デフォルトでは書込みカーソルは :term:`キャッシュストライプ` を少なくとも 1 度周回したら進むに連れてオブジェクトを上書き (キャッシュからの事実上の追い出し) します。ある場合にはこれは受け入れることが出来ずオブジェクトはキャッシュから読み込まれてキャッシュに書き戻され、オブジェクトの物理ストレージを書込みカーソルの前から書込みカーソルの後ろに移動することで *退避* されます。退避されたオブジェクトは (:cpp:class:`Vol` インスタンスに付与された) ストライプデータ構造内のデータに基いてこのように扱われます。

en: Evacuation data structures are defined by dividing up the volume content into a disjoint and contiguous set of regions of ``EVACUATION_BUCKET_SIZE`` bytes. The :cpp:member:`Vol::evacuate` member is an array with an element for each evacuation region. Each element is a doubly linked list of :cpp:class:`EvacuationBlock` instances. Each instance contains a :cpp:class:`Dir` that specifies the fragment to evacuate. It is assumed that an evacuation block is placed in the evacuation bucket (array element) that corresponds to the evacuation region in which the fragment is located although no ordering per bucket is enforced in the linked list (this sorting is handled during evacuation). Objects are evacuated by specifying the first or earliest fragment in the evactuation block. The evactuation operation will then continue the evacuation for subsequent fragments in the object by adding those fragments in evacuation blocks. Note that the actual evacuation of those fragments is delayed until the write cursor reaches the fragments, it is not necessarily done at the time the earliest fragment is evacuated.
ja: 退避データ構造はボリュームコンテンツを ``EVACUATION_BUCKET_SIZE`` バイトのバラバラな連続したセットの領域に分割することで定義されます。各要素は :cpp:class:`EvacuationBlock` インスタンスの二重連結リストです。退避ブロックは退避バケット (配列の要素) 内に配置され、退避バケット内の退避領域に対応してフラグメントが配置されますが、連結リスト内のバケット毎の順序は強制されません (この並び替えは退避の最中に処理されます)。オブジェクトは退避ブロック内の最初または最古のフラグメントを指定することによって対比されます。退避の操作は退避ブロックにこれらのフラグメントを追加することでオブジェクト内の後続のフラグメントの退避を継続するでしょう。これらのフラグメントの実際の退避は書込みカーソルがフラグメントに達するまで遅延され、最初のフラグメントが対比された時点では必ずしも実行されないことに注意してください。

en: There are two types of evacuations: *reader based* and *forced*. The ``EvacuationBlock`` has a reader count to track this. If the reader count is zero, then it is a forced evacuation and the the target, if it exists, will be evacuated when the write cursor gets close. If the reader value is non-zero then it is a count of entities that are currently expecting to be able to read the object. Readers increment the count when they require read access to the object, or create the ``EvacuationBlock`` with a count of 1. When a reader is finished with the object it decrements the count and removes the ``EvacuationBlock`` if the count goes to zero. If the ``EvacuationBlock`` already exists with a count of zero, the count is not modified and the number of readers is not tracked, so the evacuation is valid as long as the object exists.
ja: 2 つの種類の退避があります。 *リーダー (reader) に基づく* と *強制される* です。 ``EvacuationBlock`` はこれを追跡するためにリーダーの数を持っています。リーダーの数がゼロなら、それは強制された退避であり、ターゲット、もしそれが存在するなら、は書込みカーソルが近くなったときに退避されるでしょう。リーダーの数がゼロでない場合はそれはオブジェクトを読みだすことができると現在期待されているエンティティの数です。リーダーはオブジェクトへの読み取りアクセスを要求されたときにカウントを増加させるか、 1 のカウントとともに ``EvacuationBlock`` を作成します。リーダーがオブジェクトを読み終えた時はカウントを減少させカウントがゼロになったら ``EvacuationBlock`` を削除します。もし ``EvacuationBlock`` がカウントがゼロで既に存在していたら、カウントは変更されず、リーダーの数も追跡されません。そのためオブジェクトが存在する限り退避は有効になります。

en: Evacuation is driven by cache writes, essentially in :cpp:member:`Vol::aggWrite`. This method processes the pending cache virtual connections that are trying to write to the stripe. Some of these may be evacuation virtual connections. If so then the completion callback for that virtual connection is called as the data is put in to the aggregation buffer.
ja: 退避はキャッシュ書込み、特に :cpp:member:`Vol::aggWrite` によって引き起こされます。このメソッドはストライプに書き込もうとしているペンディングされたキャッシュの仮想接続を処理します。これらのいくつかは仮想接続の退避かもしれません。もしそうならデータが集約バッファーに入れられたときに仮想接続の完了コールバッックが呼ばれます。

en: When no more cache virtual connections can be processed (due to an empty queue or the aggregation buffer filling) then :cpp:member:`Vol::evac_range` is called to clear the range to be overwritten plus an additional :const:`EVACUATION_SIZE` range. The buckets covering that range are checked. If there are any items in the buckets a new cache virtual connection (a *doc evacuator*) is created and used to read the evacuation item closest to the write cursor (i.e. with the smallest offset in the stripe) instead of the aggregation write proceeding. When the read completes it is checked for validity and if valid, the cache virtual connection for it is placed at the front of the write queue for the stripe and the write aggregation resumed.
ja: 処理可能なキャッシュ仮想接続がこれ以上無くなった (キューが空か集約バッファーが満杯のために) とき、 :cpp:member:`Vol::evac_range` が呼ばれてレンジがクリアされ、追加の :const:`EVACUATION_SIZE` レンジが上書きされます。このレンジをカバーするバケットがチェックされます。バケット内に何かアイテムがあるならば、新しいキャッシュ仮想接続 (*doc evacuator*) が作成され、集約書込みを進める代わりに書込みカーソルに最も近い (つまりストライプ内で最も小さいオフセットを持つ) 退避アイテムを読み込むのに使用されます。読み出しが完了した時有効性がチェックされ、有効であればキャッシュ仮想接続がストライプの書込みキューの前に配置され、書込み集約が再開されます。

en: Before doing a write, the method :cpp:func:`Vol::evac_range()` is called to start an evacuation. If any fragments are found in the buckets in the range the earliest such fragment (smallest offset, closest to the write cursor) is selected and read from disk and the aggregation buffer write is suspended. The read is done via a cache virtual connection which also effectively serves as the read buffer. Once the read is complete, that cache virtual connection instance (the *doc evacuator*) is placed at the front of the stripe write queue and written out in turn. Because the fragment data is now in memory it is acceptable to overwrite the disk image.
ja: 書込みの前に :cpp:func:`Vol::evac_range()` メソッドが呼ばれて退避を開始します。レンジのバケット内でなんらかのフラグメントが見つかった場合は最古のそのような (最小のオフセットを持ち、書込みカーソルに最も近い) フラグメントが選択されディスクから読まれ集約バッファーの書込みは一時中断されます。読込みはキャッシュ仮想接続を経由して行われ、それは実質的には読込みバッファとしても機能します。ひとたび読込みが完了したらキャッシュ仮想接続のインスタンス (*doc evacuator*) はストライプ書込みキューの前に配置され順に書きだされます。フラグメントデータは今やメモリ内にあるのでディスクイメージを上書きすることも受け入れられます。

en: Note that when normal stripe writing is resumed, this same check is done again, each time evauating (if needed) a fragment and queuing them for writing in turn.
ja: 通常のストライプへの書込みが再開した時は同じチェックが再び実行され、 (もし必要なら) フラグメントの退避と続いて書込みへのキューイングが行われることに注意してください。

en: Updates to the directory are done when the write for the evacuated fragment completes. Multi-fragment objects are detected after the read completes for a fragment. If it is not the first fragment then the next fragment is marked for evacuation (which in turn, when it is read, will pull the subsequent fragment). The logic presumes that the end of the :term:`alternate` is when the next key is not in the directory.
ja: ディレクトリへの更新は対比したフラグメントの書込みが完了したときに行われます。複数のフラグメントからなるオブジェクトはフラグメントの読込みが完了したときに検出されます。もしそれが最初のセグメントでなかったら次のフラグメントに退避の印が付けられます (そして次にそれが読み込まれたら後続のフラグメントが引っ張られます。ロジックは :term:`代替` の終了が次のキーがディレクトリ内に無いときだという前提です。

en: This interacts with the *one at a time* strategy of the aggregation write logic. If a fragment is close to the fragment being evacuated, it may end up in the same evacuation bucket. Because the aggregation write checks every time for the next fragment to evacuate it will find that next fragment and evacuate it before it is overwritten.
ja: これは集約書込みロジックの *1 度に 1 つずつ* の戦略と相互作用します。フラグメントが対比されようとしているフラグメントに近い場合は、それは結局同じ退避バケット内になるかもしれません。集約書込みは退避する次のフラグメントを毎回チェックするので、次のフラグメントを見つけてそれが上書きされる前に退避するでしょう。

en: Evacuation Operation
ja: 退避処理

en: The primary source of fragments to be evacuated are active fragments. That is, fragments which are currently open for reading or writing. This is tracked by the reader value in the evacuation blocks noted above.
ja: 退避されるフラグメントの主な発生源はアクティブフラグメントです。つまり、読込みもしくは書込みのために現在オープンされているフラグメントです。これは上記の退避ブロック内のリーダーの数によって追跡されています。

en: If object pinning is enabled, then a scan is done on a regular basis as the write cursor moves to detect pinned objects and mark them for evacuation.
ja: オブジェクトのピン留めが有効なら、書込みカーソルが移動してピン留めされたオブジェクトを検出したときに定期的にスキャンが実行されそれらに退避の印を付けます。

en: Fragments can also be evacuated through *hit evacuation*. This is configured by :ts:cv:`proxy.config.cache.hit_evacuate_percent` and :ts:cv:`proxy.config.cache.hit_evacuate_size_limit`. When a fragment is read it is checked to see if it is close and in front of the write cursor, close being less than the specified percent of the size of the stripe. If set at the default value of 10, then if the fragment is within 10% of the size of the stripe, it is marked for evacuation. This is cleared if the write cursor passes through the fragment while it remains open (as all open objects are evacuated). If, when the object is closed, the fragment is still marked then it is placed in the appropriate evacuation bucket.
ja: フラグメントは *ヒット退避* を通して退避することも出来ます。これは :ts:cv:`proxy.config.cache.hit_evacuate_percent` と :ts:cv:`proxy.config.cache.hit_evacuate_size_limit` で設定されます。フラグメントが読み出された時それが書き込みカーソルに近くて手前にあるかチェックされます。近いというのはストライプのサイズの指定したパーセントより小さいかどうかです。もしデフォルト値の 10 に設定されていたらフラグメントがストライプのサイズの 10% 以内にあれば、退避の印を付けられます。この印はフラグメントがオープンされている間に書込みカーソルがフラグメントを通過したら (全てのオープンされたオブジェクトが退避されたら) クリアーされます。オブジェクトがクローズされたときにフラグメントにまだ印がついていたら適切な退避バケットに配置されます。

en: Initialization
ja: 初期設定

en: Initialization starts with an instance of :cpp:class:`Store` reading the storage configuration file, by default :file:`storage.config`. For each valid element in the file an instance of :cpp:class:`Span` is created. These are of basically four types:
ja: 初期設定は :cpp:class:`Store` のインスタンスがストレージ設定ファイル、デフォルトでは :file:`storage.config` を読み込むことで開始します。ファイル内の有効な各要素に対して :cpp:class:`Span` のインスタンスが生成されます。これらは基本的に 4 つの種類からなります :

en: File
ja: ファイル

en: Directory
ja: ディレクトリ

en: Disk
ja: ディスク

en: Raw device
ja: ローデバイス

en: After creating all the :cpp:class:`Span` instances, they are grouped by device ID to internal linked lists attached to the :cpp:member:`Store::disk` array[#store-disk-array]_. Spans that refer to the same directory, disk, or raw device are coalesced in to a single span. Spans that refer to the same file with overlapping offsets are also coalesced [#coalesced-spans]_. This is all done in :c:func:`ink_cache_init()` called during startup.
ja: 全ての :cpp:class:`Span` インスタンスを生成した後、それらは :cpp:member:`Store::disk` アレイ[#store-disk-array]_ に付与された内部的な連結リストにデバイス ID でグループ分けされます。同じディレクトリ、ディスク、あるいはローデバイスを参照するスパンは単一のスパンに合体されます。同じファイルを参照しオフセットがオーバーラップしているスパンも合体されます [#coalesced-spans]_ 。これらは全てスタートアップの最中に呼ばれる :c:func:`ink_cache_init()` の中で実行されます。

en: The span logic is also used by the HostDB and more than one otherwise inexplicable feature is provided by the span logic for that module.
ja: スパンロジックは HostDB でも使われていて、 1 つより多い他の説明し難い機能がそのモジュールのスパンロジックにより提供されています。

en: After configuration initialization, the cache processor is started by calling :cpp:func:`CacheProcessor::start()`. This does a number of things:
ja: 設定の初期化の後、キャッシュプロセッサーが :cpp:func:`CacheProcessor::start()` を呼ぶことで開始されます。これはいくつかのことをします :

en: For each valid span, an instance of :cpp:class:`CacheDisk` is created. This class is a :term:`continuation` and so can be used to perform potentially blocking operations on the span. The primary use of these is to be passed to the AIO threads as the callback when an I/O operation completes. These are then dispatched to AIO threads to perform :term:`storage unit` initialization. After all of those have completed, the resulting storage is distributed across the :term:`volumes <cache volume>` in :c:func:`cplist_reconfigure`. The :cpp:class:`CacheVol` instances are created at this time.
ja: 有効なスパンのそれぞれに対して、 :cpp:class:`CacheDisk` のインスタンスが生成されます。このクラスは :term:`継続` であり、そのためスパンをブロッキングする可能性のある操作にも使うことが出来ます。これらの主たる用途は AIO スレッドに引き渡されて I/O 処理が完了したときにコールバックとして使われることです。これらはその後 AIO スレッドにディスパッチされて :term:`ストレージユニット` の初期化を実行します。これら全てが完了したら、結果として生じるストレージは :c:func:`cplist_reconfigure` 内の :term:`ボリューム <キャッシュボリューム>` を横断して分散されます。この時点で :cpp:class:`CacheVol` インスタンスが生成されます。

en: :term:`Cache stripe <cache stripe>` assignment setup is done once all stripes have initialized (that is, the stripe header information has been successfully read from disk for all stripes). The assignment information is stored as an array of indices. These are indices in to an array of stripes. Both the assignment and the stripe arrays are stored in an instance of :cpp:class:`CacheHostRecord`. Assignment initialization consists of populating the assignment array, which is much larger than the stripe array.
ja: :term:`キャッシュストライプ <cache stripe>` の割り当てのセットアップはひとたび全てのストライプが初期化されたら (つまり、全てのストライプについてストライプヘッダー情報がディスクから読み出し成功したら) 完了となります。割り当て情報はインデックスの配列として保持されます。これらはストライプの配列内のインデックスです。割り当てとストライプの配列の両方は :cpp:class:`CacheHostRecord` インスタンス内に保持されます。割り当ての初期化は割り当て配列にデータを投入することで構成されます。割り当て配列はストライプ配列よりも大幅に大きいです。

en: There is an instance of :cpp:class:`CacheHostRecord` for each line in :file:`hosting.config` and one generic record. For the configured instances, the set of stripes is determined from the cache volume specified in the line. If no lines are specified, all stripes are placed in the generic record, otherwise only those stripes marked as default are placed in the generic record.
ja: :file:`hosting.config` 内の各行と 1 つの包括的なレコードに対して :cpp:class:`CacheHostRecord` のインスタンスがあります。設定されたインスタンスに対して行内に指定されたキャッシュボリュームから一組のストライプが決定されます。行が全く指定されなかった場合は、全てのストライプが包括的なレコード内に配置されます。そうでなければ、デフォルトとマークされたストライプだけが包括的なレコード内に配置されます。

en: If hosting records are specified, it is an error to not specify at least one default cache volume.
ja: 格納するレコードが指定された場合、最低 1 つのデフォルトキャッシュボリュームを指定しなければエラーとなります。

en: The assignment table is initialized in :c:func:`build_vol_hash_table` which is called for each :cpp:class:`CacheHostRecord` instance. For each stripe in the host record, a sequence of pseudo-random numbers is generated. This begins with the folded hash of the stripe hash identifier, which is the device path followed by the ``skip`` and ``size`` values for that stripe, making it unique. This also makes the sequence deterministic for any particular stripe.
ja: 割り当てテーブルは :c:func:`build_vol_hash_table` 内で初期化され、それは :cpp:class:`CacheHostRecord` インスタンスのそれぞれについて呼びだされます。ホストレコード内のストライプのそれぞれに対して擬似乱数のシーケンスが生成されます。これはストライプのハッシュ識別子の折り畳まれたハッシュで開始し、ストライプのハッシュ識別子はデバイスのパスの後にストライプの ``skip`` と ``size`` の値が続いたもので、ユニークなものです。これはまたどんな特定のストライプについてもシーケンスが決定性を持つようにします。

en: Each stripe gets one number in its sequence for every `VOL_HASH_ALLOC_SIZE` (8 MB currently) of storage. These numbers are paired with the stripe index, combined across all stripes, then sorted by the random values. The resulting array is sampled for every slot in the stripe assignment table by dividing the maximum random value by the size of the assignment table and using the value midway between each multiple of the result of the division. The coalesced pseudo-random sequence is scanned for each sample in turn and the first number not greater than the sample is found. The stripe associated with that value is used for that assignment table entry.
ja: それぞれのストライプはそのシーケンス内でストレージの `VOL_HASH_ALLOC_SIZE` (現状 8MB)ごとに 1 つの数字を得ます。これらの数字はストライプのインデックスとペアにされ、全てのストライプを横断して結合され、そしてランダムな値によってソートされます。結果として作られる配列はストライプ割り当てテーブル内の各スロットでサンプリングされます。サンプリングは最大のランダムな値を割り当てテーブルのサイズで割って、割った結果の各倍数の間の中間の値を使って行われます。次に合体された擬似乱数のシーケンスから各サンプルがスキャンされサンプルより大きくない最初の数字が見つかります。その値に関連付けられたストライプがその割り当てテーブルのエントリとして使用されます。

en: While this procedure is deterministic, it is sensitive to initial conditions, including the size of each stripe.
ja: この手続は決定性を持っていますが、各ストライプのサイズを含む初期状態に影響を受けやすいです。

en: Footnotes
ja: 脚注

en: `Work is under way <https://issues.apache.org/jira/browse/TS-2020>`_ on extending this to include objects that are in the memory cache.
ja: メモリキャッシュ内にあるオブジェクトを含むように拡張する作業 <https://issues.apache.org/jira/browse/TS-2020>`_ が進行中です。

en: This linked list is mostly ignored in later processing, causing all but one file or directory storage units on the same device to be ignored. See `TS-1869 <https://issues.apache.org/jira/browse/TS-1869>`_.
ja: この連結リストは後の処理ではほとんど無視されます。それは同じデバイス上の 1 つを除いた全てののファイルやディレクトリのストレージユニットが無視されることを引き起こします。 `TS-1869 <https://issues.apache.org/jira/browse/TS-1869>`_ を参照してください。
