0
点赞
收藏
分享

微信扫一扫

08-01 分布式系统理论

hwwjian 2023-05-12 阅读 68

本期是【你好,面试官】系列文章的第21期,持续更新中…。

《你好,面试官》系列目前已经连载 20 篇了,据说看了这个系列的朋友都拿到了大厂offer~

  • 欢迎星标+订阅,持续更新中。。。致力打造校招核心面试攻略~
  • Java 校招面试网站:www.java2top.cn

考点速查

本期考点涉及,JVMMySQL高级Redis持久化

本期题改编自 ——2023届春招 阿里 实习 二面

面试现场

叮叮叮…

面试官:“你好,我是XX面试官,请问是小龙吗?”

小龙:“您好,面试官,我是小龙”

面试官:“好的,现在有空吗,我们开始面试吧”

小龙:“嗯嗯,准备好啦”

other questions(自我介绍、项目略)

面试官:“我看你简历写熟悉 JVM,system.gc()一定会触发gc吗?和full gc有什么关系?”

独白:“wc,平时还真没关注过这个问题”

小龙:“system.gc() 可以显示触发 fullgc,以回收老年代和新生代,释放无用对象占用的内存,底层通过 Runtime . getRuntime() .gc() 调用。”

小龙:“但是这个显示调用附带免责声明,只是提醒 JVM 的垃圾收集器执行 Full Gc ,具体执行与否什么时候执行,还得看收集器。”

面试官:“好的,了解 Redis 持久化吗?”

小龙:“enen,是这样的,Redis 为了保证宕机能恢复数据,提供了持久化手段,可以采用RDB、AOF持久化,Redis4.x后更支持RDB、AOF混合持久化。”

面试官:“那说说 AOF 持久机制是怎样的?”

小龙:“简单来说,AOF 文件是将写操作命令按照约定的格式保存下来,若宕机顺序执行命令即可恢复数据;并且它采用 “写后日志”的模式,即 Redis 先执行命令写内存,后写日志;”

面试官:“为何采用写后日志呢?”

小龙:“嗯,首先 Redis 执行命令先写内存,这样可以对命令做预检,防止错误命令记录到日志;同时,记录AOF日志时,无须对语法做检查,因此写后日志还可以避免额外开销。”

小龙:“并且,由于是命令执行完后再写日志,也不会阻塞主进程写操作。”

面试官:“刚才你说 AOF 是一直追加命令,那随着时间推移,这个AOF文件不会越来越大吗,Redis是怎样处理的呢?”

小龙:“Redis 为了避免 AOF 文件越写越大,提供了 AOF 重写机制。”

独白:“关于小龙面试经典分析全记录在【面试笔记】中,有详细总结。”

面试官:“这个重写机制是怎样的呢?”

小龙:“简单来说就是,首先知道 AOF 里面存的写操作命令,但是很多条执行命令可能起到的效果最后只需要几条命令即可实现。”

小龙:“重写即把冗余的命令用新的命令替换,再将新命令记录到新的 AOF 文件中,最后再替换老的 AOF 文件。”

面试官:“那如果是大量写入,线程将会被长时间阻塞,Redis 是单线程的,这样就不能处理客户端的请求命令,怎么办?”

小龙:“主进程是通过 fork 一个 bgrewriteaof 子进程进行 aof 日志重写。由于后台新开进程重写,主进程可以继续处理命令请求,可以避免阻塞主进程。”

小龙:“但是fork子进程这个操作也是主进程实现,其中由于要复制父进程的页表等数据结构,若页表过大,便可能阻塞主线程。”

面试官:“那假如你在写原来的数据时,父进程又处理了新的命令,会造成子父进程数据不一致吗?”

独白:“这就有装逼得啦~”

小龙:“子进程进行日志重写时,若有新数据写入,主进程执行完命令后会将命令写入到 「AOF 缓冲区」和 「AOF 重写缓冲区」”

小龙:“然后,子进程重写完成后,会异步向主进程发送一条信号;”

小龙:“主进程接收到信息,便将 AOF 重写缓冲区中的所有内容追加到新的 AOF 的文件中,最后修改文件名,原子切换老文件,完成重写便保证了数据的一致性。”

面试官:“那如何开启AOF的?”

小龙:“可以手动触发,也可以文件配置。”

面试官:“具体说说呢?”

小龙:“可以通过配置 redis.conf 文件来开启 AOF 持久化 appendonly yes,同时需要联合配置同步策略,触发时机。但是 AOF 的重写需要 fork,这是一个重量级操作,可能会对 Redis 造成阻塞。”

小龙:“因此为了不影响 Redis 主进程响应,我们需要尽可能降低 fork 的频率,降低阻塞,可以通过 bgrewriteaof 手动来触发 AOF 重写。”

面试官:“Ok,我看你简历写了 MySQL,说说什么是 MySQL 两段提交吧?”

小龙:“其实所谓的两阶段就是把一个事物分成两个阶段(prepare、commit)来提交,而实际上开启两阶段提交只是为了保证 redolog 和 binlog 日志数据的安全一致性。”

小龙:“若你压根不需要使用 binlog 进行日志备份,主从复制相关的,其实完全可以不用两阶段提交,因为仅保证 redolog 成功写盘就可以保证 crash 的恢复啦。”

面试官:“能讲一下具体怎样提交的吗?”

小龙:“可以完整的分析一下,假如现在需要更新一条数据,前面肯定都知道会权限判断,词发语法分析,优化器生成最佳执行计划,准备执行,执行前还会记录 undolog 便于回滚,然后开始调用存储引擎执行 SQL。”

小龙:“此时若选用 InnoDB 引擎,会看 buffer pool 里有无相关数据,没有会将数据先加载到 buffer pool 进行更新;”

独白:“当然还涉及到唯一索引,普通索引等细节,这里不详细展开,具体可以看【面试笔记】”

小龙:“最后内存数据更新后,会将这个更新操作会记录到 redo log,redo log 处于 prepare 状态,告知执行器执行完,可提交事务。”

小龙:“执行器生产这个操作的 binlog,并将 binlog 写入磁盘,执行器调用引擎事务提交接口,引擎把刚写入的 redo log 改为 commit 状态,最后更新完成;”

小龙:“此刻整个过程完成,最后事务提交时便是分两个阶段提交。”

面试官:“Ok,用过 explain 吗,explain 语句会执行 SQl 吗?”

小龙:“explain 只走到优化器,要扫描多少行也只是个估计值,并没有实际执行。它只是一个执行计划,生成来自优化器关于 SQL 的执行信息,但是如果查询在 FROM 中子句包括子查询,MySQL 会执行子查询”

独白:“不愧是我,真男人是也!【面试笔记】在手,大厂 offer 不愁。”

知识总结

本期我们通过面试模拟还原阿里二面。订阅+星标持续追更。

面试重点

Redis 持久化机制MySQL undoLog 日志

举报

相关推荐

0 条评论