设为首页 加入收藏

TOP

Redis到底该如何利用?(一)
2019-09-17 19:05:45 】 浏览:47
Tags:Redis 到底 如何 利用

    Redis是个好东西,经过上两个星期的研究和实践,目前正在项目里大规模的替换掉原来的本地内存cache。但是替换过程中却发现,Redis这东西高端,大气上档次,似乎不是我想象里的使用方法。

    在没有深入Redis之前,在我的概念里,缓存,就是key-value。而使用方式肯定不需要改动多少代码,一切都是Get/Set。但是实际用的时候却发现,我错了,不是所有的场景都是简单的Get/Set。也不是所有的数据都适合key-Value,于是有了这个问题,Redis到底该如何使用?我问自己,也向园子里的朋友们求助,希望帮忙解答。当然,这篇文章抛砖引玉,先谈谈我这两周的感悟。

使用场景

    在我的项目里,有一个提供给Autocomplete的功能,数据量大概在几万。这篇文章里我用姓名检索的例子来说明,列表请戳来自Redis作者的Demo。

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

1 public Class User 2 { 3      public string Id{get; set;} 4      public string Name {get; set;} 5  .... 6      public string UserHead {get; set;} 7 }

    系统里需要一个用户的下拉列表,由于数据量大不能一次显示完,于是就加上了一个AutoComplete功能。如果是不用Redis这样的集中式缓存,直接缓存在本机内存里,那么结构很简单如下:

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

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

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

    相当简单,完全不用考虑如何存储,存储的数据结构。但是换到了Redis这些集中式缓存服务之后,咱们再来思考,该如何存储。

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

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

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

    上面的方式逻辑上是没有问题的,编译也可以通过。但是仔细想一想,Redis作为独立的缓存服务和appSever是分开来的,这样的读取方式对redis服务器的IO是个负担,甚至这样的读取比本地内存缓存慢了太多了。

    那如何解决呢?试想key-value的精髓是在于Key,那么对于List来说应该要把item分开来存储。

    方案二:Keys模糊匹配。

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

 1 var redis = ConnectionMultiplexer.Connect("localhost");  2 var db = redis.GetDatabase();  3            
 4 var users = new List<User> {  5     new User{Id = 6, Name = "aaren", Age=10},  6     new User{Id = 7, Name = "issy", Age=11},  7     new User{Id = 8, Name = "janina", Age=13},  8     new User{Id = 9, Name = "karena", Age=14}  9 }; 10 
11 users.ForEach(item => { 12    var key = string.Format("capqueen:user:{0}:{1}", item.Id, item.Name); 13    var value = JsonConvert.SerializeObject(item); 14  db.StringSet(key, value); 15 });

    建立好的缓存如下图所示:

    所有的user都以单独的Key-Value方式存储,那么如何利用Keys搜索呢?我们来看下Redis的Keys命令:

1 KEYS pattern 2 
3 查找所有符合给定模式 pattern 的 key 。 4 
5 KEYS * 匹配数据库中所有 key 。 6 KEYS h?llo 匹配 hello , hallo 和 hxllo 等。 7 KEYS h*llo 匹配 hllo 和 heeeeello 等。 8 KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。 9 特殊符号用 \ 隔开

 

     也就是说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(key
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇从头开始搭建一个Spring boot+Act.. 下一篇.Net缓存管理框架CacheManager

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目