サーバー

サーバー障害の検出およびNoSQLログ・イベントとの関連付け
サーバー障害の解決
用語の確認
前提
交換手順1: SNを同一のSNと交換する
交換手順2: 除外したSNの役割を新しいSNで引き継ぐ
設定
例1: 障害が発生したSNを同一のSNと交換する
確認
例2: 新しいSNで既存のSNの役割を引き継ぐ

ディスクの障害ほど一般的ではありませんが、特定のKVStoreのデプロイメントを構成するサービスのホストとなっているマシン(SN)のいずれかを管理者が交換する必要に迫られるのは珍しいことではありません。マシン全体の交換が発生する一般的なシナリオが2つあります。1つ目は、1つ以上のハードウェア・コンポーネントで障害が発生した場合です。障害が発生したコンポーネントを交換するよりも単にマシン全体を交換したほうが便利で、また費用対効果に優れています。2つ目は、問題なく稼働しているマシンをより大型で堅牢なマシンにアップグレードする場合です。たとえば、ディスクの容量が大きく、パフォーマンス特性に優れたマシンです。この項で示す手順は、既存のマシンと交換する新規マシンの準備を整えるための手順と、既存のマシンを廃棄するための手順について説明することを目的としています。

サーバー障害の検出およびNoSQLログ・イベントとの関連付け

Oracle NoSQL Databaseなどの分散では、ネットワークの停止とマシンの障害を区別するのは一般的に困難です。レプリケーション・ノードへの到達不可があると、それがNoSQL DatabaseのHAコンポーネントによって検出され、イベントとして管理ログに記録されます。ただし、このログ・イベントをgrep検索すると、誤検出が見つかります。このため、SNMPやJMXなどのシステム監視パッケージを使用して、マシン/サーバー障害を検出することをお薦めします。

サーバー障害の解決

2つの交換手順を次に示します。どちらの手順でも実質的に同じ結果がもたらされ、1つ以上のネットワーク・リストア・プロセスが実行されます(次を参照)。最初に示す手順では、古いマシンをすべての利害関係者にとって元のマシンとまったく変わらないマシンと交換します。つまり、新規マシンは同じホスト名、IPアドレス、ポートおよびSN idを持ちます。これに比べて2つ目の手順では、古いマシンをストアのトポロジから削除し、ホスト名、IPアドレス、SN idが異なる別のマシンのように見えるマシンと交換しますが、動作は元のマシンの動作と同じです。つまり、新規マシンは元のマシンと同じサービスを実行し、まったく同じデータを管理します。それが異なるネットワークおよびSN idで行われるだけです。したがって、最初のケースはハードウェアのみの交換であると考えることができます。つまり、ストアから見ると、元のSNが一時的に停止し、その後再開されたことになります。新しいハードウェアは、ストアのトポロジに反映されません。もう一方のケースでは、元のSNが削除され、異なるSNが元の役割を引き継ぎます。ストアの内容および動作は変わりませんが、ハードウェアの変更はストアの新しいトポロジに反映されます。

ストレージ・ノードを交換する際にどの手順を使用するかを決定しても、その決定はストア管理者の裁量に委ねられます。管理者によっては、常に1つの手順のみを使用し、他の手順は使用しないことも考えられます。また、管理者が優先条件に基づいてポリシーを確立する場合もあります。たとえば、ハードウェアで障害が発生したためSNの交換を実行する必要があるときには1つ目の手順を使用し、問題なく稼働しているハードウェアをより新しくて優れたハードウェアにアップグレードするときには2つ目の手順を使用するというポリシーを想像してみてください。1つ目のケースの場合、障害が発生したSNは交換プロセスの間停止し、使用できません。2つ目のケースの場合、新規マシンの移行準備を整えている間、交換対象のマシンを稼働させて使用可能な状態にしておくことができます。その後、古いマシンを停止し、トポロジから除外できます。

用語の確認

『Oracle NoSQL Databaseスタート・ガイド』および『Oracle NoSQL Database管理者ガイド』で導入された用語をいくつか確認しておくと有益です。これらのドキュメントから、KVStoreのプロセスを実行する物理マシンがストレージ・ノード(SN)と呼ばれていることを思い出してください。典型的なKVStoreデプロイメントは一般に、Oracle NoSQL Database KVStoreから提供されるプロセスおよびソフトウェア・サービスを実行する数多くのマシン(つまり数多くのSN)で構成されています。また、KVStoreソフトウェアを最初に特定のSNマシンで起動すると、ストレージ・ノード・エージェント(SNA)と呼ばれるプロセスが起動されることも思い出してください。次に、SNAを起動した後、KVStore管理CLIを使用してストアを構成し、トポロジをデプロイします。その結果、SNAはレプリケーション・ノードと呼ばれる1つ以上のサービス(RNサービス)のライフサイクルを実行および管理するようになります。最後に、RNサービスを起動および管理するだけでなく、SNAはオプションで(構成に応じて)管理サービスと呼ばれる別のサービス・タイプも起動および管理します。

特定のKVStoreデプロイメントを構成するマシンと、ストアをインストールしてデプロイする際に各マシンで最初に起動されたSNAプロセスとを1対1で対応付けるため、この注意も含めOracle NoSQL Databaseドキュメントでは、SNAを実行しているマシンまたはSNAプロセス自体を参照する場合にストレージ・ノード、SN、またはSNx (xは正の整数)という用語を区別なく使用していることがよくあります。用語を使用する特定のディスカッションの文脈から、概念が意図することをはっきりさせる必要があります。たとえば、マシンの障害やリカバリなどハードウェアの問題に関するディスカッションの一環としてSN3またはsn3という用語を使用した場合、その用語はid値3が割り当てられ、ストアのトポロジで文字列sn3で識別されるSNAプロセスを実行中の物理ホスト・マシンを指します。その他の文脈、たとえば、ストアのソフトウェアの動作について説明している場合、SN3やsn3という用語は関連付けられたマシンで実行中の実際のSNAプロセスを指します。

ディスカッションには直接関係しませんが、万全を期すためだけでなく、どのSN交換手順を使用するかを決定しようとするときにその意味するところを理解しておくと有益であるため、次の用語を紹介します。

まず、Oracle NoSQL Databaseドキュメントから、各SNAによって起動および管理されるRNサービスが、ストアのトポロジでそれぞれのサービス識別番号(正の整数)と、そのサービスがメンバーとなっているレプリケーション・グループ(シャード)の識別番号とで表されることを思い出してください。たとえば、ある特定のストアのトポロジが特定のRNサービスを文字列rg3-rn2で参照しているとします。これは、idが2に等しくかつid 3のレプリケーション・グループ(シャード)のメンバーであるRNサービスを表します。特定のKVStoreクラスタの一部として動作している特定のSNマシンの容量は、そのSNホストにデプロイされたSNAプロセスによって開始および管理されるRNサービスの数です。また、KVStoreのレプリケーション係数(またはrf)は、保持する必要があるストアに書き込まれた各キー/値ペアのコピー(またはレプリカ)の数です。容量が特定のマシンで実行するRNサービスの数に対応する個別/SNの概念であるのに対して、レプリケーション係数はストア全体の概念であり、ストアによって管理される各シャード(またはレプリケーション・グループ)に属するRNサービスの数を決定する場合に使用されます。

最後に、ネットワーク・リストアはストアが特定のRNサービスによって以前に書き込まれたすべてのデータを自動的にリカバリするプロセスです。つまり、様々なSNで実行中の1つ以上のRNサービスからデータのレプリカを取得し、そのデータを(ネットワークを横断して)データベースがリストアされるRNに転送します。このプロセスがシステム・パフォーマンスに及ぼす可能性がある影響を理解することが重要です。このプロセスはかなりの時間がかかる場合があり、リストアされたRNのデータ・ストアを再移入している間、大量のネットワーク・トラフィックおよび負荷が発生することがあります。また、SN交換については、交換対象のSNの容量が1を超えていると、複数のネットワーク・リストアが実行されるため、これらの影響が拡大する場合があります。

