Azure Cache for Redisを使ってみた！

この記事はAzure AdventCalendar2019 15日目の記事です。
あまり新規性はないかもしれませんが最後の方にwebappsをVNet統合経由で連携させてみた検証内容も載せてみましたので最後までお付き合いください。

# はじめに
仕事でAzure cache for Redis(以降Azure Redis)を導入する機会があったのですが、自分への復習も兼ねて投稿してみます。

# [Azure Cache for Redis](https://docs.microsoft.com/ja-jp/azure/azure-cache-for-redis/cache-overview)とは
その名からの想像通りAzure版Redisのマネージドサービスとなります。AWSのAmazon ElastiCacheに該当するものですね。

# 特徴
* クラスタ構成が簡単に組める　※一部プランのみ  
それにより複数ノードにデータセット分割できる。また障害時のフェールオーバーにも対応。
* メンテナンスは自動的に実施　※有効/無効設定可  
所謂メンテナンスフリー
* リージョンレベルでの冗長化（Geo Replication）が可能 ※Premiumのみ  
そのため災害対策として高可用構成が組める
* redis-cliやphpredisなど通常のRedisで利用しているクライアントがそのまま利用できる  

等々

# 構築方法
## 前提条件  
* サブスクリプションが開設されていること  
* Azure Potalに繋がること

## STEP1
ここからはAzure Potalから構築を進めます。Azure CLIやPowershell等も可能です.  
[リソースの作成]から検索窓で「redis」と入力すると表示されます。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/da6d7fbf-e8b9-c7b5-06d9-0f3e6960990f.png)

## STEP2
概要が表示されるので[作成]をクリックして次へ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/7865c4ae-1b0a-23e4-a956-f32277b99917.png)

## STEP3
ここから詳細な設定となります。 ポイントをピックアップします。

* 価格レベル  
開発向けのBasic〜エンタープライズ用途のPremiumまでラインナップが提供されています。
機能差は[こちら](https://azure.microsoft.com/ja-jp/pricing/details/cache/)を参照ください。

* クラスタ
Premiumはクラスが構成が組めます。  
シャード数分金額が乗算となりますのでお財布と要件検討の上、決定ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/e07e3e67-64ad-5662-c8f4-f9e46b610da4.png)

* キャッシュの永続化
RDBかAOF（preview）のいずれかが選択できます。　※執筆時点
ざっくりと違いを挙げると、、  
  * RDBは定期的にスナップショットを取得
  * AOFは書き込みコマンドを記録し、随時追記する形で取得  
サービス要件や両者のメリデメを比較した上で採用を検討ください。  
両者ともバックアップ先に[ストレージアカウント](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-account-overview)が必要になりますので合わせて設定ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/fa409941-dd70-5aa3-a713-ce4b2a7028bf.png)

* ネットワーク
次項にて取り上げます。

### ネットワーク
（執筆時点では）Azure RedisにはService EndpointやPrivate Linkは対応していないのですが、VNet内のサブネットに配置することでセキュアなネットワークを構成させることができます。
その際、Azure Redis用に利用される最低限のIPは

* サブネットで利用される予約IP５つ
* Non Cluster
    * シャードごとのIP1つ
* Cluster
    * シャードごとのIP2つ
    * ロードバランサのIP1つ

となるので、最低でも/29の専用サブネットを予め設定しておく必要があります。
※自信はないが、合っているはず。。

### アクセス制限
Azure Redis標準のIPファイアウォールまたは上記で作成したサブネットに割り当てるなNSGが選択できます。
きめ細かい設定をしたい方は後者を選択することとなりますが、要件がありますのでご注意ください。

