Heim >Datenbank >Redis >So verwenden Sie Redis

So verwenden Sie Redis

WBOY
WBOYnach vorne
2023-06-03 12:48:001174Durchsuche

Nutzungsszenario

In meinem Projekt gibt es eine Funktion für Autocomplete, und die Datenmenge beträgt wahrscheinlich Zehntausende. In diesem Artikel verwende ich zur Veranschaulichung das Beispiel des Namensabrufs. Für die Liste klicken Sie bitte auf die Demo des Autors von Redis. Autocomplete的功能,数据量大概在几万。这篇文章里我用姓名检索的例子来说明,列表请戳来自Redis作者的Demo。

在这样的列表里全是用户名,例如我们的系统里有一个用户对象:

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

系统里需要一个用户的下拉列表,由于数据量大不能一次显示完,于是就加上了一个AutoComplete功能。缓存可以在本地内存中直接存储,不必使用像Redis这样的集中式缓存,这样缓存结构会更加简单

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

因为都是在内存里,所以直接存List就可以了,搜索的时候也可以直接的如下:

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

相当简单,完全不用考虑如何存储,存储的数据结构。然而,一旦转向使用Redis这样的集中式缓存服务,我们需要重新考虑如何存储。

方案一:类似内存式的缓存实现。

本文里使用的Redis链接库是StactkExchange.Redis,出自StackOverFlow的开源产品。

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来说应该要把item分开来存储。

方案二:Keys模糊匹配。

在翻阅Redis的命令文档(见参考资料4)后,他惊奇地发现了Keys命令,这让他立刻修改了自己的方案。首先我们需要把要搜索的关键词建立为key,这里我把key定义为 "capqueen:user:{id}:{name}",其中{}内的是要用item对应属性替换的。代码如下:

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);
});

所有的user都以单独的Key-Value方式存储,那么如何利用Keys搜索呢?我们来看下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 。
特殊符号用 \ 隔开

也就是说Keys能够进行简单的模糊匹配,那么我们这里的搜索就可以换成如下的方式:

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());

注意以上的代码里,因为每个value是一个json,为了增加转化时的效率,我先处理成json arry再进行反序列化。

这种方案,确实是解决了我目前的问题,然而我注意到了Redis文档里的一段话:

KEYS 的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的 key

In einer solchen Liste sind es alle Benutzernamen. Beispielsweise gibt es in unserem System ein Benutzerobjekt: #🎜🎜#rrreee#🎜🎜#Das System benötigt ein Drop-. Da die Datenmenge zu groß war, um sie auf einmal anzuzeigen, wurde eine AutoComplete-Funktion hinzugefügt. Der Cache kann direkt im lokalen Speicher gespeichert werden. Es ist nicht erforderlich, einen zentralen Cache wie Redis zu verwenden, daher ist die Cache-Struktur einfacher. Es kann auch direkt wie folgt sein: #🎜🎜#rrreee#🎜🎜# Ganz einfach: Es besteht keine Notwendigkeit, darüber nachzudenken, wie die gespeicherten Daten gespeichert werden sollen. Sobald wir jedoch zu einem zentralen Caching-Dienst wie Redis wechseln, müssen wir die Art und Weise der Speicherung überdenken. #🎜🎜##🎜🎜#Option 1: Ähnliche speicherbasierte Cache-Implementierung. #🎜🎜##🎜🎜#Die in diesem Artikel verwendete Redis-Linkbibliothek ist StactkExchange.Redis, ein Open-Source-Produkt von StackOverFlow. #🎜🎜#rrreee#🎜🎜#Es gibt kein logisches Problem mit der oben genannten Methode und die Kompilierung kann auch erfolgreich sein. Aber wenn Sie darüber nachdenken, ist Redis ein unabhängiger Cache-Dienst und von appSever getrennt. Diese Art des Lesens belastet die E/A des Redis-Servers, und selbst ein solches Lesen ist viel langsamer als der lokale Speichercache. #🎜🎜##🎜🎜#Wie lässt sich das Problem lösen? Stellen Sie sich vor, dass die Essenz des Schlüsselwerts im Schlüssel liegt, daher sollten die Elemente für die Liste separat gespeichert werden. #🎜🎜##🎜🎜#Option 2: Schlüssel-Fuzzy-Matching. #🎜🎜##🎜🎜#Nachdem er die Redis-Befehlsdokumentation durchgeblättert hatte (siehe Referenz 4), war er überrascht, den Keys-Befehl zu finden, was ihn dazu veranlasste, seinen Plan sofort zu ändern. Zuerst müssen wir das zu durchsuchende Schlüsselwort als Schlüssel festlegen. Hier definiere ich den Schlüssel als „capqueen:user:{id}:{name}“, wobei die Elemente in {} durch die entsprechenden Attribute des ersetzt werden sollen Artikel. Der Code lautet wie folgt: #🎜🎜#rrreee#🎜🎜#Alle Benutzer werden in separaten Schlüsselwertmethoden gespeichert. Wie verwendet man also Schlüssel zum Suchen? Werfen wir einen Blick auf den Keys-Befehl von Redis: #🎜🎜#rrreee#🎜🎜#Das heißt, Keys kann einen einfachen Fuzzy-Matching durchführen, daher kann unsere Suche hier in die folgende Methode geändert werden: #🎜🎜#rrreee# 🎜🎜 #Beachten Sie, dass im obigen Code jeder Wert ein JSON ist. Um die Effizienz der Konvertierung zu erhöhen, verarbeite ich ihn zuerst in JSON Arry und deserialisiere ihn dann. #🎜🎜##🎜🎜#Diese Lösung hat tatsächlich mein aktuelles Problem gelöst. Allerdings ist mir eine Passage im Redis-Dokument aufgefallen: #🎜🎜##🎜🎜#KEYS ist sehr schnell, aber in einer Datenbank möglicherweise sehr schnell Wenn Sie einen bestimmten Schlüssel aus einem Datensatz finden müssen, sollten Sie stattdessen besser die Sammlungsstruktur (Satz) von Redis verwenden. #🎜🎜#

Das obige ist der detaillierte Inhalt vonSo verwenden Sie Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen