Redis个人总结简洁版

Redis

基础和应用

5种基本结构

  • string

    • 动态字符串
    • 结构类似于ArrayList
    • 最大value - 512MB
  • list

    • 双向链表
    • 结构类似于LinkedList
  • hash

    • 数组+链表
    • 结构类似于老的HashMap
  • set

    • 数组+链表
    • value全用null填充
    • 结构类似于老的HashSet
  • zset

    • 跳跃链表

分布式锁

  • 应用

    • 第一步:setnx
    • 第二步:expire
  • set-expire原子性

    如果setnx和expire中间出现意外打断,造成expire没有得到执行,那么这个锁将永远得不到释放

    • set key value ex

      后来提供的指令
      可以保证赋值的过程和过期的设置是两个操作是一个原子性的

  • 超时问题

    • 阻塞-锁过期-其他线程拿到锁

      假设A持有锁,过期时间是10s,但是A由于某种阻塞,自身阻塞超过10s。
      这时候锁过期了,B也得到了锁,会造成锁不互斥的情况。
      解决方式见:Redlock

  • 可重入问题

    上述的策略都是不支持可重入锁的

    • 使用hash实现可重入锁

      可以使用hash结构实现可重入锁
      实现思路:
      key :锁名称
      field :线程id
      value:锁计数
      每次获得锁的时候,检查锁是否存在,线程id是不是对应
      离开锁的时候,锁计数-1

  • RedLock

    普通算法存在的问题:
    在主从结构中,如果某个线程A刚在主节点刚获得锁,还没来得及同步到从节点,然后主节点挂掉了,就会造成锁丢失。
    下一个线程B还是可以在新晋升的主节点申请到这把锁

    • 前提:更多独立的Redis示例

    • RedLock算法

      加锁,向过半的节点发送set key value nx ex 指令
      只要过半的节点都认为成功,那就成功
      释放锁,向全部的节点发送del指令

    • 代价

      • 同时对多个独立的redis读写,性能降低
      • 引入了额外的library
      • 运维代价也上升

bitMap

  • 底层还是字符串

  • 用法

    注意bitcount和bitpos的[start,end]是以字节为单位的

    • setbit
    • getbit
    • bitcount
    • bitpos

HyperLogLog

GeoHash

  • 底层是zset

  • GeoHash算法

    把二维坐标映射到一维

  • 用法

    • geoadd
    • geodist
    • geopos
    • geohash
    • georadiusbymember

布隆过滤器

  • 原理

    添加key的时候:输入一个key,经过多个Hash函数得到多个下标,然后把对应值的下标位数设为1。
    判断key存在的时候:输入一个key,经过多个Hash函数得到多个下标。(1) 如果下标都为1,那么认为存在(2)如果下标有一个不为1,认为不存在

    • 优点:用很小的空间完成工作
    • 缺点:有一定的误判率
  • 用法

    • bfadd
    • bfexists
    • bfmadd(批量)
    • bfmexists(批量)
  • 误判率

    如果数组很大,很稀疏,误判率就会很低
    如果数组很小,很拥挤,误判率就会上升
    在实际使用的时候,应当注意,不要让实际元素数量超过初始化容量。否则应该进行更大size的重建。

限流

  • 简单限流

    • 断尾限流

      • 效果

        一个用户在指定的时间内进行某个行为最多只能N次

  • 漏斗限流

    • 基本原理

      漏斗结构重要的几个参数
      漏斗容量
      漏嘴流水速率
      漏斗剩余空间
      上次漏水时间

      每次申请往里添水的时候,先计算从上次漏水到当前时间,流了多少水,更新漏斗剩余空间。
      如果剩余空间够此次添水,允许添水。
      如果剩余空间不够此次添水,不允许添水

    • RedisCell

      • cl.throttle指令

scan

  • 应用

    查找符合某种规则的key,带有limit选项
    游标从0开始,每次查找,都会返回下次的游标地址
    游标地址重新归零的时候,代表查找完一圈

  • 比keys多了limit选项

  • 说明

    • limit指的是槽位数量

    • 遍历顺序

      遍历顺序不是按照槽位地址递增

原理

线程IO模型

  • 非阻塞IO
  • 多路复用
  • 指令队列
  • 相应队列
  • 定时任务

通信协议

  • RESP

    • 直观的文本协议

持久化

  • 快照

    • 二进制序列化形式

    • 文件紧凑

    • 实现原理

      • COW原理
      • fork子进程
      • 数据页的COW处理
  • AOF

    • 修改数据的指令记录文本

    • 可读性强

    • 随着运行会越来越大

      • 上线加载AOF耗时长

      • AOF重写(瘦身)

        • 原理

          • 开辟一个子进程
          • 对内存进行扫描
          • 转化成操作指令
          • 拼接上增量AOF
    • AOF策略

      • 从不
      • 每秒
      • 每个操作
  • 混合持久化

    • 快照
    • 增量AOF

