高级篇-剖析Redis

本文详细介绍了Redis的多种应用,包括分布式锁、统计计数、延时队列等。还阐述了布隆过滤器的原理与Java实现,以及Redis的限流、持久化操作、事务、消息队列等功能。此外,介绍了Redis的内存管理、主从同步、高可用方案、集群方案和容错机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis 应用

  • 分布式锁
  • 统计计数
    • bitcount : 位图统计指令
    • bitpos: 位图查找指令
  • 统计计数-估算去重
    • HyperLogLog :去重统计 UV,标准误差是0.81%
      • pfadd
      • pfcount
    • incrby 指令统计PV
  • 延时队列 list FIFO  (rpush + lpop  or  lpush + rpop)
    • 阻塞读 brpop or  brpop
  • 并发处理延时队列: zrem 多线程争抢任务的关键,返回当前实例是否抢到任务
  • 布隆过滤器: 文章推送,去重内容等
    • 说某个值存在,那么这个值可能不存在;当说某个值不存在,就肯定不存在
    • bf.add  bf.madd (批量)
    • bf.exists  bf.mexists  (批量)
    • 布隆过滤器JAVA 实现 
      • Guava Bloom Filter ( 缓存、限流、集合。。。) (不可删除,因为hash碰撞)
        • <dependency>
        •     <groupId>com.google.guava</groupId>
        •     <artifactId>guava</artifactId>
        •     <version>19.0</version>
        • </dependency>
      • CountingBloomFilter带计数器的布隆过滤器 (可删除)
        • <dependency>
              <groupId>com.baqend</groupId>
              <artifactId>bloom-filter</artifactId>
          </dependency>
  • 限流: Redis-Cell (漏斗算法)  「Redis 深度历险  P72」
    • cl.throttle
    • cl.throttle keyname 15 30 60  1
      • 15: capatity 漏斗容量
      • 30 operations / 60 seconds 这是漏斗速率
      • need 1 quota(可选参数,默认1)
  • GeoHash  附近的人
  • Scan 

Redis 持久化操作:

  • RDB快照:glib 函数fork产生一个子进程。持久化操作交给子进程处理,父进程处理客户端请求
    • 缺点:内存快照必须进行文件IO操作,但是文件IO操作不能使用多路复用API。Redis使用多进程COW(Copy on write)机制实现快照持久化。数据段是由多个操作系统的页面组合而成,每个页面大小只有4kb,当父进程需要对其中一个页面的数据进行修改时,会将被共享的页面复制一份分离出来,然后对这个复制的页面进行修改。这时子进程相应的页面是没有变化的,还是进程产生时的那一瞬间的数据。
  • AOF日志:redis是先执行指令后将日志存盘; linxu的glibc 会提供了fsync(int fd)函数可以将指定文件的内容强制从内核缓存刷到磁盘。
    • 优点:
    • 缺点:文件指令过多重写时间会很长,
  • 混合持久化

Redis 事务

  • multi 开始事务;
  • do something 。。。 (queued)命令后返回 标识 OK
  • exex 事务的执行
  • discard 事务的丢弃

 

优化

  •     内部指令较多时,需要的网络IO时间也会线性增长,所以通常Redis客户端在执行事务时会结合pipeline一起使用,这样可以将多次IO操作压缩为单次IO操作

 


分布式锁

  •  悲观锁
  • 原子指令:
    • setnx(se if not exists) + del
    • set(key ,value ,nx=True,ex=xxx)
  • 非原子指令:setnx + expire(死锁)

Watch 机制

  • 乐观锁
  • 会在事务开始之前顶住一个或多个关键变量,当事务执行时,也就是服务器收到了exec指令要顺序执行缓存的事务队列时,Redis会检查关键字变量自watch 之后是否被修改了(包括当前事务所在的客户端),如果关键变量被修改了,exec指令就会返回NULL回复告知客户端事务执行失败,这个时候客户端一般会选择重试
  • 使用方式:

 


