シャードの容量

シャードの容量を決定するには、まずこの項で説明するアプリケーションおよびハードウェアの特性を確認します。このような特性を確認した後、添付のスプレッドシートに入力します。スプレッドシートでは、指定されたアプリケーションおよびハードウェアの特性に基づいてシャードの容量が計算されます。

アプリケーションの特性

レプリケーション係数

一般に、大半のアプリケーションで適正であり有効な開始点となるプライマリ・レプリケーション係数は3であり、これは、1つのプライマリ・ゾーンに障害が発生した場合、3つのレプリカにより書込み可用性が得られるためです。パフォーマンス・テストによって特定の作業負荷に対する最適な数が判明している場合、数を調整できます。プライマリ・レプリケーション係数として2を選択した場合、障害が1つでも発生すると、サイトが少なすぎて新しいマスターを選択できなくなるため、2は選択しないでください。これは、アービタ・ノードが存在する場合には当てはまりません。レプリケーション係数が2で、レプリケーション・ノードが失われても、新しいマスターを選択できるためです。ただし、両方のレプリケーション・ノードに追い付く前に複数の障害が発生した場合は、新しいマスターを選択できない可能性があります。Oracle NoSQL Databaseにはデータのコピーが1つしかないため、通常は、1のプライマリ・レプリケーション係数は使用しないでください。データをホストするストレージ・デバイスに障害が発生した場合、データが失われます。

プライマリ・レプリケーション係数を大きくすると、2つの利点があります。
  1. ディスクやマシンの障害に耐えられるように永続性が向上します。

  2. 読取りリクエストのスループットが向上します。これは、リクエストのサービスに使用できるシャード当たりのノード数が増えるためです。

ただし、永続性と読取りスループットの向上には、それに関連するコストが発生します。各シャードには更新をレプリケートする必要があるノードが増えるため、データの追加のコピーをホストおよびサービスするハードウェア・リソースがそれだけ増え、書込みパフォーマンスが低下します。

ノート:

書込み可用性に影響するのはプライマリ・レプリケーション係数のみですが、読取り可用性に影響するのは、プライマリおよびセカンダリ・レプリケーション係数の両方とも、したがってストア・レプリケーション係数となります。

プライマリ・レプリケーション係数は、セルRFによって定義されます。

平均キー・サイズ

平均的なキー長は、アプリケーションのキー・スキーマと様々なキーの相対分布を調べればわかります。ディスク上のキーの長さは、キーのコンポーネントを表すために必要なUTF-8バイト数にコンポーネント数を加えて1を引いたものです。

この値は、セルAvgKeySizeによって定義されます。

平均値サイズ

平均的なシリアル値サイズを調べるには、アプリケーションを調べればわかります。値サイズは、アプリケーションで使用される特定のシリアル化形式によって異なります。

この値は、セルAvgValueSizeによって定義されます。

読取りおよび書込み操作の割合

アプリケーションで使用されるKVS API操作に基づいて、ストア・レベルの読取りおよび書込み操作の相対的な頻度を概算します。

最も基本的なレベルでは、各KVS get()コールはストア・レベルの読取り操作になり、各put()操作はストア・レベルの書込み操作になります。各KVSの複数キー操作(KVStore.execute()、multiGet()またはmultiDelete())は、複数のストア・レベルの読取り/書込み操作になる可能性があります。それで、アプリケーションにおいてこのような操作でアクセスされるキーの数を考慮に入れて、見積を作成します。

見積は読取りの割合として表します。つまり、ストア上の操作合計に対する読取り操作の割合です。残りの操作は、書込み操作であるとみなされます。

この値は、セルReadOpsPercentによって定義されます。

ファイル・システム・キャッシュからで満たされる可能性がある読取り操作の割合を見積もります。この割合は、主にアプリケーションのデータ・アクセス・パターンおよびファイル・システム・キャッシュのサイズによって異なります。「サイズ設定に関する注意事項」には、このキャッシュの使用方法に関する説明が記載されています。

この値は、セルReadCacheHitPercentによって定義されます。

ハードウェアの特性

ストアのホストに使用されるマシンのタイプの概略に基づいて、次のハードウェア特性を決定します。

  • KVペアの格納に使用されるマシン当たりのディスク数。この値は、セルDisksPerMachineによって定義されます。「ストレージ・ノード・パラメータ」で説明されているように、通常、このマシン当たりのディスク数によりストレージ・ノードの容量が決定されます。

  • 各ディスクの使用可能なストレージ容量。この値は、セルDiskCapacityGBによって定義されます。

  • 各ディスクのIOP容量。この情報は通常、ディスクが提供できる継続的なランダムIO操作/秒の数として、ディスクの仕様書に記載されています。この値は、セルDiskIopsPerSecによって定義されます。

