この記事では、Redis に関する関連知識を提供します。主に分散キャッシュに関連する問題が整理されています。分散とは、異なるサーバーに分散される可能性がある複数のアプリケーションで構成されることを意味します。上記は、最終的に提供するものです。ウェブ側のサービスについても一緒に見ていきましょう。皆様のお役に立てれば幸いです。

推奨される学習: Redis ビデオ チュートリアル
分散キャッシュの説明:
分散キャッシュの焦点は分散にあり、分散開発、分散デプロイ、分散ロック、物、システムなど、多くの分散のものに触れたことがあると思います。これにより、ディストリビューション自体について明確に理解できるようになり、ディストリビューションは複数のアプリケーションで構成され、それらのアプリケーションは異なるサーバーに分散され、最終的には Web 側にサービスを提供します。
分散キャッシュには次の利点があります:
- すべての Web サーバー上のキャッシュされたデータは同じであり、異なるアプリケーションや異なるサーバーによってキャッシュされたデータが異なることはありません。
- キャッシュは独立しており、Web サーバーの再起動や削除や追加の影響を受けません。つまり、Web に対するこれらの変更によってキャッシュされたデータが変更されることはありません。
従来の単一アプリケーション アーキテクチャでは、ユーザーのアクセス数がそれほど多くないため、キャッシュの大部分はユーザー情報と一部のページを保存するために存在し、ほとんどの操作は DB で直接実行されます。
ERP、SCM、CRM、その他のシステムなどの従来の OA プロジェクトは、ユーザー数が少なく、また、ほとんどの企業のビジネス上の理由によるものです。シングルアプリケーションのアーキテクチャは依然として非常に複雑であり、一般的に使用されているアーキテクチャですが、ユーザー数の増加やビジネスの拡大に伴い、システムによっては DB のボトルネックが発生します。
この状況に対処する方法は次の 2 つです。
(1): ユーザーのアクセス数は多くないが、読み書きされるデータの量が多い場合, 一般的に採用されるのは、DBの読み書きを分離し、1つのマスターと複数のスレーブを使用し、ハードウェアをアップグレードしてDBのボトルネック問題を解決することです。
このような欠点も純粋にあります:
1. ユーザーの数が多い場合はどうすればよいでしょうか? 、
2. パフォーマンスの向上には限界があります。
3. 価格/パフォーマンスの比率は高くありません。パフォーマンスの向上には多額の費用が必要です (たとえば、現在の I/O スループットは 0.9 ですが、1.0 に増やす必要があります。マシン構成を増やすと、この費用は確かにかなりの金額になります)
(2):ユーザーのアクセス数も増加するため、問題を解決するにはキャッシュを導入する必要があります。キャッシュの一般的な機能を図で説明します。

