2020年から始めるAzure Cosmos DB - Azure Synapse Link を試してみる

# はじめに

[MS Build 2020][msbuild2020] にて、[Azure Cosmos DB][cosmosdb] のアップデートの1つに [Azure Synapse Link for Azure Cosmos DB][cosmosdb-blog] が発表されました。
今回は、Azure Synapse Link for Azure Cosmos DB の環境を作成して、実際に Azure Synapse ワークスペース上から Azure Cosmos DB のデータを参照できることを確認します。

# Azure Synapse Link for Azure Cosmos DB

Azure Synapse Link とは、**クラウドネイティブのハイブリッドトランザクションと分析処理 (HTAP)** の機能で、Azure Cosmos DB の[分析ストア][msdocs-analytical-store] を活用しています。Azure Synapse Analytics の環境から、Azure Cosmos DB の分析ストアに対してリンクサービス(Linked Services)として接続することで、Azure Cosmos DB 上にある運用データに対してほぼリアルタイムの分析を実行できるというものです。

![word-image-2.png](https://devblogs.microsoft.com/cosmosdb/wp-content/uploads/sites/52/2020/05/word-image-2.png)

Azure Cosmos DB におけるドキュメントの読み取り/書き込みは、通常`トランザクションストア(Transaction Store)`とよばれる**読み取りおよび書き込みに特化された行ストア**の領域で行われます。`分析ストア(Analytical Store)`は**分析クエリに特化された列ストア**の領域であり、Azure Cosmos DB 単体でも利用することが可能です。

- 詳細は[こちら][msdocs-analytical-store]

分析ストアを有効化すると、5分毎に、トランザクションストアから分析ストアへデータの同期が行われるようになります。分析ストアにかかる料金は、以下のサイトを参照してください。

- [Azure Cosmos DB の価格][cosmosdb-pricing]

## 料金について

Azure Synapse Link for Azure Cosmos DB の場合、2020/8/31 までは無料で試すことができます。 ※2020/08/17現在
無料期間が終了した後は、Azure Synapse Link for Azure Cosmos DB を構成する、以下2つの内容の課金が発生します。

- Azure Cosmos DB: Azure Cosmos DB 分析ストアの利用料
- Azure Synapse Link: SQL プール または Spark プールの利用料

2020/08/17現在で確認できている Azure Cosmos DB 分析ストアの料金体系は以下の通りです。　※東日本リージョンの場合

![スクリーンショット 2020-08-17 23.28.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348116/668f0d0d-27e6-62bc-db45-0fc55f74fc5d.png)

分析ストアは、トランザクションストアから同期され`分析ストアに保存されているデータの容量(ストレージ)`と`分析ストアに対するデータの読み取り/書き込み`の2つについて課金が発生します。これは、Azure Cosmos DB 自体の課金とは別で行われます。
Azure Synapse Analytics における SQL プール、および Spark プールの料金については、以下を参照してください。
_なお、2020/08/17現在、SQL プールを使用した Azure Synapse Link はプライベートプレビューです。Spark プールの利用を検討しましょう。_

- [Azure Synapse Analytics の価格][synapse-pricing]


# 環境構築

## Azure Cosmos DB 

以下の記事を参考に、**SQL API** で Azure Cosmos DB アカウントを作成します。

- [2020年から始める Azure Cosmos DB - 環境構築][myqiita-01]

1点注意点として、Azure Cosmos DB アカウントを作成する際の`リージョン`は**以下のものから選択する**ようにしてください。
理由は、**Azure Synapse ワークスペースが下記のリージョンでのみしか作成できない**からです。リージョンを跨いだデータ転送はレイテンシの問題など、通常想定しないので、同じリージョンに作成するようにします。

- オーストラリア東部
- 英国南部
- 西ヨーロッパ
- 東南アジア
- 米国西部2
- 米国中西部
- 米国中南部
- 米国東部
- 米国東部2

Azure Cosmos DB アカウントを作成したら、データベースとコンテナーを作成します。本記事においては、データベースやコンテナー(コレクション)、コンテナー内のデータについては指定しません。好きな値を入れてください。
本記事のサンプルとして、私の好きな Perfume の楽曲データサンプルを投入することにします。

- Database id: Perfume
    - Provision throughput: On
    - Throughput: 400 
- コンテナー名: Songs
    - Provision database throughput: On
    - Throughput: 400
    - Container id: Songs
    - Indexing： Automatic
    - Partition key: /album/name
        - My partition key is larger than 100 bytes: Off
    - Analytical store: On

```json:perfume-songs.json(一部)
[
    {
        "no": 1,
        "title": "スウィートドーナッツ",
        "album": {
            "name": "Fan Service ～Prima Box～"
        },
        "release": 2003
    },
    {
        "no": 2,
        "title": "シークレットメッセージ",
        "album": {
            "name": "Fan Service ～Prima Box～"
        },
        "release": 2003
    },
    {
        "no": 3,
        "title": "ジェニーはご機嫌ななめ",
        "album": {
            "name": "Fan Service ～Prima Box～"
        },
        "release": 2003
    },
    {
        "no": 4,
        "title": "モノクロームエフェクト",
        "album": {
            "name": "Fan Service ～Prima Box～"
        },
        "release": 2004
    },
    {
        "no": 5,
        "title": "エレベーター",
        "album": {
            "name": "Fan Service ～Prima Box～"
        },
        "release": 2004
    }
]
```

## Azure Synapse ワークスペース

以下の記事を参考に環境を作成してください。

- [Azure Synapse Analytics workspace 環境構築][myqiita-02]

### Spark プールの作成

Azure ポータル、もしくは Azure Synapse ワークスペースから Spark プールを作成します。
_※今回は、Azure Synapse ワークスペースを使用します。_

Azure ポータルから作成した Azure Synapse ワークスペースの概要タブに移動し、**ワークスペースの Web URL'** を選択して Azure Synapse ワークスペースにアクセスします。
**Manage / Analytics pools / Apache Spark pools** に移動し、**+New** ボタンを選択し、Spark プールを新規作成します。

- Apache Spark pool name: <任意の名前>
- Autoscale: Enabled
- Node size family: MemoryOptimized
- Node size: Small
- Number of nodes: 3

![スクリーンショット 2020-08-18 0.24.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348116/8f62dfd8-14cf-9d9e-0319-71825cf926a7.png)

**Review + create** を選択すると、Spark プールの作成が開始されます。

## Azure Synapse Link の設定

2つの環境ができたので、Azure Synapse Link を設定していきます。
まずは、先ほど作成した Azure Cosmos DB アカウントのデータエクスプローラーを表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348116/e17da5f7-93f7-87e6-d94d-9d824814ee47.png)

