Help us understand the problem. What is going on with this article?

Azure Cache for Redis ASP.NETでの使用方法、注意点

今回はAzure Web Service(以下Web Server)からAzure Redis(以下Redis)にデータを読み書きします。
その際の注意点や、ベストプラクティスとして紹介されているアプローチを紹介したいと思います。

簡単にRedisの概要

・KeyとValueの組み合わせでデータを保存できるDB。
・読み書きがとても速い。
・データの保存期間を設定できるので時限式で消せる。
・Get,Set,Update,Sortなど単純な機能を持っている。
・永続させたいデータの保存には使用できない。(再起動で消える)
・ただのミドルウェア(自由にダウンロードできるので、ローカルにもRedisServerを立てれます)

利用を考えている方にまず知らせたいこと

・ほかのAzureサービスと比べて価格設定が高め。
キャッシュさせたいものにもよりますが、DBの性能にお金を出したほうが良い場合もあると思います。
(私はキャッシュしたいものが認証情報だけだったので、最終的にDBにお金を出しました。。)

キャッシュするデータ、量、Redisの機能で判断していただければと思います。

・すぐ始められる、使い方や設定がすごく簡単、機能が単純なのでハマるポイントが少ない(べた褒め)

・スケールアップに(途中でプランを上げる)再起動が必要
運用途中で性能を上げるためにはサービスのダウンタイムが発生してしまう。
(これはシャード構成にしておけば、解決できるものなのかもしれない)

AzureポータルからRedisの作成

作成時の注意としてWeb ServerとRedisは同じリージョンに配置します。
公式より引用

最大限のパフォーマンスと最短の待機時間を実現するには、キャッシュ クライアント アプリケーションと同じリージョンに Azure Cache for Redis を配置します。

選ぶプランの指標ですが、
基本的なことは価格表と説明を見てもらって、私が疑問に思った部分だけ補足します。

Redis価格表
https://azure.microsoft.com/ja-jp/pricing/details/cache/

・クライアント接続の数
今回のクライアントはWeb Serverになります。
なのでRedisに接続するクライアント数はWeb Serverのインスタンス数になります(実際にはそれより少しだけ多いです。)
Web Serverは最大10インスタンスなので最小の256で足りますね。

実際に私はWeb Server1台からRedisを使っていたのですが、接続数を確認したところ最大13コネクションがありました。
多分Azureの監視系のサーバーやコンソールのカウントだと思うのですが、確信がないです。

・ネットワーク帯域
認証情報を扱うぐらいなら「低」で問題なかったです。
1秒間に7KBでネックになることはなかったですが、大きいデータを扱う際には先に検証してみることをお勧めします。

実装前に環境設定をします。

Redisの接続文字列を設定します。

ポータルからRedisを開きサブメニューを概要とアクセスキーから
urlとキーを確認します。

Web.configにRedisへの接続文字列を追加します。

Web.config
<appSettings>
    <add key="CacheConnection" value="概要のURL.redis.cache.windows.net:6380,abortConnect=false,ssl=true,allowAdmin=true,password=アクセスキー"/>
</appSettings>

ソース上にキー情報を置きたくない場合は、Azureポータル上に置くこともできます。
置き場所は、ポータル>App Service>構成>新しいアプリケーション設定を追加
キーと値に上記と同じ内容を入れて保存。
※保存した際にサーバーが再起動します。

どちらに配置してもコード上からの参照方法は変わりません。

Redisを扱うためのパッケージをインストールします

「StackExchange.Redis」をNugetパッケージマネージャでインストールします。

以上の設定を使って実際の使い方を示します。

以下のコードだけでRedisの接続部分はできます。
これは公式で推奨された書き方で、すべてのRedis接続は同じインスタンスを介すようにします。

private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
    // Web.configに設定してもポータル上の場合でも、ConfigurationManagerで取得できます。
    string cacheConnection = ConfigurationManager.AppSettings["CacheConnection"];
    return ConnectionMultiplexer.Connect(cacheConnection);
});

public static ConnectionMultiplexer Connection
{
    get
    {
        return lazyConnection.Value;
    }
}

実際にRedisにGet,Setしてみます。

var cacheKey = "Redis_Key_Name";
// Redisにはシリアライズしたオブジェクトも入れることができます。
var cacheValue = "Allow_Content_SerializeObject";

// Connectionはどこから参照してもOKな、スレッドセーフになっています。
IDatabase cache = Connection.GetDatabase();

// Redisに値をセットします。(Key, Value, 保存期間、 Set動作の詳細)
cache.StringSet(cacheKey, cacheValue, TimeSpan.FromMinutes(5), When.Always);

// Redisの値をゲットします。非同期もできます。StringGetAsync,StringSetAsync
RedisValue value = cache.StringGet(cacheKey);
if (value.IsNullOrEmpty)
{
    return null;
}
// 保存期間の再セットです。
cache.KeyExpire(cacheKey, TimeSpan.FromMinutes(5));

あとはデプロイして試してみてください。
次に実際にRedisに値が入ったかを確認する方法を記します。

Redisにコンソールからアクセス

Redisコンソールにアクセスして、Keyを操作してみましょう。
Azureポータルから入るパターンと、ローカルのcmdからアクセスするパターンがあります。

Azureポータルからは簡単には入れます、Redisの中にSSHのタブがあったとおもうので、そこからアクセスできると思います。(うろ覚えでごめんなさい)
色々とコマンドを試してください。

cmdから入る方法は公式をチェックでおねがいします。。。
https://docs.microsoft.com/ja-jp/azure/azure-cache-for-redis/cache-how-to-redis-cli-tool

負荷試験をした際に躓いたこと。

負荷試験を行ったところRedisのタイムアウトが頻発しました。
Redisのプランを上げても解決しなかったので、しばらく原因がわからなかったのですが、
Web ServerのCPUが100%になってたので、Web Serverのプランを上げたところRedisのタイムアウトがなくなりました。
腑に落ちなかったので調べたところ、公式に記載がありました。

Redis クライアントでのメモリ不足
https://docs.microsoft.com/ja-jp/azure/azure-cache-for-redis/cache-troubleshoot-client

クライアントの性能が足りないと、Redisが即時にレスポンスを返しても、受け取ることができずにRedisのタイムアウトが発生するとのことです。
Web Serverが悪いのにRedisのせいされててかわいそう。

最後に

Redis自体は本当に早いと思います。
プランのネットワーク帯域についてはもっと言及された記載があるとうれしいですね。

smi
2019年11月までゲームプログラマ、Macユーザー 12月からシステムエンジニア、windowsユーザー
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away