赞
踩
MySQL
存储引擎、事务、锁、索引
Redis
数据类型、过期策略、淘汰策略、缓存穿透、缓存击穿、缓存雪崩、分布式锁
Spring
Spring IoC、Spring AOP、Spring MVC
事务的特性
事务的隔离性
并发异常:第一类丢失更新、第二类丢失更新、脏读、不可重复读、幻读
隔离级别:Read Uncommitted、Read Committed、Repeatable Read、Serializable
Spring事务管理
范围
类型(InnoDB)
共享锁(S):行级,读取一行;
排他锁(X):行级,更新一行;
意向共享锁(IS):表级,准备加共享锁;
意向排他锁(IX):表级,准备加排他锁;
间隙锁(NK):行级,使用范围条件时,
对范围内不存在的记录加锁。一是为了防止幻读,二是为了满足恢复和复制的需要。
加锁
死锁
悲观锁(数据库)
乐观锁(自定义)
版本号机制
UPDATE … SET …,VERSION=#{version+1} WHERE … AND VERSION=${version}
CAS算法(Compare and swap) 是一种无锁的算法,该算法涉及3个操作数(内存值V、旧值A、新值B),当V等于A时, 采用原子方式用B的值更新V的值。该算法通常采用自旋操作,也叫自旋锁。它的缺点是:
B+Tree(InnoDB)
Redis会把设置了过期时间的key放入一个独立的字典里,在key过期时并不会立刻删除它。
Redis会通过如下两种策略,来删除过期的key:
惰性删除
客户端访问某个key时,Redis会检查该key是否过期,若过期则删除。
定期扫描
Redis默认每秒执行10次过期扫描(配置hz选项),扫描策略如下:
当Redis占用内存超出最大限制(maxmemory)时,可采用如下策略(maxmemory-policy), 让Redis淘汰一些数据,以腾出空间继续提供读写服务:
LRU算法
近似LRU算法(Redis)
场景
解决方案
缓存空对象
存储层未命中后,仍然将空值存入缓存层。 再次访问该数据时,缓存层会直接返回空值。
布隆过滤器
将所有存在的key提前存入布隆过滤器,在访问缓存层之前, 先通过过滤器拦截,若请求的是不存在的key,则直接返回空值。
场景
一份热点数据,它的访问量非常大。在其缓存失效瞬间,大量请求直达存储层,导致服务崩溃。
解决方案
加互斥锁
对数据的访问加互斥锁,当一个线程访问该数据时,其他线程只能等待。
这个线程访问过后,缓存中的数据将被重建,届时其他线程就可以直接从缓存取值。
永不过期
不设置过期时间,所以不会出现上述问题,这是“物理”上的不过期。
为每个value设置逻辑过期时间,当发现该值逻辑过期时,使用单独的线程重建缓存。
场景
由于某些原因,缓存层不能提供服务,导致所有的请求直达存储层,造成存储层宕机。
解决方案
场景
修改时,经常需要先将数据读取到内存,在内存中修改后再存回去。在分布式应用中,可能多个进程 同时执行上述操作,而读取和修改非原子操作,所以会产生冲突。增加分布式锁,可以解决此类问题。
基本原理
实现方式
Redis实现分布式锁的原则
单Redis实例实现分布式锁
获取锁使用命令:
SET resource_name my_random_value NX PX 30000
NX:仅在key不存在时才执行成功。PX:设置锁的自动过期时间。
通过Lua脚本释放锁:
if redis.call(“get”,KEYS[1]) == ARGV[1] then
return redis.call(“del”, KEYS[1])
else return 0 end
可以避免删除别的客户端获取成功的锁: A加锁 -> A阻塞 -> 因超时释放锁 -> B加锁 -> A恢复 -> 释放
多Redis实例实现分布式锁
Redlock算法,该算法有现成的实现,其Java版本的库为Redisson。
Bean的作用域
AOP的术语
完结撒花,感谢老师!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。