redis使用(redis使用注意事项)
本篇文章给大家谈谈redis使用,以及redis使用注意事项对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
Redis 都有哪些应用场景?
缓存:这应该是 Redis 最主要的功能了,也是大型网站型逗必备机制,合理地使用缓樱租祥存不仅可以加 快数据的访问速度,而且能够有效地降低后端数据源的压力。
共享Session:对于一些依赖 session 功能的服务来说,如果需要从单机变成集群的话,可以选择 redis 来统一管理 session。
消息队列系统:消息队列系统可以说是一个大型网站的必备基础组件,因为其具有业务 解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功 能,虽然和专业的消息队列比还不够足够强大,但是对于一般的消息队列功 能基本可以满足。比如在分布式爬虫系脊搏统中,使用 redis 来统一管理 url队列。
分布式锁:在分布式服务中。可以利用Redis的setnx功能来编写分布式的锁,虽然这个可能不是太常用。 当然还有诸如排行榜、点赞功能都可以使用 Redis 来实现,但是 Redis 也不是什么都可以做,比如数据量特别大时,不适合 Redis,我们知道 Redis 是基于内存的,虽然内存很便宜,但是如果你每天的数据量特别大,比如几亿条的用户行为日志数据,用 Redis 来存储的话,成本相当的高。
[img]Redis的基本使用(二) 消息队列
使用消息中间件的时候,并非每次都需要非常专业的消息中间件,假如只有一个消息队列,只有一个消费者,那就没有必要去使用专业的消息中间件,这种情况可以直接使用 Redis 来做消息大敬则队列。
Redis 的消息队列不是特别专业,他没有很多高级特性,适用简单的场景,如果对稿扰于消息可靠性有着极高的追求,那么不适合使用 Redis 做消息队列。
Redis 做消息队列,使用它里边的 List 数据结构就可以实现,使用 lpush/rpush 操作来实现入队,然后使用 lpop/rpop 来实现出队。
在客户端(例如 Java 端),我们会维护一个死循环来不停的从队列中读取消息,并处理,如果队列中有消息,则直
接获取到,如果没有消息,就会陷入死循环,直到下一次有消息进入,这种死循环会造成大量的资源浪费,这个滚棚时候,
可以使用之前讲的 blpop/brpop 。
blpop 阻塞式的弹出,相当于 lpop 的阻塞版。
延迟队列可以通过 zset 来实现,因为 zset 中有一个 score,我们可以把时间作为 score,将 value 存到redis 中,然后通过轮询的方式,去不断的读取消息出来。
首先,如果消息是一个字符串,直接发送即可,如果是一个对象,则需要对对象进行序列化,这里我们
使用 JSON 来实现序列化和反序列化。
首先在项目中,添加 JSON 依赖:
接下来,构造一个消息对象:
接下来封装一个消息队列:
测试:
如何连接redis
本人也是刚开始使用redis,目前接触到的根据业务的不同连接redis的情况有两种:
一:
1、先进到redis安装目录的bin目录下,本人的机器安装在这里,即/data/redis/bin
2、在/data/redis/bin目录下可以发现有一个redis-cli文件,执行该文件后即可进入命令为:./redis-cli,由于有密码,要输入密码,命令为:auth 密码,出现ok的时候即已经进入了redis
1、一般测试在使用redis的时候,使用的命令改告也较少,在此列岩备举常用的几个:
查看所有的key:keys *
查看key的value:get 某核枣明个key
删除某个key: del 某个key
如何使用redis实现分布式锁功能?
由于redis是单线程的且性能很快,所以比较适合做全局分布式锁。
基本流程就是在操作可能某个全局冲突资源的时候,使用一个全局唯一key来判断是否有其腔谨他线程占用了资源,如果有其他线程占用,则报错退出或者循环等待。如果没有其他线程占用,则就可以通过添加分布式锁来占用这个资源,然后再执行后续的任务,在任务执行完成之后,再释放分布式锁,其他线程就可以继续使用这个资源了。
那么通过redis加锁的动作是什么呢?
简单加锁命令:
命令是:setnx
内部的实现机制就是判断这个key位置是不是有数据,没有数据就设置成value返回,有数据就返回一个特殊数值。
但是这里有一个问题是,如果占用资源的线程错误退出了,没有来得及释放分布式锁,这个锁就被永远的占用了
改进版的加锁:
命令是:1. setnx 2. expire
添加分布式锁的同时,添加一个锁锁过期的时间。这样,当加锁线程退出之后,至少等一段时间之后,锁是有机会释放掉的。
这里有一个小问题是,这两个命令是分开执行的,不是原子操作。那么就存在理论上来说,第一个命令执行完之后,就出现错误,来不及执行expire命令的可能,一种办法是自己写lua脚本,可以实现多条命令的原子化执行。一种办法是引用一些开源库。在2.8版本之后,redis为了解决这个问题,提供了官方版的解法,就是命令:set key value nx expireTimeNum ex,将上述两个命令合并成了一个命令。
有了过期时间之后解决了一部分问题,但是也有可能出现锁都过期了,但是中间执行的任务还没有结束,第一个线程还在执行了,第二个线程已经拿到锁开始执行了,那么这时候第一个线程如果执行完成之后,那么就会将第二个线程的锁释放掉了。第二个线程释放锁的时候,要不然出错,要不然是释放的其他线程的锁,这样也会和预期不符。
如果单纯地要解决这个问题的话,可以在设置value的时候使用一个随机数,释放锁的时候,先判断这个随机数是否一致,如果一致再删除锁,否则就退出。但是判断value和删除key也不是一个原子操作,这时候就需要使用lua脚本了。
上面的方案依然不能解决超时释放的问题,依然违背分布式锁的初衷。怎么办了?
解题思路是另外启动一个线程,它的任务就是每隔一段时间判断一下如果发现当前线程的任务快过期了还没有完成,则定雹圆芦期给当前线程的锁续个期。
有个开源库解决了这个问题,它大概率会比你实现得更好一些。这个库就是redisson,非常好记,就是redis的儿子son,连起来就是reidsson,虽然可能不是亲的,但是也足够了。
这个库里面有一个组件是watchdog,直译过来就是看门狗,它的作用就是每隔一段时间判断的。
再继续思考,还有一个更极端的问题是,redis如果是单节点的,它宕机了;或者是主备节点的,但是备份节点还没有来得及同步主节点的数据,主节点拿到锁之后,在同步数据之前就马上宕机了,则也有可能出现锁不住的问题。如果认为这是一个问题,想要解决这个问题,这个问题怎么解决了?
思路是在加锁的时候多加锁几台redis服务器,通常情况下redis部源带署的时候是2n+1台,那么在加锁的时候需要保证过半数服务器加锁成功了,也就是说n+1台服务器。这时候除非整个集群都不可用了,则这个安全性将大幅度提升。
这个问题也有开源库解决了,就是redis红锁。
下一个问题是分布式锁可以重入么?
如果想要实现可重入的分布式锁的话,需要在设置value的时候加上线程信息和加锁次数的信息。但是这是简单的思路,如果加上过期时间等问题之后,可重入锁就可能比较复杂了。
关于redis使用和redis使用注意事项的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。