Redis应用之缓存实现-阿里云开发者社区

开发者社区> 游客a74jvhcp7vclg> 正文

Redis应用之缓存实现

简介: Redis的众多应用场景中缓存绝对是频率最高的场景了。本文来介绍下Redis作为缓存要注意的地方。
+关注继续查看


文章目录

   Redis缓存

       1.缓存概述

       2.缓存方式

           2.1不设置过期时间

           2.2设置过期时间

       3.名称解释

           缓存穿透

           缓存雪崩

           缓存击穿

       4.总结

 Redis的众多应用场景中缓存绝对是频率最高的场景了。本文来介绍下Redis作为缓存要注意的地方。

Redis缓存

1.缓存概述

 缓存(Cache)的作用是减少服务器对数据源的访问频率,从而提高数据库的稳定性。访问的流程如下。

image.png

流程图

image.png

代码逻辑

public Goods searchArticleById(Long goodsId){
    Object object = redisTemplate.opsForValue().get(String.valueOf(goodsId));
    if(object != null){// 缓存查询到了结果
        return (Goods)object;
    }
    // 开始查询数据库
    Goods goods = goodsMapper.selectByPrimaryKey(goodsId);
    if(goods!=null){
        // 将结果保存到缓存中
        redisTemplate.opsForValue().set(String.valueOf(goodsId),goods,60,TimeUnit.MINUTES);;
    }
    return goods;
}

2.缓存方式

 缓存中的数据在redis中的存储方式有两种,一种是永久存在,不设置过期时间,第二种是设置过期时间。这两种方式都需要尽可能的保证数据的一致性(和数据源中的数据保持同步)。

2.1不设置过期时间

 当我们将缓存数据的key设置为永久存在时会存在数据同步和内存消耗逐渐增大的情况,解决方式如下:

数据同步:

   禁止直接操作数据源,避免因数据源直接被改动而造成缓存数据不一致的问题

   如果有其他系统操作同一个数据源,这种情况肯定会产生数据不一致的情况。

   系统执行DML操作时,应该将缓存中对应的数据删除。用户下一次相关请求时直接从数据源中获取。

内存消耗:

 随着业务的增多,缓存数据必然会越来越多,所占用的内存也随之增多,系统的压力也会变大,这时一种方式是给key设置过期时间,但是过期时间长短不太好把握,这时我们可以通过设置redis最大内存来实现,并让Redis按照一定的规则淘汰不需要的缓存键,这种方式在redis只作为缓存使用时非常实用。

具体实现方式:修改redis配置文件(redis.conf)中的maxmemory参数既可,限制Redis最大可用内存大小(单位字节),当超出了这个限制时Redis会依据maxmemory-policy参数指定的策略来删除不需要的key直到Redis占用的内存小于指定内存。

image.png

image.png