Redis PubSub 消息队列

  • 消费者: 
  • 生产者:
  • 必须先启动消费者,再执行生产者。这样可以保证多个消费者收到相同的消息序列
  • 模式订阅
    • subscribe 
    • psubscribe 模式订阅 >psubscribe codehole.*  主题是以codehole.开头的消息都可以收到
  • PubSub缺点
    • 当一个消费者都没有时,消息直接丢掉
    • 断连期间生产者发送的消息,对于这个消费者来说就是彻底丢失
    • Redis重启,Pubsub消息不会持久化,直接丢弃

 


小对象压缩存储 ziplist: 压缩列表是一块连续的内存空间,元素之间紧挨着没有任何冗余空隙;长度为8kb

  • hash 元素个数超过512个 就必须用标准结构存储
  • hash 的任意元素的k /v 的长度超过64 就必须用标准结构存储
  • list 的元素个数超过512 就必须用标准结构存储
  • list 的任意元素的长度超过64 就必须用标准结构存储
  • zset 的元素个数超过128 就必须用标准结构存储
  • zset 的任意元素长度超过 64 就必须用标准结构存储
  • set 的整数元素个数超过512 就必须用标准结构存储
  • object encoding [keyname] 输出对象的存储结构

redis 内存回收机制

  • Redis并不是总是将空闲内存立即归还给操作系统
  • 当删除了1G的key时,内存并没有变化太大,原因是操作系统是以页为单位来回收内存的,页上只要有一个key在使用,那就不能被回收
  • flushdb 执行后会被回收内存,是因为所有key都被删除了

redis 内存分配算法

  • redis 可以使用jemalloc(facebook) 库来管理内存,也可以切换到tcmalloc(google)库, je库性能要比tc 要好一些。 默认jemalloc
  • 使用info memory  查下内存管理

redis 主从同步

  • 增量同步
  • 环形数组-buffer 重头覆盖
  • 快照同步
  • 无盘同步:
    • 主服务器直接通过套接字将快照内容发送到从节点,生成快照是一个遍历的过程, 主节点会一边遍历内存,一边将序列化的内容发送到从节点,从节点还是跟之前一样,先将接收到的内容存储到磁盘文件中,再进行一次性加载
  • wait 命令  :3.0版本后出现-将异步复制变成同步复制
    • wait N t : 第一次参数是从节点数量N,第二个参数是同步等待时间t,t=0 时表示无限等待直到N个从节点同步完成
    • 缺点:出现网络分区时,主从同步无法继续进行,wait指令会永远阻塞,Redis丧失可用性

redis Sentinel 高可用方案

  • 防止消息丢失:Sentinel无法保证消息不丢失,也能尽量保证消息少丢失
    • min-slaves-to-write 1 : 表示主节点必须至少有一个从节点在进行正常复制,否则就停止对外写服务,丧失可用性
    • min-slaves-max-lag 10 :单位是秒,表示如果再10s内没有收到从节点的反馈,就意味着从节点同步不正常,要么是网络断开,要么就是一直没有给反馈

redis 集群方案1  Codis 

  • Codis :豌豆荚中间件团队
  • 数据划分为1024个槽位,可修改
  • 需要额外的分布式存储槽位信息
  • 槽位算法:默认会对key 值使用crc32 算法进行hash,hash后的整数值对1024 进行取模得到余数就是槽位

redis 集群方案2 Redis Cluster 

  • 数据划分为16384个槽位
  • 槽位信息存放于每个节点中
  • 槽位算法:默认会对key值使用crc16算法进行hash,得到一个整数值,然后用这个整数值对16384 取模得到具体槽位 (允许用户强制将某个key挂到某个槽位上)

        redis容错

  • cluster-require-full-coverage 允许部分节点发生故障,其他节点还可以继续提供对外访问

        网络抖动

  • cluster-node-timeout 表示某个节点持续timeout的时间失联时,才可以认定该节点出现故障。需要主从切换,否则,redis会因为网络抖动导致频繁切换(数据重新复制 )
  • cluster-slave-validity-factor 作为倍数系数放大这个超时时间来宽松容错的紧急程序,如果为0,那么主从切换是不会抗拒网络抖动

         可能下限 PFail 与确定下线 Fail

  • Cluster 去中心化,收到节点失联后会广播出去 PFail ,当PFail count为大多数时,判断为Fail
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值