SA.02.4 集中型及び分散型ストレージ (重要度: 5)
EXT4, XFS, Btrfs について
B-Tree, ジャーナリング
B-Treeは、ディスク上のデータの効率的な検索と管理を可能にするアルゴリズムです。B-Treeは、データを階層的な構造で保存し、検索を高速化します。EXT4、XFS、およびBtrfsは、すべてB-Treeを使用してファイルシステム内のデータを管理します。
ジャーナリングは、ファイルシステムの正当性と一貫性を保つための手法です。ジャーナリングは、ファイルシステムへの変更をログ(ジャーナル)に記録し、ファイルシステムの異常終了や障害時にジャーナルを使用して回復します。ジャーナリングにより、ファイルシステムの修復時間が短縮され、データの損失を最小限に抑えることができます。
EXT4は、B-Treeとジャーナリングの両方を使用しています。これにより、高速なデータアクセスとファイルシステムの信頼性が実現されます。
XFSも、B-Treeとジャーナリングを使用しています。XFSは、大容量のファイルシステムに向いており、一貫性を高速に維持するためのジャーナリング機能が特徴です。
Btrfsも、B-Treeとジャーナリングの両方をサポートしています。Btrfsは、スナップショットやデータの圧縮、RAIDなどの高度な機能も備えており、非常に柔軟なファイルシステムです。また、リストアやデータの整合性の回復も効率的に行うことができます。
重複排除, Copy on Write, スナップショット
重複排除は、ファイルシステムがデータの重複を検出して削除する機能です。例えば、同じ内容のファイルが複数回保存されている場合、重複排除によってディスクの使用容量を節約することができます。
Copy on Write (書き換え時にコピーを作成) は、ファイルシステムがデータを更新する際に、元のデータを書き換えるのではなく、新しいデータを書き込む動作です。この方式はデータの整合性を保つために使用されることが多く、データ更新時のエラーや障害が発生した場合にも元のデータが保持されます。
スナップショットは、ある時点でのファイルシステム全体の状態を保存する仕組みです。スナップショットを作成することで、その時点のデータやファイルの状態をバックアップとして保存したり、特定の時点に戻したりすることができます。これはデータ復旧やバージョン管理に非常に便利です。
EXT4 は、重複排除の機能はありませんが、Copy on Write とスナップショットのサポートがあります。
XFS は、重複排除機能はありませんが、Copy on Write のサポートはあります。ただし、元のデータを保持するためのスナップショット機能はありません。
Btrfs は、重複排除、Copy on Write、スナップショットのすべての機能を備えています。これにより、効率的なディスク使用、データの整合性、バックアップおよび復旧の方法が提供されます。
論理ボリュームの割り当て
事前割り当て(シックプロビジョニング)とは、ストレージ容量が事前に割り当てられる方式です。仮想マシンやストレージデバイスには、あらかじめ必要な容量が確保されるため、容量の増減や追加の手続きが必要ありません。利点としては、メモリやネットワーク帯域の確保によるパフォーマンス向上が挙げられます。ただし、容量の予約に伴う無駄な使用やコスト、容量の不足による問題が発生する可能性があります。
一方、動的割り当て(シンプロビジョニング)とは、初期時に必要な容量を指定し、必要に応じて容量を追加する方式です。ストレージ容量は必要の分だけ確保され、オーバーヘッドやコストを抑えることができます。また、増減や追加が柔軟に行えるため、容量不足のリスクを最小限に抑えることができます。しかし、容量の増加には時間や処理がかかるため、動作が遅くなる場合があります。
障害復旧手順については、事前割り当てでは通常のバックアップや復元手法が使用されます。一方、動的割り当てではストレージの追加やスケーリング手法が利用されることがあります。一時的な障害によるリソース不足も解消し、システムの可用性を高めることができます。
どちらの方式を選択すべきかは、利用目的や要件によります。長期的で安定的な容量を必要とする場合は、事前割り当てが適しています。一方、柔軟性を重視し、容量の変動や拡張が必要な場合は、動的割り当てが適しています。また、システムのパフォーマンスや障害復旧手順も考慮する必要があります。
SAN によるブロックストレージの構築
接続方式の選択と設定
接続方式として、FC(Fibre Channel)とiSCSI(Internet Small Computer Systems Interface)があります。
FCは、専用のファイバーチャネルを使用して高速かつ信頼性の高い接続を提供します。ファイバーチャネルスイッチを使用してスイッチファブリックを構成し、ブロックレベルのデータ転送を実現します。FCは通常、大規模なデータセンターやミッションクリティカルな環境で使用されます。接続するデバイスには、FCターゲット(ストレージデバイス)とFCイニシエータ(ホストベース)があります。
一方、iSCSIは、標準のEthernetネットワークを使用してデータ転送を行います。iSCSIターゲット(ストレージデバイス)は、TCP/IPプロトコルを介してホスト(iSCSIイニシエータ)と通信します。iSCSIは低コストで導入しやすく、既存のIPネットワークを活用することができます。ただし、Ethernetネットワークの遅延や混雑が発生するとパフォーマンスに影響が出る可能性があります。
FCとiSCSIの適切な選択は、使用環境や要件によります。大規模なデータセンターや高性能なストレージニーズを持つ組織では、FCが推奨されます。一方、小規模な環境や限られた予算のある組織では、iSCSIがよりコスト効果が高い選択肢となることがあります。
また、FCとiSCSIはどちらも共通のプロトコルであるSCSIを使用しており、ブロックレベルのストレージアクセスを提供します。つまり、オペレーティングシステムからはブロックデバイスとして認識されるため、同じように使用することができます。
ボリュームレベル排他制御
ボリュームレベルの排他制御は、複数のホストがSAN上の同じストレージボリュームにアクセスすることを制御するために使用されます。LUNマスキングとゾーニングは、ボリュームレベルの排他制御を実現するための主なメカニズムです。
LUNマスキングは、ストレージデバイス側で実施される制御手法です。ストレージデバイスは、各ホストシステムに対してアクセス可能なLUN(論理ユニット番号)を制限するための設定を行います。LUNマスキングでは、各ホストのユニークな識別子(たとえば、ホストのWWN(ワールドワイドネーム))を使用して、ホストがアクセスできるLUNを制御します。これにより、特定のホストだけが指定されたボリュームにアクセスできるように制限することが可能です。
ゾーニングは、SANスイッチ(ファブリックスイッチ)上で実施される制御手法です。ゾーニングでは、SAN上のデバイス(ホスト、ストレージデバイス)を独立したゾーンとしてグループ化します。各ゾーン内では、デバイス同士の通信が許可され、他のゾーン内のデバイスとの通信は制限されます。この制御により、特定のホストとストレージの組み合わせのみが許可され、他のホストやストレージとのアクセスは制限されます。
LUNマスキングとゾーニングは、異なるレベルで排他制御を行います。LUNマスキングはストレージデバイス自体に対して制御をかけ、ホストに最終的な制御権限を付与します。一方、ゾーニングはSANスイッチ上で制御を行い、特定のホストとストレージの接続を制約することでセキュリティを確保します。
cLVM によって多ノードから利用できる仮想化ストレージ
cLVM(Clustered Logical Volume Manager)は、Linux クラスタ上で動作するための仮想化ストレージ管理システムです。cLVM を使用することで、複数のノードが同時にストレージボリュームにアクセスできるようになります。
cLVM は、LVM(Logical Volume Manager)の機能を拡張して、クラスタ環境でのストレージの共有利用を実現します。通常の LVM では、ストレージボリュームは単一のホストによって利用されますが、cLVM を使用すると、複数のノードが同じストレージボリュームにアクセスできます。これにより、データの冗長性や高可用性を実現するためのクラスタシステムを構築することができます。
cLVM では、共有ストレージボリューム(例:SAN など)へのアクセスをノード間で同期するために、クォーラムメカニズムを使用します。クォーラムは、ノード間の一貫性を確保し、データの競合や矛盾を避けるための制御手段です。複数のノードが cLVM を使用してストレージボリュームにアクセスする場合、クォーラムが使用され、各操作の順序や優先度が管理されます。このように、cLVM はデータ整合性を保ちつつ、複数ノードからのアクセスを可能にします。
cLVM は、クラスタ環境でのストレージ管理を効果的に行うためのツールとして提供されます。これにより、複数のノードでの負荷分散、高可用性、データの冗長化など、クラスタシステムに求められる機能を実現します。クラスタ環境での仮想化ストレージの効率的な管理を可能にするため、cLVM の利用は非常に有益です。
物理ボリューム, ボリュームグループ, 論理ボリュームの管理
cLVMを使用して物理ボリューム(PV)、ボリュームグループ(VG)、論理ボリューム(LV)を管理する方法は、通常のLVMと同じように行われます。以下に一般的なコマンドと手順を示します。
- 物理ボリューム(PV)の作成:
pvcreate /dev/sdb # 物理ボリュームを作成
pvdisplay # 作成した物理ボリュームを表示
- ボリュームグループ(VG)の作成:
vgcreate myvg /dev/sdb # ボリュームグループを作成
vgdisplay # 作成したボリュームグループを表示
- 論理ボリューム(LV)の作成:
lvcreate -L 10G -n mylv myvg # 10GBサイズの論理ボリュームを作成
lvdisplay # 作成した論理ボリュームを表示
これらのコマンドは、任意の物理ボリューム、ボリュームグループ、および論理ボリュームを作成するための基本的な手順です。
しかし、cLVMではLVMと異なり、複数のノードから利用する場合に注意が必要です。クラスタ環境では、以下のようなクラスタ固有のコマンドや設定が必要となります。
- cLVMリソースの有効化:
lvchange -a y /dev/myvg/mylv # 論理ボリュームを有効化
- クォーラム制御の設定:
lvm.conf # クォーラム制御を有効化し、設定を適切に行う
- ノードの追加または削除時の手順:
vgextend myvg /dev/sdc # 新しい物理ボリュームをボリュームグループに追加
lvchange --refresh /dev/myvg/mylv # 論理ボリュームをリフレッシュ
これらのコマンドと手順は、cLVMで多ノードから利用する仮想化ストレージを管理するための基本的なものです。ただし、クラスタ構成や環境に応じて設定が異なる場合があるため、公式のドキュメントやクラスタソフトウェアのガイドを参照することをおすすめします。
ボリュームレベル排他制御
cLVMでは、ボリュームレベルの排他制御を実現するために、lvchangeやvgchangeなどのコマンドを使用します。以下に具体的なコマンドとその説明を示します。
- ボリュームグループ(VG)のロック解除:
vgchange -an <VG_NAME> # ボリュームグループのロックを解除
このコマンドは、指定されたボリュームグループをロック解除し、他のノードからのアクセスを許可します。
- 論理ボリューム(LV)のロック解除:
lvchange -ay <LV_PATH> # 論理ボリュームのロックを解除
このコマンドは、指定された論理ボリュームをロック解除し、他のノードからのアクセスを許可します。
- ボリュームグループ(VG)のロック設定:
vgchange -ay <VG_NAME> # ボリュームグループをロックする
このコマンドは、指定されたボリュームグループをロックし、他のノードからのアクセスをブロックします。
- 論理ボリューム(LV)のロック設定:
lvchange -an <LV_PATH> # 論理ボリュームをロックする
このコマンドは、指定された論理ボリュームをロックし、他のノードからのアクセスをブロックします。
なお、`-a` オプションは、「all」を表し、指定されたボリュームグループ(VG)または論理ボリューム(LV)がすべて変更の対象になることを指定します。このオプションを使用すると、特定のボリュームグループや論理ボリュームに対してではなく、すべてのボリュームグループや論理ボリュームに対して操作を行うことができます。
`-n` オプションは、「no」を表し、指定されたボリュームグループ(VG)または論理ボリューム(LV)が変更の対象外であることを指定します。このオプションを使用すると、特定のボリュームグループや論理ボリュームに対して操作を行わず、変更せずに状態を保持することができます。
`-y` オプションは、「yes」を表し、コマンドの実行時に対話的なプロンプトが表示されずに、自動的に実行を続行することを指定します。これにより、コマンド実行時の確認がなくなり、プロンプト入力を省略することで、コマンドの一連の操作がスムーズに行えます。ただし、このオプションを使用する場合は、実行する操作に慎重に慣れておく必要があります。
これらのコマンドを使用することで、ボリュームレベルでのロック制御を行うことができます。ただし、これらのコマンドを実行する前に、クラスタノード間で適切なクォーラム制御やロックの同期を行う必要があります。
スナップショットの領域確保, 作成, 管理
上で作ったLVをマウントすれば、元のボリュームに変更を加えても元のデータがスナップショット領域に保持されるため、元のデータを復旧できます。スナップショットの使用が終了した場合は、`lvremove`コマンドを使用してスナップショットを削除します。例えば、`lvremove /dev/myvg/mysnapshot`というようにコマンドを実行します。
分散ストレージ・分散データベース
分散ストレージと分散データベースは、複数のノードでデータを分散して格納するシステムです。以下に分散ストレージと分散データベースの理論的な動作原理を説明します。
分散ストレージ:
- ノード間でデータを分散することにより、単一のストレージノードがシステム全体の負荷を処理することなくスケーラビリティを実現します。
- データの分散は、レプリケーション(複数のノードに同じコピーを保存)またはシャーディング(データを複数のノードに分割して保存)の形式で行われます。
- レプリケーションは、耐障害性を確保することができますが、データの整合性や一貫性の維持にはコストがかかります。
- シャーディングは、データを横断的に分割してノードに分散させることで、パフォーマンスの向上を図ることができますが、データが複数のノードに分散して格納されるため、データの整合性や一貫性を維持する必要があります。
分散データベース:
- 分散データベースは、複数のノード間でデータベースを分散して格納することにより、複数のノードでの同時処理とデータ可用性の向上を実現します。
- 分散データベースでは、データのレプリケーションやシャーディング、または両方を使用してデータを分散します。
- レプリケーションにより、データの冗長性や耐障害性を高めることができます。他のノードに障害が発生しても、データへのアクセスが継続できます。
- シャーディングは、データの処理負荷を分散するため、高いパフォーマンスを実現します。
- 分散データベースでは、データの配置やアクセス制御、データの整合性などの問題に対して、適切なアルゴリズムやプロトコルを使用して解決します。
分散ストレージと分散データベースは、それぞれ異なるユースケースに応じて使用されますが、共通して複数のノードでデータを分散させることで、スケーラビリティ、耐障害性、パフォーマンスを向上させることができます。
整合性 (強い整合性, 結果整合性), 可用性, 分断耐性, これらのトレードオフ
分散ストレージおよび分散データベースでは、整合性、可用性、および分断耐性という3つの重要な要素のトレードオフが存在します。
強い整合性(Strong Consistency):
- 強い整合性では、データの読み取りアクションが常に最新の書き込みを反映します。つまり、データを更新する前に、読み取りアクションは常に同じ値を返します。
- これにより、データの整合性が高くなりますが、分散環境での可用性には制約があります。
結果整合性(Eventual Consistency):
- 結果整合性では、一時的にデータが整合していない状態が発生する可能性がありますが、最終的にはデータが整合します。
- 分散環境では、ノード間のレプリケーションや処理の遅延などの理由で一時的にデータの不整合が生じることがあります。しかし、データは後で自動的に整合するため、可用性が高くなります。
可用性(Availability):
- 可用性は、ユーザーがデータにアクセスできる状態を指します。システムが常に応答し、アクセスできることが求められます。
- 強い整合性を持つシステムは、一時的な障害やネットワークの分断などの状況に対しても、データの可用性が低下する可能性があります。
分断耐性(Partition Tolerance):
- 分断耐性は、システムがネットワークの分断やノードの障害などに対して強いかどうかを示します。
- 分散環境では、ネットワークの遅延や通信の故障などの問題が頻発するため、システムが分断耐性を持つことが重要です。
これらの要素はトレードオフの関係にあります。例えば、強い整合性を持つシステムは可用性や分断耐性に制約がありますが、結果整合性を持つシステムは可用性が高くなります。分散ストレージや分散データベースを設計する際には、このトレードオフを考慮に入れる必要があります。
読み書きアルゴリズム
分散ストレージや分散データベースでは、複数のノードにデータが格納されるため、読み書きアルゴリズムは重要な要素です。主なアルゴリズムは次のようになります。
- Read One Write All (ROWA):
- このアルゴリズムでは、書き込み操作ではすべてのノードに書き込みを行います。一方、読み取り操作では、いずれかのノードから読み取ることができれば十分です。
- 書き込みの一貫性を確保するため、すべてのノードに書き込みが成功するまで待機します。一方、読み取り操作では、最も近くのノードや負荷の軽いノードなど、どのノードから読み取るかを選択することができます。
- このアルゴリズムはデータの整合性を高められますが、可用性やパフォーマンスには影響を及ぼす場合があります。
- Primary Copy:
- Primary Copyアルゴリズムでは、データの書き込み操作は特定のプライマリノードにのみ行われます。他のセカンダリノードは、データのリードオペレーションにのみ関与します。
- データはプライマリノードに書き込まれると、プライマリノードは変更をセカンダリノードにレプリケーションします。
- このアルゴリズムは書き込みの一貫性を確保しますが、プライマリノードの障害が可用性に影響を与える場合があります。
- Read Repair:
- Read Repairアルゴリズムでは、読み取り操作時にデータの修復が行われます。
- データを読み取る際、複数のノードからデータを収集し、整合性の確認を行います。
- もしデータの整合性に問題があった場合、これを修正するために、収集したデータの中で最新のものを他のノードに修復操作を行います。
- このアルゴリズムは強い整合性やデータの信頼性を確保するために使用されます。
分散ストレージとしてのCeph
Cephはオープンソースの分散ストレージプラットフォームであり、可用性、耐障害性、スケーラビリティに優れた特徴を持っています。
- RADOS(Reliable Autonomic Distributed Object Store):
- Cephの分散オブジェクトストレージシステムです。
- RADOSクラスタは複数のノードで構成され、各ノードは自身のディスクにデータを保存します。
- 分散オブジェクトストレージのため、データはオブジェクトとして管理され、オブジェクトの名前やメタデータと共にストアされます。
- データはストライピングやレプリケーションによって冗長化され、高い可用性と耐障害性を実現します。
- RBD(RADOS Block Device):
- Cephのブロックストレージサービスです。
- RBDは、仮想ブロックデバイスとして動作し、アプリケーションがブロックレベルのデータを格納およびアクセスできるようにします。
- データはRADOSに保存され、ストライピングとレプリケーションによって冗長化されます。
- RBDは、仮想マシンのディスクイメージやデータベースのストレージなど、多くのアプリケーションに使用されます。
- Ceph FS:
- Cephの分散ファイルシステムです。
- Ceph FSはPOSIX互換性を持ち、複数のクライアントが同時にファイルシステムにアクセスできます。
- ファイルやディレクトリはオブジェクトとしてRADOSに格納され、ストライピングやデータの冗長化が行われます。
- Ceph FSはデータの一貫性と耐障害性を提供し、データセンター内のさまざまなアプリケーションに使用されます。
これらのコンポーネントを組み合わせることで、Cephは柔軟でスケーラブルな分散ストレージソリューションを提供します。
ceph.conf による構成設定
ceph.confの設定ファイルは以下のような記述方式になります。
[global]
debug_ms = 0
[osd]
debug_ms = 1
[osd.1]
debug_ms = 10
[osd.2]
debug_ms = 10
[ ]で囲われているのはセクション名であり、セクションに対応した設定パラメータを記述します。
セクション | 説明 | 具体例 |
global | 全体的な設定パラメータ | クラスタ名、モニターのアドレス、データの保存場所、ログの保存場所 |
mon | モニター (monitor) サーバーに関する設定 | モニターの IP アドレスやポート番号、共有ファイルシステムのパス |
osd | オブジェクトストレージデバイス (OSD) に関する設定 | OSD のデータ保存場所、ジャーナルの保存場所、バックエンドの種類、ストレージプールの定義 |
mds | メタデータサーバー (MDS) に関する設定 | メタデータプールの定義、ワークディレクトリのパス、クラスタ名の指定 |
参考:https://docs.ceph.com/en/reef/rados/configuration/ceph-conf/
ノード追加
Ceph クラスタにノードを追加するためには、次の手順に従います。
- Ceph モニターが実行されているノードに SSH 経由で接続します。
- sudo 管理者権限でターミナルを開き、次のコマンドを使用して Ceph ユーザーに切り替えます。
sudo -u ceph -i
- ノードの IP アドレスを把握してください。
- Ceph クラスタにノードを追加するために、
ceph-deploy
コマンドを使用します。ローカルの管理ノードで次のコマンドを実行して、ノードの追加準備をします。
ceph-deploy new <MON_NODE_NAME>
<MON_NODE_NAME>
をノードの名前 (例: mon1
) に置き換えてください。このコマンドは新しい ceph.conf
ファイルを作成します。
- 続いて、以下のコマンドを実行してモニターノードをインストールします。
ceph-deploy mon create-initial
このコマンドは、指定されたノードに Ceph モニターをセットアップします。追加のモニターがある場合は、上記の手順をそれぞれのノードで繰り返します。
- 次に、OSD ノードを追加します。ノードには、データを格納する OSD を起動するためのストレージが必要です。以下のコマンドを実行して、各 OSD ノードを追加します。
ceph-deploy osd create <OSD_NODE_NAME>
<OSD_NODE_NAME>
を追加する OSD ノードの名前に置き換えます。これにより、各 OSD ノード上で OSD プロセスが起動し、データがライブに保存されます。
- ノードが正常に追加されたかどうかを確認するために、次のコマンドを実行します。
ceph -s
これにより、クラスタの状態や追加されたノードの一覧を確認できます。
以上の手順を実行することで、Ceph クラスタにノードを追加することができます。