LRU:(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”

LFU:(Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。

2.2设置过期时间

 对保存到Redis中的key设置过期时间,但同样也会遇到问题,比如过期时间怎么设置,内存资源同样也会过大。

内存资源

 同样需要设置maxmemory来限制redis使用的最大内存和配置maxmemory-policy来指定删除策略。

过期时间设置

 过期时间不要设置统一固定的时间,比如60分钟,这样会造成相同时间点大量缓存被清空,数据库访问量突然增大的情况,我们应该对过期时间设置合理范围内的随机值。比如:采取不同分类商品,缓存不同周期。在同一分类中的商品,加上一个随机因子。这样能尽可能分散缓存过期时间,而且,热门类目(女装)的商品缓存时间长一些,冷门类目(图书)的商品缓存时间短一些,也能节省缓存服务的资源。

public Goods searchArticleById(Long goodsId){
    Object object = redisTemplate.opsForValue().get(String.valueOf(goodsId));
    if(object != null){// 缓存查询到了结果
        return (Goods)object;
    }
    // 开始查询数据库
    Goods goods = goodsMapper.selectByPrimaryKey(goodsId);
    if(goods!=null){
        Random random = new Random();
        // 将结果保存到缓存中
        if(goods.getGoodsCategory().equals("女装")){
            int time = 3600 + random.nextInt(3600);
            // 热门商品
            redisTemplate.opsForValue()
                        .set(String.valueOf(goodsId)
                            ,goods
                            ,time
                            ,TimeUnit.MINUTES);
        }else{
            int time = 600 + random.nextInt(600);
            // 冷门商品
            redisTemplate.opsForValue()
                        .set(String.valueOf(goodsId)
                            ,goods
                            ,time
                            ,TimeUnit.MINUTES);
        }
    }else{
        // 防止缓存穿透
        redisTemplate.opsForValue()
                        .set(String.valueOf(goodsId)
                            ,null
                            ,60
                            ,TimeUnit.MINUTES);
    }
    return goods;
}

3.名称解释

缓存穿透

 缓存穿透,是指查询一个数据库一定不存在的数据。正常的使用缓存流程大致是,数据查询先进行缓存查询,如果key不存在或者key已经过期,再对数据库进行查询,并把查询到的对象,放进缓存。如果数据库查询对象为空,则不放进缓存。

public Goods searchArticleById(Long goodsId){
    Object object = redisTemplate.opsForValue().get(String.valueOf(goodsId));
    if(object != null){// 缓存查询到了结果
        return (Goods)object;
    }
    // 开始查询数据库
    Goods goods = goodsMapper.selectByPrimaryKey(goodsId);
    if(goods!=null){
        // 将结果保存到缓存中
        redisTemplate.opsForValue().set(String.valueOf(goodsId),goods,60,TimeUnit.MINUTES);
    }else{
redisTemplate.opsForValue().set(String.valueOf(goodsId),null,60,TimeUnit.SECONDS);
    }
    return goods;
}

 采用缓存空值的方式,如果从数据库查询的对象为空,也放入缓存,只是设定的缓存过期时间较短,比如设置为60秒。

缓存雪崩

 缓存雪崩,是指在某一个时间段,缓存集中过期失效.解决方式就是上面设置过期时间中使用的方式,灵活设置过期时间。

缓存击穿

 缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。解决方式直接设置为永久key就可以了。mutex key互斥锁可以学习下,但一般情况下用不上!

4.总结

 搞清楚了缓存的这些知识点我们选择就比较清楚了,具体的灵活使用。

   设置Redis最大使用内存是必须的。

   通过不同的策略设置过期时间。

   如果是热点key我们可以直接设置为永久key。


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10072 0
缓存应用--Memcached分布式缓存简介
 一.   什么是Memcached Memcached 是一个高性能的分布式内存 对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象 来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。
1183 0
[地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache
阅读国外的技术博客和技术网站是跟随时代脚步的重要方式,Netflex 有自己的开源门户OSS,更是微服务架构的推崇者,拥有自己的微服务架构技术站,其技术博客中有不少干货,于是在地铁阅读时光里便有了这篇译文。
1029 0
缓存应用--Memcached分布式缓存简介(二)
1 命令行查看状态   很多时候我们需要去查看Memcached 的使用状态,比如Memcached 的运行时间,使用状态等等。在Windows系统中我们可以使用telnet 命令来查看Memcached 的相关运行情况。
676 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13882 0
ASP.NET状缓存Cache的应用-提高数据库读取速度
原文:ASP.NET状缓存Cache的应用-提高数据库读取速度一、 Cache概述       既然缓存中的数据其实是来自数据库的,那么缓存中的数据如何和数据库进行同步呢?一般来说,缓存中应该存放改动不大或者对数据的实时性没有太多要求的数据。
845 0
设计一个移动应用的本地缓存机制 .
http://blog.csdn.net/zhuqilin0/article/details/6653532
477 0
+关注
游客a74jvhcp7vclg
10余年开发架构经验,同时乐于技术分享!
332
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载