【总结】MyBatis、Redis、RocketMQ

2022/1/11 19:08:17

本文主要是介绍【总结】MyBatis、Redis、RocketMQ,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、MyBatis

4.1 MyBatis核心组件

image-20210928163549787

image-20210928165719139

image-20210928165819040

4.2 SqlSession执行过程

image-20210928170123433

二、Redis

5.1数据类型

image-20210928170707337

视频、很大的文件可以转为二进制后,存在string的redis里面。但是注意最大为512M

image-20210928171014328

5.2线程模型

1.单线程的前提

  • Redis的网络IO和键值对读写是由一个线程来完成的;

  • Redis的其他功能,如持久化、异步删除、集群数据同步等,则依赖其他线程来执行;

2.单线程的优劣

  • 单线程可以简化数据结构和算法的实现,并且可以避免线程切换和竞争造成的消耗;

  • 如果某个命令执行的时间过长,会造成其他命令的阻塞;

3.单线程的IO模型

  • Redis的大部分操作是在内存上完成的;
  • Redis采用 了IO多路复用机制,可以并发处理大量的客户端请求。

image-20210928172004580

IO多路复用:一个线程可以监听多个文件描述符(socket描述符)

传输媒体的带宽或容量往往会大于传输单一信号的需求,为了有效地利用通信线路,希望一个信道同时传输多路信号,这就是所谓的多路复用技术

将就绪的socket丢到套接字队列里,排队。文件事件分派器去根据socket的不同状态调用不同的事件处理器。

单线程指的是IO多路复用哪里是单线程的。后面还是多线程。

好处:同时有上万个连接接入,而同时激活态只有几百个进入队列,那么分派一个线程池几十个线程就能解决这个问题。

5.3持久化机制

1、RDB持久化

  • Redis默认采用的持久化方式;
  • 以快照的形式将数据持久化到硬盘中(即将内存中的数据序列化二进制存到硬盘里,);

快照的持久化会耗时,还会造成阻塞,适合用来冷备份,例如一天备份一次。不适合用来做实时持久化。要想实时持久化就用AOF

  • 通过bgsave命令触发, 手动、自动均可;

2、AOF持久化

  • 以独立日志的方式,记录每次写入的命令;(执行一个命令,将命令追加到一个日志里,每次执行都追加)
  • 实时性好,在保证性能的前提下,可以做到最多丢失1秒的数据(刷盘频率) ;(写日志也是把数据先写到页缓存里再刷新到磁盘里,刷新频率参数可配。)
  • 比RDB的文件体积大,可以通过重写机制压缩AOF文件的体积;

3、RDB-AOF混合持久化

  • 从Redis 4.0开始支持,基于AOF实现;
  • 在AOF重写时,先执行bgsave命令 生成RDB文件,再将新处理的命令追加到AOF文件的末尾。

RDB的实现机制

image-20210928173423688

在什么情况下RDB会阻塞?

bgsave命令出发RDB,调父进程来创建一个子进程,通过子进程持久化数据,父进程还要响应正常的命令。即持久化的时候有两个进程在做这个事情。

创建子进程fork函数时,父进程会被阻塞,但是速度很快,阻塞很短。

子进程创建之后,父进程解决阻塞,响应其他命令。子进程读父进程的内存数据,并将其存到RDB文件里。

一边持久化一边改,冲突?父子进程的同时读写是基于写时复制技术,不会产生阻塞

父进程将数据存在内存里,是多页的。子进程持久化时和父进程要修改的页是同一个时,父进程会将该页复制一个副本,再进行修改。

所谓快照就是在fork出子进程时,父进程内存的数据相当于照一张相,这些数据不会动了。

AOF的实现机制

image-20210928174651698

把命令写到缓冲区里,aof有一个同步机制,写道旧AOF文件里,可以用于重启服务时恢复数据。

AOF怎么重写的?

每次命令的追加,文件逐渐增大。到一定大小就要压缩。

通过bgrewriteaof命令重写(先判断是不是AOF重写或者RDB持久化),通知父进程fork一个子进程,子进程去产生新的压缩后的AOF文件。父进程解除阻塞后,继续往aof_buf写,同时记录rewrite_buf在子进程产生文件时追加的命令,最后同步到新AOF文件中。当子进程写好了,通知父进程,父进程再响应命令的时候就不会往rewrite_buf写入,但会把rewrite_buf同步到新AOF文件里,新的文件就会替换旧的文件。

rewrite_buf:记录在重写期间新的命令的,重写完成后将其命令刷到新AOF文件里

创建子进程fork函数时,父进程会被阻塞,但是速度很快,阻塞很短。