管道

  • 提高速度

  • 原理

    • 用缓冲区,暂存一些指令
    • 一起发送,一起接受
    • 减少网络传输次数

事务

  • multi
  • exec
  • discard
  • 可配合watch使用
  • 使用管道执行事务可以更优化

订阅发布

用的不多

内存机制

  • 内存回收

    • 以页为单位回收

      操作系统以页为单位回收内存,只要这个页上有一个key还在使用,就不会被回收。
      因此删除了很多key,也不能马上看到内存腾出来。
      redis会重新利用那些尚未回收的空闲内存

  • 内存分配

    • jemalloc(facebook)默认,性能好一些
    • tcmalloc(google)

集群

CAP

  • 一致性

    • Redis不满足一致性,但是满足最终一致性
  • 可用性

    • Redis满足可用性
  • 分区容忍性

最终一致性

  • 从节点努力追赶主节点

主从同步

  • 主从同步

  • 从从同步

    链状,减轻主节点的负担

  • 增量同步

    • 同步的是指令流
    • 修改性的执行记录在本地缓冲
    • 缓冲异步发给从节点
    • 如果缓冲环状数组发生覆盖,就要进行快照同步
  • 快照同步

    • 先bgsave到本地磁盘

    • 再把快照文件发送到子节点

    • 子节点加载快照文件

    • 然后进行增量同步

    • 如果快照部分太慢,增量又会出现缓冲覆盖,从而形成死循环

      • 解决:配置合适的buffer大小
  • 无盘复制

    • 一遍遍历内存,一遍序列化发送到从节点
    • 通过套接字
  • wait指令

    • wait N time

      等待N个从节点完成同步,最多等待time秒
      time为0表示一直等待
      如果发生了网络分区,会造成永久阻塞,丧失可用性

    • 让异步变成同步

哨兵

  • 监控主节点的健康

  • 3-5个节点,保证高可用

  • 消息丢失问题

    • 因为主从的异步复制(缓冲区)
  • 基本原理

    • 客户端连接从Sentinel获得主节点位置
    • 主节点故障的时候,会把新的主节点位置告诉客户端
    • 监控挂掉的原主节点,恢复之后变成从节点
  • 基本用法

Cluster

  • 槽位

    • 16384个(2的14次方)
    • 槽位信息存于每个节点
    • 客户端来连接获得槽位信息,直接定位到目标节点
  • 槽位定位算法

    • CRC16算法,然后对16384取模
  • 跳转

  • 迁移

  • 网络抖动

  • 可能下线-确定下线

    • 协商机制
    • 认为某个节点可能失联的节点数达到大多数则认为该节点确认下线

扩展

Info指令

  • Server
  • Clients
  • Memory
  • Persistence
  • Stats
  • Replication

过期策略

  • 主节点

    • 定时删除

      • 贪心策略

        从过期字典中随机选出20个key
        删除其中已经过期的key
        如果过期的key超过了1/4,重新执行 1步骤

      • 有最大时间限制,默认25ms

      • 要避免大量key同时到期,加一点随机时间

    • 惰性删除

  • 从节点

    • 主节点发送del到从节点
    • 还是异步会不一致的问题

淘汰策略

  • noeviction

    • 不继续写服务-默认
  • volatile-lru

    • 设置了过期时间的key,lru
  • volatile-ttl

    • 设置了过期时间的key,ttl最小的淘汰
  • volatile-random

    • 设置了过期时间的key随机
  • allkeys-lru

    • 全部key-lru
  • allkeys-random

    • 全部key-随机

懒惰删除

  • 引入

    删除一个大的key的时候,会造成明显卡顿

  • 原理

    把要删除的key的数据结构从原数据结构上断开
    把后续内存回收操作包装成一个任务放入异步队列
    留给后台线程处理
    并不是所有的key都向上面一样
    小key直接删
    大key先断开再删

  • flushdb和flushall后面加async会变成异步任务

  • AOF的Sync也很慢,也有一个独立的任务队和异步线程处理

源码

字符串

  • embstr(短)
  • raw(长)
  • 阈值:长度超过44字节(64-1-16-3)

字典

  • 包含两个Hashtable

  • 渐进式搬迁

  • 扩容条件

    元素个数超过长度
    如果在做bgsave,为了减少COW,不会去扩容
    如果元素个数达到了5倍,不管bgsave强制扩容

  • 缩容条件

    元素个数低于数组长度的10%

压缩列表

快速列表

跳跃列表

紧凑列表

XMind - Trial Version

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值