分享redis基础知识(三)

90 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情

image.png

redis默认16个库

5中数据类型

String,Hash,List,Set,Stored-Set

String : set name  lisi

Hash:HMSET user_hash zhangsan 21 lisi 22 

List:LPUSH user_list zhangsan lisi wangwu  (秒杀库存1个对应多个用户)

Set:SADD user_set zhangsan lisi wangwu wangwu (不允许重复,且无序)

Stored-Set:ZADD user_zset zhangsan lisi wangwu wangwu (不允许重复,有序)

redis中存放对象可以使用json和二进制,有哪些区别?

二进制只能在java语言使用,json可以跨语言

RDB与AOF同步的区别?

RDB属于全量同步(定时同步),优点:同步效率非常高,数据可能会丢失。

AOF属于增量同步,有点偏向实时,优点:同步效率比较低,最多只会丢失1S的数据。

平衡点:既要效率高也要保证数据不丢失。使用AOF的everysec

redis数据存放在内存里面,有可能会撑爆内存。需要内存淘汰策略,自动驱逐老的数据(不经常使用的数据)。

内存淘汰策略:在redis服务器上设置存放缓存的阈值(100mb)

六种淘汰策略:

noeviction:当内存使用达到阈值的时候,执行命令直接报错

allkeys-lru:在所有的key中,优先移除最近未使用的key。(推荐)

volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。

allkeys-random:在所有的key中,随机移除某个key。

volatile-random:在设置了过期时间的键空间中,随机移除某个key。

volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除。

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

1、定时任务,30分钟后检查该笔订单是否支付。(效率低)

2、根据key的有效期事件回调。

原理:

1、创建订单的时候绑定一个订单token,存放在redis中(有效期30分钟)

key=token; value=订单id

2、对该key绑定过期事件回调

执行我们的回调方法传递token,检查是否支付成功。

1、reids.conf开启key失效时,客户端回调监听的方法

notify-keyspace-events "Ex"

2、监听回调配置+回调方法

@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);

    }



    /**

     * 待支付

     */

    private static final Integer ORDER_STAYPAY = 0;

    /**

     * 失效

     */

    private static final Integer ORDER_INVALID = 2;

    @Autowired

    private OrderMapper orderMapper;



    /**

     * Redis失效事件 key

     *

     * @param message

     * @param pattern

     */

    @Override

    public 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);

        }

    }

}