Redis中的自动过期机制怎么使用

Redis中的自动过期机制

实现需求:处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态

1.使用Redis Key自动过期出发事件通知2.使用定时任务30分钟后检查3.按照每分钟轮训检查

CREATE TABLE `order_number` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_name` varchar(255) DEFAULT NULL,
`order_status` int(11) DEFAULT NULL,
`order_token` varchar(255) DEFAULT NULL,
`order_id` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
一、使用Redis Key自动过期机制

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

【Redis的自动过期机制:让缓存数据时效有保障】

1.打开redis.conf配置文件

vi redis.conf

2. 在配置文件中查找notify-keyspace-events

/notify-keyspace-events

3. 修改为notify-keyspace-events Ex

4.重启redis

二、SpringBoot整合key失效监听@Configuration
public class RedisListenerConfig {
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();

container.setConnectionFactory(connectionFactory);

return container;

}
} @Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);

}

@Resource
private OrderMapper orderMapper;


/**
* 待支付
*/
private static final Integer ORDER_STAYPAY = 0;


/**
* 失效
*/
private static final Integer ORDER_INVALID = 2;


/**
* 使用该方法监听 当我们的key失效的时候执行该方法
*
* @param message
* @param pattern
*/
@Override
public void onMessage(Message message, byte[] pattern) {
String expiraKey = message.toString();

System.out.println("
该key:expiraKey:"
+ expiraKey + "
失效啦~"
);

// 前缀判断 orderToken
OrderEntity orderNumber = orderMapper.getOrderNumber(expiraKey);

if (orderNumber == null) {
return;

}
// 获取订单状态
Integer orderStatus = orderNumber.getOrderStatus();

// 如果该订单状态为待支付的情况下,直接将该订单修改为已经超时
if (orderStatus.equals(ORDER_STAYPAY)) {
orderMapper.updateOrderStatus(expiraKey, ORDER_INVALID);

// 库存加上1
}
}
} @RestController
public class MemberController {
@Autowired
private UserMapper userMapper;


/**
*
* @return
*/
@RequestMapping("
/getListMember"
)
@Cacheable(cacheNames = "
member"
, key = "
'
getListMember'
"
)
public List<
MemberEntity>
getListMember() {
return userMapper.findMemberAll();

}
} @Data
public class OrderEntity {
private Long id;

private String orderName;

/**
* 0 待支付 1 已经支付
*/
private Integer orderStatus;


private String orderToken;

private String orderId;


public OrderEntity(Long id, String orderName, String orderId, String orderToken) {
this.id = id;

this.orderName = orderName;

this.orderId = orderId;

this.orderToken = orderToken;

}
} public interface OrderMapper {

@Insert("
insert into order_number values (null,#{orderName},0,#{orderToken},#{orderId})"
)
int insertOrder(OrderEntity OrderEntity);



@Select("
SELECT ID AS ID ,order_name AS ORDERNAME ,order_status AS orderstatus,order_token as ordertoken,order_id as orderid FROM order_number\n"
+
"
where order_token=#{orderToken};
"
)
OrderEntity getOrderNumber(String orderToken);


@Update("
\n"
+
"
\n"
+
"
update order_number set order_status=#{orderStatus} where order_token=#{orderToken};
"
)
int updateOrderStatus(String orderToken, Integer orderStatus);

}

1.访问addOrder接口

2.查看数据库数据

3. 10s后redis过期,执行回调机制

4.再次查看数据库,状态已被修改



Redis在应用中是一个非常实用的缓存工具,但是缓存都是有时效性的,过期的缓存会占用空间还会导致性能问题,那么Redis是如何实现自动过期的呢?下面为大家详细解析!
【设置过期时间】
Redis中通过设置过期时间来实现自动过期,通过使用expire命令可以将key设置指定秒数后过期,如:expire key 10,表示在10秒后key过期。如果想让这个时间更具体,那么可以使用pexpire命令以毫秒为单位设置key过期时间。
【随机过期】
有些键不是固定的,它们的过期时间应该是随机的,以防止它们同时过期造成缓存性能问题。Redis提供了一种简单的解决方案,即使用randomkey命令随机获取一个键,判断其过期时间是否已到。如果到期了就将其删除。
【惰性删除】
Redis的自动过期机制是惰性的,没必要每次获取key时都去检查其是否过期了,这会产生很大的开销。因此,Redis使用的是惰性删除机制,当获取某个key时发现该key已过期,才真正从内存中删除它。同时,Redis还会监控一些未使用的过期key,当内存不足时,会优先删除这些key以节省内存。
【注意事项】
尽管Redis的自动过期机制非常实用,但也存在一些需要注意的问题。第一,当key被重新设置为其他值时,之前的过期时间会被清除。第二,如果想要在有限的时间内获取某些key的值,可以使用mget命令一次性获取这些key的值,而不是多次进行get操作。
总之,Redis自动过期机制的使用可以让我们在缓存数据时效上更加有保障,同时也要注意缓存的时效,避免过期的数据污染内存空间,对应用程序产生性能问题。