美文网首页
Redis终极整理

Redis终极整理

作者: 枫之沫翊 | 来源:发表于2020-10-21 10:18 被阅读0次

    一、 Redis简介

    1. redis的优点
      ● 数据间没有必然的关联关系
      ● 内部采用单线程机制
      ● 高性能
      ● 多数据类型支持(String,Hash,List,Set,ZSet)
      ● 持久化支持(数据恢复)
    2. redis的应用场景
      ● 为热点数据加速查询(热点商品、热点资讯等)
      ● 任务队列(秒杀、抢票等)
      ● 即时信息查询(排行榜、在线人数、微博粉丝数等)
      ● 时效性信息控制(验证码等)
      ● 分布式数据共享(分布式session)
      ● 分布式锁
      ● 消息队列

    二、 数据类型的基本操作

    1. String类型
      ● 添加数据
      set key value
      ● 获取数据
      get key
      ● 删除数据
      del key
      ● 添加/修改多个数据
      mset key1 value1 key2 value2 ...
      ● 获取多个数据
      mget key1 key2 ...
      ● 获取数据字符长度
      strlen key
      ● 追加信息(原始信息存在就追加不存在就新建)
      append key value
      扩展操作
      ● 设置数值增加指定范围的值(分布式中id的自增)
      incr key
      incrby key increment
      incrbyfloat key increment
      ● 设置数据减少指定范围的值
      decr key
      decrby key increment
      ● 设置数据具有指定的时效
      setex key seconds value
      psetex key millseconds value
    2. Hash类型
      存储对象类的数据,底层使用hash表结构实现(常应用于商品购物车的实现)
      ● 添加/修改数据
      hset key value
      ● 获取数据
      hget key field
      hgetall key
      ● 删除数据
      hdel key field1 field2 ...
      ● 添加/修改多个数据
      hmset key field1 value1 field2 value2 ...
      ● 获取多个数据
      hmget key filed1 field2 ...
      ● 获取hash表中字段的数量
      hlen key
      ● 获取hash表中是否存在指定的字段
      hexists key field
      扩展操作
      ● 获取hash表中所有字段的名和值
      hkeys key
      hvals key
      ● 设置指定字段的数值数据增加指定范围的值
      hincrby key field increment
      hincrbyfloat key field increment
    3. List类型
      ● 添加/修改数据
      lpush key value1 value2 ...
      rpush key value1 value2 ...
      ● 获取数据
      lrang key start stop
      lindex key index
      llen key
      ● 删除并移除数据
      lpop key
      rpop key
      扩展操作
      ● 规定时间内获取并移除数据
      blpop key1 key2 ... timeout
      brpop key1 key2 ... timeout
      ● 移除指定数据
      lrem key count value
    4. Set类型
      ● 添加数据
      sadd key memer1 member2 ...
      ● 获取全部数据
      smembers key
      ● 删除数据
      srem key member1 member2
      ● 获取集合数据总量
      scard key
      ● 判断集合中是否包含指定数据
      sismember key member
      扩展操作
      ● 随机获取集合中指定数量的数据
      srandmember key count
    5. SortedSet类型
      ● 添加数据
      zadd key score1 member1 score2 member2 ...
      ● 获取全部数据
      zrange key start stop withscores
      zrevrange key start stop withscores
      ● 删除数据
      zrem key member1 member2 ...
      ● 按条件获取数据
      zrangebyscore key min max withscores limit
      zrevrangebyscore key max min withscores
      ● 获取集合数据总量
      zcard key
      zcount key min max

    三、 key的通用操作

    ● 删除key
    del key
    ● 获取key是否存在
    exists key
    ● 获取key的类型
    type key
    ● 为key设置有效期
    expire key seconds
    pexpire key milliseconds
    expireat key timestamp
    pexpireat key millinseconds-timestamp
    ● 获取key的有效时间
    ttl key
    pttl key
    ● 将key从时效性转换为永久性
    persist key
    ● 通配符查询key
    key * 查询所有
    key name* 查询所有以name开头的
    key ?name 查询以一个任意字符开头的name结尾的
    key n[ab]e 查询以n开头的e结尾的中间包含字母a或b的

    四、 Redis持久化

    为了防止数据的意外丢失,确保数据的安全性,需要对数据进行持久化。
    Redis中的持久化分为两种方式RDB(快照)和AOF(过程日志)
    RDB
    以数据快照的方式进行存储
    手动执行:
    save命令:手动执行一次保存操作(每保存一次会生成一个.rdb文件)
    会阻塞当前的Redis服务器,直到RDB过程完成为止,可能会造成长时间阻塞(不建议使用)
    bgsave命令:手动启动后台保存操作,但不是立即执行,对阻塞问题进行了优化,Redis内部所有涉及到的RDB的操作都采用bgsave的方式
    执行过程:

    image
    自动执行:
    更改redis的conf目录下的redis.conf文件
    # 指定端口号为6379
    port 6379
    # 设置redis后台运行
    daemonize yes
    # 指定日志文件
    logfile "6379.log"
    # 文件存储的位置
    dir /redis/data
    # 指定快照存储的名称
    dbfilename dump-6379.rdb
    # 设置压缩rdb
    rdbcompression yes
    # 对rdb的数据进行校验
    rdbchecksum yes
    # 每隔10秒有30次增删改则生成rdb文件
    save 10 30
    

    优点:
    RDB是一个紧凑压缩的二进制文件,存储效率高,数据恢复速度比AOF更快
    缺点:
    无法做到实时持久化,可能会丢失数据,每次执行需要创建fork子进程,消耗性能
    AOF
    以独立日志的方式记录每次写命令,重启时再重新执行AOF中的命令,以达到恢复数据的目的,解决了数据持久化的实时性问题
    AOF写数据过程:

    image
    描述:在redis客户端执行写操作,服务器接收到写操作之后,将写命令刷新到缓存区中,再通过某种策略,将命令同步到AOF文件中
    AOF写数据的三种策略
    ● always:每次写入操作均同步到AOF文件中,数据零误差,性能较低
    ● everysec:每秒将缓存中的指令同步到AOF中,准确性较高,性能较高,在系统突然宕机时会丢失1秒的数据
    ● no:系统控制每次同步到AOF文件的周期,过程不可控
    配置:
    在(上面RDB的)redis.cnf文件中追加内容:
    # 开启AOF支持
    appendonly yes
    # 指定写策略
    appendfsync always
    # 指定aof持久化的文件名
    appendfilename appendonly-6379.aof
    

    AOF重写
    将对同一个数据的若干条命令执行结果转化为最终结果数据对应的指令进行记录

    image
    好处:降低磁盘占用空间,提高IO性能,提高数据恢复效率
    重写规则:
    ● 手动重写:直接在客户端使用命令 bgwriteaof
    ● 自动重写:
    自动重写触发条件设置
    auto-aof-rewrite-min-size 70
    auto-aof-rewrite-percentage 70
    自动重写触发比对参数
    aof_current_size
    aof_base_size
    自动重写触发条件
    aof_current_size>auto-aof-rewrite-min-size
    (aof_current_size-aof_base_size)/aof_base_size>=auto-aof-rewrite-percentage

    五、 Redis事务

    事务执行示例:

    # 开启事务,后续的命令将加入到事务队列中
    multi
    set name tom
    set age 10
    set gender male
    # 如果发现加入事务队列的命令写错了,使用该命令来取消事务,该命令发生在multi之后,exec之前
    discard
    # 执行事务,和multi成对出现
    exec
    

    加入到事务队列中的命令并不会立即执行,只有在执行了exec命令后才开始执行
    错误处理:
    ● 语法错误(命令格式有误)
    如果定义的事务中所包含的命令存在语法错误,那么整个事务将不会执行
    ● 运行错误(指令格式正确,但无法正确执行)
    能够正确运行的命令会执行,运行错误的命令不会执行,已经执行完毕的命令对应的数据不会自动回滚,需要程序员在代码中实现回滚

    六、 Redis锁

    加锁示例:

    • 对key添加监视锁,在事务执行exec前如果数据发生了变化,会终止事务的执行(wath命令需要放在multi命令之前)
      watch [key1] [key2]
    • 取消对所有key的监视
      unwatch
      分布式锁:
    • 使用setnx命令设置一个公共的锁,返回0表示设置失败,业务需排队或等待,返回1表示设置成功,执行业务操作
      setnx lock-key value
    • 操作完成后,需通过del命令释放锁,以免后面请求无法获取锁
      del lock-key
      改良方案(为锁设置超时时间,一段时间后自动释放锁):
    • 设置锁
      setnx lock-key value
    • 设置超时时间,expire为秒级,pexpire为毫秒级
      expire lock-key [second]
      pexpire lock-key [millsecond]
      再次改良
      使用lua脚本,使设置锁和设置超时时间成为一个原子操作
    if redis.call("get",KEYS[1]) == ARGV[1]
    then
        return redis.call("del",KEYS[1])
    else
        return 0
    end
    

    七、 Redis删除策略

    ● 定时删除(过期时间到达时,立即删除:降低内存,占用cpu)
    ● 惰性删除(过期时间到达时,不做处理,下次访问时进行删除:占用内存,节约cpu)
    ● 定期删除(周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度:cpu性能占用设置有峰值,检测频度可以自定义)
    逐出算法:
    redis在执行每一个命令之前会调用freeMemoryIfNeeded()检测内存是否充足,如果内存不满足新加入数据的最低存储要求,redis会临时删除一些数据为新数据存储腾出空间,这种策略称为逐出算法。(不保证100%清理出足够的空间,如不成功,则反复执行,仍不能达到则报错)
    数据逐出策略:

    image
    配置:
    在redis.conf文件中配置
    maxmemory-policy [策略] 如:maxmemory-policy volatile-lru

    八、 高级数据类型

    bitmaps:一般用于信息状态统计
    HyperLogLog:用于基数统计
    GEO:用于地理坐标运算

    九、 主从复制

    主从复制避免了单点故障,提供了数据的冗余备份
    一个master可以拥有多个slave,一个slave只对应一个master
    读写分离职责:
    master:负责写数据,并将数据同步到slave
    slave:负责读数据
    三个阶段:
    ● 建立连接
    1.设置master的地址和端口,保存master信息
    2.建立socket连接,发送ping命令
    3.身份验证
    4.发送slave端口信息

    image
    配置:
    master配置
    • master节点要求密码
      requirepass [password]
      slalve配置
      在slavle节点的redis.conf文件下配置
      slave联通master配置
      slaveof [master的IP地址] [master的端口]
      配置master的密码
      masterauth [password]
      ● 数据同步
      1.slave请求同步
      2.master创建rdb同步数据
      3.slave接收rdb,进行数据恢复
      以上过程叫做全量复制
      4.slave请求同步部分数据
      5.slave接收复制缓冲区的数据,执行bgrewriteaof命令,恢复数据
      以上过程叫做部分复制
      image
      数据同步阶段master说明
      1.如果master数据量巨大,数据同步阶段应该避免流量高峰期,避免造成master阻塞,影响业务正常执行
      2.复制缓冲区大小设定不合理,会导致数据溢出。如进行全量复制周期太长,进行部分赋值时发现数据已经存在丢失的情况,必须进行第二次全量复制,致使slave陷入死循环状态,修改缓冲区大小操作如下
      repl-backlog-size 1mb
      3.master单机内存占用主机内存的比例不应过大,建议使用50-70%的内存,留下30-50%的内存用于执行bgsave命令和创建复制缓冲区
      数据同步阶段slave说明
      1.为避免slave进行全量复制、部分复制时服务器响应阻塞或数据不同步,建议关闭此期间的对外服务
      slave-server-stale-data yes|no
      2.数据同步阶段,master发送给slave信息可以理解master是slave的一个客户端,主动向slave发送命令
      3.多个slave同时对master请求数据同步,master发送的RDB文件增多,会对带宽造成巨大冲击,如果master宽带不足,因此数据同步需要根据业务需求,适量错峰。
      4.slave过多时,建议调整拓扑结构,由一主多从结构变为树状结构,中间接待你即是master,也是slave。注意使用树状结构时,由于层级深度,导致深度越高的slave与最顶层master间数据同步延迟较大,数据一致性变差,应谨慎选择
      ● 命令传播
      image
      主从复制工作流程完整版
      image

    十、 哨兵模式

    哨兵:哨兵(sentinel) 是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的master并将所有slave连接到新的master
    哨兵的作用
    ● 监控
    不断地检查master和slave是否正常运行
    master存活检测、master与slave运行情况检测

    image
    ● 通知(提醒)
    当被监控地服务器出现问题时,向其他(哨兵间,客户端)发送通知
    image
    ● 自动故障转移
    断开master与slave连接,选取一个slave作为master,将其他slave连接到新的master,并告知客户端新的服务器地址
    image
    注意:哨兵也是一台redis服务器,只是不提供数据服务,通常哨兵配置数量为单数

    十一、 集群

    集群就是使用网络将若干台计算机联通起来,并提供统一的管理方式,使其对外呈现单机的服务效果。


    image
    image
    image

    十二、 故障及解决方案

    缓存预热:系统启动前提前将相关的缓存数据直接加载到缓存系统,避免用户在请求的时候先查询数据库,然后再将数据缓存的问题。用户可以直接查询事先被预热的缓存数据

    缓存雪崩:短时间内,大量的缓存集中失效,数据库同时接收到大量的请求无法处理,redis大量请求被积压,数据库崩溃。重启后仍然面对缓存中无数据可用,redis服务器资源被严重占用,最后redis服务器崩溃,导致集群坍塌。
    解决办法:1.多级缓存 2.mysql是否存在严重耗时,对mysql进行优化 3.限流 4.过期时间设置为随机时间

    缓存击穿:redis某个高热key过期瞬间,大量请求过来在redis中均未命中,直接压倒了数据库上
    解决办法:1.预先设定热点key 2.多级缓存,设置不同的失效时间 3.设置为永久key
    缓存穿透:大量访问一个不存在的数据,在跳过了合法数据在redis中的缓存阶段,每次都直接访问数据库
    解决办法:1.对查询结果为null的数据缓存null值,并设定过期时间
    2.黑白名单 3.布隆过滤器

    相关文章

      网友评论

          本文标题:Redis终极整理

          本文链接:https://www.haomeiwen.com/subject/ohdsmktx.html