redis
概念:
redis是一个存储key-value的非关系型数据库,数据存储在缓存中,读取速度很快,可以很好的解决每次都去数据库执行数据查询时间消耗问题,数据库支持的并发有限,redis单机可以支持上万并发。
作用:
缓存高频读的数据,减轻数据库的io;
不用redis的话可能只能承受几千的QPS,用了之后单机能达到几万
数据类型:
string,list,set,zset,hash
redis命令:
keys * 查看当前库所有的键
exists <key> 判断是否存在key
del <key> 删除某个键
expire <key> <second> 设置键过期时间 单位是s秒
ttl <key> 查看还有多少秒过期 -1表示用不过期 -2表示已经过期
move <key> <db> 把键移到另一个库下
dbsize 查看数据库key的数量
flushdb 清空当前库
flushall 通杀所有库
持久化:
RDB(redis database)/AOF(append of file)
RDB:指定时间将内存中的数据同步到磁盘,
持久化过程:redis单独创建一个进程来持久化,会先将数据写入临时文件,当上次持久化完成,用临时文件替换上次持久化文件,可能存在最后一次数据丢失。
AOF:根据设定时间将操作指令写到日志里面。
一般两者配合使用,先把RDB的内容搞到redis,然后再通过AOF把剩下的数据搞进去,如果断电也只会丢失最近一段时间AOF没来得及同步的数据。
redis备份的文件:redis.config中设置,dbfileName默认为:dump.rdb。
默认策略:
save 900 1 # 表示900 秒内如果至少有 1 个 key 的值变化,则触发RDB
save 300 10 # 表示300 秒内如果至少有 10 个 key 的值变化,则触发RDB
save 60 10000 # 表示60 秒内如果至少有 10000 个 key 的值变化,则触发RDB
常见问题:
缓存雪崩:redis中大量数据过期,同时大量请求访问,直接请求数据库,导致数据库崩了。
解决方案:过期时间设置随机,防止大量数据同时过期。
缓存击穿:缓存没有数据但是数据库有数据,导致大量请求直接访问数据库,导致数据库挂掉。
解决方案:热点数据不过期,互斥锁
缓存穿透:大量请求恶意访问数据库没有的数据,导致数据库崩掉。
解决方案:参数异常校验,eg:id小于0直接返回,或者第一次访问数据库没有的数据就在缓存创建一条数据,然后设置一个返回值,过期时间短一点。
布隆过滤器,将需要的数据放到过滤器,缓存不存在该数据就去过滤器查,如果有就去DB查然后更新缓存KV,没有直接return,主要是利用高效的算法判断数据是否存 在。缺点:一定的误识别和删除困难。
如何避免:
事前:Redis 高可用,主从+哨兵,Redis cluster,避免全盘崩溃。
事中:本地 ehcache 缓存 + Hystrix 限流+降级,避免MySQL 被打死。
事后:Redis 持久化 RDB+AOF,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。
互斥锁代码实现:
redis默认16个库 默认存到第一个库 也就是0 要修改可以直接yml文件设置database
# redis 配置
redis:
# 地址
host: 119.3.39.172
#host: 172.19.198.12
# 端口,默认为6379
port: 6379
# 密码
password: password
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 默认0 共0-15
database: 7