内存淘汰策略

将Redis用作缓存时,如果内存空间用满,就会自动驱逐老的数据。

Redis六种淘汰策略

noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错。
allkeys-lru:在主键空间中,优先移除最近未使用的key。(推荐)
volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。
allkeys-random:在主键空间中,随机移除某个key。
volatile-random:在设置了过期时间的键空间中,随机移除某个key。
volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除。
noeviction:当内存使用达到阈值的时候,执行命令直接报错
allkeys-lru:在所有的key中,优先移除最近未使用的key。(推荐)
volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。
allkeys-random:在所有的key中,随机移除某个key。
volatile-random:在设置了过期时间的键空间中,随机移除某个key。
volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除。

如何配置Redis淘汰策略!
在redis.conf文件中

设置Redis 内存大小的限制,我们可以设置maxmemory ,当数据达到限定大小后,会选择配置的策略淘汰数据
比如:maxmemory 300mb。

通过配置 设置Redis的淘汰策略。比如:maxmemory-policy volatile-lru

Redis中的自动过期机制
实现需求:处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态
实现方案1:
1.使用Redis Key自动过期出发事件通知
2.使用定时任务30分钟后检查
3.按照每分钟轮训检查

使用Redis Key自动过期机制

当我们的key失效时,可以执行我们的客户端回调监听的方法。
需要在Redis中配置:
notify-keyspace-events "Ex"

SpringBoot整合key失效监听

@Configuration
public class RedisListenerConfig {@BeanRedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory(connectionFactory);return container;}
}
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {super(listenerContainer);}/*** 待支付*/private static final Integer ORDER_STAYPAY = 0;/*** 失效*/private static final Integer ORDER_INVALID = 2;@Autowiredprivate OrderMapper orderMapper;/*** Redis失效事件 key** @param message* @param pattern*/@Overridepublic void onMessage(Message message, byte[] pattern) {String expiraKey = message.toString();// 根据key查询 value 如果还还是为待支付状态 将订单改为已经超时~~OrderEntity orderNumber = orderMapper.getOrderNumber(expiraKey);System.out.println(expiraKey);if (orderNumber == null) {return;}if (orderNumber.getOrderStatus().equals(ORDER_STAYPAY)) {// 将订单状态改为已经失效orderMapper.updateOrderStatus(expiraKey, ORDER_INVALID);}}
}
@RestController
public class OrderController {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RedisUtils redisUtils;@RequestMapping("/saveOrder")public String saveOrder() {// 1.生成tokenString orderToken = UUID.randomUUID().toString();String orderId = System.currentTimeMillis() + "";//2. 将该token存放到redis中redisUtils.setString(orderToken, orderId, 5L);OrderEntity orderEntity = new OrderEntity(null, "蚂蚁课堂永久会员", orderId, orderToken);int result = orderMapper.insertOrder(orderEntity);return result > 0 ? "success" : "fail";}
}

Redis事务操作

Multi 开启事务
EXEC 提交事务
Watch 可以监听一个或者多个key,在提交事务之前是否有发生了变化 如果发生边了变化就不会提交事务,没有发生变化才可以提交事务 基于 版本号码 乐观锁 实现
watch name
multi
set name xiaoxiao
exec
Discard 取消提交事务

注意:Redis官方是没有提供回滚方法, 值提供了取消事务。

Redis中本身就是单线程的能够保证线程安全问题。
取消事务跟回滚有什么区别呢?
为什么redis不支持回滚事务,
Mysql中开启了事务,对该行数据上行锁—
Commit 数据可以提交
回滚:对事务取消和行锁都会撤销
Redis没有回滚 单纯取消事务(不提交事务) 不上锁