1.redis 事务
我做了一个导航站(域名是挂路灯的全拼gualudeng.com),里面精选了各种影视,动漫,黑科技,实用工具,搞笑有趣的站点,动动大家可爱的小手,点进来看看吧,良心站点。
redis的事务是将单条命令入队,序列化执行。是不保证原子性的。即其中一条命令出现逻辑错误,后面的语句仍会执行成功。
multl 开启事务
set k1 1
set k2 2
exec 执行事务
discard 取消事务
2.redis乐观锁
乐观锁需要依靠事务执行
watch k1 监听k1
get k1
multi 开启事务
set k2
exec 如果 k1的值在执行exec之前,被修改了的话。就会执行失败返回空。
失败后的处理是
unwatch k1 解除监听。然后再重新执行一边业务。
3.redis 基本配置文件
protected_mode yes 开启保护模式。如果redis需要远程访问则需要关闭这个配置。
daemonize yes 是否以守护进程运行服务器
logfile "" 日志位置,默认为空不保存。
4.redis 持久化
RDB 模式,保存数据快照 (全量备份)
save 60 1 60秒内有一次修改则备份一次
AOF 模式,增量备份。每秒备份每一条写命令
5.redis 分布式锁
#利用redis可以实现分布式锁,因为redis的读写性能高,可以应对一些高并发场景的资源竞争问题
#注意除了可以用redis实现分布式锁之外,还可以用zookeeper实现。
#伪代码
set key value NX PX 10000
#加锁,并设置一个值,这个值必须要和当前请求的客户端关联。这样才能实现当前客户端只能解自己的锁
#NX当key值不存在的时候才能设置成功值。(别人已经加索了,你就不能加锁成功)
#PX设置过期时间为10秒,可能在业务处理的某个过程中,程序崩溃,不能执行解锁操作。其他客户端不能加锁,形成死锁。所以需要设置过期时间。该语句可以保证,设置值和设置过期时间是原子性的。
#设置锁后需要启动一个后台进程间隔9秒检查锁是否存在,如果存在则续期过期时间。
#可以解决业务逻辑的执行时间大于锁过期时间问题。如果业务逻辑执行时间大于过期时间。会导致另外一个客户端能在当前客户端执行业务的过程中加索成功。
do something #执行业务逻辑
......
......
#执行解锁需要用value值判断当前锁是否是自己加的。是的话再执行解锁操作。判断和解锁是需要保证原子性的。所以会使用到lua脚本。(可能会存在你在判断完过后锁过期了,其他客户端成功加了锁,而导致当前客户端删了别人的锁)
6.redis分布式锁和redis乐观锁的区别,分布式锁不止能锁redis中的数据,还能锁mysql中的数据,以及文件,是锁的一个过程。而乐观锁,只能锁redis中的数据。
7.redis锁的应用场景。乐观锁实现秒杀应用
1.在秒杀前把热数据存到redis中。包括商品信息,秒杀库存量,以及秒杀成功的存放购买者id信息的list
2.一个请求来的时候使用watch 监听库存 numbers
3.读取numbers的值(可以采取读写分离的架构),大于零则开启事务,执行抢购的业务逻辑
4.decr库存减一,list中添加用户信息。然后提交事务,判断提交结果。返回相应信息。
5.可以启用一个异步线程持久化数据到mysql中
8.分布式锁实现秒杀
1.请求到来先读取库存(读写分离)大于零的话尝试加锁,加锁失败可以循环等待(用户量少的话可以),或则直接返回抢购失败(因为秒杀本来就是一个随机的过程)
2.加锁成功,读取库存,库存大于零则开启事务,库存减一,用户购买set插入用户id(可以使用lua脚本)
3.执行完毕解锁
9.redis 缓存问题
1.缓存击穿
缓存击穿是指高并发情况下,某一个点的key失效,而导致所有的请求都到达数据库。导致服务崩溃。解决办法是提高热点数据的缓存时间。还有就是采用分布式锁串行执行到达mysql数据库的请求。
2.缓存穿透
指大量的请求查询了redis中不存在的可以,然后数据库中也不存在的值。(一般是黑客伪造的垃圾数据)导致服务崩溃。可以使用布隆过滤器来判断key是否是真实存在的数据。
3.缓存雪崩
只在同一时间大量的缓存过期,导致请求全部到达数据库。一般是redis宕机的情况,可以采用redis的高可用集群架构。还可以对每一个缓存数据设置不同的过期时间。