次の説明は、システムがディスク当たり1つのRNで構成されることを前提としています。

シャードのストレージおよびスループットの容量

この説明に関連する容量には、1)ストレージ容量、2)スループット容量の2つのタイプがあります。次の項では、この2つの容量の基準を計算する方法について説明します。以前に示したアプリケーションとハードウェアの特性に基づいて、基になる計算は付属のスプレッドシートによって自動的に実行されます。

シャードのストレージ容量

ストレージ容量は、1つのシャードに格納できるKVペアの最大数です。(安全マージンおよびクリーナ使用率として取り分けられるストレージを考慮した後の)生のKVペアに実際に使用できるストレージを、各KVペアで必要なストレージ(Btreeオーバーヘッドの概算を含む)で割ることで計算されます。

KVストレージの容量は、セルMaxKVPairsPerShardによって計算されます。

シャードのI/Oスループットの容量

スループット容量は、1つのシャードでサポートできる読取りおよび書込み操作の基準です。次の計算では、論理的なスループット容量を、キャッシュ・ヒット数を考慮した後に実際にディスクIOPに変換される論理操作の割合に基づいて、ディスクIOPの容量から導出します。マシンの物理メモリーの項には、Oracle NoSQL Databaseで使用されるキャッシュの構成に関する詳細情報が含まれています。

論理的な読取り操作の場合、シャード全体のIOPは次のように計算されます。

(ReadOpsPercent * (1 - ReadCacheHitPercent))

すべての割合が分数で表されることに注意してください。

論理的な書込み操作の場合、シャード全体のIOPは次のように計算されます。

(((1 - ReadOpsPercent) / WriteOpsBatchSize) * RF)

書込み操作の計算は非常に大まかなものです。ログ構造化ストレージ・システムで使用される連続書込みにより、読取り操作よりも書込み操作の方がIOP負荷に対する関与は少なくなります。WriteOpsBatchSizeを使用するのは、基になるJEログ構造化ストレージ・システムへの書込みの連続性を考慮することを目的としています。ワークロードに読取りがない、つまり純粋な挿入または更新負荷の場合、前述の算式は機能しません。純粋な挿入では、書込みは主に式でモデル化されていない確認レイテンシによって制限されます。純粋な更新負荷では、確認レイテンシとクリーナのパフォーマンスの両方が重要な役割を果たします。

前述の2つの数の合計は、実際にディスク操作になる論理操作の割合(DiskIopsPercentセル)を表します。その後、シャードの論理スループットを次のように計算できます。

(DiskIopsPerSec * RF)/DiskIopsPercent

セルOpsPerShardPerSecによって計算されます。

メモリーおよびネットワークの構成

シャードのストレージおよびスループットの容量を設定した後、各マシンで必要な物理メモリーおよびネットワークの量を決定できます。ストアが適切に動作するためには、物理メモリーおよびネットワーク・リソースを正しく構成する必要があります。ストアの合計サイズを決定することが主な目的の場合は、「シャードおよびマシンの総数の見積」に進みます。ただし、後でマシン・レベルのハードウェア要件を最終決定する段階になったら、必ずこの項に戻ってください。

ノート:

makebootconfigユーティリティのmemory_mbパラメータまたはmemorymbストレージ・ノード・パラメータを使用して、ストア内のストレージ・ノードごとに使用可能なメモリー・サイズを設定することもできます。詳細は、それぞれインストール構成パラメータおよびストレージ・ノード・パラメータを参照してください。

マシンの物理メモリー

シャードのストレージ容量(セルMaxKVPairsPerShardによって計算)および平均キー・サイズ(セルAvgKeySizeによって定義)を使用すると、マシンの物理メモリー要件を見積もることができます。マシンの物理メモリーには、Oracle NoSQL Databaseで使用されるキャッシュがバックアップされます。

ストアのパフォーマンス目標を満たすためには、インメモリー・キャッシュのサイズを適切に設定する必要があります。ディスクI/Oは、パフォーマンスの観点ではメモリーの消費が多い動作です。キャッシュからサービスされる動作が多いほど、ストアのパフォーマンスが向上します。

