Redis官方文档
http://redisdoc.com/
redis for windows
https://github.com/tporadowski/redis/releases
缓存穿透
1.定义
缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,
缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。
2.造成缓存穿透的原因
业务自身代码或者数据出现问题
一些恶意攻击、爬虫等造成大量空命中
3.解决方法
缓存空对象
空值做缓存,即缓存层中存了更多的键,这就需要更多的内存空间 ,可以对其设置一个较短的过期时间,让其自动清除。
优点是实时性高,代码维护简单。
布隆过滤器拦截
如果布隆过滤器认为某个键 不存在,那么就不会访问存储层。
适用于数据命中不高,数据相对固定实时性低(通常是数据集较大)的应用场景,代码维护较为复杂,但是缓存空间占用少。
缓存雪崩
描述:
缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库
解决方案:
- 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
- 如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中。
- 设置热点数据永远不过期。
热点 key 的重建
1.热点key需要重建的原因
当前 key 是一个热点 key( 例如一个热门的娱乐新闻),并发量非常大。
重建缓存不能在短时间完成,可能是一个复杂计算,例如复杂的 SQL、多次 IO、多个依赖等。
2.解决思路
减少重建缓存的次数
数据尽可能一致
较少的潜在危险
3.解决方法
互斥锁 (mutex key)
只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可
可使用 Redis 的 setnx 命令实现该功能。
永远不过期
物理”不过期:没有设置过期时间,所以不会出现热点 key 过期后产生的问题。
为每个 value 设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去构建缓存。
缓存击穿
热点键, 在高并发时缓存失效的瞬间高并发的访问持续着, 导致缓存被击穿, 直接高并发的访问了数据库的情况
加个分布式锁 SETNX(set if not exists), 同一时间访问指定键生成数据缓存后, 删除该锁结束访问
Redis五种数据类型
字符串string:
字符串类型是Redis中最为基础的数据存储类型,是一个由字节组成的序列,他在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据货Json对象描述信息等,是标准的key-value,一般来存字符串,整数和浮点数。Value最多可以容纳的数据长度为512MB
应用场景:很常见的场景用于统计网站访问数量,当前在线人数等。incr命令(++操作)
列表list:
Redis的列表允许用户从序列的两端推入或者弹出元素,列表由多个字符串值组成的有序可重复的序列,是链表结构,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。List中可以包含的最大元素数量是4294967295。
应用场景:1.最新消息排行榜。2.消息队列,以完成多程序之间的消息交换。可以用push操作将任务存在list中(生产者),然后线程在用pop操作将任务取出进行执行。(消费者)
散列hash:
Redis中的散列可以看成具有String key和String value的map容器,可以将多个key-value存储到一个key中。每一个Hash可以存储4294967295个键值对。
应用场景:例如存储、读取、修改用户属性(name,age,pwd等)
集合set:
Redis的集合是无序不可重复的,和列表一样,在执行插入和删除和判断是否存在某元素时,效率是很高的。集合最大的优势在于可以进行交集并集差集操作。Set可包含的最大元素数量是4294967295。
应用场景:1.利用交集求共同好友。2.利用唯一性,可以统计访问网站的所有独立IP。3.好友推荐的时候根据tag求交集,大于某个threshold(临界值的)就可以推荐。
有序集合sorted set:
和set很像,都是字符串的集合,都不允许重复的成员出现在一个set中。他们之间差别在于有序集合中每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。尽管有序集合中的成员必须是唯一的,但是分数(score)却可以重复。
应用场景:可以用于一个大型在线游戏的积分排行榜,每当玩家的分数发生变化时,可以执行zadd更新玩家分数(score),此后在通过zrange获取几分top ten的用户信息。
最后,还有个对key的通用操作,所有的数据类型都可以使用的
交集SINTER
并集SUNION
SDIFF 以set1为标准,set1-(set2+set3) 减去后,剩下的set1剩下的元素
防止在加完锁,刚开始设置时间的时候服务宕机了,造成的死锁问题,将加锁和设置时间作为一个原子的操作
高并发情境下锁永久失效的问题
加唯一标志
创建并注入redisson实例
抽奖
如何解决高并发情况下商品减库存的效率
使用分段库存 (多个线程对同一个商品不同的库存段执行减库存操作)