zoukankan      html  css  js  c++  java
  • 12.redis 之阅读大佬文章随笔

    1.熟悉redis备份持久化机制(RDB和AOF机制)
    RDB:
    -- RDB:将当前进程数据生成快照保存起来
    -- 自动触发和手动触发
    -- save和bgsave(手动触发): save会阻塞当前redis服务器,知道rdb过程完成为止。对于内存比较大的实例会造成长时间阻塞
    线上环境不建议使用。且save命令已经废弃。
    bgsave:redis会fork一个子进程,rdb的过程会有子进程负责,阻塞一般只会发生在fork阶段。时间较短

    -- 自动触发:
    1.可以在配置文件配置,例如 save m n :表示在m秒内数据集发生n次变化,会自动触发bgsave
    2.如果从节点执行全量复制,主节点会自动执行bgsave生成RDB文件并且发送给从节点,
    3.执行debug reload 命令时重新加载redis时,也会自动触发save操作
    4.默认情况下,执行shutdown时,如果没有开启AOF持久化功能则会自动执行bgsave

    --RDB文件处理:
    config set dir xxxxx:rdb文件保存目录
    config set dbfilename xxxx :rdb文件名称
    -->注意以上的配置只能是在临时配置,如果想要永久的使用该配置,应该将上面的配置写到redis.conf文件中。

    --RDB的优点
    1.它是一个紧凑的二进制文件,代表Redis在某个时间点上的数据快照,非常适合备份 、全量复制等场景,比如每6个小时执行bgsave备份,并且把rdb文件拷贝到远程机器或者文件系统(如hdfs),用于灾难恢复。
    2.Redis加载RDB恢复数据远远快于AOF方式

    --RDB缺点:
    不能实时、因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作、频繁执行成本过高。
    老版本的redis服务器无法兼容新版本的RDB格式

    AOF
    --主要作用是解决数据持久化的实时性,目前已经是Redis持久化的主流方式。
    --功能开启:appendonly yes 默认是不开启
    --执行过程
    1.所有命令都写入到aof_buf缓冲中
    2.aof缓冲以对应的刷盘策略向磁盘写入
    3.随着aof文件越大,需要对其进行重写,到达压缩目的
    4.redis重启,加载AOF文件
    --刷盘策略
    有appendfsync控制
    1 always:命令写入aof_buf后调用系统fsync操作同步到AOF文件,fsync完成后线程返回
    2.everysec: 命令写入aof_buf后调用系统write操作,write完成后线程返回,fsync同步文件操作有专门线程每秒调用一次
    3.no:命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作有操作系统完成,通常同步周期为30s
    --->
    第一种是最安全的一种方法,但是会损失部分redis性能
    第二种选项是默认的配置。能够兼顾性能和数据安全。
    第三种该选项下redis的性能可以保证,但是数据安全性不足

    2.熟悉redis的主从复制技术
    --从库上执行
    slaveof host port -->host:代表主库ip地址 port:代表主库的端口号

    --断开复制
    slaveof no one -->从库从主库上断开复制连接


    --数据一致性
    除此之外,我们可以设置slave-read-only=yes来配置从节点为只读模式,防止从节点人为写入数据,导致主从数据不一致。


    --复制原理--
    1.保存主节点的master值
    2.主从建立socket连接
    从节点内部会通过每秒运行的定时任务维护复制的相关逻辑,当定时任务发现存在新的主节点之后,会尝试与该节点建立网络连接
    从节点会建立一个socket套接字,专门用于接收主节点发送的复制命令。如果此时从节点无法建立连接,定时任务会进行无数次的重试知道连接成功或者执行slaveof no one取消复制。
    3.发送ping命令
    4.权限验证
    5.同步数据集
    6.命令持续复制

    3.Redis的阻塞,一般来讲,是由以下原因构成的:
    不合理的使用API或者数据结构、CPU饱和、持久化阻塞等内在原因;
    CPU竞争、内存交换、网络问题等外在原因
    下面我们分别分析这些原因

    4.Redis内存优化
    从内存消耗、管理内存的原理与方法、内存优化技巧三个方面讲述如何高效高效实现内存的存储

    缩减键值对象:降低redis内存最直接的方式就是缩减key和value的长度

    共享对象池:redis在内存中维护了一个[0-9999]的整数对象池,用于节约内存,除了整数值对象,其它类型,如list/hash/set/zset中元素也可以使用整数对象池、

    5.redis sentinel(哨兵)
    我们知道Redis主从模式下,一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点的地址。然后在很多场景下这种故障处理的方式是无法接受的,应用程序需要实时感知当前的可用节点。为了解决这个问题,Redis sentinel就来了,也被称为’哨兵‘。

    主从复制问题:
    1.一旦主节点发生故障,从节点晋升为主节点的过程和应用调整新主节点的过程,都需要认为干预
    2.主节点的存储能力容易受到单机的限制
    一种常见的方法就是使用脚本来触发主从节点的角色切换,例如在一个一主两从的结构中,假设主节点master,从节点slave1.slave2,我们来看看故障发生时架构的状态
    2.1 主节点master故障,客户端连接失败,两个从节点复制失败
    2.2 选择一个主节点slave1,对其执行slaveof no one命令使其成为主节点master2
    2.3 更新应用程序连接的节点为slave1的ip地址
    2.4 slave2以slave1为新的主节点,复制slave1上的命令
    2.5 待原来的master恢复之后,让它成为slave1的从节点
    上述过程可以做成自动化的过程,但是需要考虑三点:a、要确保判断节点不可达的机制健全、否则容易出现误判情况,b.如果有多个从节点,如果保证只有一个从节点被晋升为主节点是个关键的问题,c.通知客户端新的主节点的机制是否足够健壮。

    Redis Sentinel的高可用机制
    Sentinel 能够自动完成故障发现和故障转移,并及时通知应用方,这个是它的核心价值所在。
    Redis Sentinel是一个分布式架构,其中包含若干个Sentinel和若干个Redis数据节点, 每个Sentinel节点会对数据节点和其余sentinel节点进行监控,当它发现节点不可达时,会对节点做下线表示。如果被标识的是主节点,它还会和其他的sentinel进行协商,当大多数sentinel节点都认为主节点不可达时,它们会选举出来一个sentinel节点来实现故障自动转移,同时会将这个变化通知给Redis应用方,整个过程是自动的,不需要人工介入。Redis Sentinel与Redis主从复制模式只是多了若干个sentinel节点,并没有对redis节点做特殊处理,


    sentinel monitor


    6.redis sentinel 实现原理
    sentinel的实现原理主要分为三个定时任务、主观下线和可观下线、sentinel领导者选举以及故障转移4个部分

    1.三个定时任务
    redis sentinel通过三个定时监控任务完成对各个节点的发现和监控
    任务一:每隔10s,每个sentinel节点向主节点和从节点发送info命令,获取最新的拓扑结构
    sentinel通过对info节点的结果解析,就能找到响应的从节点,这个info的定时任务,它的具体作用有如下有个三个方面:
    a.通过向主节点执行info命令,获取从节点的信息
    b.当有新的从节点加入时,都可以立即感应出来
    c.节点不可达或者故障转移之后,可以通过info命令实时更新节点的拓扑信息

    任务二:每隔2s.每个sentinel节点会向redis数据节点的_sentinel_:hello频道上发送该sentinel节点对于主节点的判断以及当前sentinel节点的信息。同时每个sentinel节点也会订阅频道,来了解其他sentinel节点以及他们对主节点的判断,所以这个定时任务可以在sentinel节点之间交换主节点的状态,作为后面可观下线以及领导者选举的依据。

    任务三:每隔1s,每个sentinel节点会向主节点,从节点,其余sentinel节点发送一条ping 命令做一次心跳检测,来确认这些节点当前是否可达,实现对每个节点的监控,这个定时任务是节点失败的重要依据

    2.主观下线和客观下线
    主观下线:监控过程中的第3个定时任务ping,如果在down-after-milliseconds没有收到有效的回复,sentinel节点就会对该节点做失败判断,这个行为叫做主观下线,主观下线是sentinel做出的判断,存在误判的可能

    客观下线:当sentinel主观下线的节点是主节点时,该sentinel节点会通过sentinel is-master-down-by-addr命令向其他sentinel节点询问对主节点的判断,当超过<quorum>个数的sentinel节点认为主节点确实有问题,这时sentinel节点会做出客观下线的决定,也就是说,当大部分sentinel节点都对主节点的下线做了同意的判定,那么这个判定就是客观的。

    这里的is-master-down-by-addr命令: sentinel is-master-down-by-addr ip port current_epoch runid
    其中:
    ip指的是主节点ip,port指的是主节点端口
    current_epoch只当前配置纪元

    7.Redis事务
    1 Redis事务就是一次性,顺序性、排他性的执行一个队列中的一系列命令,分为三个过程:开始事务、命令入队、执行事务
    2.Redis提供了简单的事务,使用multi、exec 、discard这三个命令来控制
    3.exec命令之前,所有原子操作都被放到了队列中缓存,并不会真正执行
    4.Redis事务不存在隔离级别的概念
    5.事务中的单条命令是原子执行的,但是事务本身不保证原子性,没有回滚机制


    8.redis大key问题
    在redis中,大key指的是key对应的value值所占的内存空间比较大,例如一个字符串类型的value最大可以存储512M的内容,一个列表类型的value最多可以存储2的32次方-1个元素,
    一般情况下,我们认为字符串类型的key的value的值超过10kb,就算大key


    大key的危害
    1.内存空间不均匀
    2.操作耗时,存在阻塞风险
    3.网络阻塞,每次获取大key产生的网络流量较大
    4.如果一个key的大小为1MB,每秒访问量为1000,那么每秒产生1000MB的流量。这对于普通千兆网卡的服务器来说是灾难性的。

    如果发现大key
    1.redis-cli --bigkeys命令可以统计bigkey的分布情况
    2.使用debug object key 命令,从命令结果中serializedlength的值来判断当前key的字节数
    3.使用strlen命令来判断当前key的长度


    9.redis-cluster
    Redis-Cluster是redis的分布式解决方案,有效解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用cluster架构方案达到负载均衡的目的。

    之前,Redis分布式方案一般有两种:
    1.客户端分区方案,优点是分区逻辑可控,缺点是需要自己处理数据路由、高可用、故障转移等问题
    2.代理方案,优点是简化客户端分布式逻辑和升级维护便利,缺点是加重架构部署复杂度和性能损耗。

    官方提供了专有的集群方案:Redis Cluster

  • 相关阅读:
    省市区三级联动
    jeDate日期控件
    Juery返回Json数据格式,webForm中使用
    JS补充
    winfrom中上传文件保存在webFrom里面
    游标
    函数
    触发器
    Leetcode练习(Python):数组类:第106题:根据一棵树的中序遍历与后序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。
    Leetcode练习(Python):数组类:第105题:根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。
  • 原文地址:https://www.cnblogs.com/zmc60/p/15057875.html
Copyright © 2011-2022 走看看