首先redis中可以使用的5种数据类型有:String、Hash、List、Set和Zset。
1)Redis支持的5种数据类型分别使用场景如下:
数据类型 | 使用场景 |
String | 比如存储用户登录的session信息;或者我想知道什么时候*一个IP地址(疑似长时间攻击服务器,存在风险的,就需要*),就使用String类型的incrby命令记录访问IP次数,达到一定阈值就* |
Hash |
存储用户信息[id,name,age] 怎么使用呢? 使用Hset(key, field, value)来存,例如:Hset(userKey, id, 101)、Hset(userKey, name, admin)、Hset(userKey, age, 18) ----修改案例---- 比方说,修改用户的年龄,从18改为20: Hget(userKey, age) --> Hset(userKey, age, 20) 那么这时候就有人会问了,为什么不使用String类型来存储呢?请看下面String类型存储的情况: set(userKey, 用户信息的字符串) ,redis对用户信息进行序列化后存进redis --> get(userKey) 获取反序列化后的整个用户的全部信息,我只是要修改年龄,你却返回一堆东西给我,序列化和反序列化要进行IO,你把用户其余无关的信息也获取,是不是增加了IO,那肯定会导致性能有所下降呀,那如果又遇到高并发情况下呢,是不是严重影响系统的性能。 所以,不推荐使用String类型! |
List |
实现最新消息的排行,还可以利用List的push命令,将任务存放到list集合中,同时使用另一个命令pop,将任务从list集合中取出。 Redis可以通过List数据类型来模拟消息队列。例如,电商中的秒杀活动就可以采用这种方式来完成。 |
Set | 记住,特殊之处:可以自动排重(不重复)。比如,微博中将每个人的好友都存进set集合中,这样求两个人的共同好友的操作,我们只需要求交集即可。 |
Zset |
以某一个条件为权重,进行排序。 例如,京东商城的查看某类商品列表(电脑),都会有一个综合推荐排名,还可以按照价格、销量进行排名。 |
2)String类型的使用场景,举例说明
一. 缓存功能
我们都知道,项目中的所有的数据都是从存储层获取的,也就是数据库中。但如果所有的请求都从数据库中获取,会导致系统有很大的压力,因为直接从数据库中获取数据,会涉及到数据库中读写操作,而数据库中读写操作是会耗费系统资源的。所以对于大部分公司来说,系统的架构中都会添加一个缓存层,大部分的请求数据都会先从缓存层中获取,如果缓存层中没有查到数据,在从存储层获取,也就是数据库中。然后在将存储层获取到的数据同步到缓存层中。这样一来,对于大部分请求来说都会从缓存层中查找到,这样就大大降低了存储层的压力。而缓存层Redis是一种解决方案之一。下面我们简单模拟一下用户请求数据的过程。
二. 计数
计数功能在很多网站中都比较常见,最典型的就是页面的播放量。对于一个视频网站来说,由于访问的人数较多,如果每次有人访问,都直接修改数据库的话,那这种大并发量并且频繁的修改数据库的话,一定会对数据库造成较大的压力,极端情况下可能会导致数据库宕机等,并且由于访问量较大,我们在开发时,还要考虑多线程的兼容问题,否则会造成数据的不准确。除此之外,由于访问量很大,也会造成每个用户请求返回的时间变长(请求阻塞),用户访问网站时,可能会显示迟钝等等。
如果使用Redis之后,则可以解决这种情况。首先Redis是将数据保存到内存中的,相比数据库的磁盘IO操作,性能提升较明显。其次Redis(Redis 6.0 版本开始支持多线程了)是单线程架构,我们不用为大并发,而做特殊的多线程处理。其三就是Redis提供了很多支持原子性操作的命令,我们可以直接使用,而不用考虑相关细节。所以用Redis来实现网站或者其它业务的计数功能是比较合适的。但有一点要特别注意,我们将计数的数据保存在Redis中是为了不频繁的执行数据库的修改操作。而数据的最终结果还是要保存在数据库中的(虽然Redis有持久化功能)。所以我们在实际的开发中,可以选择某个时间点(比如夜深人静的凌晨1点左右),在将Redis中的计数数据同步到数据库中,大多数都会采用定时调度的方式,来同步数据,当然也可以考虑其它的计数实现。
三. 共享Session
我们知道在项目开发中Session中保存着用户的登录信息,当用户访问系统时,首先判断该用户的Session中有没有该用户的信息,当然同时还要判断是否超过了Session失效时间。如果有则认为用户已经成功登录过,可以允许继续访问,反之,则提示用户先登录,然后直接跳转到登录。在单一的架构中,上述场景是没有问题的,但是在分布式架构中上述场景就有问题了。我们知道Session是保存在服务端的,也就是说,我们的服务端部署在哪台机器上,Session就保存在哪台机器上。而分布式的方式是将服务端部署到了多台机器上。这就会导致一个问题,虽然用户登录成功了,但是由于负载均衡等原因,给用户提供服务的服务端和给用户登录的服务端,不在一台机器上,这样就会出现:虽然用户登录成功了,但是我们还是会提示用户没有登录。因为除了用户登录那台机器有用户Session信息外,其它的机器没有用户的Session信息,所以会出现上述情况。也就是如下图所示的那样:
既然上述的场景在分布式中有问题,那我就要想办法解决它。解决的方式有很多种,在这里,只介绍一种解决方案,也就是采用Redis解决。当用户登录成功时,我们不再将Session信息保存到本地的服务器中,而是将它保存到Redis中。这样无论哪个服务器先登录成功,对于用户的Session信息只有一份,也就是保存到Redis中的那一份。这样,当其它服务器判断用户是否登录时,都从Redis中进行同步获取Session信息。如果Redis中有用户的Session信息,而表示用户已登录;否则认为用户未登录过,或者登录失败。这样就解决了分布式用户登录的问题。也就是如下图所示:
上述这些都是Redis中String字符串类型的使用场景,但在实际开发中使用场景远远不只这些,而且我们要结合实际业务需求来使用。只要我们熟练的使用Redis中字符串类型的相关命令,就可以解决我们开发中很多复杂的问题。
参考文章:
https://blog.csdn.net/weixin_34187822/article/details/88860161