Qouson's blog Qouson's blog
首页
  • Java 基础

    • 基础
    • String
  • Java 中级

    • 网络编程
  • Java 高级

    • JVM
    • 多线程
  • Spring
  • SpringMVC
  • SpringBoot
  • MySQL
  • Redis
  • MQ
  • ZooKeeper
  • git
  • linux
  • 设计模式
  • 数据结构与算法
  • 计算机基础
  • Java相关框架
  • 分布式
  • DDD领域驱动设计
  • 系统设计
  • 杂乱无章
Java知识图谱
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

qouson

Java界的小学生
首页
  • Java 基础

    • 基础
    • String
  • Java 中级

    • 网络编程
  • Java 高级

    • JVM
    • 多线程
  • Spring
  • SpringMVC
  • SpringBoot
  • MySQL
  • Redis
  • MQ
  • ZooKeeper
  • git
  • linux
  • 设计模式
  • 数据结构与算法
  • 计算机基础
  • Java相关框架
  • 分布式
  • DDD领域驱动设计
  • 系统设计
  • 杂乱无章
Java知识图谱
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • mysql

  • redis

    • Redis
      • 数据结构
        • 1.String
        • 字符串类型
        • 2.Hash
        • 哈希类型,存放键值对
        • 3.List
        • 列表类型,有序集合
        • 4.Set
        • 无序集合类型,通常用来去重,交集,并集
        • 微信抽奖小程序
        • 微信微博点赞,收藏,标签
        • 5.ZSet
        • 有序集合类型,有序集合,可以关联一个分数,通常用来做排行榜
        • 6.BitMap
        • 7.Geo
        • 8.HyperLogLog
      • Redis 为什么快
        • 1.单线程,避免上下文切换
        • Redis为什么早期选择单线程
        • Redis的多线程是怎么回事
        • 2.基于内存操作,避免磁盘IO
        • 3.使用多路I/O复用机制,非阻塞IO
        • I/O多路复用
        • 4.高效的数据结构
      • 数据持久化
        • 1.RDB:Redis DataBase
        • 2.AOF:Append Only File
        • 3.RDB和AOF同时开启
      • key过期策略
        • 1.定时删除
        • 2.惰性删除
        • 3.定期删除
        • Redis同时使用惰性和定期删除是比较好的策略
      • 高可用
        • 1.主从
        • 2.哨兵
        • 3.集群
      • 缓存
        • 双写不一致问题
        • 现象
        • 解决方案
        • 缓存穿透
        • 现象
        • 解决方案
        • 缓存击穿(失效)(只穿缓存,数据库还有数据)
        • 现象
        • 解决方案
        • 缓存雪崩(同时穿缓存,数据库没有数据)
        • 现象
        • 解决方案
      • 分布式锁
        • 普通锁
        • Redisson
        • Lock
        • RedLock
    • 版本介绍
    • redis分布式锁
    • 缓存淘汰策略
    • Redis_xiaolingcode
  • mq

  • zookeeper

  • 中间件
  • redis
qouson
2024-06-01
目录

Redis

# Redis

# 数据结构

# 1.String

# 字符串类型

  • 单值存储
    • SET key value
    • GET key
  • 对象存储
    • SET user:1 value(json数据)
    • MSET user:1:name zhangsan user:1:age 20
    • MGET user:1:name user:1:age
  • 分布式锁
  • 计数器
  • Web集群session共享
    • spring session + redis实现session共享
  • 分布式系统序列号
    • INCRBY orderId 1000,redis批量生成序列号提升性能
    • 拿批量到jvm,宕机浪费id,无所谓

# 2.Hash

# 哈希类型,存放键值对

  • key-(field-value)
  • 对象缓存,避免大key,可以分段
    • HMSET user 1:name zhangsan 1:age 20
    • HMGET user 1:name 1:age
  • 电商购物车
    • 以用户id为key,商品id为field,商品数量为value
      1. 添加商品:hset cart:1001 10088 1
      2. 增加数量:hincrby cart:1001 10088 1
      3. 商品总数:hlen cart:1001
      4. 删除商品:hdel cart:1001 10088
      5. 获取购物车所有商品:hgetall cart:1001
  • 优缺点
    • 优点:
      • 同类归类整合存储,方便管理
      • 相比string消耗内存和cpu小
    • 缺点:
      • 过期功能不能使用在field,只能使用在key
      • Redis集群架构不适合大规模使用

