Redis相关知识

1、小的知识点
  • Redis是单线程工作的,作用:缓存、数据库、消息中间件

  • 支持的数据结构:String、List、Set、Hash、Zset, Bitmaps、Hyperloglogs 、Geospatial

  • Redis默认有16个数据库,端口默认是6379

  • redis事务单条保证原子性,但是整体不保证原子性

  • springboot2.0之后默认使用的是 Lettuce 连接Redis

  • 和memCached的区别

    • memCached的value没有类型之分
2、常用命令
- incr 变量: 变量+1
- decr 变量: 变量-1
- mult 开启事务
3、Redis持久化方式
  • RDB(Redis Data Base):把内存中的数据以快照的形式写入磁盘,实际操作中是通过fork一个子进程来写的

    • 环境变量 子进程的修改不会影响父进程的,父进程的修改不会破坏子进程(copy on write机制)
    • 手动触发落盘 save — 关机维护
    • 自动触发: 900 1:900秒内操作了1次; 300 10; 60 10000: 60秒内操作了10000次
    • 缺点:时点和时点之间的数据容易丢失,优点:恢复数据的速度快,对系统性能影响小,fork子进程去做数据持久化的
  • AOF(append only file):以文本日志的形式记录Redis处理的每一个写入、更新、或者删除的操作

    • 丢失数据少,写入性能惊人

    • RDB和AOF可以同时开启,但是数据恢复的时候只用AOF

    • 恢复的时候相对于RDB慢,而且文件体量大

    • rewrite 优化措施:重写并优化aof文件,4.0以后优化aof文件的时候是先RDB,然后增量aof,增量的aof只是在rdb的过程中的执行的命令

      优化时机:

      • 可以手动,
      • 也可以在配置文件中配置为自动: auto-aof-rewrite-min-size(只有最开始的时候使用) 和 auto-aof-rewrite-percentage这2个参数, auto-aof-rewrite-percentage表示当前AOF文件大小相对于最后一次重写后aof文件的大小增长的百分比,当超过这个百分比进行重写
    • 触发时刻: no always:有数据操作就持久化一次 seconds

4、NIO BIO AIO
  • BIO: block IO,阻塞IO,对于客户端的每个IO连接,服务端创建一个线程去通信,阻塞等待客户端发送消息
  • NIO:not block IO,非阻塞IO,
5、select、poll、epoll
  • 参考文章:

    • https://www.cnblogs.com/tianzeng/p/9997432.html

    • https://blog.csdn.net/wteruiycbqqvwt/article/details/90299610

    • https://zhuanlan.zhihu.com/p/64138532?utm_source=com.huawei.works&utm_medium=social&utm_oi=815957394881388544

  • select: 同步多路IO复用,在一段时间内,内核帮助用户监听用户感兴趣的文件描述符的可读、可写、连接信息等,循环遍历描述符,一旦其中有一个描述符就绪了(可读、可写、有客户端连接),则内核将所有的文件描述符拷贝给程序,程序再去遍历所有文件描述符,找到就绪的,然后对应后续操作,用数组 fd_set来存放文件描述符,大小由FD_SETSIZE指定,一般是1024

  • poll:采用链表存放文件描述符,文件描述符不受限制,其他和select一样。时间复杂度O(n)

  • epoll

6、同步异步、阻塞非阻塞区别
  • 同步和异步关注的是消息通信机制,阻塞和非阻塞关注的是程序在等待结果的时候的状态

  • 同步指发出一个调用时,在没有得到结果之前,该调用就不返回,得到结果后直接返回。强调的是被调用方得到结果之后再返回给调用方

    而异步则是相反,调用在发出之后,这个调用就直接返回了,所以没有返回结果,返回结果可能后续再通知调用者

  • 阻塞调用是指调用结果返回之前,当前线程会被挂起, 非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。

举个通俗的例子:

你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。
而异步通信机制,书店老板直接告诉你我查一下啊,查好了打电话给你,然后直接挂电话了(不返回结果)。然后查好了,他会主动打电话给你。在这里老板通过“回电”这种方式来回调。

而阻塞调用说的是你在等老板消息的时候一直在等着,不做其他的任何事,非阻塞调用指你在等老板消息的时候去看了个电影

7、布隆过滤器

