2.1. Neo4j のキャッシュ

2.1.1. ファイルバッファキャッシュ
2.1.2. オブジェクトキャッシュ

Neo4j は、ファイルバッファキャッシュとオブジェクトキャッシュという 2 つの異なるタイプのキャッシュを使用します。ファイルバッファキャッシュは、ストレージファイルデータを、これらのデータが永続的なストレージメディアに格納されるときと同じ形式でキャッシュします。オブジェクトキャッシュは、トラバーサル速度の高速化とトランザクションによる変更を目的として最適化された形式で、ノード、リレーション、およびプロパティをキャッシュします。

2.1.1. ファイルバッファキャッシュ

ファイルバッファキャッシュは、Neo4j のデータを永続的なストレージメディア上での表現形式と同じ形式でキャッシュします。ファイルバッファキャッシュレイヤの目的は、読み取りと書き込みの両方のパフォーマンスを向上させることです。ファイルバッファキャッシュは、キャッシュに書き込みを行い、論理ログがローテートされるまで永続的な書き込みを遅らせることで、書き込みパフォーマンスを向上します。このような動作は安全です。なぜなら、すべてのトランザクションは必ず論理ログに永続的に書き込まれ、クラッシュ時には永続的ログを使ってストアファイルを回復することができるからです。

キャッシュの操作は、キャッシュが格納するデータと密接な関係があるので、必要な背景知識として、Neo4j の永続的な表現形式を簡単に説明しておきます。Neo4j はデータを複数のファイルに格納し、基本となるファイルシステムを利用してこの操作を効率的に行います。Neo4j の各ストレージファイルは、特定のタイプの均一の固定サイズレコードから構成されています。

ストアファイル レコードサイズ 内容

nodestore

9 B

ノード

relstore

33 B

リレーション

propstore

25 B

ノードとリレーションのプロパティ

stringstore

133 B

文字列プロパティの値

arraystore

133 B

配列プロパティの値

文字列と配列については、データが可変長になるので、1 つ以上の 120B チャンクにデータが格納され、13B のレコードオーバーヘッドが付きます。これらのブロックのサイズは、ストアが作成されるときに string_block_size パラメータと array_block_size パラメータを使って構成できます。各レコードタイプのサイズを使えば、Neo4j グラフのストレージ要件や、各ファイルバッファキャッシュの適切なキャッシュサイズを計算することもできます。文字列の中には、stringstore を使わずに格納されるものがあることに注意してください (「短い文字列の圧縮格納」を参照してください)。

Neo4j は、複数のファイルバッファキャッシュを使用し、異なるストレージファイルのそれぞれについて 1 つファイルバッファキャッシュを使用します。各ファイルバッファキャッシュは、対応するストレージファイルを、サイズの等しい一連のウィンドウに分割します。各キャッシュウィンドウには、等しい数のストレージレコードが含まれています。キャッシュは、最もアクティブなキャッシュウィンドウをメモリに保持しており、ウィンドウのヒット対ミスの比率を追跡しています。キャッシュされていないウィンドウのヒット率が、キャッシュされているウィンドウのミス率よりも高くなった場合には、キャッシュされているウィンドウはメモリから追い出され、それまでキャッシュされていなかったウィンドウが代わりにキャッシュされます。

構成

パラメータ 設定できる値 意味

use_memory_mapped_buffers

true または false

true に設定した場合、Neo4j は、ファイルバッファキャッシュウィンドウに対してオペレーティングシステムのメモリマップ機能を使用します。 false に設定した場合は、Neo4j は独自のバッファ実装を使用します。 この場合、バッファは JVM ヒープ上に存在することになるので、それにあわせて JVM ヒープのサイズを引き上げる必要があります。 このパラメータのデフォルト値は、Windows の場合を除いて true です。

neostore.nodestore.db.mapped_memory

該当するファイルバッファキャッシュのメモリマップバッファ用に使用する最大メモリ量。 デフォルトの単位は MiB で、その他の単位を使用するには、B, k, M, G のいずれかのサフィックスを使用します。

ノードストレージファイルのファイルバッファキャッシュに使用する最大メモリ量。

neostore.relationshipstore.db.mapped_memory

リレーションストアファイルのファイルバッファキャッシュに使用する最大メモリ量。

neostore.propertystore.db.index.keys.mapped_memory

something-something ファイルのファイルバッファキャッシュに使用する最大メモリ量。

neostore.propertystore.db.index.mapped_memory

something-something ファイルのファイルバッファキャッシュに使用する最大メモリ量。

neostore.propertystore.db.mapped_memory

プロパティストレージファイルのファイルバッファキャッシュに使用する最大メモリ量。

neostore.propertystore.db.strings.mapped_memory

文字列プロパティストレージファイルのファイルバッファキャッシュに使用する最大メモリ量。

neostore.propertystore.db.arrays.mapped_memory

配列プロパティストレージファイルのファイルバッファキャッシュに使用する最大メモリ量。

string_block_size

ブロックあたりのバイト数。

文字列格納用のブロックサイズを指定します。 このパラメータはストアの作成時にのみ参照され、それ以外の場合には無視されます。 文字列内の各文字は 2 バイトを占有するので、ブロックサイズが 120 (デフォルトのサイズ) の場合、60 文字の長さまで保持することができ、あふれた部分は次のブロックに送られることに注意してください。 また、各ブロックには 13 バイトのオーバーヘッドがあることにも注意してください。 したがって、ブロックサイズが 120 の場合、格納されたレコードのサイズは 133 バイトになります。