続行する前に、この説明に関連する2つのキャッシュがある点に注目してください。

  1. JEキャッシュ。Oracle NoSQL Databaseで使用されるベースとなるストレージ・エンジンはBerkeley DB Java Edition (JE)です。JEには、インメモリー・キャッシュが備わっています。ほとんどの場合、これは制御および構成が最も簡単なキャッシュであるため、最も重要なキャッシュ・サイズです。

  2. ファイルシステム(FS)キャッシュ。最新のオペレーティング・システムでは、ディスクI/O専用のキャッシュやバッファを用意してI/Oサブシステムのパフォーマンスが向上するようになっています。FSキャッシュを使用すると、キャッシュに格納されているデータによって読取りが完結する場合、読取り操作を非常に高速に行うことができます。

サイズ設定に関する注意事項

JEでは、格納するデータの編成にBツリーが使用されます。Bツリーでは、木のようなデータ編成構造で高速な情報検索を実現します。木構造は、内部ノード(IN)とリーフ・ノード(LN)で構成されます。INは、データのナビゲーションに使用されます。LNは、Bツリーでデータが実際に格納される場所です。

Oracle NoSQL Databaseアプリケーションで使用される予定のデータ・セットが非常に大きいため、データの一部でさえJEのインメモリー・キャッシュに格納することはあまりありません。したがって、最もよい方法は、データベースのINの大半(すべてではなくても)を保持するのに十分な大きさにキャッシュのサイズを設定し、ノードの残りのメモリーがシステム・オーバーヘッド(ごくわずか)とFSキャッシュに使用されるようにします。

INとLNの両方ともFSキャッシュを使用できます。FSキャッシュにある場合、INとLNにはJavaオブジェクト・オーバーヘッドがない(JEキャッシュの場合はある)ため、JEキャッシュ・メモリーよりもFSキャッシュ・メモリーの方が効率的に使用できます。

当然、このFSキャッシュが十分に機能するには、データ・アクセス・パターンが完全にランダムではないようにします。有用なキャッシュ・ヒット率を達成するには、一部のキーと値のペアが他のペアよりも優先される必要があります。アクセス・パターンがランダムでなないアプリケーションの場合、LNとINのファイルシステム・キャッシュ・ヒット率が高いと、スループットが向上し、平均読取りレイテンシが低下します。また、適切にチューニングされている場合、ファイルシステム・キャッシュが大きいほど、ログ・ファイルへの順次書込みの際のストールの数が減り、書込みレイテンシが低下します。キャッシュが大きい場合、ほとんどの書込みを非同期に行うこともでき、スループットが向上します。

JEキャッシュ・サイズの決定

JEキャッシュの適切なサイズを決定するには、com.sleepycat.je.util.DbCacheSizeユーティリティを使用します。このユーティリティでは、レコードの数とアプリケーション・キーのサイズを入力として必要とします。必要に応じて、予想されるデータのサイズなどの他の情報を指定することもできます。ユーティリティによって、短い表形式の情報が表示されます。必要な数は、Cache Size列およびInternal nodes and leaf nodes: MAIN cache行に指定されます。

たとえば、平均キー・サイズが12バイトで平均値サイズが1000バイトの1億個のレコードを含む環境のJEキャッシュ・サイズを決定する場合、次のようにDbCacheSizeを起動します。

java -Xmx64m -Xms64m \
-d64 -XX:+UseCompressedOops -jar je.jar DbCacheSize \
-key 12 -data 1000 -records 100000000 -replicated 

	  === Environment Cache Overhead ===

	  2,536,302 minimum bytes

	  To account for JE daemon operation, record locks, HA network
          connections, etc, a larger amount is needed in practice.

	  === Database Cache Size ===

	   Number of Bytes  Description
	   ---------------  -----------
	     3,896,520,528  Internal nodes only: 
	     4,660,565,808  Internal nodes and records version
	   110,107,803,216  Internal nodes and leaf nodes 

次のjvm引数を書き留めてください(DbCacheSizeに対して指定した場合、特別な意味があります)。

  1. 前述のコマンド例では、Java 10以降を使用することを前提としています。Java 8または9で実行している場合は、コマンドに-d64引数を追加してください。その場合、-d64引数が使用されていることで、キャッシュ・サイズで64ビットJVMが考慮されます。64ビットJVMのみがNoSQL DBでサポートされます。
  2. -XX:+UseCompressedOopsによって、CompressedOopsモード(NoSQL DBでデフォルトで使用される)がキャッシュ・サイズで考慮されます。このモードでは、64ビットJVMでより効率的な32ビット・ポインタを使用するため、JEキャッシュの使用率が向上します。
  3. -replicatedが使用されていることで、JE ReplicatedEnvironment (NoSQL DBで常に使用される)でのメモリー使用量が考慮されます。