前提

ここで2つの手順を示す際、簡略化するため、KVStoreが最初に3つのマシンにデプロイされ、その結果host-sn1、host-sn2、host-sn3という名前のホスト上のそれぞれsn1、sn2、sn3という3つのストレージ・ノードからなるクラスタが存在していることを前提としています。次のことを前提としています。

  • 各マシンには、/optおよび/disk1という名前のディスクがあります。各SNはその構成および管理データベースを/opt/ondb/var/kvrootに格納しますが、他の個別のディスクに書き込まれるデータを/disk1/ondb/dataに格納します。

  • KVStoreは各マシンの /opt/ondb/kvにインストールされています。つまり、KVHOME=/opt/ondb/kvとなります。

  • KVStoreは、KVROOT=/opt/ondb/var/kvrootでデプロイされます。

  • KVStoreは、example-storeという名前です。

  • 名前がdc1でrf=3と構成された1つのデータセンターがストアにデプロイされています。

  • 各SNはcapacity=1と構成されています。

  • 各SNをdc1という名前のデータセンターにデプロイすると、各SNはsnpoolという名前のpoolに加わります。

  • SNAサービスおよびRNサービスだけでなく、管理サービスも各マシンにデプロイされます。つまり、admin1host-sn1にデプロイされ、admin2host-sn2にデプロイされ、admin3host-sn3にデプロイされ、それぞれがポート13230でリスニングします。

前述の「前提」に反映される値など特定の値を使用すると、各手順のステップに従うことができます。『Oracle NoSQL Database管理者ガイド』に記載されている情報と組み合せることで、管理者はそれらの手順を一般化し、独自の特定のデプロイメント・シナリオに拡張し、必要に応じて指定の環境に固有の値に置き換えることができます。

交換手順1: SNを同一のSNと交換する

ここで示す手順では、目的のSNをネットワークおよびSN idが同じマシンと交換する方法について説明します。この手順を実行する前に、次のような数多くの要件を満たす必要があります。

  • 管理サービスが実行中で、システム内のどこかでアクセス可能である必要があります。

  • 交換対象のSNのidを知っている必要があります。

  • 新しいSNを起動する前に、交換対象のSNは管理上の理由または障害のために停止している必要があります。

交換対象のSNの現在の構成を管理サービスのデータベースから取得して新しいSNでのインストール用にパッケージ化できるように、管理サービスが必要です。このため処理を進める前に、管理者は管理サービスの場所(ホスト名またはIPアドレス)と、そのサービスがリクエストをリスニングしているポートを知っている必要があります。また、このプロセスでは交換対象のSNのidが必要になるため、管理者は次の手順を開始する前にsn1、sn2、sn3などその値も知っている必要があります。

最後に、交換対象のSNで障害が発生したため、そのSNがすでに停止している場合、前述の最後の要件は自動的に満たされます。一方、交換対象のSNが稼働している場合は、新しいSNを起動する前にある時点で古いSNを停止して、そのSNと交換先のSNが競合しないようにする必要があります。

管理サービスに関連する要件については、システムで管理の複数のインスタンスが実行中である場合、次の手順でどのインスタンスを使用するかは重要ではなく、管理が現在実行中でアクセス可能であることが重要です。つまり、交換対象のSNが稼働しているだけでなく管理サービスを実行している場合、その管理サービスを使用してそのSNの現在の構成を取得し、パッケージ化できます。しかし、そのSNで障害が発生した場合や、なんらかの理由で停止するか、またはアクセスできなくなった場合は、そのSN上の管理サービスも停止したりアクセスできなくなります。つまり、次の手順ではシステム内の他のいずれかのSNで実行中の管理サービスを使用する必要があります。このような理由から、Oracle NoSQL Databaseドキュメントでは、管理者が複数の管理サービスをデプロイすることを薦めています。デプロイされた数により、クォーラムが失われる可能性が低くなります。

たとえば、ストアのデプロイ時に1つの管理サービスのみを指定し、そのサービスを交換対象のSNにデプロイし、そのSNで障害が発生したりアクセスできなくなった場合、その唯一の管理サービスが失われるため、ここに示す手順を使用して問題のSNを交換するのは容易でないことは明らかです。複数の管理(たとえば2つの管理)をデプロイしたとしても、SNの障害のためにそのうちの1つの管理でも障害が発生してクォーラムを失った場合には、稼働中の管理は残るものの、管理サービスが問題のSNの交換に必要な役割を果たせるようにクォーラムをリカバリするには追加の作業が必要です。

「前提」の項の説明に従ってKVStoreがデプロイされたものとします。また、なんらかの理由でsn2マシン(ホスト名host-sn2)で障害が発生し、交換する必要があるものとします。管理者は、問題のSNを同一の問題なく稼働しているマシンと交換する場合、次の処理を実行します。

  1. なんらかの理由でhost-sn2が実行中である場合は停止します。

  2. host-sn1 (またはhost-sn3)にログインします。

  3. コマンドラインからgenerateconfigユーティリティを実行して、問題のSN (sn2)の現在の構成が含まれているZIPファイルをsn2-config.zipという名前で生成します。

    > java -jar /opt/ondb/kv/lib/kvstore.jar generateconfig
    -host host-sn1 -port 13230 \
    

    これにより、ファイル/tmp/sn2-config.zipが作成され、移入されます。

  4. 新規マシンを導入し、交換対象のマシンと同じネットワーク構成、特に同じホスト名とIPアドレスでプロビジョニングします。

  5. KVHOME=/opt/ondb/kvの新規マシンにKVStoreソフトウェアをインストールします。

  6. ディレクトリKVROOT=/opt/ondb/var/kvrootが存在する場合はそれが空であることを確認し、そうでない場合はそれを作成します。

    > rm -rf /opt/ondb/var/kvroot
    > mkdir -p /opt/ondb/var/kvroot
    
  7. ZIPファイルをhost-sn1から新しいhost-snにコピーします。

    > scp /tmp/sn2-config.zip host-sn2:/tmp
    
  8. 新しいhost-sn2で、コピーしたZIPファイルの内容をインストールします。

    > unzip /tmp/sn2-config.zip -d /opt/ondb/var/kvroot
    
  9. インストールした古いsn2構成を使用して、新しいhost-sn2マシンでsn2ストレージ・ノードを再起動します。

    > nohup java -jar /opt/ondb/kv/lib/kvstore.jar start \
    -root /opt/ondb/var/kvroot \
    -config config.xml&
    

    これにより、SNA、RNおよび管理サービスの起動後、ネットワーク・リストアが開始されて(時間がかかる可能性があります)、この新しいsn2で管理されるデータ・ストアが再移入されます。

交換手順2: 除外したSNの役割を新しいSNで引き継ぐ

ここで示す手順では、ネットワークおよびSN idがストア内の現在のすべてのSNとは異なり、そのSNの役割およびデータを引き継ぐことで現在のSNのいずれかと効果的に置き換わる、新しいSNをデプロイする方法について説明します。前の手順と異なり、この2つ目の手順を実行するときに満たす必要がある唯一の前提条件は管理サービスの稼働中のクォーラムが存在することです。また、前の手順では交換先のSNの電源を入れる前に交換対象のSNを停止する必要がありした(2つのSNがidを共有するため)が、この手順では、プロセスの移行手順まで交換対象のSNを稼働させたままにしておくことができ、交換先のSNは最終的に交換対象のSNの役割を引き継ぎます。このため、必要に応じて手順全体を通して交換対象のSNを停止できますが、交換先のSNの準備を整えている間も引き続きリクエストに対応できるように、そのSNを稼働させておくこともできます。

