Redis事务+分布式锁+持久化策略+淘汰策略

项目开发视频:
SpringCloud微服务开发入门
手把手开发基于SpringBoot的员工管理系统
亿度云盘~Java小白入门实战


前言

本文我们将学习Redis的事务、分布式锁以及持久化策略和淘汰策略。

事务

Redis提供的事务是将多个命令打包,然后一次性、按照先进先出的顺序(FIFO)有序的执行。在执行过程中不会被打断(在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中),当事务队列中的所以命令都被执行(无论成功还是失败)完毕之后,事务才会结束。

事务相关命令

  • multi 启动事务
  • exec 提交事务
  • discard 放弃事务
  • watch 监视一个或多个键,如果有其他客户端修改键的值,事务将失败

事务操作

案例1:开启事务,正常执行,提交事务
Redis事务+分布式锁+持久化策略+淘汰策略_第1张图片
案例2:开启事务,放弃事务,事务中的操作没有执行
Redis事务+分布式锁+持久化策略+淘汰策略_第2张图片
案例3:开始事务,出现了语法错误,提交事务后,操作都没有执行
Redis事务+分布式锁+持久化策略+淘汰策略_第3张图片
案例4:开始事务,出现数值错误(k1是字符串不能递增),提交事务后,其它的操作可以执行
Redis事务+分布式锁+持久化策略+淘汰策略_第4张图片
案例5:监视score键,没有其它客户端修改,事务正常执行
Redis事务+分布式锁+持久化策略+淘汰策略_第5张图片
案例6:监视score键,提交前打开另一个客户端修改score,提交事务后incrby score没有执行
Redis事务+分布式锁+持久化策略+淘汰策略_第6张图片

分布式锁

我们的软件系统经常会遇到并发问题,比如:网络购票,N个用户同时抢购100张票,只能有100个用户抢到,如果不进行处理,可能会出现:一张票卖给A又卖给B的情况。

悲观锁和乐观锁

并发问题一般采用锁机制来解决,分为悲观锁和乐观锁。

  • 悲观锁
    认为当前的资源存在竞争,所以每次获得资源时都会上锁,阻塞住其它线程。
    数据库中的行锁、表锁、读锁、写锁以及Java的synchronized和Lock都属于悲观锁。
    悲观锁会降低系统性能和吞吐量,提高数据的安全性,适用于多写少读的场景。
  • 乐观锁
    认为当前的资源不存在竞争,所以每次获得资源时都不上锁,通过监视数据,提交修改前通过比较数据和原来的值,判断是否有其他并发操作,最后决定修改的成功和失败。
    乐观锁执行效率高,有利于提高系统吞吐量,适用于多读少写的场景。

Redis的watch命令采用的是乐观锁机制,性能很高,适合于作为分布式锁来解决并发问题。

分布式锁操作

模拟购票,核心代码:

@Repository
public class TicketCache{

	Logger logger = Logger.getLogger(TicketCache.class);
    @Autowired
    private RedisTemplate redisTemplate;

	public String buyTicket(){
		//执行购票逻辑
	    Boolean execute = redisTemplate.execute(new SessionCallback() {
	        @Override
	        public Boolean execute(RedisOperations redisOperations) throws DataAccessException {
	            //监视票数
	            redisOperations.watch("ticket_num");
	            //读取票数
	            int num = Integer.parseInt(redisOperations.opsForValue().get("ticket_num").toString());
	            if (num <= 0) {
	                logger.info("票已售完");
	                return false;
	            }
	            //开启事务
	            redisOperations.multi();
	            //修改票数
	            redisOperations.opsForValue().increment("ticket_num", -1);
	            //提交事务
	            List list = redisOperations.exec();
	            //list为空,提交失败
	            if (list == null || list.isEmpty()) {
	                logger.info("购票失败");
	                return false;
	            }
	            logger.info("购票成功" + list.get(0));
	            return true;
	        }
	    });
	    return String.valueOf(execute);
	}
}

Redis持久化

Redis数据保存在内存中,为避免关闭程序后数据的丢失,就需要将数据保存到磁盘文件上。

持久化策略

持久化策略包含

  • AOF:默认每秒对数据进行持久化
  • RDB:按条件触发持久化操作,满足任意一个条件
  1. 900 1 900秒中修改1次
  2. 300 10 300秒中修改10次
  3. 60 10000 60秒中修改10000次

配置方法

可以在redis.conf中配置持久化
如:RDB
Redis事务+分布式锁+持久化策略+淘汰策略_第7张图片
启动AOF的配置

appendonly yes   开启AOF  
appendfsync everysec  每秒保存

选择持久化策略

我们如何选择RDB和AOF呢?视业务场景而定:

  • 允许少量数据丢失,性能要求高,选择RDB
  • 只允许很少数据丢失,选择AOF
  • 几乎不允许数据丢失,选择RDB + AOF

Redis淘汰策略

Redis中的数据太多可能导致内存溢出,Redis会根据情况淘汰一些数据。
Redis的内存上限:64位系统,上限就是内存上限;32位系统,最大是4G
配置最大内存:

max-memory  配置0就是无上限(默认)

淘汰策略

配置淘汰策略

maxmemory-policy

值:

  • noevication(默认)不淘汰
  • allkeys-lru (推荐)使用LRU算法淘汰比较少使用的键
    LRU算法:Least Recently Used 最近最少使用算法,淘汰长期不用的缓存
  • volatile-lru 在过期的键中淘汰较少使用的
  • allkeys-random 在所有键中随机淘汰
  • volatile-random 在过期键中随机淘汰
  • volatile-ttl 在过期键中淘汰存活时间短的键

结束


大家如果需要学习其他Java知识点,戳这里 超详细的Java知识点汇总

你可能感兴趣的:(分布式,redis,缓存,分布式锁,持久化,淘汰策略)