これらの引数をDatabase Cache Sizeに対して指定すると、JEアプリケーションにもこれらの引数が渡されることを意味し、Database Cache Sizeによって計算が適切に調整されます。Oracle NoSQL Databaseによってこれらのキャッシュを使用するレプリケーション・ノードが起動されるとき、これらの引数が使用されます。

この出力は、JEキャッシュ内のBtreeを表すすべての内部ノードを保持するには3.6GBのキャッシュ・サイズで十分であることを示しています。このサイズのJEキャッシュでは、INノードはJEキャッシュから取得され、LNはオフヒープ・キャッシュまたはディスクから取得されます。

DbCacheSizeユーティリティの使用方法の詳細は、このJavadocページを参照してください。このユーティリティを使用するためには、<KVHOME>/lib/je.jarファイルをJavaクラスパスに追加する必要があることに注意してください。<KVHOME>は、Oracle NoSQL Databaseパッケージ・ファイルを配置したディレクトリを表します。

DbCacheSizeを使用してJEキャッシュ・サイズを取得した後、その値からヒープ・サイズを計算できます。これを行うには、DbCacheSizeから取得した数値をDbCacheSizeMBという名前のセルに入力します。必ず、単位をバイトからMBに変換してください。ヒープ・サイズは、次のようにセルRNHeapMBによって計算されます。

(DBCacheSizeMB/RNCachePercent)

ここで、RNCachePercentはJEキャッシュに使用されるヒープの割合です。java VMが効率的なCompressedOops形式を使用してメモリー内のjavaオブジェクトを表せるように、計算されるヒープ・サイズが32GBを超えないようにしてください。32GBを超える値のヒープ・サイズは、この要件を強調するためにRNHeapMBセルでは取消線付きで表示されます。ヒープ・サイズが32GBを超える場合は、キーのサイズを小さくしてJEキャッシュのサイズを小さくし、ヒープ・サイズ全体が32GBを下回るようにしてください。

ヒープ・サイズは、次のようにマシンで必要なメモリーを計算するための基準として使用されます。

(RNHeapMB * DisksPerMachine)/SNRNHeapPercent

ここで、SNRNHeapPercentは、マシンでホストされるRNに使用できる物理メモリーの割合です。結果は、セルMachinePhysicalMemoryMBで使用できます。

マシンのネットワーク・スループット

マシンに付属するNICが、「シャードのI/Oスループット容量」で以前に計算したアプリケーションI/Oスループットを提供できることを確認する必要があります。これは、提供できない場合にボトルネックになる可能性があるためです。

クライアントで開始された書込み操作の結果としてネットワーク経由でマシンが受信するバイト数は、次のように計算されます。

(OpsPerShardPerSec * (1 - ReadOpsPercent) * 
 (AvgKeySize + AvgValueSize)) * DisksPerMachine

スプレッドシートではReceiveBytesPerSecで示されます。計算の際には、ノードがマスターかレプリカかは問題ではないことに注意してください。受信書込みバイトは、マスターのクライアントおよびマシンのレプリカのマスターから発生します。

読取りリクエストの結果としてマシンが受信するバイト数は、次のように計算されます。

((OpsPerShardPerSec * ReadOpsPercent)/RF) * 
 (AvgKeySize + ReadRequestOverheadBytes) * DisksPerMachine

ここで、ReadRequestOverheadBytesは100バイトの固定定数オーバーヘッドです。

読取り操作の結果としてネットワーク経由でマシンが送信するバイト数には、基になる2つのコンポーネントがあります。

  1. アプリケーションの読取りリクエストに対する直接応答で送信されるバイト数は、次のように表されます。

    ((OpsPerShardPerSec *  ReadOpsPercent)/RF) * 
     (AvgKeySize + AvgValueSize) * DisksPerMachine
  2. マシンのマスターによってレプリケーション・トラフィックとして送信されるバイト数は、次のように表されます。

    (OpsPerShardPerSec * (1 - ReadOpsPercent) * 
     (AvgKeySize + AvgValueSize) * (RF-1)) * MastersOnMachine

前述の2つの値の合計は、スプレッドシートのSendBytesPerSecで表される送信トラフィックの合計を表します。

受信トラフィックと送信トラフィックの合計が、NICの容量内に適切に収まる必要があります。スプレッドシートでは、トラフィックのサポートに必要なネットワーク・カードの種類(GigEまたは10GigE)が計算されます。