「前提」の項の説明に従ってKVStoreがデプロイされたものとします。また、sn2マシンは現在稼働中ですが、メモリーとディスクの容量が大きくパフォーマンス特性全体に優れた新規マシンにアップグレードする必要があるものとします。次に、管理者は次の処理を実行します。

  1. デプロイ済のKVStore用の管理サービスを実行しているいずれかのマシンにネットワーク経由でアクセスできる、Oracle NoSQL Databaseソフトウェアがインストールされたマシンから、管理CLIを起動してそれをその管理サービスに接続します。CLIが実行されているマシンは、ストアを構成するマシンのいずれか(交換対象のマシンでも可)、または独立したクライアント・マシンになることに注意してください。たとえば、管理CLIをsn1ストレージ・ノードで起動し、その同じsn1ホストで実行中の管理サービスにそのCLIを接続する場合、host-sn1という名前のホストのコマンド・プロンプトから次のように入力します。

    > java -jar /opt/ondb/kv/lib/kvstore.jar
    runadmin -host host-sn1 -port 13230
    
  2. 起動した管理CLIから、show poolsコマンドを実行して、デプロイ後に新しいストレージ・ノードが加わる必要があるストレージ・ノードpoolを決定します。たとえば、次のようにします。

    kv-> show pools
    

    初期の前提であると、次のような出力が生成されます。

    AllStorageNodes: sn1 sn2 sn3
    

    この出力から、新しいストレージ・ノードをデプロイするときに使用するデータセンターのidは1となります。

  3. 新規マシンを導入し、デプロイ済のKVStoreに現在認識されている各マシンとは異なるネットワーク構成でプロビジョニングします。たとえば、host-sn4などのホスト名およびストアのメンバーに一意のIPアドレスで新規マシンをプロビジョニングします。

  4. KVHOME=/opt/ondb/kvの新規マシンにKVStoreソフトウェアをインストールします。

  5. 新しいストレージ・ノードのKVROOTディレクトリを作成します。たとえば、次のようにします。

    > mkdir -p /opt/ondb/var/kvroot
    
  6. KVROOTとは別のディスクに新しいストレージ・ノードのデータ・ディレクトリを作成します。たとえば、次のようにします。

    > mkdir -p /disk1/ondb/data
    

    注意

    交換先のSNのデータ・ディレクトリに使用されるパスは、交換対象のSNで使用されているパスと同じである必要があります。

  7. 新しいhost-sn4マシンのコマンド・プロンプトから、makebootconfigユーティリティ(『Oracle NoSQL Database管理者ガイド』の第2章のインストール構成に関する項を参照)を使用して、前述の「前提」と整合性がある新しいストレージ・ノードの初期構成を作成します。たとえば、次のようにします。

    > java -jar /opt/ondb/kv/lib/kvstore.jar makebootconfig \
    -root /opt/ondb/var/kvroot \
    -port 13230  \
    -admin 13231 \
    -host host-sn4
    -harange 13232,13235 \
    -num_cpus 0  \
    -memory_mb 0 \
    -capacity 1  \
    -storagedir /disk1/ondb/data
    

    これにより、config.xmlという名前のファイルがKVROOT=/opt/ondb/var/kvrootに生成されます。

  8. 作成した構成を使用して、新しいhost-sn4マシンでKVStoreソフトウェア(SNAとその管理対象サービス)を起動します。たとえば、次のようにします。

    > nohup java -jar /opt/ondb/kv/lib/kvstore.jar start \
    -root /opt/ondb/var/kvroot \
    -config config.xml &
    
  9. 前述のshow topologyおよびshow poolsコマンドから収集されたsn2ストレージ・ノード(交換するSN)に関連付けられた情報を使用して、管理CLIで新しいストレージ・ノードをデプロイし、目的のプールに加えます。つまり、次のようにします。

    kv-> plan deploy-sn -dcname dc1 -host host-sn4 -port 13230 -wait
    kv-> pool join -name snpool -sn sn4
    

    SNをプールに加えるには、SNを正常にデプロイし、デプロイしたSNのidをたとえば前述のsn4というようにpool joinコマンドに指定する必要があります。しかし、plan deploy-snコマンドを調査すると、デプロイ対象のSNに割り当てるidが指定されていないことがわかります。これは、新規にデプロイしたSNに割り当てるidを決定するのが管理者ではなくKVStore自体であるためです。このため、この手順を示すために使用された例では当初3つのストレージ・ノードのみがデプロイされることを前提とした場合、次のストレージ・ノードをデプロイすると、最近デプロイしたSNに割り当てられたidの整数部分(sn3の場合は3)が1だけ増分され、その結果を使用して次にデプロイされるSNに割り当てるidを構成します。このため、sn4が前述のpool joinコマンドに指定するidであることを前提としました。ただし、割り当てられたidを確認する場合は、プールに加える前にshow topologyコマンドを実行して、新規にデプロイしたSNに構成されて割り当てられたidを表示します。

  10. 移行処理を実行するときに古いSNが実行中でないようにする必要があるため(次の手順を参照)、交換対象のSNがこの時点でまだ実行中である場合はプログラムで停止してから、電源を切り、関連付けられたマシンを切断します。この手順は、次の手順を実行する前のどの時点でも実行できます。このため、交換対象のSNを停止するには、そのSNのホストとなっているマシンのコマンド・プロンプトから次のように入力します。

    > java -jar /opt/ondb/kv/lib/kvstore.jar stop -root 
    /opt/ondb/var/kvroot
    

    完了後、必要に応じて関連付けられたマシンの電源を切って切断できます。

  11. 新しいストレージ・ノードがデプロイされて目的のプールに加わり、交換対象のSNが実行中でなくなった後、管理CLIを使用してその古いSNを新しいSNに移行します。つまりこの場合、sn4に関連付けられたSNA、RNおよび管理サービスは、sn2に関連付けられた対応するサービスがストアでそれまで果たしていた役割を引き継ぎます。また、sn2によってそれまで格納されたデータがネットワーク経由でsn4用のストレージ・ディレクトリに移動されます。その後この手順を実行するには、CLIから次のコマンドを実行します。

    kv-> plan migrate-sn -from sn2 -to sn4 -admin-port 13231 [-wait]
    

    この場合、古いSNは管理サービスを実行していたため、makebootconfigコマンドの管理引数に対して上記で使用したのと同じ値でadmin-port引数を指定する必要があります。前述のコマンドで-wait引数はオプションであることに注意してください。-waitを使用した場合、コマンドは完全移行が完了するまで戻らず、移行対象のデータ量によっては非常に長い時間がかかる場合があります。-waitを指定しない場合、show plan -id <migration-plan-id> コマンドを使用して移行の進行状況を追跡することで、移行中に他の管理タスクを実行できます。

  12. 移行プロセスが完了した後、古いSNをストアのトポロジから削除する必要があります。このためには、管理CLIからplan remove-snコマンドを実行します。たとえば、次のようになります。

    kv-> plan remove-sn -sn sn2 -wait
    

    この時点で、sn2がそのノードのrg1-rn2サービスを介してhost-sn2という名前のホストに元々格納していたデータを現在sn4ストレージ・ノードが(sn4が現在管理しているrg1-rn2という名前の移行サービスを介して) host-sn4に格納していることを除いて、ストアはその元の構造に似た構造になっています。

この項では、前述のSN交換手順で実践的な経験を得ることができる2つの例を示します。各例では、同じ初期構成を使用し、単一のディスクを搭載した単一のマシンを使用して3つのノードからなるKVStoreクラスタをシミュレートすることを目的としています。マシンで実際に障害が発生したり、マシンを物理的に交換することはありませんが、それでも前に説明した手順のいずれかを使用してそのストレージ・ノードを交換するときに、特定のSNによって格納されたクラスタおよびデータがどのように自動的にリカバリされるかを感じ取ることができます。