# 3.List

# 列表类型,有序集合

  • 栈(Stack)
    • LPUSH + LPOP
  • 队列(Queue)
    • LPUSH + RPOP
  • 阻塞队列(BlockingQueue)
    • LPUSH + BRPOP

# 4.Set

# 无序集合类型,通常用来去重,交集,并集

  • 集合操作
    • 交集----SINTER set1 set2
    • 并集----SUNION set1 set2
    • 差集----SDIFF set1 set2
  • 实现关注模型
    1. 诸葛关注的人,zhugeSet->{guojia,xushu}
    2. 杨过关注的人,yangguoSet->{zhuge,baiqi,guojia,xushu}
    3. 郭嘉关注的人,guojiaSet->{zhuge,yangguo,baiqi,xushu,xunyu}
    4. 诸葛和杨过共同关注,SINTER zhugeSet yangguoSet
    5. 关注诸葛的人也关注杨过,SISMEMBER guojiaSet yangguo
    6. 可能认识的人,SDIFF yangguoSet zhugeSet->{zhuge,baiqi}

# 微信抽奖小程序

  1. 点击参与抽奖加入集合,SADD key userid
  2. 查看参与抽奖所有用户,SMEMBERS key
  3. 抽取count名中奖者, SRANDOMKEY key count元素还在,SPOP key count会删元素

# 微信微博点赞,收藏,标签

  • 用户点赞
    • SADD like:{消息id} {用户id}
  • 取消点赞
    • SREM like:{消息id} {用户id}
  • 检查用户是否点赞
    • SISMEMBER like:{消息id} {用户id}
  • 获取点赞用户列表
    • SMEMBERS like:{消息id}
  • 获取点赞用户数量
    • SCARD like:{消息id}

# 5.ZSet

# 有序集合类型,有序集合,可以关联一个分数,通常用来做排行榜

  • 点击新闻
    • ZINCRBY hotNews:20190819 1 守护香港
  • 展示当日排行前十
    • ZREVRANGE hotNews:20190819 0 9 WITHSCORES
  • 七日搜索榜单计算
    • ZUNIONSOURT hotNews:20190813-20190819 7
  • 展示七日排行前十
    • ZREVRANGE hotNews:20190813-20190819 0 9 WITHSCORES

# 6.BitMap

布隆过滤器

# 7.Geo

基于经纬度计算距离

# 8.HyperLogLog

去重,统计UV

# Redis 为什么快

# 1.单线程,避免上下文切换

# Redis为什么早期选择单线程

官方解释:https://redis.io/topics/faq 官方FAQ表示,因为Redis是基于内存的操作,CPU成为瓶颈的情况很少,Redis的瓶颈最有可能是内存的大小或网络限制。

如果想要最大程度利用cpu,可以再一台机器上启动多个Redis实例。

# Redis的多线程是怎么回事

Redis6.0之前,Redis是单线程的,6.0之后,Redis引入了多线程。 Redis的多线程是用多线程来处理数据的读写和协议解析的,但是Redis执行命令还是单线程的。

这样做的目的是因为Redis的性能瓶颈在于网络IO,而不是CPU,使用多线程能提升IO读写效率,从而整体提高Redis的性能。

# 2.基于内存操作,避免磁盘IO

# 3.使用多路I/O复用机制,非阻塞IO

# I/O多路复用

知乎高赞回答,假如你是一个老师,让30个学生解答一道题目,然后检查学生做的是否正确,你有下面几个选择:

  • 1.按顺序逐个检查,先检查A,然后是B,之后是C,D。这中间如果有一个学生卡住,全班都会被耽误。这种模式就好比,你用循环挨个处理socket,根本不具备并发能力。
  • 2.你创建30个分身,每个分身检查一个学生的答案是否正确。这种类似于为每一个用户创建一个进程或者线程处理连接。
  • 3.你站在讲台上等,谁先解答完谁举手。这时C,D举手,表示他们解答完毕,你下去一次检查C,D的答案,然后继续回到讲台上等,此时E,A又举手,然后处理E和A。

