今回は、ASP.NET Core アプリケーションで使用するセッション情報を Redis に格納する方法を紹介します。環境は次の2パターンです。
- Kubernetes 上に ASP.NET Core App コンテナ + Redis コンテナ
- Windows OS の IIS で ASP.NET App をホスト + Redis on Windows
ASP.NET Core は、Windows、Mac、Linux で最新のクラウド ベースの Web アプリケーションをビルドするための、オープン ソースのクロスプラットフォーム .NET Framework ですが、ここ数年の Microsoft のオープンソース(OSS)への取り組みは勢いがあります。記憶に新しいのは2018年に、あのソースコードの共有プラットフォーム GitHub を買収しましたね。
Redis とは
Redisは、データ構造サーバーを実装するオープンソースソフトウェアプロジェクトである。いわゆるNoSQLデータベースの一つであり、Redis Labs(英語版)がスポンサーとなって開発されている[4]。ネットワーク接続されたインメモリデータベースでかつキー・バリュー型データベース(英語版)であり、オプションとして永続性を持つ。
Redis persistence (永続化)
Redis の永続化には次の3種類があります。
RDB
指定された間隔でデータセットの即時スナップショットを実行します。
AOF
サーバーが受信したすべての書き込み操作をログに記録します。
永続化無効
メモリで管理します(揮発性)
また、RDB、AOF の併用も可能となっています。
redis-cli コマンド
Redis に格納した値を確認するときに便利なコマンドをいくつか紹介します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# # redisに登録されているキーの一覧を取得します keys * # value の種類を返します type [key] # type が string だった場合の値を確認します get [key] # type が list だった場合の値を確認します lrange [key] # type が set だった場合の値を確認します smembers [key] # type が zset だった場合の値を確認します zrange [key] # type が hash だった場合の値を確認します hgetall [key] # type が hash だった場合に field の一覧を確認します hkeys [key] # type が hash だった場合に value の一覧を確認します hvals [key] # 選択しているデータベース内の全てのキーを削除します flushdb |
Kubernetes 環境
以前の記事 ↓ でローカル環境に Kebernetes を準備する方法を紹介しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# # redis.conf を configmap に登録します。 # redis.conf はGit Hub に公開されているのをダウンロードして使用します。 # ただ、永続化等の検証が必要でない場合は、redis.conf を configmap に登録する必要はありません。 # redis 5.x は組み込みになっています。 # 公式で公開されている config ファイル:https://redis.io/topics/config # ※組み込み config を利用する場合は、docker-for-windows-redis-deployment.yaml の configmap をマウントする定義を削除してください。 kubectl create configmap --from-file=redis.conf=./redis.conf # redis をデプロイします kubectl apply -f docker-for-windows-redis-deployment.yaml # redis コンテナに接続します kubectl exec -it [pod] -- sh # redis-cli で値をセットします redis-cli set app-key hogehoge # redis-cli でセットした値を取得します get app-key |
Visual Studio 2017 Community を使っての ASP.NET Core の Dockerアプリケーションについては ↓ で少し紹介しています。
パッケージインストール
Visual Studio 2017/ツール/NuGetパッケージマネジャー/ソリューションのNuGetパッケージの管理から次の2つをインストールします。
ここでASP.NET Core のセッションについての基本情報です。
ASP.NET Core は、セッション ID を含む Cookie をクライアントに提供することで、セッションの状態を維持します。Cookie は要求ごとにサーバーに送信されます。 アプリは、セッション ID を使用してセッション データをフェッチします。
appsettings.json に追記
Redis の接続情報を追記します。ここでは、先ほどデプロイした Redis の Service オブジェクトの仮想IPアドレス(ClusterIP)を指定してください。Kubernetes 上に Pod としてデプロイするときは名前を指定します(redis.default.svc.cluster.local)が、今回は Visual Studio 2017 のDocker デバック機能で動作させることを前提としているためです。
1 2 3 |
"ConnectionStrings": { "Redis": "********" }, |
Startup.cs にコードを追加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public void ConfigureServices(IServiceCollection services) { ・・・ #region == redis == var redisConnString = Configuration.GetConnectionString("Redis"); services.AddDistributedRedisCache(options => options.Configuration = redisConnString; options.InstanceName = "myapp."; }); var redis = ConnectionMultiplexer.Connect(redisConnString); services.AddDataProtection().SetApplicationName("MyApp").PersistKeysToRedis(redis, "DataProtection-Keys"); services.AddSession(options => { options.Cookie.Name = ".MyApp.Session"; options.IdleTimeout = TimeSpan.FromMinutes(10); options.Cookie.HttpOnly = true; }); #endregion ・・・ } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ・・・ #region == redis == app.UseSession(); #endregion ・・・ } |
Controller にコードを追加
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// // using Microsoft.AspNetCore.Http; // ↑ を追加します。これがないとHttpContext.Session.SetStringの拡張メソッドが使用できません // Controller の Action メソッドに以下のコードを追加します // セッション情報(ユーザ情報など)を Redis に Set HttpContext.Session.SetString("mykey", val); await HttpContext.Session.CommitAsync(); // Controller の Action メソッドに以下のコードを追加します // セッション情報(ユーザ情報など)を Redis から Get await HttpContext.Session.LoadAsync(); var val = HttpContext.Session.GetString("mykey"); |
Windows 環境
Windows 版の Redis は ↓ の Microsoft が提供している Git Hub よりダウンロードしてインストールします。インストールが完了すると redis-cli が使用できます。コマンドプロンプトから redis-cli と入力してEnter キーを押下すると接続できます。
Windows 環境下も Kuberbetes 環境下と 1 ~ 3 は同様です。せっかくなので 4 の実装を DI(依存関係の挿入)した IDistributedCache を使用する方法に変更します。ユーザ情報などは、HttpContext.Session を使用してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// controller #region == member == private readonly IDistributedCache _cache; #endregion #region == constructor == public LoginController(IDistributedCache cache) { _cache = cache; } #endregion // Controller の Action メソッドに以下のコードを追加します // セッション情報(共有情報など)を Redis に Set _cache.SetString("key", serializeObject); // Controller の Action メソッドに以下のコードを追加します // セッション情報(共有情報など)を Redis から Get var val = await _cache.GetStringAsync("key"); var myapp = JsonConvert.DeserializeObject<MyApp>(val); |
ASP.NET MVC のように [Serializable]属性を付与したクラスを Redis にぶち込もうとしたら怒られました。JsonConvert 等でシリアライズする必要があるみたいです。Redis に格納されたセッション情報は redis-cli を使用すると ”type [key]” の結果は ”hash” のため、”hgetall [key]” で確認できます。
クラウドの Redis サービス
Azure
AWS
GCP
まとめ
ASP.NET Core の セッション情報を Redis に格納する方法を紹介しました。ASP.NET Core も Redis も僕はお初なので新鮮でした。今回はRedis コンテナを Kubernetes 上に1つしかデプロイしていませんが、プロダクション環境下では Redis Cluster を採用するのが主流だと思われます(実は Redis Cluster に挑戦しようとしましたが、お初の僕には少しハードルが高く、次回以降に持ち越ししました。。。)
また Kubernetes 上にデプロイした Redis に ASP.NET Core App から現在の時間(DateTime.Now)を格納したのですが・・・あ、UTC だね。。。と Linux に慣れていない僕は、文字コードや改行コードなど基本的なところでもハマりました。でもこればっかりは少しずつインプットしていくしかないですね。因みに UTC から JST の変更はうまくいったので、また別の機会に。
おススメ書籍
技術本を読むなら Kindle がおすすめです。こちらの記事をご覧ください。
AWS をベースに Azure、GCP の3大パブリッククラウドについて、まとめた本です。クラウドに興味を持ち始めた人、1つのパブリッククラウドは知っているけど、他のパブリッククラウドを知らない人にとっては、比較できる良い本になっています。
Docker の基礎(インストール、Docker Engine、Dockerfile etc)から実践的な活用方法まで知ることができる本になっています。初心者には適度なボリューム(本の厚さ)で、とっかかりとしては良い本になっています。
NoSQLはAWS、Azure、GCPで多様なサービスが提供されています。分散キャッシュとして使われる Redis も NoSQL の分類となります。特にRDBMS に慣れた人が、NoSQL を知るには良い本です。今やデータベースも、目的に応じて選択、組み合わせ(ハイブリッド)をするようになっています。