このため、KVStoreは「前提」の項と同じようにデプロイされることを前提としています。特に、KVStoreは当初sn1、sn2、sn3という名前の3つのストレージ・ノードを使用してIPアドレスが文字列<host-ip>で表される単一のホストにデプロイされるものとします。この場合、どちらの例を実行するときでも、<host-ip>をホストの実際のIPアドレス(またはホスト名)に置き換えてください。また、開発システムには(「前提」の項の指定に従って)通常/disk1という名前のディスクが含まれないため、このようなディスクをプロビジョニングするのではなく、ストアに書き込まれたデータはそれぞれ/tmp/sn1/disk1/tmp/sn2/disk1/tmp/sn3/disk1に格納されるものとします。最後に、各ストレージ・ノードは同じホストで稼働するため、各ストレージ・ノードはそれらのノードによって実行されるサービスおよび管理用の様々なポートで構成されているものとします。そうでない場合、他のすべての前提は前述の「前提」の項で説明されているとおりです。

設定

前述のように、初期構成および設定は次のどの例でも同じです。このため、まだそうしていない場合は、まず次のようにKVROOTディレクトリを作成します。

> mkdir -p /opt/ondb/var/kvroot 

次に、データ・ディスクをシミュレートするため、次のディレクトリを作成します。

> mkdir -p /tmp/sn1/disk1/ondb/data
> mkdir -p /tmp/sn2/disk1/ondb/data
> mkdir -p /tmp/sn3/disk1/ondb/data

続いて、各ストレージ・ノードを実行している3つのマシンを表すWin_A、Win_B、Win_Cの3つのウィンドウを開きます。各ウィンドウで、makebootconfigコマンド(文字列<host-ip>を実際のIPアドレスまたはホスト名に置き換えることを忘れないでください)を実行して、構成対象のSNごとに別の同じようなブート構成を作成します。

Win_A

java -jar /opt/ondb/kv/lib/kvstore.jar makebootconfig \
-root /opt/ondb/var/kvroot 
-host <host-ip> \
-config config1.xml \
-port 13230 \
-harange 13232,13235 \
-admin 13231 \
-memory_mb 100 \
-capacity 1 \

Win_B

java -jar /opt/ondb/kv/lib/kvstore.jar makebootconfig \
-root /opt/ondb/var/kvroot \
-host <host-ip> \
-config config2.xml \
-port 13240 \
-harange 13242,13245 \
-admin 13241 \
-memory_mb 100 \
-capacity 1 \
-storagedir /tmp/sn2/disk1/ondb/data

Win_C

java -jar /opt/ondb/kv/lib/kvstore.jar makebootconfig \
-root /opt/ondb/var/kvroot \
-host <host-ip> \
-config config3.xml \
-port 13250 \
-harange 13252,13255 \
-admin 13251 \
-memory_mb 100 \
-capacity 1 \
-storagedir /tmp/sn3/disk1/ondb/data

これにより、次の3つの構成ファイルが生成されます。

/opt/ondb/var/kvroot
    /config1.xml
    /config2.xml
    /config3.xml

次に、各ウィンドウから生成した様々な構成を使用して、KVStoreストレージ・ノード・エージェント(SNA)の対応するインスタンスを起動します。これは、生成された特定の構成に基づいて、管理サービスおよびRNサービスを開始および管理します。

Win_A

> nohup java -jar /opt/ondb/kv/lib/kvstore.jar start \
-root /opt/ondb/var/kvroot \
-config config1.xml &

Win_B

> nohup java -jar /opt/ondb/kv/lib/kvstore.jar start \
-root /opt/ondb/var/kvroot \
-config config2.xml &

Win_C

nohup java -jar /opt/ondb/kv/lib/kvstore.jar start \
-root /opt/ondb/var/kvroot \
-config config3.xml &

最後に、任意のウィンドウ(Win_A、Win_B、Win_Cまたは新しいウィンドウ)からKVStore管理CLIを起動し、それを使用してストアを構成およびデプロイします。たとえば、前述のWin_Aに使用されている構成を使用して開始した管理サービスに接続されている管理CLIを起動するには、次のコマンドを実行します。

> java -jar /opt/ondb/kv/lib/kvstore.jar runadmin
-host <host-ip> -port 13230

ストアを構成およびデプロイするには、管理CLIプロンプトから次のコマンドを入力します(文字列<host-ip>を実際のIPアドレスまたはホスト名に置き換えることを忘れないでください)。

kv-> configure -name example-store
kv-> plan deploy-datacenter -name dc1 -rf 3 -wait
kv-> plan deploy-sn -dcname dc1 -host <host-ip>
-port 13230 -wait
kv-> plan deploy-admin -sn 1 -port 13231 -wait
kv-> pool create -name snpool
kv-> pool join -name snpool -sn sn1
kv-> plan deploy-sn -dcname dc1 -host <host-ip>
-port 13240 -wait
kv-> plan deploy-admin -sn 2 -port 13241 -wait
kv-> pool join -name snpool -sn sn2
kv-> plan deploy-sn -dcname dc1 -host <host-ip>
-port 13250 -wait
kv-> plan deploy-admin -sn 3 -port 13251 -wait
kv-> pool join -name snpool -sn sn3
kv-> change-policy -params "loggingConfigProps=oracle.kv.level=INFO;"
kv-> change-policy -params cacheSize=10000000
kv-> topology create -name store-layout -pool snpool
-partitions 300
kv-> plan deploy-topology -name store-layout -plan-name
RepNode-Deployment -wait

前述のコマンドが完了すると(kv-> show plansを使用して各プランの完了を確認します)、ストアが稼働し、データ書込みの準備が整います。処理を進める前に、次に示すようなディレクトリが作成され、移入されていることを確認します。

     - Win_A -                  - Win_B -                - Win_C -

/opt/ondb/var/kvroot      /opt/ondb/var/kvroot      /opt/ondb/var/kvroot
  log files                 log files                 log files
  /example-store            /example-store            /example-store
    /log                      /log                      /log
    /sn1                      /sn2                      /sn3
      config.xml                config.xml                config.xml
      /admin1                   /admin2                   /admin3
        /env                      /env                      /env

/tmp/sn1/disk1/ondb/data  /tmp/sn2/disk1/ondb/data /tmp/sn3/disk1/ondb/data
  /rg1-rn1                  /rg1-rn2                  /rg1-rn3
    /env                      /env                      /env
      00000000.jdb              00000000.jdb              00000000.jdb 

デプロイ済のストアに対してrf=3、そのストア内の各SNに対してcapacity=1であるため、キー/値ペアが最初にストアに書き込まれるとき、ペアはrn1、rn2、rn3の各レプリケーション・ノードによってそれぞれの対応する00000000.jdbという名前のデータ・ファイルに格納されます。各レプリケーション・ノードは、rg1という名前のレプリケーション・グループ(またはシャード)のメンバーです。つまり、キー/値ペアは次に格納されます。

/tmp/sn1/disk1/ondb/data/rg1-rn1/env/00000000.jdb
/tmp/sn2/disk1/ondb/data/rg1-rn2/env/00000000.jdb
/tmp/sn3/disk1/ondb/data/rg1-rn3/env/00000000.jdb

この時点で設定内の各ファイルには、キー/値ペアは含まれていません。データは、最も便利な方法でストアに書き込むことができます。しかし、これを行うための便利なユーティリティの1つに、KVStoreクライアント・シェル・ユーティリティがあります。これは、目的のストアに接続して、対話型コマンドによってキー/値ペアの入力や取得を行うコマンドライン・インタフェースを表示するプロセスです。KVStoreクライアント・シェルを起動するには、コマンド・ウィンドウから次を入力します(文字列<host-ip>を実際のIPアドレスまたはホスト名に置き換えることを忘れないでください)。

> java -jar /opt/ondb/kv/lib/kvcli.jar \
-host <host-ip> -port 13230 -store example-store

kvshell-> get -all
0 Record returned.

kvshell-> put -key /FIRST_KEY -value "HELLO WORLD"
Put OK, inserted.

kvshell-> get -all
/FIRST_KEY
HELLO WORLD

