Redis を使用した分散キャッシュの実装について話しましょう
この記事では、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 を参照します
public void ConfigureServices(IServiceCollection services) { //将Redis分布式缓存服务添加到服务中 services.AddDistributedRedisCache(options => { //用于连接Redis的配置 Configuration.GetConnectionString("RedisConnectionString")读取配置信息的串 options.Configuration = "localhost";// Configuration.GetConnectionString("RedisConnectionString"); //Redis实例名DemoInstance options.InstanceName = "DemoInstance"; }); services.AddMvc(); }
public void ConfigureServices(IServiceCollection services) { //将Redis分布式缓存服务添加到服务中 services.AddDistributedRedisCache(options => { //用于连接Redis的配置 Configuration.GetConnectionString("RedisConnectionString")读取配置信息的串 options.Configuration = "192.168.1.105:6380,password=1qaz@WSX3edc$RFV";//指定Redis服务器的IP地址、端口号和登录密码 //Redis实例名DemoInstance options.InstanceName = "DemoInstance"; }); services.AddMvc(); }
public void ConfigureServices(IServiceCollection services) { //将Redis分布式缓存服务添加到服务中 services.AddDistributedRedisCache(options => { options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions() { Password = "1qaz@WSX3edc$RFV", ConnectTimeout = 5000,//设置建立连接到Redis服务器的超时时间为5000毫秒 SyncTimeout = 5000,//设置对Redis服务器进行同步操作的超时时间为5000毫秒 ResponseTimeout = 5000//设置对Redis服务器进行操作的响应超时时间为5000毫秒 }; options.ConfigurationOptions.EndPoints.Add("192.168.1.105:6380"); options.InstanceName = "DemoInstance"; }); services.AddMvc(); }
IDistributedCache インターフェイス
プロジェクトで参照されています。 using Microsoft.Extensions.Caching.Distributed; IDistributedCache の使用IDistributedCache インターフェイスには同期メソッドと非同期メソッドが含まれています。インターフェイスにより、分散キャッシュ実装で項目の追加、取得、削除が可能になります。 IDistributedCache インターフェイスには次のメソッドが含まれています。
Get、GetAsync は文字列キーを受け取り、キャッシュ内に見つかった場合はキャッシュ アイテムを byte[] として取得します。
Set、SetAsync 文字列キーを使用して、キャッシュに項目を追加または変更します (byte[] 形式)。
Refresh、RefreshAsync キーに基づいてキャッシュ内の項目を更新し、調整可能な有効期限タイムアウト値 (存在する場合) をリセットします。
削除、RemoveAsync キーに基づいてキャッシュ項目を削除します。 Remove メソッドに渡されたキーが Redis に存在しない場合、Remove メソッドはエラーを報告せず、何も起こりませんが、Remove メソッドに渡されたパラメータが null の場合は、例外がスローされます。
using Microsoft.Extensions.Caching.Distributed; using Newtonsoft.Json; using System.Text; namespace AspNetCoreRedis.Assembly { /// <summary> /// RedisCache缓存操作类 /// </summary> public class RedisCache { protected IDistributedCache cache; /// <summary> /// 通过IDistributedCache来构造RedisCache缓存操作类 /// </summary> /// <param name="cache">IDistributedCache对象</param> public RedisCache(IDistributedCache cache) { this.cache = cache; } /// <summary> /// 添加或更改Redis的键值,并设置缓存的过期策略 /// </summary> /// <param name="key">缓存键</param> /// <param name="value">缓存值</param> /// <param name="distributedCacheEntryOptions">设置Redis缓存的过期策略,可以用其设置缓存的绝对过期时间(AbsoluteExpiration或AbsoluteExpirationRelativeToNow),也可以设置缓存的滑动过期时间(SlidingExpiration)</param> public void Set(string key, object value, DistributedCacheEntryOptions distributedCacheEntryOptions) { //通过Json.NET序列化缓存对象为Json字符串 //调用JsonConvert.SerializeObject方法时,设置ReferenceLoopHandling属性为ReferenceLoopHandling.Ignore,来避免Json.NET序列化对象时,因为对象的循环引用而抛出异常 //设置TypeNameHandling属性为TypeNameHandling.All,这样Json.NET序列化对象后的Json字符串中,会包含序列化的类型,这样可以保证Json.NET在反序列化对象时,去读取Json字符串中的序列化类型,从而得到和序列化时相同的对象类型 var stringObject = JsonConvert.SerializeObject(value, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, TypeNameHandling = TypeNameHandling.All }); var bytesObject = Encoding.UTF8.GetBytes(stringObject);//将Json字符串通过UTF-8编码,序列化为字节数组 cache.Set(key, bytesObject, distributedCacheEntryOptions);//将字节数组存入Redis Refresh(key);//刷新Redis } /// <summary> /// 查询键值是否在Redis中存在 /// </summary> /// <param name="key">缓存键</param> /// <returns>true:存在,false:不存在</returns> public bool Exist(string key) { var bytesObject = cache.Get(key);//从Redis中获取键值key的字节数组,如果没获取到,那么会返回null if (bytesObject == null) { return false; } return true; } /// <summary> /// 从Redis中获取键值 /// </summary> /// <typeparam name="T">缓存的类型</typeparam> /// <param name="key">缓存键</param> /// <param name="isExisted">是否获取到键值,true:获取到了,false:键值不存在</param> /// <returns>缓存的对象</returns> public T Get<T>(string key, out bool isExisted) { var bytesObject = cache.Get(key);//从Redis中获取键值key的字节数组,如果没获取到,那么会返回null if (bytesObject == null) { isExisted = false; return default(T); } var stringObject = Encoding.UTF8.GetString(bytesObject);//通过UTF-8编码,将字节数组反序列化为Json字符串 isExisted = true; //通过Json.NET反序列化Json字符串为对象 //调用JsonConvert.DeserializeObject方法时,也设置TypeNameHandling属性为TypeNameHandling.All,这样可以保证Json.NET在反序列化对象时,去读取Json字符串中的序列化类型,从而得到和序列化时相同的对象类型 return JsonConvert.DeserializeObject<T>(stringObject, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }); } /// <summary> /// 从Redis中删除键值,如果键值在Redis中不存在,该方法不会报错,只是什么都不会发生 /// </summary> /// <param name="key">缓存键</param> public void Remove(string key) { cache.Remove(key);//如果键值在Redis中不存在,IDistributedCache.Remove方法不会报错,但是如果传入的参数key为null,则会抛出异常 } /// <summary> /// 从Redis中刷新键值 /// </summary> /// <param name="key">缓存键</param> public void Refresh(string key) { cache.Refresh(key); } } }
Use test
その後、ASP.NET Core で実行します。 MVC プロジェクトで、新しい CacheController を作成し、その Index メソッドで RedisCache クラスの関連メソッドをテストします。public class CacheController : Controller { protected RedisCache redisCache; //由于我们前面在Startup类的ConfigureServices方法中调用了services.AddDistributedRedisCache来注册Redis服务,所以ASP.NET Core MVC会自动依赖注入下面的IDistributedCache cache参数 public CacheController(IDistributedCache cache) { redisCache = new RedisCache(cache); } public IActionResult Index() { bool isExisted; isExisted = redisCache.Exist("abc");//查询键值"abc"是否存在 redisCache.Remove("abc");//删除不存在的键值"abc",不会报错 string key = "Key01";//定义缓存键"Key01" string value = "This is a demo key !";//定义缓存值 redisCache.Set(key, value, new DistributedCacheEntryOptions() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10) });//设置键值"Key01"到Redis,使用绝对过期时间,AbsoluteExpirationRelativeToNow设置为当前系统时间10分钟后过期 //也可以通过AbsoluteExpiration属性来设置绝对过期时间为一个具体的DateTimeOffset时间点 //redisCache.Set(key, value, new DistributedCacheEntryOptions() //{ // AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(10) //});//设置键值"Key01"到Redis,使用绝对过期时间,AbsoluteExpiration设置为当前系统时间10分钟后过期 var getVaue = redisCache.Get<string>(key, out isExisted);//从Redis获取键值"Key01",可以看到getVaue的值为"This is a demo key !" value = "This is a demo key again !";//更改缓存值 redisCache.Set(key, value, new DistributedCacheEntryOptions() { SlidingExpiration = TimeSpan.FromMinutes(10) });//将更改后的键值"Key01"再次缓存到Redis,这次使用滑动过期时间,SlidingExpiration设置为10分钟 getVaue = redisCache.Get<string>(key, out isExisted);//再次从Redis获取键值"Key01",可以看到getVaue的值为"This is a demo key again !" redisCache.Remove(key);//从Redis中删除键值"Key01" return View(); } }
string key = "Key01";//定义缓存键"Key01" string value = "This is a demo key !";//定义缓存值 redisCache.Set(key, value, new DistributedCacheEntryOptions() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(10) });//设置键值"Key01"到Redis,使用绝对过期时间,AbsoluteExpirationRelativeToNow设置为当前系统时间10分钟后过期
以上がRedis を使用した分散キャッシュの実装について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Redisクラスターモードは、シャードを介してRedisインスタンスを複数のサーバーに展開し、スケーラビリティと可用性を向上させます。構造の手順は次のとおりです。異なるポートで奇妙なRedisインスタンスを作成します。 3つのセンチネルインスタンスを作成し、Redisインスタンスを監視し、フェールオーバーを監視します。 Sentinel構成ファイルを構成し、Redisインスタンス情報とフェールオーバー設定の監視を追加します。 Redisインスタンス構成ファイルを構成し、クラスターモードを有効にし、クラスター情報ファイルパスを指定します。各Redisインスタンスの情報を含むnodes.confファイルを作成します。クラスターを起動し、CREATEコマンドを実行してクラスターを作成し、レプリカの数を指定します。クラスターにログインしてクラスター情報コマンドを実行して、クラスターステータスを確認します。作る

Redis指令を使用するには、次の手順が必要です。Redisクライアントを開きます。コマンド(動詞キー値)を入力します。必要なパラメーターを提供します(指示ごとに異なります)。 Enterを押してコマンドを実行します。 Redisは、操作の結果を示す応答を返します(通常はOKまたは-ERR)。

Redisは、単一のスレッドアーキテクチャを使用して、高性能、シンプルさ、一貫性を提供します。 I/Oマルチプレックス、イベントループ、ノンブロッキングI/O、共有メモリを使用して同時性を向上させますが、並行性の制限、単一の障害、および書き込み集約型のワークロードには適していません。

Redisソースコードを理解する最良の方法は、段階的に進むことです。Redisの基本に精通してください。開始点として特定のモジュールまたは機能を選択します。モジュールまたは機能のエントリポイントから始めて、行ごとにコードを表示します。関数コールチェーンを介してコードを表示します。 Redisが使用する基礎となるデータ構造に精通してください。 Redisが使用するアルゴリズムを特定します。

Redisデータをクリアする方法:Flushallコマンドを使用して、すべての重要な値をクリアします。 FlushDBコマンドを使用して、現在選択されているデータベースのキー値をクリアします。 [選択]を使用してデータベースを切り替え、FlushDBを使用して複数のデータベースをクリアします。 DELコマンドを使用して、特定のキーを削除します。 Redis-CLIツールを使用してデータをクリアします。

Redisのすべてのキーを表示するには、3つの方法があります。キーコマンドを使用して、指定されたパターンに一致するすべてのキーを返します。スキャンコマンドを使用してキーを繰り返し、キーのセットを返します。情報コマンドを使用して、キーの総数を取得します。

Redisのキューを読むには、キュー名を取得し、LPOPコマンドを使用して要素を読み、空のキューを処理する必要があります。特定の手順は次のとおりです。キュー名を取得します:「キュー:キュー」などの「キュー:」のプレフィックスで名前を付けます。 LPOPコマンドを使用します。キューのヘッドから要素を排出し、LPOP Queue:My-Queueなどの値を返します。空のキューの処理:キューが空の場合、LPOPはnilを返し、要素を読む前にキューが存在するかどうかを確認できます。

Redisサーバーを起動する手順には、以下が含まれます。オペレーティングシステムに従ってRedisをインストールします。 Redis-Server(Linux/Macos)またはRedis-Server.exe(Windows)を介してRedisサービスを開始します。 Redis-Cli ping(Linux/macos)またはRedis-Cli.exePing(Windows)コマンドを使用して、サービスステータスを確認します。 Redis-Cli、Python、node.jsなどのRedisクライアントを使用して、サーバーにアクセスします。
