私のプロジェクトでは、オートコンプリート用に提供されている機能があり、そのデータ量はおそらく数万件に達します。この記事では、名前検索の例を使用して説明しますが、リストについては、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 サイトの他の関連記事を参照してください。