キー/値ペアが各RNサービスによって格納されたことを確認するには、簡略的であまりプログラム的ではありませんが、それぞれのデータ・ファイルで文字列"HELLO WORLD"をgrepで検索する方法が簡単です。これは、ほとんどのLinuxシステムのバイナリ・ファイルに対して実行できます。このようにgrepコマンドを使用するのは、ほんの少量のデータで構成されている例では実践的です。

> grep "HELLO WORLD" /tmp/sn1/disk1/ondb/data/rg1-rn1/env/00000000.jdb
Binary file /tmp/sn1/disk1/ondb/data/rg1-rn1/env/00000000.jdb matches
> grep "HELLO WORLD" /tmp/sn2/disk1/ondb/data/rg1-rn2/env/00000000.jdb
Binary file /tmp/sn2/disk1/ondb/data/rg1-rn2/env/00000000.jdb matches
> grep "HELLO WORLD" /tmp/sn3/disk1/ondb/data/rg1-rn3/env/00000000.jdb
Binary file /tmp/sn3/disk1/ondb/data/rg1-rn3/env/00000000.jdb matches

前述の出力によると、ストアに書き込まれたキー/値ペアはシャードrg1に属する各RNサービス、つまりidが1に等しいレプリケーション・グループのメンバーである各RNサービス(rg1-rn1、rg1-rn2およびrg1-rn3)によって格納されました。特定のキーがどのシャードに関連付けられるかは、キーの値(特にキーの値のハッシュ)とストアによって保持されるシャードの数(この場合は1)によって異なります。また、この例には00000000.jdbという名前のログ・ファイルが示されていますが、これらのファイルは、対応するRNサービスにより書き込まれたデータを含むこのような(多数存在する可能性がある)ログ・ファイルの最初の一部にすぎません。時間の経過に伴って現在のログ・ファイルがその最大容量に達すると、書込み対象のすべての新しいデータを受信するために新規ファイルが作成されます。その新規ファイルには、前のファイルの接頭辞を増分することで前のファイルから導出された名前が付けられます。たとえば、00000997.jdb、00000998.jdb、00000999.jdb、00001000.jdb、00001001.jdbなどの名前がファイルに付与されます。データがストアに書き込まれたところで、障害が発生したストレージ・ノードをシミュレートし、最初のSN交換手順の例を実行できます。

例1: 障害が発生したSNを同一のSNと交換する

障害が発生したストレージ・ノードをシミュレートするには、上で起動したストレージ・ノードのいずれかを選択し、その関連付けられたプロセスをプログラムで停止し、そのプロセスに関連付けられたすべてのファイルおよびディレクトリを削除します。たとえば、sn2が障害の発生したストレージ・ノードであるとします。ただし、sn2ストレージ・ノードを停止する前に、まず(オプションで)デプロイ済のストアの一部として実行されているプロセスを次のように特定できます。

> jps -m
408 kvstore.jar start -root /opt/ondb/var/kvroot -config config1.xml
833 ManagedService -root /opt/ondb/var/kvroot -class Admin -service
BootstrapAdmin.13230 -config config1.xml
1300 ManagedService -root /opt/ondb/var/kvroot/example-store/sn1 -store
example-store -class RepNode -service rg1-rn1
....
563 kvstore.jar start -root /opt/ondb/var/kvroot -config config2.xml
1121 ManagedService -root /opt/ondb/var/kvroot/example-store/sn2
-store example-store -class Admin -service admin2
1362 ManagedService -root /opt/ondb/var/kvroot/example-store/sn2 
-store example-store -class RepNode -service rg1-rn2
....
718 kvstore.jar start -root /opt/ondb/var/kvroot -config config3.xml
1232 ManagedService -root /opt/ondb/var/kvroot/example-store/sn3 -store
example-store -class Admin -service admin3
1431 ManagedService -root /opt/ondb/var/kvroot/example-store/sn3 -store
example-store -class RepNode -service rg1-rn3
....

前述の出力は読みやすいように手動で順序を変更しました。実際には、リストの各プロセスはランダムな順序で出力される場合があります。ただし、例のデプロイメントの各SNは次の3つのプロセスに対応しています。

  • SNAプロセスは、文字列kvstore.jar startで特徴付けられ、対応する構成ファイルで識別されます。たとえば、sn1config1.xmlsn2config2.xmlsn3config3.xmlとなります。

  • 管理サービスは、文字列-class Adminと、-service BootstrapAdmin.<port>という形式の文字列または-service admin<id>という形式の文字列で特徴付けられます(次の説明を参照)。

  • RNサービスは、文字列-class RepNodeと、-service rg1-rn<id>という形式の文字列(<id>は1や2など)で特徴付けられ、そのRNサービスのホストとなっているSNにマップされます。ある特定のSNでそのSNの容量がN>1である場合、そのSNに対してリストには異なるRepNodeサービスを参照するN個のプロセスがあります。

注意

文字列-service BootstrapAdmin.<port>を参照する前述のプロセス・リストの行に関して、参考のため少し説明しておきます。SNAが起動し、-admin引数が構成に指定されていると、SNAは最初にブートストラップ管理と呼ばれるものを起動します。この例では3つすべてのストレージ・ノードの構成に-admin引数を指定したため、例の各SNAは対応するブートストラップ管理を起動します。前述のプロセス・リストにはブートストラップが1つのみ含まれているため、ここでは管理プロセスについて説明します。

Oracle NoSQL Databaseでは1つ以上の管理サービスのデプロイが必要になることを思い出してください。このような管理を2つ以上デプロイした場合は、デプロイされた管理はまずKVStore内の特別なロールを引き受けます。この例では、対応するSNAによって起動された3つのブートストラップ管理のいずれも、最初のデプロイ済管理サービスになることができます。ストアを構成し、データセンターをデプロイした後、デプロイヤは起動したストレージ・ノードのいずれかを選択し、plan deploy-snコマンドを使用してそのストレージ・ノードをストア内の目的のデータセンターにデプロイする必要があります。その最初のストレージ・ノードをデプロイした後、次にplan deploy-adminコマンドを使用してそのストレージ・ノードに対応する管理サービスをデプロイする必要があります。

その最初の管理サービスをデプロイするまで、他のストレージ・ノードまたは管理はデプロイできません。最初のSN (この場合はsn1)を実行しているマシンにその最初の管理サービスをデプロイすると、そのマシンで実行中のブートストラップ管理は引き続き稼働し、ストア内の最初の管理サービスのロールを引き受けます。このような理由から、BootstrapAdmin.<port>プロセスは引き続きプロセス・リストに記載されます。一方次に説明するように、他のストレージ・ノードに関連付けられたプロセスは BootstrapAdmin.<port>ではなくadmin2およびadmin3で識別されます。他のストレージ・ノード(および管理)をデプロイできるのは、この最初の管理をデプロイした後のみです。

他のストレージ・ノードのデプロイ時に、このような各ストレージ・ノードに関連付けられたBootstrapAdminプロセスは停止し、RMIレジストリから削除されます。これは、これらの追加のストレージ・ノードではブートストラップ管理が必要ないためです。ブートストラップ管理の存在は、関連付けられたSNAが必要に応じて最初の管理のホストとなることができることを示します。ただし、最初のストレージ・ノードをデプロイし、その対応するブートストラップ管理が最初の管理のロールを引き受けると、他のストレージ・ノードはその最初の管理のホストとなることができなくなります。そのため、追加の各ストレージ・ノードのデプロイ時に、対応するBootstrapAdminプロセスが停止します。

最後に、ストアは1つの管理サービスのみでデプロイできますが、複数の管理サービスを稼働させて可用性を高めることをお薦めします。デプロイされる管理の数は、SNで障害が発生してもクォーラムが失われる可能性がほとんどない十分な数にしてください。このため、この例で示すように、追加の各ストレージ・ノードをデプロイした後(および対応するブートストラップ管理を停止した後)、新しい管理サービスをデプロイしてください。これは最初の管理サービスと調整しながら、保持される管理情報をレプリケートします。したがって、前述のプロセス・リストのsn1に関連付けられた管理サービスはBootstrapAdmin (最初の管理サービス)であると識別され、他の管理サービスは単にadmin2およびadmin3であると識別されます。

