GCPのストレージサービスまとめ

# この記事はなに？
- Google Cloud認定資格の[Professional Data Engineer](https://cloud.google.com/certification/data-engineer?hl=ja)の勉強内容をまとめたものです。
- 一部、筆者の理解不足により誤った内容が書かれている可能性があります。
- 参考にしていただく際は必ず公式リファレンスも併せてご参照ください。
- また、`この内容を覚えれば資格に合格できる`と保証されたものではないことをご了承ください。


# Google Cloud Storage(GCS)
## 特徴
- `バケット`と呼ばれるコンテナに、`オブジェクト`と呼ばれる様々な形式のファイルを保存し使用することができる。
    - 1オブジェクトあたり`5TB`のサイズ上限あり。
- バケットの保存場所は3種類。
    - マルチリージョン(ex:Asia&US)
    - デュアルリージョン(ex:asia-northeast1&asia-northeast2)
    - リージョン(ex:asia-northeast1)
- WebUI以外に、`gsutilコマンド`や`Storage Transfer Service`を利用することで、データを読み込むことができる。
    - $ gsutil -m で、マルチスレッドによるデータの読み込みが可能。
    - $ gsutil rsync で、ローカルファイルをGCSに読み込ませることができる。
    - 合計データ容量が10TB未満であれば、gsutil、それ以上であればStorage Transfer Service`の利用が推奨される。

## ストレージクラス
- 保存するデータのアクセス頻度にあわせてストレージクラスを設定することで、ストレージ費用を最適化することができる。

| ストレージクラス | 推奨データ |
| :-- | :-- |
| Standard Storage | 頻繁にアクセスされるホットデータ |
| Nearline Storage | 30日に1回アクセスされるデータ |
| Coldline Storage | 90日に1回アクセスされるデータ |
| Archive Storage | 365日に1回アクセスされるデータ |

## ライフサイクル管理
- 特定条件にマッチした際に、ストレージクラスを変更したり、オブジェクトを削除するような制御をおこなう機能を`ライフサイクル`と呼ぶ。
    - JSONもしくはXMLで条件を定義できる。


# BigQuery
## 特徴
- `数TB〜数PB`のデータを、遅くとも数分でクエリできるフルマネージドなデータウェアハウスサービス。
- SQLによる集計以外にも、`BigQueryML`による機械学習モデルの生成や、`地理空間分析`もできる。
- 主にクエリ処理、ストレージ使用容量、ストリーミング挿入に対して費用が発生する。
- Avro、Parquet、ORC、CSV、JSON、Datastore、Firestoreなどの形式で、ローカルファイルやGCSからデータを読み込むことができる。

## パーティション分割テーブル
- 特定のカラムを基準に、テーブルのレコードをいくつかの小さなパーティションに分割することで、クエリのパフォーマンスを向上させることができる。
    - パーティションで分割されたテーブルを、`パーティション分割テーブル`と呼ぶ。
- 分割方法は3種類。
    - TIMESTAMP、DATE、DATETIMEのカラムに基づいて分割される`時間単位の列`方式。
    - BigQueryへデータを取り込んだ際のTIMESTAMPに基づいて分割される`取り込み時間`方式。
    - INTEGER型のカラムに基づいて分割する`整数範囲`方式。
- 1つのテーブルに対して、パーティションの上限は`4000個`。

## クラスタ化テーブル
- 特定のカラムの値をクラスタリングし、いくつかのブロックに整理して並び替えることでクエリのパフォーマンスを向上させることができる。
    - クラスタリングされたカラムを持つテーブルを、`クラスタ化テーブル`と呼ぶ。
    - クエリ実行時に、クラスタリングされたカラムでフィルタリングすることで、不要なデータのスキャンを省略することができる。
- クラスタリングできるカラムは、1テーブルあたり`4個`まで。
    - クラスタリングは順番が重要。
    - カラムA、カラムB、カラムCの順番でクラスタリングしていた場合、カラムA→カラムBの順番でのフィルタリングであればクエリのパフォーマンス向上が見込めるが、カラムAを飛ばしてカラムB→カラムCの順番でフィルタリングしたり、カラムB→カラムAと順番を入れ替えると、クエリのパフォーマンス向上を見込めなくなる。

## 外部データソース、外部テーブル
- BigQueryのストレージにデータを保存せずに、BigQueryからクエリを実行できるデータソースを`外部データソース`と呼ぶ。
    - Bigtable、Cloud Spanner、Cloud SQL、GCS、Googleドライブがサポートされている。
- BigQueryの標準テーブルのように機能し、メタデータもBigQueryに保管されるものの、データ自体は外部ストレージに持つテーブルを`外部テーブル`と呼ぶ。
    - Bigtable、GCS、Googleドライブがサポートされている。
    - クエリの速度を優先する場合は、標準テーブルを作ることが推奨される。
    - 外部テーブルに対して、ワイルドカードのクエリを実行することはできない。
- GCSを外部テーブルとして利用する場合、Avro、Parquet、ORC、CSV、JSON、Datastoreエクスポート、Firestoreエクスポートがサポートされている。
    - 永続テーブル化すると、既存のテーブルと同様に扱うことができる。
    - 一時テーブル化すると、ストレージ費用はかからないものの、他ユーザーと共有ができなかったり、一定時間で消滅してしまうため、アドホック分析やETLの中間テーブルとして使われることが推奨される。

## マテリアライズドビュー
- 通常のビューと違い、ベーステーブルと同じデータを持つ。
- ベーステーブルに更新がかかると、自動でマテリアライズドビューも差分更新される。
- ベーステーブルにクエリが実行された際に、可能な場合はキャッシュと差分を読み込んだ上で計算し、最新の結果を返してくれる。

## オーソライズドビュー
- 元のデータソースへのアクセスを許可せずに、クエリの結果だけを特定のユーザーやグループに許可することができる。

## アクセス制御
- データセット及びテーブルに対しては、プリンシパルを追加することでアクセス制御をかけることができる。
- カラムに対するアクセス制御は、`Data Catalog`を利用する。


# Cloud SQL
## 特徴
- MySQL、PostgreSQL、SQL Serverをサポートするフルマネージドなリレーショナルデータベースサービス。
- 最大`64TB`まで保存可能で、必要に応じてストレージをスケールアップすることができる。

## 高可用性とフェイルオーバー
- 高可用性向けに作られたインスタンスを`リージョンインスタンス`と呼ぶ。
    - リージョンインスタンスは、`プライマリインスタンス`と`スタンバイインスタンス`で構成されている。
    - インスタンスまたはゾーンに障害が発生し、プライマリインスタンスが動作しなくなった場合、スタンバイインスタンスが昇格することで、高可用性を実現している。
    - このプロセスを`フェイルオーバー`と呼ぶ。

## リードレプリカ
- プライマリインスタンスのコピーのこと。
- 読み込み専用のため、読み込みをリードレプリカで行い、書き込みをプライマリインスタンスで行うことで負荷分散させることができる。


# Cloud Spanner
## 特徴
- 無制限の水平スケーリング、強整合性、高可用性を兼ね備えたフルマネージドなリレーショナルデータベースサービス。
- `ACIDトランザクション`の特性を持つ。
    - Atomicity(原子性):トランザクションの読み書きや更新、削除を1つの単位として扱い、「必ず実行する」「何も実行しない」のどちらかしか行わない特性。
    - Consistency(一貫性):トランザクションの前後でデータの整合性が担保され、矛盾のない状態が維持される特性。
    - Isolation(独立性):トランザクションの処理は外部から隠され、他の処理に影響を与えない特性。
    - Durability(永続性):トランザクションが完了したら、その結果は保存され障害が起きても欠損しない特性。
- `マルチリージョン構成`を選択することで、複数ゾーンやリージョンにデータベースをレプリケーションできる。
    - 異なるリージョン間(ex:USとEU)で利用しても、低レイテンシでデータの読み書きができる。

## アーキテクチャ
- コンピューティングを行う`ノード`と、ストレージを担う`スプリット`で構成されている。
    - ノードとスプリットは、3つのゾーンに複製されて配置される。
- スプリットごとに担当するノードが決められている。
    - ノードは紐づくスプリットが持つデータに対して読み書きを行う。
    - ノードがどのスプリットを担当するかは、Cloud Spannerが自動で決め、状況に合わせて動的に変更される。
- ノードを追加することで、1ノードあたりが担当するスプリットが分散し、処理能力の向上に繋げられる。
- 1ノード辺り2TBまでのスプリットを管理できる。
    - 特定のスプリットが肥大化してきたら、自動的に分割され、ノードの再割り振りが行われる。

## ホットスポット
- 主キーの辞書順にテーブルにデータを格納し、上から一定のサイズに区切ってスプリットに割り振る。
- 主キーがidやタイムスタンプのような単調増加する値の場合、特定のスプリットに対する読み書きが集中し、`ホットスポット`が生まれてしまう。
    - 主キーには、UUIDやハッシュ化したIDなど、単調増加しないカラムを選択することでホットスポットを回避できる。

## セカンダリインデックス
- Cloud Spannerはテーブルの主キーに対して、自動的にインデックスを生成する。
- 主キー以外のカラムに対して、`セカンダリインデックス`を作成してクエリのパフォーマンスを向上させることもできる。

# Cloud Bigtable
## 特徴
- フルマネージドなワイドカラム型のNoSQLデータベースサービス。
- `数TB〜数PB`までのデータを格納できる。
- テーブルの行キーがインデックスとして働き、セカンダリインデックスを作ることはできない。
- `低レイテンシ、高スループット`の強みを持つためIoTのデータ格納や、強整合性を活かして時系列データや金融データの格納に使われることが多い。
- 自動スケーリング機能を持つ。
- ストリーミングデータを保存する場合はSSD、10TB超で、レイテンシがあまり重要でない場合やアクセス頻度が低い場合はHDDの利用が推奨される。
    - インスタンス作成後にストレージを切り替える場合は、新しくインスタンスを作りエクスポートする必要がある。
- 各セルは10MBのサイズ制限があり、タイムスタンプ付きで一意のバージョンが格納されている。
- `スパース`特性を持つため、特定の行で使用されていない列がストレージ容量を消費することがない。

## アーキテクチャ
- コンピューティングを担う`ノード`と、ストレージを担う`タブレット`で構成されている。
    - データの実体は、GoogleのファイルシステムであるColossusに格納されており、タブレットはColossusのポインタを保持している。
    - そのため障害が起きてもデータが失われることはなく、ノード間のタブレット移動を高速に行うことができる。
- クラスタにノードを追加することでスケールアップも可能。
- クラスタを追加することで、Cloud SQL同様に`フェイルオーバー`させることも可能。

## 負荷分散
- プライマリプロセスによって、クラスタ内の負荷とデータ量の均衡が図られる。
    - アクセス数の多い大容量のタブレットを分割し、アクセス数の小さなタブレットと結合させ、必要に応じてノードとタブレットの組み合わせを再配置する。
- 書き込みのパフォーマンスを最大化させるには、書き込み操作をノード間でできる限り`均等に分散させる`。
    - 行キーにはUUIDやハッシュ化したIDを用いることで、特定ノードに負荷がかかることを回避し`ホットスポット`の発生を抑制することができる。
    - ホットスポットの特定には、`Key Visualizer`を利用する。

## アプリケーションプロファイル
- 受信したリクエストをどう処理するかインスタンスに指示を出す設定。
- 特定のクラスタに対して、アプリケーションからストリーミング処理とバッチ処理を行っている場合、それぞれ用にアプリケーションプロファイルを作成し、Bigtableへのリクエストと一緒に渡すことで、別のクラスタに処理をレプリケーションしてくれる。(ここの理解が曖昧...)

# ストレージ選択早見表

![スクリーンショット 2022-03-19 22.31.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311026/2be5a6c6-9365-ec4c-a9d7-46186ba688f3.png)