array_block_size

配列格納用のブロックサイズを指定します。 このパラメータはストアの作成時にのみ参照され、それ以外の場合には無視されます。 デフォルトのブロックサイズは 120 バイトで、各ブロックのオーバーヘッドは文字列ブロックの場合と同じで 13 バイトです。

dump_configuration

true または false

true に設定した場合、現在の構成の設定がデフォルトのシステム出力に書き出されます。デフォルトのシステム出力は、多くの場合、コンソールかログファイルです。

メモリマップバッファが使われる場合 (use_memory_mapped_buffers = true)、JVM のヒープサイズは、コンピュータで利用可能な総メモリ量からバッファに使われる総メモリ量を引いたものよりも小さくなければなりません。ヒープバッファが使われる場合 (use_memory_mapped_buffers = false)、JVM のヒープサイズは、すべてのバッファを収容し、さらにアプリケーションとオブジェクトキャッシュの実行時ヒープメモリ要件を満たすのに十分な大きさを持たなければなりません。

Neo4j は、起動時に構成パラメータを読み取る際、指定のないパラメータについては自動的に構成を行います。キャッシュサイズは、コンピュータで利用可能なメモリと、JVM ヒープによって使われるメモリ、およびストレージファイルの大きさに基づいて構成されます。

2.1.2. オブジェクトキャッシュ

オブジェクトキャッシュは、個々のノードとリレーション、およびこれらのプロパティを、グラフの高速なトラバーサルに最適化された形式でキャッシュします。オブジェクトキャッシュの中身は、Neo4j オブジェクト API とグラフのトラバーサルに適した表現形式になったオブジェクトです。オブジェクトキャッシュからの読み取りは、ファイルバッファキャッシュからの読み取りより 5 倍から 10 倍高速です。オブジェクトキャッシュは JVM のヒープに収められており、サイズは現在利用可能なヒープメモリに応じて調整されます。

ノードとリレーションは、これらがアクセスされるとただちにオブジェクトキャッシュに追加されます。ただし、キャッシュされたオブジェクトはゆっくりと (lazily) 読み込まれます。ノードまたはリレーションのプロパティは、該当するノードまたはリレーションでプロパティがアクセスされるまで読み込まれません。文字列 (と配列) プロパティは、そのプロパティがアクセスされるまで読み込まれません。特定のノードのリレーションも、該当するノードでそれらのリレーションがアクセスされるまで読み込まれません。キャッシュからの追い出しは、メモリが必要になったときに LRU 方式で行われます。

構成

オブジェクトキャッシュの主な構成パラメータは、cache_type パラメータです。このパラメータでは、オブジェクトキャッシュにどのキャッシュ実装を使うかを指定します。指定できるキャッシュタイプは次のとおりです。

cache_type 説明

none

高レベルキャッシュを使用しません。オブジェクトはキャッシュされません。

soft

利用可能なメモリを最適な形で使用します。 トラバーサルのパフォーマンスを高めたい場合に適しています。 頻繁にアクセスされるグラフがキャッシュに収まらない場合、高負荷下では GC の問題が生じる可能性があります。

これがデフォルトのキャッシュ実装です。

weak

キャッシュされたオブジェクトの有効期間を短くします。 グラフの中で頻繁にアクセスする部分のサイズがメモリに収まらないアプリケーションのスループットを高めたい場合に適しています。

strong

このキャッシュは、グラフ全体すべてのデータ をキャッシュします。 キャッシュが取得したメモリは決して解放されません。 グラフが十分に小さく、メモリに収まる場合には、最高のパフォーマンスを発揮します。

ヒープメモリの使われ方

オブジェクトキャッシュ内のデータが 64 ビット JVM 上で消費するメモリを計算するには、次の表を使ってください。

オブジェクト サイズ コメント

Node

344 B

各ノードのサイズ (リレーションとプロパティは含みません)。

48 B

オブジェクトのオーバーヘッド。

136 B

プロパティストレージ (ArrayMap 48B, HashMap 88B)。

136 B

リレーションストレージ (ArrayMap 48B, HashMap 88B)。

24 B

最初の/次のリレーションの場所。

Relationship

208 B

各リレーションのサイズ (プロパティは含みません)。

48 B

オブジェクトのオーバーヘッド。

136 B

プロパティストレージ (ArrayMap 48B, HashMap 88B)。

Property

116 B

ノードまたはリレーションの各プロパティのサイズ。

32 B

データ要素 - トランザクションによる変更を可能にし、ディスク上の場所を追跡します。

48 B

当該要素が格納されるハッシュテーブル内のエントリ。

12 B

ハッシュテーブル内で使われるスペース。通常の格納率 (fill ratio) に対応。

24 B

プロパティキーインデックス。

Relationships

108 B

特定タイプのリレーションを持つノードの各リレーションタイプのサイズ。

48 B

該当するタイプのリレーションのコレクション。

48 B

当該要素が格納されるハッシュテーブル内のエントリ。

12 B

ハッシュテーブル内で使われるスペース。通常の格納率 (fill ratio) に対応。

Relationships

8 B

特定ノードに関連した各リレーション (内向きと外向きの両方) によって使われるスペース。

Primitive

24 B

プリミティブプロパティ値のサイズ。

String

64+B

文字列プロパティ値のサイズ。64 + 2*len(string) B (64 バイトに、文字列中の各文字につき 2 バイトを加えたもの)。