このため、障害が発生したストレージ・ノードをシミュレートするには、sn2を停止します。そのためには、コマンド・プロンプトで次のように入力します。

> java -jar /opt/ondb/kv/lib/kvstore.jar stop \
-root /opt/ondb/var/kvroot \
-config config2.xml

残りのデプロイ済のストアの一部として実行されているプロセスをオプションで調べるには、次のようにします。

> jps -m

408 kvstore.jar start -root /opt/ondb/var/kvroot
-config config1.xml
833 ManagedService -root /opt/ondb/var/kvroot
-class Admin -service BootstrapAdmin.13230 -config config1.xml
1300 ManagedService -root /opt/ondb/var/kvroot/
example-store/sn1 -store example-store -class RepNode -service rg1-rn1
....
718 kvstore.jar start -root /opt/ondb/var/
kvroot -config config3.xml
1232 ManagedService -root /opt/ondb/var/kvroot/example-store/
sn3 -store example-store -class Admin -service admin3
1431 ManagedService -root /opt/ondb/var/kvroot/example-store/
sn3 -store example-store -class RepNode -service rg1-rn3
....

以前にsn2に関連付けられたプロセスは実行されなくなります。次に、sn2プロセスは停止しているため、関連付けられたファイルを次のように削除できます。

> rm -rf /tmp/sn2/disk1/ondb/data/rg1-rn2
> rm -rf /opt/ondb/var/kvroot/example-store/sn2

> rm -f /opt/ondb/var/kvroot/config2.xml
> rm -f /opt/ondb/var/kvroot/config2.xml.log
> rm -f /opt/ondb/var/kvroot/snaboot_0.log.1*

> rm -r /opt/ondb/var/kvroot/example-store/log/admin2*
> rm -r /opt/ondb/var/kvroot/example-store/log/rg1-rn2*
> rm -r /opt/ondb/var/kvroot/example-store/log/sn2*
> rm -r /opt/ondb/var/kvroot/example-store/log/config.rg1-rn2
> rm -r /opt/ondb/var/kvroot/example-store/log/example-store_0.*.1*

接尾辞部分に1が含まれている前述のファイル(たとえば、snaboot_0.log.1、example-store_0.log.1、example-store_0.perf.1、example-store_0.stat.1など)がsn2ストレージ・ノードに関連付けられています。

次に、前述のコマンドを実行して、sn2がデプロイされたマシンの致命的な障害をシミュレートします。sn2に関連付けられた構成およびデータは、この時点で完全に使用できなくなり、新しい(およびこの例では同一の) sn2ストレージ・ノードのデプロイによってのみリカバリ可能です。これを確認するには、前に説明したように管理CLIからshow topologyコマンドを実行します。

kv-> show topology

次のような出力が生成されます。

store=example-store numPartitions=300 sequence=308
dc: id=1 name=dc1 repFactor=3

sn=[sn1] dc:[id=1 name=dc1] <host-ip> capacity=1 RUNNING
[rg1-rn1] RUNNING

sn=[sn2] dc:[id=1 name=dc1] <host-ip> capacity=1 UNREACHABLE
[rg1-rn2] UNREACHABLE

sn=[sn3] dc:[id=1 name=dc1] <host-ip> capacity=1 RUNNING
[rg1-rn3] RUNNING
........

文字列<host-ip>のかわりに実際のIPアドレスまたはホスト名が表示されます。SN2がこの時点でUNREACHABLEであることを確認してください。

この時点で、SN交換手順の最初の2つの手順はすでに実行されています。つまり、sn2プロセスが停止し、その関連するファイルが削除されたため、ストアの他のノードから見ると、対応するマシンはアクセス不可能で、効果的に停止したことになります(手順1)。また、このシミュレーションでは単一のマシンを使用しているため、sn1 (およびsn3)ホストにすでにログインしています(手順2)。このため、この時点で手順の手順3を実行できます。つまり、ストアの残りの問題なく稼働しているノードのいずれかからsn2構成を取得するには、それらの残りのいずれかのノード用のポートを使用して次のコマンドを実行します(文字列<host-ip>を実際のIPアドレスまたはホスト名に置き換えることを忘れないでください)。

> java -jar /opt/ondb/kv/lib/kvstore.jar generateconfig
-host <host-ip> -port 13230 \ 
-sn sn2 -target /tmp/sn2-config

前述のコマンドによって想定どおりのzipファイルが生成されたことを確認します。

> ls -al /tmp/sn2-config.zip \
-rw-rw-r-- 1 <group> <owner>
2651 2013-07-08 12:53 /tmp/sn2-config.zip

/tmp/sn2-config.zipの内容は次のようになります。

> unzip -t /tmp/sn2-config.zip

Archive: /tmp/sn2-config.zip
testing: kvroot/config.xml  OK
testing: kvroot/example-store/sn2/config.xml  OK
testing: kvroot/example-store/security.policy  OK
testing: kvroot/security.policy  OK
No errors detected in compressed data of /tmp/sn2-config.zip

次に、この例は単一のマシンで実行しているため、SN交換手順の手順4、5、6、7はすでに実行されています。このため、次に実行する手順は生成したZIPファイルの内容をインストールすることです。

> unzip /tmp/sn2-config.zip -d /opt/ondb/var

これは、kvroot/security.policyおよびkvroot/example-store/security.policyをそのファイルの同一バージョンで上書きします。

ストアを最初にデプロイしたとき、最上位の各構成ファイルの名前は同じではありませんでした。つまり、sn1はconfig1.xml、最初にデプロイされたsn2はconfig2.xml、sn3はconfig3.xmlです。これが必要になるのは、便宜上同じKVROOTを使用して3つすべてのSNをデプロイした結果、sn1、sn2、sn3の間で競合が発生してそれらのファイルに同じ名前が使用されたためです。これを念頭に、上記で実行したgenerateconfigコマンドは新しいsn2の最上位の構成ファイルをconfig2.xmlではなくデフォルト名(config.xml)で生成することを確認してください。config2.xmlconfig.xmlのどちらの名前もストアの他のノードの構成ファイル名を基準にして一意であるため、手順で次に実行するコマンドにいずれの名前も使用できます(次を参照)。ただし、sn2を最初にデプロイした方法との整合性を確保するため、交換先をデプロイするときにも元のファイル名を使用します。このため、次の手順に進む前に、kvroot/config.xmlファイルの名前を次のようにkvroot/config2.xmlに変更します。

> mv /opt/ondb/var/kvroot/config.xml /opt/ondb/var/kvroot/config2.xml

ここで、最初のSN交換手順の最後の手順を実行できます。つまり、古いsn2構成を使用して、新規で同一のsn2を起動します。

> nohup java -jar /opt/ondb/kv/lib/kvstore.jar start \
-root /opt/ondb/var/kvroot \
-config config2.xml &

確認

sn2が正常に交換されたことを確認するには、まず管理CLIから次のようにshow topologyコマンドを実行します。

kv-> show topology

次のような出力が生成されます。

store=example-store numPartitions=300 sequence=308
dc: id=1 name=dc1 repFactor=3

sn=[sn1] dc:[id=1 name=dc1] <host-ip> capacity=1 RUNNING
[rg1-rn1] RUNNING

sn=[sn2] dc:[id=1 name=dc1] <host-ip> capacity=1 RUNNING
[rg1-rn2] RUNNING

sn=[sn3] dc:[id=1 name=dc1] <host-ip> capacity=1 RUNNING
[rg1-rn3] RUNNING
........

文字列<host-ip>のかわりに実際のIPアドレスまたはホスト名が表示されます。SN2がこの時点で再びRUNNINGであることを確認してください。

