目录

2.3.4.1 大型互联网高并发缓存架构

1、Redis数据失效导致的雪崩

2、redis数据失效的场景

3、缓存雪崩解决方案

    3.1、Semaphore信号量限流

    3.2、容错降级

4、缓存击穿场景重现

        4.1、解决缓存击穿思路

    4.2、Bloom filter(布隆过滤器)

    4.3、自研布隆过滤器

5、Java应用层-自定义缓存注解

    5.1、元注解

    5.2、注解annotation的应用

2.3.4.2 网易后端架构中缓存方面设计


2.3.4.1 大型互联网高并发缓存架构

1、Redis数据失效导致的雪崩

        因为缓存失效,从而导致大量请求需要访问数据库。
    1、大量请求,导致数据库处理不过来,整个系统依赖数据库的功能全部崩溃。
    2、单系统挂掉,其他依赖于该系统的应用也会出现不稳定甚至崩溃。

2.3.4 缓存架构最佳实践

2、redis数据失效的场景

    1、数据淘汰(LRU/LFU)
    2、数据过期expire
    3、服务重启(宕机/升级)

2.3.4 缓存架构最佳实践

3、缓存雪崩解决方案

    1、对数据库访问限流:信号量控制并发
    2、容错降级:返回异常码
    3、针对内存不足:采用redis集群方案

    3.1、Semaphore信号量限流

        J.U.C包重要的并发编程工具类,又称“信号量”,控制多个线程争抢许可。
        核心方法:
            acquire:获取一个许可,如果没有就等待
            release:释放一个许可
        典型场景:
            代码并发处理限流
        测试运行代码本地地址:E:\meWork\study\project\subject-2\subject-2-cache\cache-stampeding\src\test\java\com\study\cache\stampeding\CacheStampedingApplicationTests.java
        测试之前需要准备环境
            1、先安装:rebloom
                $ git clone git://github.com/RedisLabsModules/rebloom
                $ cd rebloom
                $ make
                #容量100万, 容错率万分之一, 占用空间是4m
                然后启动redis:src/redis-server conf/redis.conf --loadmodule /root/rebloom/redisbloom.so INITIAL_SIZE 1000000   ERROR_RATE 0.0001
                rebloom安装参考地址:https://blog.csdn.net/zhaoyu_nb/article/details/90408036
            2、建表
            CREATE TABLE `goods` (
              `id` int(11) DEFAULT NULL,
              `quantity` varchar(255) DEFAULT NULL,
              `name` varchar(255) DEFAULT NULL,
              `price` varchar(255) DEFAULT NULL COMMENT '商品'
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    3.2、容错降级

        提示网络不给力,请确保网络连接正常后再重试
解决缓存击穿思路

2.3.4 缓存架构最佳实践

4、缓存击穿场景重现

    查询必然不存在的数据,请求透过redis,直击数据库。

        4.1、解决缓存击穿思路

        查询之前先判断目标数据是否存在,不存在的直接忽略。
            (将流量拦截于缓存和数据库之前)

    4.2、Bloom filter(布隆过滤器)

            布隆过滤器是1970年由布隆提出的。
            实际上是一个很长的二进制数组一系列hash函数
            布隆过滤器可以用于检索一个元素是否在一个集合中
        布隆过滤器并非拦截所有请求,意在将缓存击穿控制在一定的量!!!
        目的:减少内存占用
        方式:不保存所有ID信息,只在内存中做一个标记
        优点:内存空间占用少、空间效率和查询时间都比一般的算法要好得多
        缺点:不能精准过滤、是有一定的误识别率和删除困难、需要不断维护,带来新的工作
            (布隆过滤器判断不存在,100%不存在,判断存在,则可能不存在【hash重复,导致不存在的元素可能会被判断为存在】)
    1、二进制数组构建过程
        1、加载符合条件的记录
        2、计算每条元素的hash值
        3、计算hash值对应二进制数组的位置
        4、将对应位置的值改为1
    2、查找元素是否存在的过程
        1、计算元素的hash值
        2、计算hash值对应二进制数组的位置
        3、找到数组中对应位置的值,0代表不存在,1代表存在

2.3.4 缓存架构最佳实践

    4.3、自研布隆过滤器

        利用redis特性和命令:bitmaps(setbit设置指定位置的值、getbit获取值)
        可以理解为这是redis自带的二进制数组特性。
        数组构建:加载符合条件的记录,并将每一条记录对应的bitmaps位置设值为1

5、Java应用层-自定义缓存注解

    5.1、元注解

        Retention:定义注解的生命周期,可选值为(source、class、runtime)
        Documented:文档化注解,会被javadoc工具文档化
        Inherited:注解是自动继承的,想让一个类和它的子类都包含某个注解,就可以使用它来修饰这个注解
        Target:表示可以用来修饰类、接口、注解类型、枚举类型
        ......
        method:可以用来修改时方法
        field:可以用来修饰属性(包括枚举常量)
        constructor:可以用来修饰构造器
        local_variable:可用来修饰局部变量

    5.2、注解annotation的应用

        1、创建注解:public @interface AnnotationName{}
        2、元注解(描述注解的一种方式)
            @Retention:定义注解的生命周期【source -> class -> runtime】
            @Documented:文档注解,会被javadoc工具文档化
            @Inherited:是否让子类继承该注解
            @Target:描述注解的应用范围
                TYPE:可以用来修饰类、接口、注解类型、枚举类型
                Package:可以用来修饰包
                parameter:可以用来修饰参数
                annotation_type:可以用来修饰注解类型
                method:可以用来修饰方法
                field:可以用来修饰属性(包括枚举常量)
                constructor:可以用来修饰构造器
                local_variable:可用来修饰局部变量

具体代码地址:E:\meWork\study\project\subject-2\subject-2-cache\cache-stampeding\src\main\java\com\study\cache\stampeding\annotations\CoustomCacheAspect.java

2.3.4 缓存架构最佳实践

2.3.4.2 网易后端架构中缓存方面设计

相关文章: