一.什么是redis?
Redis 是一个基于内存的高性能key-value数据库。 nosql 单线程 单进程的 支持事务
二.redis 数据类型:
string list hash set hset
三.redis的优缺点
优点:
1.速度快,数据存在内存中
2.有丰富的数据类型,应用场景广泛 可用于缓存 消息
缺点:
1.受物理内存的限制
四.redis 应用场景:
1.会话缓存
2.全页缓存
3.队列 提供list 和set 的操作 push pop操作
4.排行榜 计数器
五.为什么redis 把所有数据放到内存中?(为了快的读写速度)
redis 为了最快的读写速度都读到内存中,并通过异步的方式将数据写入磁盘。如果不放入内存中,磁盘的io读写速度会影响redis 性能。
六. redis分布式锁
1.先拿setnx 来争夺锁,抢到之后 再用expire 给锁加一个过期时间防止锁忘记释放
若expire 命令 执行时出错,这个锁就会变成死锁,不被释放
解决方法 :
set 命令有复杂的参数 可以把setnx expire合成一条命令
redis.set(String key, String value, String nxxx, String expx, int time)
,这个set()方法一共有五个形参:
-
第一个为key,我们使用key来当锁,因为key是唯一的。
-
第二个为value,我们传的是requestId,很多童鞋可能不明白,有key作为锁不就够了吗,为什么还要用到value?原因就是我们在上面讲到可靠性时,分布式锁要满足第四个条件解铃还须系铃人,通过给value赋值为requestId,我们就知道这把锁是哪个请求加的了,在解锁的时候就可以有依据。requestId可以使用
UUID.randomUUID().toString()
方法生成。 -
第三个为nxxx,这个参数我们填的是NX,意思是SET IF NOT EXIST,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作;
-
第四个为expx,这个参数我们传的是PX,意思是我们要给这个key加一个过期的设置,具体时间由第五个参数决定。
-
第五个为time,与第四个参数相呼应,代表key的过期时间。
setnx 用法:
setnx key value key不存在的情况下,设置值为value,若key 存在 不进行任何动作
7.keys * 和scan:
假如redis 里面有一亿个key,其中10w 个是以某个固定已知的开头,如何查找出来
可以使用keysz指令查找 但是 redis 是单线程,keys指令会堵塞线程 可以使用scan命令,无堵塞线程(可能会有重复的) 但是花费的时间比keys 长
8.redis 异步队列
一般使用list 结构 作为队列 rpush 生产消息 lpop消费消息,当lpop没有消息的时候,要适当sleep一会在重试
如何不用sleep 用指令blpop,在没有消息的时候,会堵塞住直到消息到来
如何生产一次 消费多次 使用pub/sub 主题订阅者模式 可以实现1:N的消息队列
pub/sub的缺点:在消费者下线的情况下,生产的消息会丢失,
redis 延时队列:
使用sortedset 拿时间戳作为score,消息内容作为key 调用zadd来生产消息,消费者使用zrangebyscore 来获取n秒之前的数据轮询进行处理
9.redis 的同步机制
redis可以使用主从同步,从从同步。
10.redis集群
redis cluster 着眼于扩展性,在单个redis内存不足时,使用cluster进行分片存储
Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
11.redis 缓存雪崩 缓存穿透 缓存击穿
缓存雪崩:(某一时间段,缓存失效)
redis 挂掉,请求都打到mysql上
缓存数据设置相同的过期时间,缓存在同一时间大面积失效,这时很多请求到mysql
解决方法:
redis cluster 和设置过期时间时,加下随机数 大幅度减少缓存在同一时间过期
缓存穿透:
一直请求缓存中不存在的数据,比如id =-1的 大量的请求穿透redis,打到mysql
解决方法:
使用布隆过滤器或者提前拦截不合法的参数
或者查到为空的数据时,也放到缓存中
缓存击穿:
一个key 非常热点,在不停的被访问,当这个key 在失效的瞬间,持续的请求穿破缓存到 mysql
解决方法:
热点key 设置永不过期
来源:oschina
链接:https://my.oschina.net/u/4324735/blog/4816312