项目理解(六)Redis分布式缓存及性能优化

本文探讨了如何利用Redis实现点赞与关注功能,以及优化登录模块。Redis凭借其内存存储、高性能和多种数据结构特性,成为理想的缓存解决方案。通过配置@Configuration和@Bean注解简化Spring容器初始化,实现点赞、点踩功能。同时,文中详细阐述了Redis的RDB和AOF持久化策略。此外,还介绍了Redis在验证码存储、登录凭证管理和用户信息缓存方面的应用,确保系统的高性能和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录
Redis实现点赞与关注
使用Redis优化登录模块


Redis实现点赞与关注

Redis:支持数据类型完善;使用简单;性能好;Redis是一款基于键值对的NoSQL数据库,对于Redis数据库保存的键值对来说,键总是一个字符串对象,而值可以是字符串对象、列表对象、哈希对象、集合对象或有序集合对象:String, hashes, Lists, Sets, Sorted Sets.

Redis将所有的数据都存放在内存中,所以他的读写性能十分惊人;(性能

同时,Redis还可以将内存中的数据以快照或日志的形式保存到硬盘上,以保证数据的安全性。(安全性

其中:快照的形式:RDB的形式,直接把内存的数据存到硬盘上,优点是数据体积小,如果想从硬盘恢复到内存速度快;缺点是比较耗时,做存储的时候可能会产生阻塞,此时在处理其他的业务会影响其他的业务。不适合实时去做,可以几小时做一次的那种;日志的方式:AOF:每执行一个Redis命令就以日志的形式存下来,可以做到实时的存;但是以不断的追加的形式存的,体积较大,占用磁盘空间,且恢复的时候是把存的命令从头到尾再跑一遍,恢复的速度较慢;

访问Redis:

redisTemplate.opsForValue()
redisTemplate.opsForHash()
redisTemplate.opsForList()
redisTemplate.opsForSet()
redisTemplate.opsForZSet()

@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

可以参考Bean重写序列化:https://blog.youkuaiyun.com/lichuangcsdn/article/details/80866253

@Configuration
public class RedisConfig {

/*
* @Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一
* 个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext
* 或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
* */
//实际上,Spring很好的实现了泛型依赖注入<String, Object>
// https://blog.youkuaiyun.com/f641385712/article/details/84679147

    /*
    * StringRedisTemplate与RedisTemplate的区别
    两者的关系是StringRedisTemplate继承RedisTemplate。
    两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,
    RedisTemplate只能管理RedisTemplate中的数据。
    默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。
    StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。
    RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。
    * */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //定义一个bean,方法名为redisTemplate;当声明了这个bean方法,
        // 参数为RedisConnectionFactory,参数也是一个Bean,它会被自动注入进来,被容器装配
        //都配好后,就可以通过redisTemplate访问redis了
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);//template具有了访问数据库的能力

        //写Java程序得到Java类型数据是要存到数据库中,所以要指定一种数据转化的方式

        // 设置key的序列化方式
        template.setKeySerializer(RedisSerializer.string());
        // 设置value的序列化方式
        template.setValueSerializer(RedisSerializer.json());
        // value本身为hash时:设置hash的key的序列化方式
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置hash的value的序列化方式
        template.setHashValueSerializer(RedisSerializer.json());

        template.afterPropertiesSet();//触发生效
        return template;
    }

}

点赞点踩:访问非常频繁;就是一个数量,这样的数据存放到关系型数据的表里,也不方便存储;

RedisKeyUtil类:定义String类型的Key

public class RedisKeyUtil {

    private static final String SPLIT = ":";
    private static final String PREFIX_ENTITY_LIKE = "like:entity";
    private static final String PREFIX_USER_LIKE = "like:user";
    private static final String PREFIX_FOLLOWEE = "followee";
    private static final String PREFIX_FOLLOWER = "follower";
    private static final String PREFIX_KAPTCHA = "kaptcha";
    private static final String PREFIX_TICKET = "ticket";
    private static final String PREFIX_USER = "user";
    private static final String PREFIX_UV = "uv";
    private static final String PREFIX_DAU = "dau";
    private static final String PREFIX_POST = "post";

    //定义一个静态方法
    // 某个实体的赞
    // like:entity:entityType:entityId -> set(userId)
    public static String getEntityLikeKey(int entityType, int entityId) {
        return PREFIX_ENTITY_LIKE + SPLIT + entityType + SPLIT + entityId;
    }

    //某个用户所获得的赞的总数,这里是key的格式,value为总数
    //like:user:userId->int
    public static String getUserLikeKey(int userId){
        return PREFIX_USER_LIKE + SPLIT + userId;
    }

    // 某个用户关注的实体:有序集合,以时间为序
    // followee:userId:entityType -> zset(entityId,now)
    public static String getFolloweeKey(int userId, int entityType) {
        return PREFIX_FOLLOWEE + SPLIT + userId + SPLIT + entityType;
    }

    // 某个实体拥有的粉丝
    // follower:entityType:entityId -> zset(userId,now)
    public static String getFollowerKey(int entityType, int entityId) {
        return PREFIX_FOLLOWER + SPLIT + entityType + SPLIT + entityId;
    }

    // 登录验证码:  kaptcha:owner  其中ower为用户的一个临时凭证
    //每一个key都不同,对应的value为验证码
    public static String getKaptchaKey(String owner) {
        return PREFIX_KAPTCHA + SPLIT + owner;
    }

    // 登录的凭证:   kaptcha:ticket
    public static String getTicketKey(String ticket) {
        return PREFIX_TICKET + SPLIT + ticket;
    }

    // 用户  kaptcha:userId
    public static String getUserKey(int userId) {
        return PREFIX_USER + SPLIT + userId;
    }
    // 单日UV
    public static String getUVKey(String date) {
        return PREFIX_UV + SPLIT + date;
    }

    // 区间UV
    public static String getUVKey(String startDate, String endDate) {
        return PREFIX_UV + SPLIT + startDate + SPLIT + endDate;
    }

    // 单日活跃用户
    public static String getDAUKey(String date) {
        return PREFIX_DAU + SPLIT + date;
    }

    // 区间活跃用户
    public static S
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值