show topologyコマンドを実行するだけでなく、以前に削除されたsn2ディレクトリ構造が再作成され、再移入されたことを確認できます。つまり、次のようなディレクトリおよびファイルが再度存在します。

/opt/ondb/var/kvroot
....
config2.xml*
....
/example-store
/log
....
admin2*
rg1-rn2*
sn2*
config.rg1-rn2
....
/sn2
config.xml
/admin2
/env

/tmp/sn2/disk1/ondb/data
/rg1-rn2
/env
00000000.jdb

最後に、元のsn2によって以前に格納されたデータがリカバリされたことを確認します。

> grep "HELLO WORLD" /tmp/sn2/disk1/ondb/data/rg1-rn2/env/00000000.jdb
Binary file /tmp/sn2/disk1/ondb/data/rg1-rn2/env/00000000.jdb matches

例2: 新しいSNで既存のSNの役割を引き継ぐ

この例では、前に説明した2つ目の交換手順を使用して、既存の問題なく稼働しているストレージ・ノード(この場合はsn2)を、古いストレージ・ノードの役割を引き継ぐ新しいストレージ・ノードに交換/アップグレードします。前に示したように、この例の前提および設定は最初の例の前提および設定と同じです。このため、以前に指定したようにこの例を設定した後、sn1ストレージ・ノードに関連付けられた管理サービスに接続されている管理CLIを起動します。つまり、文字列<host-ip>を実際のIPアドレスまたはホスト名に置き換えたうえで、次のコマンドを実行します。

> java -jar /opt/ondb/kv/lib/kvstore.jar runadmin
-host <host-ip> -port 13230

次に、起動した管理CLIから、show poolsおよびshow topologyコマンドを次のように実行します。

kv-> show pools
kv-> show topology

それぞれ次のような出力が生成されます。

AllStorageNodes: sn1 sn2 sn3
snpool: sn1 sn2 sn3

および

store=example-store numPartitions=300 sequence=308
dc: id=1 name=dc1 repFactor=3

sn=[sn1] dc: [id=1 name=dc1] host-sn1 capacity=1 RUNNING
[rg1-rn1] RUNNING

sn=[sn2] dc:[id=1 name=dc1] host-sn2 capacity=1 RUNNING
[rg1-rn2] RUNNING

sn=[sn3] dc:[id=1 name=dc1] host-sn3 capacity=1 RUNNING
[rg1-rn3] RUNNING
........

注意

この時点で、加わるプールはsnpoolという名前で、デプロイ先のデータセンターのidは1です。

次に、新旧のSNが別の物理マシンで動作する本番環境では、通常手順の最後の手順まで古いSNを稼働させたままにする(リクエストに対応する)ことができることを思い出してください。この例では、新旧のSNは単一のマシンで動作し、見た目上別のマシンおよびファイル・システムであるかのようにシミュレートしています。このため、この例で次に実行する手順は、次のコマンドを実行してsn2ストレージ・ノードをプログラムで停止することです。

> java -jar /opt/ondb/kv/lib/kvstore.jar stop \
-root /opt/ondb/var/kvroot \
-config config2.xml

sn2ストレージ・ノードを停止した後、(オプションで) show topologyコマンドを実行すると、sn2ストレージ・ノードがRUNNINGではなくUNREACHABLEになっているが、ノードがトポロジから明示的に削除されるまで引き続きトポロジで参照されることを確認できます(次を参照)。たとえば、管理CLIから次のコマンドを実行します。

kv-> show topology

想定どおりに次のような出力が生成されます。

store=example-store numPartitions=300 sequence=308
dc: id=1 name=dc1 repFactor=3

sn=[sn1] dc:[id=1 name=dc1] host-sn1 capacity=1 RUNNING
[rg1-rn1] RUNNING

sn=[sn2] dc:[id=1 name=dc1] host-sn2 capacity=1 UNREACHABLE
[rg1-rn2] UNREACHABLE

sn=[sn3] dc:[id=1 name=dc1] host-sn3 capacity=1 RUNNING
[rg1-rn3] RUNNING
........

この時点で、交換先である新しいsn4ストレージ・ノードの準備を始めることができます。つまり、この例では単一のマシンが新旧両方のSNのホストとなっているため、手順の手順4、5、6はすでに完了しています。

次の手順(7)に関して、この手順を使用する際、手順7では交換先のSNのデータ・ディレクトリのパスが交換対象のSNで使用されているパスと同じである必要があることを思い出してください。ただしこの例では、各SNによって格納されたデータの場所に同じディスクおよびファイル・システムを使用しています。このため、手順7で新しいsn4ストレージ・ノード用に作成するストレージ・ディレクトリはすでに存在し、古いsn2ストレージ・ノードによってすでに移入されています。したがって、この例のシミュレーション環境で手順7を実行し、確認(次を参照)をサポートするには、上でsn2を停止した後、そのノードで使用されているストレージ・ディレクトリの名前を変更して、手順7でsn4用にプロビジョニングする必要があるストレージ・ディレクトリの領域を確保します。次のようになります。

> mv /tmp/sn2 /tmp/sn2_old

この名前変更手順はこの例でのみ実行し、本番環境で実行することはないことを忘れないでください。

次に、sn4が使用するストレージ・ディレクトリをプロビジョニングします。指定するパスは、sn2で使用されているストレージ・ディレクトリの元のパスと同じである必要があります。次のようになります。

> mkdir -p /tmp/sn2/disk1/ondb/data

交換先のSNの準備を整えるときに次に実行する手順は、makebootconfigコマンド(文字列<host-ip>を実際のIPアドレスまたはホスト名に置き換えることを忘れないでください)を実行して、新しいストレージ・ノードのブート構成を生成することです。

java -jar /opt/ondb/kv/lib/kvstore.jar makebootconfig \
-root /opt/ondb/var/kvroot \
-host <host-ip> \
-config config4.xml \
-port 13260 \
-harange 13262,13265 \
-admin 13261 \
-memory_mb 100 \
-capacity 1 \
-storagedir /tmp/sn2/disk1/ondb/data

新しいストレージ・ノードの構成ファイル/opt/ondb/var/kvroot/config4.xmlが生成されます。

前述の構成の作成後、その新しい構成を使用してKVStoreストレージ・ノード・エージェント(SNA)の新しいインスタンスをその管理対象サービスとともに起動します。つまり、次のようにします。

> nohup java -jar /opt/ondb/kv/lib/kvstore.jar start \
-root /opt/ondb/var/kvroot \
-config config4.xml &

前述のコマンドを実行した後、管理CLIを使用して次のコマンド(文字列<host-ip>を実際のIPアドレスまたはホスト名に置き換えます)を実行することで、新しいストレージ・ノードをデプロイします。

kv-> plan deploy-sn -dcname dc1
-host <host-ip> -port 13260 -wait

前に説明したように、sn3は最近デプロイされたストレージ・ノードに(ストアによって)割り当てられたidであるため、次にデプロイされるストレージ・ノード(つまり前述のコマンドによってデプロイされるストレージ・ノード)にはその割当てidとしてsn4が付与されます。前述のsn4ストレージ・ノードをデプロイした後、(オプションで)管理CLIからshow poolsコマンドを実行すると、新しいストレージ・ノードがAllStorageNodesという名前のデフォルトのプールに加わったことを確認できます。たとえば、次のようにします。

kv-> show pools

次のような出力が生成されます。

AllStorageNodes: sn1 sn2 sn3 sn4
snpool: sn1 sn2 sn3

デプロイ時点で、sn4はAllStorageNodesという名前のプールには加わりましたが、snpoolという名前のプールにはまだ加わっていません。

次に、sn4ストレージ・ノードを正常にデプロイした後、CLIを使用して次のようにsnpoolという名前のプールに加えます。

kv-> pool join -name snpool -sn sn4