* [送信要件](https://docs.microsoft.com/ja-jp/azure/azure-cache-for-redis/cache-how-to-premium-vnet#outbound-port-requirements)
* [受信要件](https://docs.microsoft.com/ja-jp/azure/azure-cache-for-redis/cache-how-to-premium-vnet#inbound-port-requirements)

# webappsと連携させた構成
最後にWebAppsと連携させた際の構築をつらづらと書いてみます。

* 構成
![webapps_to_redis.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/a3364fba-66cb-99d1-f39e-53f80829ee59.png)

* VNet  
  * アドレス空間  
172.16.0.0/16  
  * サブネット  
VNet統合用サブネット：172.16.1.0/24  
Azure Redis用サブネット：172.16.2.0/24  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/d4910cae-ce14-e963-1fd8-fe0b959ba373.png)

* WebApps
  * App Service プラン※Linux版は後日検証します！  
Standard
  * VNet統合
サブネット名：vnet-integ
執筆時点ではプレビューですが、来年にはGAするといいな。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/458f2c2c-f120-e56b-7b3e-143b32482c76.png)
  * redisクライアント  
[peclの公式サイト](https://pecl.php.net/)からweb appsのアーキテクチャに合わせたdllをDLし、導入しました。  
ざっくり手順をまとめると下記の通りです。詳細は[こちら](https://docs.microsoft.com/ja-jp/azure/app-service/web-sites-php-configure#how-to-enable-extensions-in-the-default-php-runtime)を参照ください。
      * Webappsのwwwroot配下にbinディレクトリを作成し、アップロードする
      * Webapps内にてiniファイルを作成し、dllを読み込む設定する
      * Webappsの[アプリケーションの構成]で　上記iniファイルとdllを読みこむ設定を構成する

* Azure Redis  
  * プラン  
Premium
  * プロパティ  
今回は非SSLポートも開けてます。今回は検証のためですが、要件に合わせて検討ください。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/eed81e39-b189-1d67-65fb-05371d8eb313.png)

  * ネットワーク  
IPアドレスは初期設定時、指定しなかったので自動的に割り振られてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/806918ec-ce32-d615-2fb5-9804489d4424.png)

* いざ接続
今回は下記サンプルをWebappsのwwwroot配下に用意し、試してみました。  
`<password>`はAzure Redisの[アクセスキー]ブレードから参照ください。

```php:connect.php  
<?php
$redis = new Redis();
$redis->connect('pir0w.redis.cache.windows.net', 6379);
$redis->auth('<password>');
$redis->set("fuga","foofoo");
$res = $redis->get("fuga");
echo $res;
```
ブラウザで接続してみたところ、期待通り、セットした値が帰ってきた様です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23761/79a51824-c7e4-27de-12d1-0c2980d57616.png)

少し心配なので、コンソールからもチェックしてみました。

```
$ redis-cli -h pir0w.redis.cache.windows.net -p 6379 -a <password> --raw
pir0w.redis.cache.windows.net:6379> get fuga
foofoo
```
格納されてるみたいです。

# 最後に
ご覧の通り、簡単に早くRedisを立てることができました。
また今回初めてWebappsと連携させてみましたが、そこまで難なく連携することができました。
まだ今回書ききれなかった点（SSL通信やwebapps on Linux）も後日更新してみたいと思います。

# 参考記事
[Azure Cache for Redis の説明](https://docs.microsoft.com/ja-jp/azure/azure-cache-for-redis/cache-overview)
[Azure Cache for Redis の価格](https://azure.microsoft.com/ja-jp/pricing/details/cache/)
[Azure ストレージ アカウントの概要](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-account-overview)
[送信ポートの要件](https://docs.microsoft.com/ja-jp/azure/azure-cache-for-redis/cache-how-to-premium-vnet#outbound-port-requirements)
[受信ポートの要件](https://docs.microsoft.com/ja-jp/azure/azure-cache-for-redis/cache-how-to-premium-vnet#inbound-port-requirements)
[PECL](https://pecl.php.net/)
[既定の PHP ランタイムで拡張機能を有効にする](https://docs.microsoft.com/ja-jp/azure/app-service/web-sites-php-configure#how-to-enable-extensions-in-the-default-php-runtime)