Redis的几个问题
redis综述
redis是一个基于内存的key-value数据库,是一种非关系型数据库,常用作数据读写中间件(缓存)。支持事务,持久化,分布式锁。
项目中有哪些用到Redis的场景?
一个是新增套餐上传图片的时候,用到了Set数据类型求差的操作,图片上传为了提高用户体验选择了每选定一个图片就上传的策略,这样有可能在新建套餐时存在选定多个图片上传多个图片的情况,存储了一些无效的垃圾图片。为解决这个问题,采用redis在上传图片时将上传的图片名存入一个set集合,在写入数据库时存入另一个集合,再采用定时任务调度工具定时取两个set集合的差值,进行删除垃圾图片。
另一个是用redis存短信验证码,用户登陆和套餐预约需要获取短信验证码。设置key的过期时间为验证码的过期时间。
Redis的数据结构有哪些?
1,String,键值对类型,常用于热点数据缓存,计数器。常用指令set ,get,del,加1,减1,setex key seconds value 指定过期时间
2,hash类型,类似java中的hashMap,常用来存储类似java中对象的数据,一个主体有多个属性,常用指令 hset key field value,hget key field,hdel
3,list类型,类似于linkedList,用于做简单的队列场景,评论这种的。常用指令lpush key value1 [value2] (lpush rpush 代表左添加,右添加),获取数据lrange key star end,lindex key index, llen key,移除数据lpop(rpop)
4,set类型,类似于hashset,与list的区别是无序,不允许重复,查询效率高,可以求交集,取差值等。应用场景是不能重复,对查询效率要求高,求差集,取交集等。常用指令sadd,删除数据srem,有无指定数据sismember,项目中用到的取差集sdiff key1 key2
5,zset类型,有序set,数据结构 key - score1 - number,常用于排行榜场景,因为是有序的。常用指令zadd key score number
Redis为什么是单线程还这么快?
因为Redis是基于内存的key-value数据结构,cpu不是它的瓶颈,一定意义上多线程本质也是单线程,还增加了线程切换的性能损耗。所以redis使用单线程就避免了线程,锁的竞争,减小了性能开销。并且Redis使用多路复用非阻塞式IO的数据通信模式,也提高了系统效率。
Redis读写一致性问题
Redis与数据库数据的同步问题。设置合理的数据过期时间,每次增删改操作数据都同步到Redis。
缓存雪崩,缓存击穿,缓存穿透及解决方案
自行回顾
Redis持久化方式
AOF和RDB,AOF是以写日志的形式持久化数据,将每一个指令都追加到备份文件中,相当于与数据读写同步。而RDB是拍快照的形式持久化,设置时间到时复制,复制时会有较大时间和性能开销,且数据容灾性没有AOF好。
Redis的事务
事务的基本操作 :
开启事务 multi,设定事务的开启位置,此指令执行后,后续的所有指令均加入到事务中。 执行事务 exec,设定事务的结束位置,同时执行事务。与multi成对出现,成对使用 。加入事务的命令暂时进入到任务队列中,并没有立即执行,只有执行exec命令才开始执行。
Redis中的锁:
监视锁:watch key1 [key2] 被监视键的值被其他事务改变时,该事务不能执行。(相当于乐观锁,访问数据时认为别人不会更改数据,不加锁,等更改数据时判断在此期间有没有其他事务修改)
分布式锁:①setnx lock-key value del lock-key (悲观锁,拿不到锁就等待)。死锁解决方案:设置锁过期时间,到期不释放锁锁自动失效(expire locl-key seconds)
②对set指令进行拓展之后,可以用一条set指令合并setnx和expire。
加锁实际上就是在redis中,给Key键设置一个值,为避免死锁,并给定一个过期时间。
SET lock_key value NX PX 5000
其中:
NX 代表只在键不存在时,才对键进行设置操作。
PX 5000 设置键的过期时间为5000毫秒。
Redis删除策略
定时删除,惰性删除,定期删除
Redis淘汰(逐出策略):
设置过期时间的数据中取将过期的,使用最少的,随机删除
所有数据中取使用最少的,随机删除,不删除