新しいストレージ・ノードをデプロイし、snpoolという名前のプールに加えた後、(オプションで)管理CLIを使用してshow topologyコマンド、show poolsコマンドを順に実行すると、新しいストレージ・ノードがストアにデプロイされ、snpoolという名前のプールに加わったことを確認できます。たとえば、次のようにします。

kv-> show topology 
kv-> show pools

初期の前提であると、次のような出力が生成されます。

store=example-store numPartitions=300 sequence=308
dc: id=1 name=dc1 repFactor=3

sn=[sn1] dc:[id=1 name=dc1] host-sn1 capacity=1 RUNNING
[rg1-rn1] RUNNING

sn=[sn2] dc:[id=1 name=dc1] host-sn2 capacity=1 UNREACHABLE
[rg1-rn2] UNREACHABLE

sn=[sn3] dc:[id=1 name=dc1] host-sn3 capacity=1 RUNNING
[rg1-rn3] RUNNING

sn=[sn4] dc:[id=1 name=dc1] host-sn4 capacity=1 RUNNING
........

および

AllStorageNodes: sn1 sn2 sn3 sn4
snpool: sn1 sn2 sn3 sn4

前述の出力は、sn4ストレージ・ノードが正常にデプロイされ(RUNNING)、現時点でsnpoolという名前のプールのメンバーであることを示しています。ただし、前述の出力にはまだsn4に対応するRNサービスが含まれていません。このようなサービスは、sn2がsn4に移行されるまでストアのトポロジに表示されません(次を参照)。

この時点で、sn4ストレージ・ノードをデプロイしてsnpoolという名前のプールに加え、古いsn2ストレージ・ノードを停止した後、sn4はsn2の役割を引き継ぐ準備が整ったことになります。このためには、管理CLIから次のコマンド(文字列<host-ip>を実際のIPアドレスまたはホスト名に置き換えることを忘れないでください)を実行して、sn2サービスおよびデータをsn4に移行します。

kv-> plan migrate-sn -from sn2 -to sn4 -admin-port 13261 -wait

古いsn2ストレージ・ノードが管理サービスを実行していたため、前述のplan migrateコマンドにadmin-port引数を指定する必要があります。その引数に使用する値は、makebootconfigコマンドを実行してsn4の構成を生成する際に以前に管理引数に使用していた値である必要があります。

sn2をsn4に移行した後、(オプションで)再度show topologyコマンドを実行すると、rg1-rn2サービスがsn2からsn4に移動してこの時点でRUNNINGであることを確認できます。つまり、次のようにします。

kv-> show topology 

store=example-store numPartitions=300 sequence=308
dc: id=1 name=dc1 repFactor=3

sn=[sn1] dc:[id=1 name=dc1] host-sn1 capacity=1 RUNNING
[rg1-rn1] RUNNING

sn=[sn2] dc:[id=1 name=dc1] host-sn2 capacity=1 UNREACHABLE

sn=[sn3] dc:[id=1 name=dc1] host-sn3 capacity=1 RUNNING
[rg1-rn3] RUNNING

sn=[sn4] dc:[id=1 name=dc1] host-sn4 capacity=1 RUNNING
[rg1-rn2] RUNNING
........

最後に、移行プロセスが完了した後、古いsn2ストレージ・ノードをストアのトポロジから削除する必要があります。そのためには、管理CLIから次のようにplan remove-sn コマンドを実行します。

kv-> plan remove-sn -sn sn2 -wait

確認

sn2がsn4に正常に交換/アップグレードされたことを確認するには、まず前に説明したように管理CLIから次のようにshow topologyコマンドを実行します。

kv-> show topology

次のような出力が生成されます。

store=example-store numPartitions=300 sequence=308
dc: id=1 name=dc1 repFactor=3

sn=[sn1] dc:[id=1 name=dc1] <host-ip> capacity=1 RUNNING
[rg1-rn1] RUNNING

sn=[sn3] dc:[id=1 name=dc1] <host-ip> capacity=1 RUNNING
[rg1-rn3] RUNNING

sn=[sn4] dc:[id=1 name=dc1] <host-ip> capacity=1 RUNNING
[rg1-rn2] RUNNING
........

文字列<host-ip>のかわりに実際のIPアドレスまたはホスト名が表示されます。また、sn2ではなくsn4のみが出力に表示されることを確認してください。

show topologyコマンドを実行するだけでなく、想定どおりのsn4ディレクトリ構造が作成されて移入されていること、つまり次のようなディレクトリおよびファイルが存在することを確認できます。

/opt/ondb/var/kvroot
....
config4.xml
....
/example-store
/log
....
sn4*
....
/sn4
config.xml
/admin2
/env

/tmp/sn2/disk1/ondb/data
/rg1-rn2
/env
00000000.jdb

また、sn2によって以前に格納されたデータがsn4に移行されたことを確認できます。つまり、次のようにします。

> grep "HELLO WORLD" /tmp/sn2/disk1/ondb/data/rg1-rn2/env/00000000.jdb
Binary file /tmp/sn2/disk1/ondb/data/rg1-rn2/env/00000000.jdb matches

ただし、sn2は停止してトポロジから削除されましたが、この例でsn2が作成して移入したデータ・ファイルは削除されませんでした。それらは、/tmp/sn2_oldディレクトリに移動されました。このため、古いsn2ストレージ・ディレクトリおよびデータ・ファイルに引き続きアクセスできます。次のようになります。

/tmp/sn2_old/disk1/ondb/data
/rg1-rn2
/env
00000000.jdb

また、元のキー/値ペアは引き続き古いsn2データ・ファイルに存在します。次のようにします。

> grep "HELLO WORLD" /tmp/sn2_old/disk1/ondb/data/rg1-rn2/env/00000000.jdb
Binary file /tmp/sn2_old/disk1/ondb/data/rg1-rn2/env/00000000.jdb matches

最後に実行できる確認手順は、新しいsn4ストレージ・ノードが実際に古いsn2ストレージ・ノードの役割を引き継ぐことを示すことを目的としています。この手順では、新しいキー/値ペアをストアに書き込み、sn2を交換する前はsn1、sn3、sn2で元々そうであったように新しいペアがsn1、sn3、sn4のデータ・ファイルに書き込まれていることを確認します。この手順を実行するために、最初のキー/値ペアを当初挿入したときに「設定」で説明したのと同じ方法でKVStoreクライアント・シェル・ユーティリティを使用できます。つまり、次を実行できます(<host-ip>文字列を実際のIPアドレスまたはホスト名に置き換えることを忘れないでください)。

> java -jar /opt/ondb/kv/lib/kvcli.jar \
-host <host-ip> -port 13230 -store example-store

kvshell-> get -all
/FIRST_KEY
HELLO WORLD

kvshell-> put -key /SECOND_KEY -value "HELLO WORLD 2"
Put OK, inserted.

kvshell-> get -all
/SECOND_KEY
HELLO WORLD 2
/FIRST_KEY
HELLO WORLD

次に、挿入の実行後、grepコマンドを使用して、新しいキー/値ペアがsn1、sn3、sn4によって書き込まれたことを確認します。古いsn2データ・ファイルには引き続き最初のキー/値ペアのみが含まれています。次のようになります。

> grep "HELLO WORLD 2" /tmp/sn1/dsk1/ondb/data/rg1-rn1/env/00000000.jdb
Binary file /tmp/sn1/disk1/ondb/data/rg1-rn1/env/00000000.jdb matches
> grep "HELLO WORLD 2" /tmp/sn2/dsk1/ondb/data/rg1-rn2/env/00000000.jdb
Binary file /tmp/sn2/disk1/ondb/data/rg1-rn2/env/00000000.jdb matches
> grep "HELLO WORLD 2" /tmp/sn3/dsk1/ondb/data/rg1-rn3/env/00000000.jdb
Binary file /tmp/sn3/disk1/ondb/data/rg1-rn3/env/00000000.jdb matches
> grep "HELLO WORLD 2" /tmp/sn2_old/dsk1/ondb/data/rg1-rn2/env/
00000000.jdb