参考文章:https://zhuanlan.zhihu.com/p/43263751

  • 布隆过滤器主要解决redis缓存穿透的问题

  • 缓存穿透:前台调用后台接口获取数据时,后台先从redis缓存中获取数据,如果缓存中没有数据,则从数据库去取,然后将数据刷新到redis。

    缓存穿透是指用户不断发请求获取缓存和数据库中都没有的数据,数据库白白建立连接,搜索,压力过大有可能扛不住崩溃

  • 布隆过滤器原理:

    使用一个bit数组,存储key hash后在数组中的位置

8、redis作为缓存的知识
  • 缓存的数据不是全量数据,追求的是极速,全量数据最好放在数据库中,数据应该随着访问的变化而变化,也即热数据

  • 做到热数据有2个方面:

    • 内存有限,当内存达到最大时,再新增数据的话有一定的策略

      • 直接抛出异常
      • LFU清除数据:最少访问次数
      • LRU:多长时间没访问
    • key的有效期,当老化时间到后,数据会被删除:

      • 主动:测试随机20个keys进行过期相关检测,过期的删除,若过期数量超过25%,继续循环
      • 被动:被访问后才会被删除
      • 访问之后不会延长过期时间
      • 写之后会剔除过期时间
      • 可以倒计时和定时,redis不能延长
9、redis 是单线程还是多线程
  • Redis的工作线程只有一个
  • 6.x高版本后出现了IO多线程,把输入输出放到了多线程中去处理,但是工作线程依然是单线程的
    • 执行时间缩短,更快
    • 更好的压榨系统及硬件的资源
  • 对于使用来说是没有变化的
10、redis是线程安全的么

redis内部是单线程串行的,但是业务上的线程安全需要用户自己保证

11、缓存穿透及解决办法
  • 缓存穿透:用户调用请求获取 redis缓存和数据库中都没有的数据,就好像穿透了缓存一样,这样会导致数据库空查询
  • 解决措施:
    • 当从数据库获取不到数据时,在redis中放置一个空value
    • 访问数据的接口增加校验
    • 布隆过滤器
    • 加锁:
12、缓存击穿及解决办法
  • 缓存击穿:某个热点key过期,数据库中存在数据,大量获取该key的并发请求打到数据库上

  • 解决方法:

    • 设置热点数据永不过期

    • 接口限流和熔断降级

    • 加锁:

      • 请求redis,redis中没有
      • 大家抢锁(Redis中取不到数据的时候才会抢锁)
      • 抢上的访问DB,回写Redis数据
      • 没抢上的sleep一段时间,重新请求redis,发现redis中存在,直接获得,若还不存在抢锁,继续
13、如何避免缓存雪崩
  • 缓存雪崩:大量热点数据在一个时间段内集中失效,导致大量请求打到DB上
  • 解决方法:
    • 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
    • 加锁
14、缓存是如何回收的、怎么删除过期key的
  • 主动方式:定时随机测试:测试随机的20个keys进行相关过期检测,删除所有过期的keys,如果多于%25的key过期,继续循环。
  • 被动方式:被访问的时候清除过期的key
15、缓存是如何被淘汰的

一般淘汰只内存不足的情况下会发生淘汰

  • LRU:优先移除最近未使用的

  • LFU:优先移除使用次数最少的

  • random:随机移除

  • ttl:移除更早过期时间的

    分volatile 和 all keys, volatile只在过期的key中删除, allKey在所有key中删除

16、如何进行缓存预热
  • 提前把数据塞入redis中
  • 开发逻辑上要规避差集
17、数据库和缓存不一致怎么解决
18、Redis为什么这么快
  • Redis是内存数据库,绝大部分请求都是内存操作
  • 数据结构简单,对数据的操作简单
  • 采用单线程,避免不必要的上下文切换和竞争条件,不用考虑锁的问题,不存在因为加锁和释放锁而导致的死锁
  • 使用多路IO复用模型
19、主从之间的数据是怎么同步的

启动一台slave 的时候,他会发送一个psync命令给master ,如果是这个slave第一次连接到master,他会触发一个全量复制。master就会fork一个子进程,生成RDB快照,还会把新的写请求都缓存在内存中,RDB文件生成后,master会将这个RDB发送给slave的,slave拿到之后做的第一件事情就是写进本地的磁盘,然后加载进内存,然后master会把内存里面缓存的那些新命令都发给slave。如果不是第一次连接master;

日常的同步是增量的同步,参考文章:redis如何实现主从数据的同步 - Andy_1i - 博客园 (cnblogs.com)

20、经典的KV、DB读写模式
  • 读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
  • 更新的时候,先更新数据库,然后再删除缓存
21、redis主从不一致
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值