• 缓存问题及解决方案


    缓存问题及解决方案

    缓存雪崩

    同一时间大面积缓存失效,大量请求落到数据库上

    解决

    • 缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效

    缓存穿透

    请求缓存不存在的数据,然请求穿透缓存到数据库,通常是黑客攻击

    解决

    • 采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤
    • 访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间
    • 采用签名验证提交数据

    缓存击穿

    缓存过期的一刻,同时有大量的请求,由于缓存失效,导致请求都落到DB

    解决

    【Redis】入门

     

    Redis概述

     Redis是一个开源的、基于内存的数据结构存储器,可以用作数据库、缓存和消息中间件

    Redis最常用的功能

    • 缓存
    • 分布式锁
     本文介绍使用环境
    • Windows 10

    • Redis 3.0.504

    如何安装Redis就不做介绍,若不想安装Redis环境,可以使用try redis尝试Redis功能
    CMD 启动 Redis,打开Reids目录,执行下面命令,出现下面图片代表启动成功
    redis-server redis.windows.conf

    Redis常用数据结构

    字符串(String)

    用途

    • 存放字符串/数字
    • 常规key-value缓存应用
    • 常规计数:订单数,商品数
    常用命令用途
    set key value 设置指定 key 的值
    get key 获取指定key的值
    decr key 将指定的key的值递减1,若设置的值不是数字,报错
    incr key 将指定的key的值递增1,若设置的值不是数字,报错
    mget key1 [key2] 获取指定的key,返回多个值

    哈希(Hash)

    用途

    • hash 特别适合用于存储对象(用户信息,商品信息)
    • 可以修改/读取对象某个值
    常用命令用途
    hset key field value 设置单个对象值
    hget key field value 获取的那个对象值
    hmset key field1 value [field2 value2] 设置对象多个字段值
    hmget 获取对象多个值 , 返回列表
    hgetall 获取指定key对象字段和值

     

    列表(List)

    用途

    • 双向链表 ,支持反向查找和遍历
    • 可以添加重复数据
    • 适合存放消息列表,产品列表,订单列表等
    常用命令用途
    lpush key value 向链表左边推送值
    rpush key value 向链表右边推送值
    lpop key 链表的左边弹出值
    rpop key 链表的右边弹出值
    lrange key start end 链表左边指定范围内的元素 , 多用于分页
    llen key 获取链表长度

     

    集合(Set)

    用途

    • 跟列表类似,集合会去重复
    常用命令用途
    sadd key value 添加一个元素
    spop key value 随机返回一个元素
    smembers key 返回集合所有成员
    sunion key1 key2 返回所有给定集合的并集

    有序集合(Sorted Set)

     用途

    • 集合中的元素能够按score进行有序排列
    • 多用于排名数据
    • score 相同情况下,按字典键值排序
    常用命令用途
    zadd key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数
    zrange key start end 返回有序集合指定范围数据
    zrem key member 移除指定成员
    zcard key 获取集合成员数

    Redis删除过期数据策略

    Redis删除过期数据有两种机制

    1. 定期删除 :redis默认是每隔 100ms 就随机抽取过期的数据删除

    2. 惰性删除 : 访问数据的时候检查数据是否过期

    Redis内存淘汰机制

    当遇到写入数据的时候内存不够,Redis有下面几种机制来决定如何操作

    方式说明
    volatile-lru 从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
    volatile-ttl 从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
    volatile-random 从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
    allkeys-lru 当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key
    allkeys-random 从数据集(server.db[i].dict)中任意选择数据淘汰
    noeviction 禁止删除,若超出内存报错
    volatile-lfu 从已设置过期时间的数据集挑选使用频率最低的数据淘汰(Redis5.0 以后才有)
    allkeys-lfu 从数据集中挑选使用频率最低的数据淘汰(Redis5.0 以后才有)

    在配置文件里面打开maxmemory-policy配置项,默认是:noeviction

    通常情况配合maxmemory配置设置最大内存使用

    Redis持久化机制

    Redis支持两种持久化方式

    快照(snapshotting)持久化(RDB)

    • Redis可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本
    • Redis默认采用的持久化方式
    • 配置多个save配置项指定触发创建副本条件,例:save 900 1 , 900秒内至少一个Key发生变化触发创建快照
    • 缺点:若没达到触发条件,数据容易丢失

    AOF(append-only file)持久化

    • 开启AOF持久化后,根据选择的方式写入AOF文件中
    • 配置appendfsync 配置项,配置同步频率
    • 缺点:可能经常发生同步,影响Redis的速度 

    AOF有3种方式

    方式说明
    appendfsync always 每次有数据修改发生时都会写入AOF文件 ,严重降低Redis的速度
    appendfsync everysec 每秒钟同步一次,显示地将多个写命令同步到硬盘
    appendfsync no 让操作系统决定何时进行同步

    为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec 选项 ,让 Redis 每秒同步一次 AOF 文件,Redis 性能几乎没受到任何影响。

    Redies默认AOF是关闭的,通过修改配置打开

     

    Redis 4.0 对于持久化机制的优化

    Redis 4.0 开始支持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 aof-use-rdb-preamble 开启)。

    如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。

    这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。

    当然缺点也是有的,AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。

    由于Windows的版本最新只有3.0,这个就没法验证

    • 单体使用互斥锁(mutex key)
    • 分布式使用setnx
    • 双重校验访问缓存数据(Double Check),就是线程安全的单例模式
  • 相关阅读:
    数据结构与算法实例(数组实现)
    从王者荣耀看设计模式(二十三.访问者模式)
    20172319 2018-3_2018-7《程序设计与数据结构》课程总结
    哈夫曼编码
    20172319 实验三《查找与排序》实验报告
    20172319 《程序设计与数据结构》 第九周学习总结
    20172319 实验二《树》实验报告
    20172319 《程序设计与数据结构》 第八周学习总结
    20172319 《程序设计与数据结构》 第七周学习总结
    20172319 《程序设计与数据结构》 第六周学习总结
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/12660721.html
Copyright © 2020-2023  润新知