5.4分布式缓存

缓存的淘汰策略

数据过期策略

  • 惰性删除:
    访问一个key时,Redis会先检查它的过期时间,若发现过期则立刻删除;(如果只有惰性删除机制,如果你不访问,key也过期了,那就不会被删除,一直占用内存)
  • 定期删除:
    1.将设置过期时间的key放入-个独立字典中;
    2.对该字典进行每秒10次的扫描,并删除扫描到的已过期的key;
    3.扫描采用贪心策略,每次随机20个key,若已过期比例超过25%则再次随机。

内存淘汰策略

当写入数据发现超出maxmemory限制时,则采用指定的策略进行删除:

image-20210928180406144

image-20210928180453218

缓存与数据库的同步

  • 被动:缓存数据因到期被淘汰,下一次数据库的查询会将数据同步到缓存;
  • 主动:先更新数据库,再删除缓存,建议采用这样的方式。(不是更新缓存而是删除,是因为你更新缓存,可能这个key会用不到,那这次操作就浪费了。删除后,下次用的时候从数据库里面存到缓存里就可以了)

在出现错误的情况下对比:

image-20210928180938390

ps:第一个图的第一步为delete

读到旧数据比不同步好

在不出错的情况下对比:

image-20210928181545970

对比以上发现:先更新数据库,再删缓存更合理

如果项目中放进缓存的数据没有写数据库更新的业务逻辑,那么缓存可以设置一定时间失效,再加载。

缓存穿透

客户端查询根本不存在的数据,使得请求直达存储层,导致其负载过大,甚至宕机可能是业务层误将缓存和库中数据删除了,也可能是有人恶意攻击,专门访问库中不存在的数据。

解决方案:

1.缓存空对象:存储层未命中后,仍然将空值存入缓存层,客户端再次访问数据时,缓存层会直接返回空值;
2.布隆过滤器:将数据存入布隆过滤器,访问缓存之前以过滤器拦截,若请求的数据不存在则直接返回空值;

缓存击穿

一份热点数据,它的访问量非常大。在其缓存失效的瞬间,大量请求直达存储层,导致服务崩溃。

解决方案:

1.永不过期

  • 热点数据不设置过期时间,所以不会出现.上述问题,这是"物理"上的永不过期;

  • 为每个数据设置逻辑过期时间,当发现该数据逻辑过期时,使用单独的线程重建缓存;

2.加互斥锁
对数据的访问加互斥锁,当一个线程访问该数据时,其他线程只能等待。这个线程访问过后,缓存中的数据将被重建,届时其他线程就可以直接从缓存中取值。

缓存雪崩

和缓存击穿不一样,缓存击穿是一个数据失效,而缓存雪崩是指整个缓存层redis挂了。

在某一时刻,缓存层无法继续提供服务,导致所有的请求直达存储层,造成数据库宕机。可能是缓存中有大量数据同时过期, 也可能是Redis节点发生故障,导致大量请求无法得到处理。

解决方案:

1.避免数据同时过期
设置过期时间时,附加一一个随机数,避免大量的key同时过期;

2.启用降级和熔断措施
在发生雪崩时,若应用访问的不是核心数据,则直接返回预定义信息/空值/错误信息;在发生雪崩时,
对于访问缓存接口的请求,客户端并不会把请求发给Redis,而是直接返回;

3.构建高可用的缓存服务
采用哨兵或集群模式,部署多个Redis实例,个别节点宕机,依然可以保持服务的整体可用。

三、RocketMQ

消息存储

image-20210928205159813

生产者向截点发数据,把它存在CommitLog里面。每一个主题有一个ConsumerQueue。他的数据不是放在内存里的,是持久化的不会丢消息。

不是基于内存而是基于磁盘,因为磁盘随机读写性能很差,所以才有了上面的设计,(不管什么主题顺序写,每个队列拿到对应的主题,顺序读)

image-20210928205851651

image-20210928205955146

image-20210928210100512

消息刷盘

  • 同步刷盘
    只有在消息真正持久化至磁盘后RocketMQ的Broker端才会真正返回给Producer端一个 成功的ACK响应。同步刷盘对MQ消息可靠性来说是一种不错的保障,但是性能上会有较大影响,-般适用于金融业务应用该模式较多。

  • 异步刷盘
    能够充分利用OS的PageCache的优势,只要消息写入PageCache即可将成功的ACK返回给Producer端。消息刷盘采用后台异步线程提交的方式进行,降低了读写
    延迟,提高了MQ的性能和吞吐量。

image-20210928210230448



这篇关于【总结】MyBatis、Redis、RocketMQ的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程