Redisの使い方

WBOY
WBOY転載
2023-06-03 12:48:001174ブラウズ

利用シナリオ

私のプロジェクトでは、オートコンプリート用に提供されている機能があり、そのデータ量はおそらく数万件に達します。この記事では、名前検索の例を使用して説明しますが、リストについては、Redis の作者によるデモをクリックしてください。

このようなリストはユーザー名でいっぱいです。たとえば、システムにユーザー オブジェクトがあります:

public Class User
{     public string Id{get; set;}  
     public string Name {get; set;}
     ....     public string UserHead {get; set;}    
}

システムにはユーザーのドロップダウン リストが必要ですが、これは使用できません。データ量が多いため一度表示されるためオートコンプリート機能を追加しました。キャッシュはローカル メモリに直接保存できます。Redis のような集中キャッシュを使用する必要がないため、キャッシュ構造が単純になります。

var users = new List<User>{...};//读到一个用户列表MemoryCache.Set("capqueen:users", users);//放入内存//读取var users = MemoryCache.Get<List<User>>("capqueen:users");

すべてがメモリ内にあるため、直接リストする 検索する場合

var findUsers = users.Where(user => user.Name.StartWith("A")).ToList();例如输入的字符是 “A“

のように直接リストすることもできます 非常に簡単で、保存方法や保存されるデータ構造を考慮する必要はありません。ただし、Redis のような集中キャッシュ サービスに移行したら、その保存方法を再考する必要があります。

オプション 1: 同様のメモリベースのキャッシュ実装。

この記事で使用されている Redis リンク ライブラリは、StackOverFlow のオープン ソース製品である StactkExchange.Redis です。

var db = redis.GetDataBase();//获取0数据库var usersJson = JsonConvert.SerializeObject(users)//序列化db.StringSet("capqueen:users", usersJson);//存储var usersString = db.StringGet("capqueen:users");
var userList = JsonConvert.DeserializeObject<List<User>>(users);//反序列化

上記の方法には論理的な問題はなく、コンパイルは成功します。しかし、よく考えてみると、Redis は独立したキャッシュ サービスであり、appSever とは切り離されており、このような読み取り方法は Redis サーバーの IO に負担がかかり、さらにその読み取りでもローカル メモリ キャッシュよりもはるかに遅くなります。

どうすれば解決できますか? Key-Value の本質は Key にあるため、List の場合は項目を個別に保存する必要があると考えてください。

オプション 2: キーのあいまい一致。

Redis コマンドのドキュメント (参考資料 4 を参照) を閲覧した後、Keys コマンドを見つけて驚き、すぐに計画を変更しました。まず、検索するキーワードをキーとして設定する必要があります。ここではキーを「capqueen:user:{id}:{name}」として定義します。ここで、{} 内の項目は、対応する属性に置き換える必要があります。アイテム。コードは次のとおりです。

var redis = ConnectionMultiplexer.Connect("localhost");var db = redis.GetDatabase();           
var users = new List<User> { new User{Id = 6, Name = "aaren", Age=10},    new User{Id = 7, Name = "issy", Age=11},    new User{Id = 8, Name = "janina", Age=13},    new User{Id = 9, Name = "karena", Age=14}
};

users.ForEach(item => { 
   var key = string.Format("capqueen:user:{0}:{1}", item.Id, item.Name);   var value = JsonConvert.SerializeObject(item);
   db.StringSet(key, value);
});

すべてのユーザーは個別の Key-Value メソッドに保存されているため、キーを使用して検索するにはどうすればよいでしょうか? Redis の Keys コマンドを見てみましょう:

KEYS pattern

查找所有符合给定模式 pattern 的 key 。

KEYS * 匹配数据库中所有 key 。
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
KEYS h*llo 匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。
特殊符号用 \ 隔开

つまり、Key は単純なあいまい一致を実行できるため、ここでの検索は次の方法に変更できます:

var redis = ConnectionMultiplexer.Connect("192.168.10.178");var db = redis.GetDatabase();var server = redis.GetServer("192.168.10.178", 6379);var keys = server.Keys(pattern: "capqueen:user:*:a*");var values = db.StringGet(keys.ToArray());//反序列化var jsonValues = new StringBuilder("[");
values.ToList().ForEach(item => jsonValues.Append(item).Append(","));
jsonValues.Append("]");var userList = JsonConvert.DeserializeObject<List<User>>(jsonValues.ToString());

上記のコードでは、各値が json なので、変換効率を上げるために、まず json arry に加工してからデシリアライズしています。

このソリューションで現在の問題は実際に解決されましたが、Redis ドキュメントの一節に気付きました:

KEYS は非常に高速ですが、大規模なデータベースで使用すると依然としてパフォーマンスの問題が発生する可能性があります。データセットから特定の key を見つける必要がある場合は、代わりに Redis のセット構造 (set) を使用することをお勧めします。

以上がRedisの使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。