>  기사  >  데이터 베이스  >  레디스를 사용하는 방법

레디스를 사용하는 방법

WBOY
WBOY앞으로
2023-06-03 12:48:001153검색

사용 시나리오

제 프로젝트에는 자동완성 기능을 제공하는데, 데이터 양이 아마 수만개는 될 것 같아요. 이 기사에서는 이름 검색의 예를 사용하여 목록을 보려면 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

이러한 목록에는 모두 사용자 이름이 있습니다. 예를 들어, 우리 시스템에는 다음과 같은 사용자 개체가 있습니다. 🎜rrreee🎜시스템에는 많은 양의 데이터로 인해 사용자의 드롭다운 목록이 필요합니다. , 한꺼번에 표시할 수 없어서 추가합니다. 자동완성 기능이 설치되어 있습니다. 캐시는 로컬 메모리에 직접 저장할 수 있습니다. Redis와 같은 중앙 집중식 캐시를 사용할 필요가 없습니다. 이 캐시 구조는 더 간단합니다🎜rrreee🎜모두 메모리에 있으므로 목록을 직접 저장하면 충분합니다. 다음과 같이 직접 검색할 수도 있습니다. 🎜rrreee🎜매우 간단합니다. 저장 방법이나 저장된 데이터 구조를 고려할 필요가 없습니다. 그러나 Redis와 같은 중앙 집중식 캐싱 서비스로 전환한 후에는 이를 저장하는 방법을 다시 생각해야 합니다. 🎜🎜옵션 1: 유사한 메모리 기반 캐시 구현. 🎜🎜이 기사에 사용된 Redis 링크 라이브러리는 StackOverFlow의 오픈 소스 제품인 StactkExchange.Redis입니다. 🎜rrreee🎜위 방법은 논리적으로 정확하며 컴파일을 통과할 수 있습니다. 하지만 잘 생각해보면 Redis는 독립적인 캐시 서비스로 appSever와 분리되어 있는데, 이런 읽기 방식은 Redis 서버의 IO에 부담을 주고, 심지어 그런 읽기도 로컬 메모리 캐시보다 훨씬 느리다. 🎜🎜그럼 어떻게 해결하나요? 키-값의 본질이 Key에 있다고 상상해 보세요. 따라서 List의 경우 항목을 별도로 저장해야 합니다. 🎜🎜옵션 2: 키 퍼지 일치. 🎜🎜Redis 명령 문서(참조 4 참조)를 훑어본 후 그는 Keys 명령을 발견하고 놀랐고, 이로 인해 즉시 계획을 수정하게 되었습니다. 먼저 검색할 키워드를 키로 설정해야 합니다. 여기서는 키를 "capqueen:user:{id}:{name}"으로 정의합니다. 여기서 {}의 항목은 해당 속성으로 대체되어야 합니다. 안건. 코드는 다음과 같습니다. 🎜rrreee🎜모든 사용자는 별도의 Key-Value 방식으로 저장되는데 Key를 사용하여 검색하는 방법은 무엇인가요? Redis의 Keys 명령을 살펴보겠습니다.🎜rrreee🎜즉, Keys는 간단한 퍼지 일치를 수행할 수 있으므로 여기서 검색은 다음 방법으로 변경될 수 있습니다.🎜rrreee🎜위 코드에 주의하세요. 값은 A json입니다. 변환 효율성을 높이기 위해 먼저 json arry로 처리한 다음 역직렬화합니다. 🎜🎜이 솔루션은 실제로 현재 문제를 해결했습니다. 그러나 Redis 문서에서 다음 구절을 발견했습니다. 🎜🎜KEYS는 매우 빠르지만 대규모 데이터베이스에서 사용하면 특정 key를 데이터 세트에서 사용하려면 대신 Redis의 컬렉션 구조(세트)를 사용하는 것이 좋습니다. 🎜

위 내용은 레디스를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제