キャッシュは主に頻繁に変更されず、アクセス数が多いデータを対象としています。DB データベースはデータの固定化のみ、または読み取り専用と理解できます。変更されたデータについては、上の図では SET 操作を描画していません。キャッシュを一時データベースとして使用できることを説明したいだけです。スケジュールされたタスクを通じて、キャッシュ内のデータとデータベースを同期できます。このようにして、データベースの圧力をキャッシュに転送できることが利点です。
キャッシュの出現により、データベースの圧迫の問題は解決されますが、次のような状況が発生すると、キャッシュは役割を果たせなくなります。キャッシュの侵入、キャッシュの破壊、キャッシュなだれ、これら 3 つの状況# # #。
キャッシュの侵入: プログラムでキャッシュを使用する場合、通常は、まずキャッシュにアクセスして、必要なキャッシュ データをクエリします。必要なデータがキャッシュに存在しない場合は、そのため、キャッシュはその機能を失います (キャッシュ障害)。必要なのは DB ライブラリにアクセスしてデータを要求することだけです。このとき、そのようなアクションが多すぎると、データベースがクラッシュします。この状況を改善する必要があります。私たちによって阻止されました。たとえば、キャッシュからユーザー情報を取得しますが、キャッシュに存在しないユーザー情報を意図的に入力することで、キャッシュを回避し、圧力をデータに戻します。この問題に対処するには、キャッシュではユーザー情報が見つからず、データベースはユーザー情報をクエリできないため、初めてアクセスされたデータをキャッシュすることで、繰り返しのアクセスを避けることができます。プレッシャーを再びオンにします キャッシュに目を向けると、疑問を持つ人もいるかもしれません アクセスされた一意でキャッシュを回避できるパラメータが数万ある場合にどうすればよいですか また、データを保存し、キャッシュをクリアする有効期限を短く設定します。
キャッシュの内訳: 内容はこんな感じで、有効期限が設定されている一部のキャッシュKEYは、有効期限が切れるとプログラムへの同時アクセスが多くなります(キャッシュ無効化)。問題を解決するには、ミューテックス ロックを使用します。
ミューテックス ロックの原則:一般的な説明では、10,000 人のユーザーがデータベースにアクセスしますが、データベースにアクセスできるのは 1 人のユーザーだけです。ユーザーがこの権限を取得すると、キャッシュを再作成しますが、この時点では、残りの訪問者は権限を取得していないため、キャッシュへのアクセスを待機しています。
無期限: 有効期限を設定しなくても十分ではないかと思う人もいるかもしれません。はい、ただしこれには欠点もあり、定期的にキャッシュを更新する必要があるため、キャッシュ内のデータは比較的遅くなります。
キャッシュ雪崩: は、複数のキャッシュが同時に期限切れになることを意味します。このとき、大量のデータ アクセスが来ます (キャッシュ無効化 )。データベース DB に対するプレッシャーが再び増加します。解決策は、有効期限を設定するときに有効期限に乱数を追加して、広い領域でキャッシュが失敗しないようにすることです。
プロジェクトの準備
1. まず、ここを参照して Redis をインストールします
2. 次に、クライアント ツール: RedisDesktopManager (便利な管理)#をダウンロードしてインストールします## 3. プロジェクト Nuget で Microsoft.Extensions.Caching.Redis を参照します
このために、新しい ASP.NET Core MVC プロジェクトを作成し、最初にプロジェクト Startup クラスの ConfigureServices メソッドに Redis サービスを登録します。
1 2 3 4 5 6 7 8 9 10 11 12 | public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedRedisCache(options =>
{
options.Configuration = "localhost" ;
options.InstanceName = "DemoInstance" ;
});
services.AddMvc();
}
|
ログイン後にコピー
上記の Redis サービスを登録するときに、Redis サーバーの IP アドレス、ポート番号、ログイン パスワードを指定することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 | public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedRedisCache(options =>
{
options.Configuration = "192.168.1.105:6380,password=1qaz@WSX3edc$RFV" ;
options.InstanceName = "DemoInstance" ;
});
services.AddMvc();
}
|
ログイン後にコピー
後で、Redis インスタンス名 DemoInstance がどのように設定されるかについて説明します。上記の options.InstanceName を使用します 対処方法
また、services.AddDistributedRedisCache メソッドで Redis サーバーのタイムアウト期間を指定することもできます。後で紹介する IDistributedCache インターフェース内のメソッドを呼び出して操作すると、 Redis サーバー上でタイムアウトが発生すると、RedisConnectionException と RedisTimeoutException がスローされるため、以下では Redis サービスの登録時に 3 つのタイムアウトを指定します:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedRedisCache(options =>
{
options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions()
{
Password = "1qaz@WSX3edc$RFV" ,
ConnectTimeout = 5000,
SyncTimeout = 5000,
ResponseTimeout = 5000
};
options.ConfigurationOptions.EndPoints.Add( "192.168.1.105:6380" );
options.InstanceName = "DemoInstance" ;
});
services.AddMvc();
}
|
ログイン後にコピー
このうち、ConnectTimeout は Redis サーバーへの接続を確立するためのタイムアウトです。 、SyncTimeout および ResponseTimeout は、Redis サーバー上でデータ処理を実行するための操作のタイムアウト期間です。上記では、options.ConfigurationOptions 属性を使用して、Redis サーバーの IP アドレス、ポート番号、ログイン パスワードを設定したことに注意してください。
IDistributedCache インターフェイス
プロジェクトで参照されています。 using Microsoft.Extensions.Caching.Distributed; IDistributedCache の使用
IDistributedCache インターフェイスには同期メソッドと非同期メソッドが含まれています。インターフェイスにより、分散キャッシュ実装で項目の追加、取得、削除が可能になります。 IDistributedCache インターフェイスには次のメソッドが含まれています。
Get、GetAsync は文字列キーを受け取り、キャッシュ内に見つかった場合はキャッシュ アイテムを byte[] として取得します。
Set、SetAsync 文字列キーを使用して、キャッシュに項目を追加または変更します (byte[] 形式)。
Refresh、RefreshAsync キーに基づいてキャッシュ内の項目を更新し、調整可能な有効期限タイムアウト値 (存在する場合) をリセットします。
削除、RemoveAsync キーに基づいてキャッシュ項目を削除します。 Remove メソッドに渡されたキーが Redis に存在しない場合、Remove メソッドはエラーを報告せず、何も起こりませんが、Remove メソッドに渡されたパラメータが null の場合は、例外がスローされます。
上で述べたように、IDistributedCache インターフェースの Set メソッドと Get メソッドは byte[] バイト配列を介して Redis からデータにアクセスするため、ある意味あまり便利ではありません。 Redis からのあらゆる種類のデータ。
Json.NET Nuget パッケージは、Json 形式のシリアル化と逆シリアル化に使用されます。
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json;
using System.Text;
namespace AspNetCoreRedis.Assembly
{
public class RedisCache
{
protected IDistributedCache cache;
public RedisCache(IDistributedCache cache)
{
this.cache = cache;
}
public void Set(string key, object value, DistributedCacheEntryOptions distributedCacheEntryOptions)
{
var stringObject = JsonConvert.SerializeObject(value, new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
TypeNameHandling = TypeNameHandling.All
});
var bytesObject = Encoding.UTF8.GetBytes(stringObject);
cache.Set(key, bytesObject, distributedCacheEntryOptions);
Refresh(key);
}
public bool Exist(string key)
{
var bytesObject = cache.Get(key);
if (bytesObject == null)
{
return false;
}
return true;
}
public T Get<T>(string key, out bool isExisted)
{
var bytesObject = cache.Get(key);
if (bytesObject == null)
{
isExisted = false;
return default (T);
}
var stringObject = Encoding.UTF8.GetString(bytesObject);
isExisted = true;
return JsonConvert.DeserializeObject<T>(stringObject, new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.All
});
}
public void Remove(string key)
{
cache.Remove(key);
}
public void Refresh(string key)
{
cache.Refresh(key);
}
}
}
|
ログイン後にコピー
Use test
その後、ASP.NET Core で実行します。 MVC プロジェクトで、新しい CacheController を作成し、その Index メソッドで RedisCache クラスの関連メソッドをテストします。
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | public class CacheController : Controller
{
protected RedisCache redisCache;
public CacheController(IDistributedCache cache)
{
redisCache = new RedisCache(cache);
}
public IActionResult Index()
{
bool isExisted;
isExisted = redisCache.Exist( "abc" );
redisCache.Remove( "abc" );
string key = "Key01" ;
string value = "This is a demo key !" ;
redisCache.Set(key, value, new DistributedCacheEntryOptions()
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10)
});
var getVaue = redisCache.Get<string>(key, out isExisted);
value = "This is a demo key again !" ;
redisCache.Set(key, value, new DistributedCacheEntryOptions()
{
SlidingExpiration = TimeSpan.FromMinutes(10)
});
getVaue = redisCache.Get<string>(key, out isExisted);
redisCache.Remove(key);
return View();
}
}
|
ログイン後にコピー
以前は、サービスを提供するときに、プロジェクトの Startup クラスの ConfigureServices メソッドで services.AddDistributedRedisCache 登録を呼び出しました。 Redisではoptions.InstanceName = "DemoInstance"と設定されていますが、このInstanceNameは何に使うのでしょうか?
上記の CacheController で Index メソッドの次のコードを呼び出すと:
1 2 3 4 5 6 7 | string key = "Key01" ;
string value = "This is a demo key !" ;
redisCache.Set(key, value, new DistributedCacheEntryOptions()
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10)
});
|
ログイン後にコピー
redis-cli を使用して Redis サーバーにログインし、Keys * コマンドを使用して現在の Redis サービスに保存されている情報 すべてのキーが表示されると、次のような結果が表示されます。

コードでは Redis に保存されているキーが「Key01」、実際には Redis サービスにあります。保存されているキーは「DemoInstanceKey01」です。そのため、Redis サービスに実際に保存されているキーは「InstanceName key」の組み合わせキーです。そのため、設定することで、さまざまなアプリケーションの Redis でデータ分離を行うことができます。これが InstanceName の役割です。
推奨学習:
Redis ビデオ チュートリアル
以上がRedis を使用した分散キャッシュの実装について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。