zoukankan      html  css  js  c++  java
  • Redis从生米煮成熟饭

    转自:www.qianshan.tech

    Redis为何选用单线程

    单线程减少线程上下文切换和锁竞争。

    网络IO模型采用IO多路复用,使用EPOLL注册读写事件通知,同步非阻塞。

    Redis单线程如何发挥多核CPU优势

    在单台服务器上运行多个redis实例。 使用taskset命令,将每个redis实例和cpu核心进行绑定

    Redis分布式锁实现

    setnx key value 如果key不存在,则创建并赋值。成功返回1 失败返回0。 同时设置过期时间: expire key seconds

    也可使用set命令配合NX EX选项一次性设置 SET key value EX 10086 NX

    缓存雪崩、缓存击穿、缓存穿透

    缓存雪崩: 大量的KEY过期时间过于集中,导致瞬时很多缓存失效,由此可能导致数据库压力陡然升高。
    解决方案: 将失效时间随机打乱,如在系统启动预热时设定一定程度上离散的过期时间。

    缓存击穿: 缓存中某一个KEY过期失效,如果此时有大量请求过来无法命中缓存的KEY,缓存层像被凿开了一个口子一样流入大量数据库查询请求
    解决方案:双重校验方式从数据库中读取数据到缓存。双重校验:第一层查询缓存失败后,进入临界区,保证同时只有一个请求线程读取数据库,进入临界区后再次尝试缓存,仍然没有命中则查询数据库。

    缓存穿透: 外部请求不断查询一个系统中不存在的数据,服务无法命中缓存转而每次尝试从数据库中查询。
    解决方案

    1. 对查询结果为空key设置值为null的缓存,牺牲缓存空间换响应时间。
    2. 把所有非法的key映射到一个bitmap中,通过bitmap拦截。《布隆过滤器》原理

    Redis如何删除过期key

    1. 主动删除:redis 默认每隔一定时间检查已过期key进行删除, 或者内存不足时触发主动删除机制

    2. 惰性删除:在有请求读写key时再检查key是否过期,过期则删除

    Redis如何持久化

    AOF

    AOF(Append Only File ): 记录每次redis的写命令,如对一个key更新10次,记录10条写指令。可以设置每秒一次或者每个写动作发生后追加。 优点: 持久化频率高,异常down机时数据丢失少。 缺点: 文件大,恢复时相对耗时。

    Redis默认使用RDB持久化,可同时开启AOF持久化,如下

    appendonly yes
    appendfilename "appendonly.aof"
    

    AOF重写

    AOF文件体积过大时会进行重写。重写的作用是用一条命令去记录键值对,代替之前记录该键值对的多个命令。如一个key自增100次,原文件记录了100条指令,重写后将原来的指令合并成为最新的一条,由此大大压缩AOF文件体积。

    重写采用写时赋值(Copy On Write)原理,不直接操作原文件。

    RDB

    RDB:快照持久化。在特点时间点保存全量的数据信息。 优点: 恢复时直接将快照文件加载到内存,速度快。 缺点: 因为全量数据量大,持久化频率一般设置较低。异常关机时会丢失上次持久化到关机时刻的变更数据。

    如RDB方式配置

    save 900 1 #在900s内如果有1条数据被写入,则产生一次快照。 
    save 300 10#在300s内如果有10条数据被写入,则产生一次快照   
    save 60 10000 #在60s内如果有10000条数据被写入,则产生一次快照  
    stop-writes-on-bgsave-error yes    # 如果为yes则表示,当备份进程出错的时候,   主进程就停止进行接受新的写入操作,这样是为了保护持久化的数据一致性的问题。
    

    bgsave

    也可通过basave命令手动触发快照的持久化。bgsave fork出子进程,采用写时复制机制写入。不阻塞主进程的工作(对比save命令)。

    AOF和RDB可搭配同时使用,开启AOF时,redis启动默认从AOF日志文件中重建缓存。

    Redis集群方案

    1. Sentinel: 哨兵模式,主要实现高可用。解决Redis原有的主从同步模式,当Master实例故障时导致整个集群无法工作的缺陷。Sentinel是一个独立运行的进程,检测Redis集群状态,如Master因故障下线时则在集群机器中发起选举选出新的Master节点。
    2. Cluster: 解决单台主机的内存容量有限。 Redis集群定义有16384个哈希槽,每个节点负责一段。每个key通过CRC16校验后对16384取模来决定放置哪个分片。

    Redis和数据库不一致问题

    数据库更新时需要触发缓存更新

    如果先删除缓存再进行数据库更新, 可能在数据库更新之前,新的请求进来因为没有命中缓存从数据库中读取旧数据。 如果先进行数据库更新在删除缓存,可能出现数据库写入成功后删除缓存失败。导致缓存仍然是旧数据。

    网上流传双删策略: 先删除缓存–> 数据库写入 ——》再次删除缓存。

    好处是能数据更新前能预检查下redis工作状态,但是关键的问题:写入后删除缓存时失败的情况仍然可能存在。根本的解决方案应该在写入后删除失败时增加重试机制,或者回滚数据库更新。

    Redis内存淘汰策略

    Redis使用内存超过 maxmemory 配置大小时触发内存淘汰策略。

    • noeviction:不删除策略,内存达到上限时直接返回错误信息
    • allkeys-random: 针对所有的key,随机删除一部分
    • allkeys-lru: 针对所有的key,优先删除最少使用的
    • volatile-random: 针对设置了过期时间的key,随机删除一部分
    • volatile-ttl: 针对设置了过期时间的key,优先删除最快过期的key
  • 相关阅读:
    netcore使用IdentityServer在nginx下502错误的解决
    更新到.netcore3.0后找不到dotnet-ef的解决办法
    openssh-win64 on windows2016 ssh pub key config
    405 Method Not Allowed error with PUT or DELETE Request on IIS Server
    minikube windows hyperx填坑记
    angular当router使用userhash:false时路由404问题
    内网gitlab11.2升级至11.4.5
    Angular7上手体验
    动态规划之背包问题
    Union-Find算法详解
  • 原文地址:https://www.cnblogs.com/linwenbin/p/11725753.html
Copyright © 2011-2022 走看看