第一种就是阻塞IO,第三种就是I/O复用。

Linux中,select,poll,epoll都是I/O复用模型。

# 4.高效的数据结构

# 数据持久化

# 1.RDB:Redis DataBase

  • 默认开启
  • 指定时间fork一个子进程,将内存数据dump到rdb文件中
  • save 60 10000,60秒内有10000修改,写dump.rdb
  • 优缺点
    • 优点
      • 只包含一个dump.rdb文件,方便持久化
      • 容灾性好,方便备份
      • 性能最大化,子进程处理写操作,主进程继续接收请求
      • 数据集大时候,比AOF效率高
    • 缺点
      • 数据安全性低,可能丢失数据
      • fork子进程,性能消耗,数据大时服务器会变慢

# 2.AOF:Append Only File

  • 日志形式记录写,删操作
  • 优缺点
    • 优点
      • 安全性高,数据完整
      • 即使中途dump机,不会破坏已同步内容,可用redis-check-aof解决一致性问题
      • AOF的rewrite机制,定期对AOF文件更新,以达到压缩目的
    • 缺点
      • AOF比RDF体积大,恢复速度慢
      • 数据集大时,比RDB效率低
      • 运行效率没有RDB高

# 3.RDB和AOF同时开启

# key过期策略

# 1.定时删除

  • key过期同时设置一个定时器,过期时间到后删除
  • 定时扫描,对内存友好,对cpu不友好

# 2.惰性删除

  • 访问key的时候,若过期,删除,对内存不友好,对cpu友好

# 3.定期删除

  • 隔一段时间,扫描一定数量的key,平衡内存和cpu

# Redis同时使用惰性和定期删除是比较好的策略

# 高可用

# 1.主从

# 2.哨兵

# 3.集群

  • 16384hash槽
  • 高可用,分片存储

# 缓存

# 双写不一致问题

# 现象

# 解决方案

  • √加分布式锁
  • 加canal,监听数据库binlog,及时修改
  • 延迟双删,删一次,sleep,再删一次

# 缓存穿透

# 现象

  • 自身业务代码或者数据出问题
  • 缓存中没有的数据,数据库也没有,可能是恶意攻击或者误操作,造成数据库压力过大,查询不应该存在

# 解决方案

  • 校验
  • 缓存空值(空缓存)(过期),返回空对象(空id,而不是null)
  • bitmap布隆过滤器,存在的数据hash到bitmap,不存在的则被拦截;某个值存在时,这个值可能不存在,当它说不存在,那就肯定不存在

# 缓存击穿(失效)(只穿缓存,数据库还有数据)

# 现象

  • 热点key,缓存没有数据库有,一般是过期,数据库单条记录瞬时压力大
  • 缓存大批同时失效

# 解决方案

  • 互斥锁(DCL)
  • 加随机失效时间
  • 热点数据永不过期

# 缓存雪崩(同时穿缓存,数据库没有数据)

# 现象

  • 娱乐热点事件
  • 缓存大面积失效

# 解决方案

  • 互斥锁(DCL)
  • 限流,Sentinel或Hystrix或队列
  • 多级缓存架构
    • √ Guava
    • √ EhCache

# 分布式锁

# 普通锁

  • 1.SETNX
    • 抛异常会执行不了,死锁
  • 2.SETNX+trycath
    • 宕机,死锁
  • 3.SETNX+expire+trycath
    • 设置key和expire原子性,系统宕机,死锁
  • 4.SETNX+expire+trycath
    • 原子性问题,锁超时失效,超高并发场景可能超卖
  • 5.SETNX+expire+trycath+uuid
    • 解锁原子性问题,在临界值删除别的线程加的锁
  • 6.SETNX+expire+trycath+uuid+lua

# Redisson

# Lock

  • redisson.getLock(key)
  • redisson.lock()

# RedLock

客户端要收到半数以上的响应才能加锁成功

编辑 (opens new window)
上次更新: 2024/06/01, 23:33:02
MySQL_xiaolingcode
版本介绍

← MySQL_xiaolingcode 版本介绍→

最近更新
01
杂乱无章
12-25
02
基础-大彬
11-14
03
集合-大彬
11-14
更多文章>
Theme by Vdoing | Copyright © 2023-2025 qouson
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式