IT评测·应用市场-qidao123.com技术社区

标题: 《Redis内存淘汰策略及分布式锁应用详解》 [打印本页]

作者: 张春    时间: 2024-11-14 06:25
标题: 《Redis内存淘汰策略及分布式锁应用详解》
Redis内存淘汰策略及分布式锁应用详解

Redis内存淘汰策略

淘汰策略类型

Redis提供了多种内存淘汰策略,用于管理当内存使用到达上限时怎样处理数据。以下是六种常见的淘汰策略:
设置方法

要设置Redis的内存淘汰策略,起首必要在redis.conf文件中设置最大内存限定,例如:
  1. maxmemory 300mb
复制代码
然后,指定内存淘汰策略:
  1. maxmemory-policy allkeys-lru
复制代码
Redis中的主动逾期机制与订单逾期主动取消

主动逾期机制

Redis允许为键设置一个生存时间(TTL),一旦键逾期,它会被主动删除。这一特性可以用来实现诸如订单逾期主动取消的功能。
实现方案

示例:Spring Boot整合Redis键逾期监听

假设有一个订单表order_number,当订单30分钟内未付出时,应主动将订单状态更改为已取消。
表结构

  1. CREATE TABLE `order_number` (
  2.   `id` int(11) NOT NULL AUTO_INCREMENT,
  3.   `order_name` varchar(255) DEFAULT NULL,
  4.   `order_status` int(11) DEFAULT NULL,
  5.   `order_token` varchar(255) DEFAULT NULL,
  6.   `order_id` varchar(255) DEFAULT NULL,
  7.   PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
复制代码
Redis设置

在redis.conf中启用键逾期通知:
  1. notify-keyspace-events "Ex"
复制代码
Spring Boot设置

  1. @Configuration
  2. public class RedisListenerConfig {
  3.     @Bean
  4.     RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
  5.         RedisMessageListenerContainer container = new RedisMessageListenerContainer();
  6.         container.setConnectionFactory(connectionFactory);
  7.         return container;
  8.     }
  9. }
  10. @Component
  11. public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
  12.     public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
  13.         super(listenerContainer);
  14.     }
  15.     private static final Integer ORDER_STAYPAY = 0;
  16.     private static final Integer ORDER_INVALID = 2;
  17.     @Autowired
  18.     private OrderMapper orderMapper;
  19.     @Override
  20.     public void onMessage(Message message, byte[] pattern) {
  21.         String expiredKey = message.toString();
  22.         OrderEntity order = orderMapper.getOrderNumber(expiredKey);
  23.         if (order != null && order.getOrderStatus().equals(ORDER_STAYPAY)) {
  24.             orderMapper.updateOrderStatus(expiredKey, ORDER_INVALID);
  25.         }
  26.     }
  27. }
复制代码
控制器

  1. @RestController
  2. public class OrderController {
  3.     @Autowired
  4.     private OrderMapper orderMapper;
  5.     @Autowired
  6.     private RedisUtils redisUtils;
  7.     @RequestMapping("/saveOrder")
  8.     public String saveOrder() {
  9.         String orderToken = UUID.randomUUID().toString();
  10.         String orderId = System.currentTimeMillis() + "";
  11.         redisUtils.setString(orderToken, orderId, 30L); // 30分钟
  12.         OrderEntity orderEntity = new OrderEntity(null, "蚂蚁课堂永久会员", orderId, orderToken);
  13.         int result = orderMapper.insertOrder(orderEntity);
  14.         return result > 0 ? "success" : "fail";
  15.     }
  16. }
复制代码
Redis事件操作

Redis事件通过MULTI、EXEC、WATCH和DISCARD命令来实现。事件确保一系列命令要么全部执行,要么都不执行,但Redis并不支持事件回滚。
事件与回滚的区别


Redis实现分布式锁

分布式锁原理

分布式锁是一种在分布式体系中实现互斥访问共享资源的机制。Redis通过SETNX命令实现分布式锁,该命令只有在键不存在时才会设置键。
核心代码示例

  1. public class RedisUtil {
  2.     private static String IP = "192.168.212.148";
  3.     private static int PORT = 6379;
  4.     private static int MAX_ACTIVE = 100;
  5.     private static int MAX_IDLE = 20;
  6.     private static int MAX_WAIT = 3000;
  7.     private static int TIMEOUT = 3000;
  8.     private static boolean TEST_ON_BORROW = true;
  9.     private static boolean TEST_ON_RETURN = true;
  10.     private static JedisPool jedisPool = null;
  11.     public final static int EXRP_HOUR = 60 * 60;
  12.     public final static int EXRP_DAY = 60 * 60 * 24;
  13.     public final static int EXRP_MONTH = 60 * 60 * 24 * 30;
  14.     private static void initialPool() {
  15.         JedisPoolConfig config = new JedisPoolConfig();
  16.         config.setMaxTotal(MAX_ACTIVE);
  17.         config.setMaxIdle(MAX_IDLE);
  18.         config.setMaxWaitMillis(MAX_WAIT);
  19.         config.setTestOnBorrow(TEST_ON_BORROW);
  20.         jedisPool = new JedisPool(config, IP, PORT, TIMEOUT, "123456");
  21.     }
  22.     private static synchronized void poolInit() {
  23.         if (jedisPool == null) {
  24.             initialPool();
  25.         }
  26.     }
  27.     public synchronized static Jedis getJedis() {
  28.         if (jedisPool == null) {
  29.             poolInit();
  30.         }
  31.         return jedisPool.getResource();
  32.     }
  33.     public static void returnResource(Jedis jedis) {
  34.         if (jedis != null && jedisPool != null) {
  35.             jedisPool.returnResource(jedis);
  36.         }
  37.     }
  38.     public static Long sadd(String key, String... members) {
  39.         Jedis jedis = null;
  40.         Long res = null;
  41.         try {
  42.             jedis = getJedis();
  43.             res = jedis.sadd(key, members);
  44.         } catch (Exception e) {
  45.             e.printStackTrace();
  46.         } finally {
  47.             returnResource(jedis);
  48.         }
  49.         return res;
  50.     }
  51. }
复制代码
应用场景



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4