データエクスプローラーの画面上部に、`Enable Azure Synapse Link (preview)`のボタンがあります。これを選択します。
**Azure Cosmos DB 側の操作はこれだけです！** (簡単)

次に、Azure Synapse ワークスペースにて、リンクサービス (Linked Service) の設定を行います。
Azure Synapse ワークスペースにアクセスし、**Manage / External connections / Linked services** に移動します。

![スクリーンショット 2020-08-18 0.33.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348116/31271542-98f6-22b0-c620-83f83cd7877c.png)

**+New** ボタンを選択し、New linked service の画面の検索窓に`Cosmos DB`を入力します。
**Azure Cosmos DB (SQL API)** を選択して、**Continue** を選択します。

![スクリーンショット 2020-08-18 0.37.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348116/29cecedc-2bfc-f949-0396-1644dd9f5455.png)

リンクサービスに関する設定値の入力を求められます。名前 (Name) は好きなものを入力してください。
**Account sekection method** の欄にて、作成した Azure Cosmos DB の値を設定してください。
設定が終わったら、**Create** ボタンを選択してリンクサービスを作成します。

![スクリーンショット 2020-08-18 0.39.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348116/c946c518-d1b8-eb6a-ac84-a5a64cf3b198.png)


# Azure Cosmos DB 分析ストアに接続

これで、Azure Synapse Link for Azure Cosmos DB として、Azure Cosmos DB 分析ストアにあるデータにアクセスできるようになりました。
実際に PySpark でデータを取得し、データフレームにデータを入れてみましょう。

Azure Synapse ワークスペースにアクセスし、**Data / Linked / Azure Cosmos DB** タブを確認します。
データベースに存在するコンテナー(コレクション)が表示されるので、右クリック、もしくは Action ボタンを選択し、**New notebook / Load to DataFrame** を選択します。

![スクリーンショット 2020-08-18 0.46.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348116/1abfb097-6db1-5ee9-d9ed-4db71b77b2d6.png)

ノートブックが作成されますので、以下の部分を確認しましょう。

- Attach to: 先ほど作成した Spark プール
- Language: PySpark(Python)

確認できたら、コードは自動で作成されているので、そのまま`Shift+Enter`でセル実行しましょう。
Spark プールは、デフォルトで15分未使用の場合、自動でアイドル状態に移行します。そのため、アイドル状態からコードを初回実行をする場合、Spark プールの起動のため、完了までに少し時間がかかります。

```python
df = spark.read\
    .format("cosmos.olap")\
    .option("spark.synapse.linkedService", "Perfume")\
    .option("spark.cosmos.container", "Songs")\
    .load()

display(df.limit(10))
```

処理が正常に完了したら、以下のような出力を確認できるはずです。

![スクリーンショット 2020-08-18 0.56.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348116/71f8d87e-bc35-bb56-68bd-28cdd6053b07.png)


# さいごに

今回は、Azure Synapse Link for Azure Cosmos DB を実行できる環境を作成し、PySpark にて Azure Cosmos DB のデータを参照できることを確認しました。
この後は、実際に PySpark を使ってデータを加工・分析していくことになります。その話はまた次回にします。


---

[msdocs]:https://docs.microsoft.com/ja-jp/azure/cosmos-db/synapse-link
[msdocs-analytical-store]:https://docs.microsoft.com/ja-jp/azure/cosmos-db/analytical-store-introduction
[msbuild2020]:https://register.build.microsoft.com/
[cosmosdb]:https://azure.microsoft.com/ja-jp/services/cosmos-db/
[cosmosdb-pricing]:https://azure.microsoft.com/ja-jp/pricing/details/cosmos-db/
[synapse-pricing]:https://azure.microsoft.com/ja-jp/pricing/details/synapse-analytics/
[cosmosdb-blog]:https://devblogs.microsoft.com/cosmosdb/announce-azure-synapse-link-no-etl-analytics/
[github]:https://github.com/Azure-Samples/Synapse

[myqiita-01]:https://qiita.com/ymasaoka/items/3784c64baf30bbe7b761
[myqiita-02]:https://qiita.com/ymasaoka/items/2f311dff91de84e13f36