读书笔记——凤凰架构
周志明出的新书——《凤凰架构》。强烈推荐
地址:http://icyfenix.cn/
读书时,一些知识点简略记录一下。
========================================================================
事务
Local Transaction 单服务单数据源
为了保证数据库原子性和持久性,就只能在崩溃后采取恢复的补救措施,这种数据恢复操作被称为“崩溃恢复”Crash Recovery。
方式:
1.Commit Logging
首先将修改什么数据,数据位置,改成什么值等信息记录到日志中(在文件末尾顺序追加的方式记录,最高效的写入方式),在日志记录全都安全落盘后,db再根据日志信息对数据库数据进行修改,修改完成后,在日志中追加一条“结束记录”。
2.Shadow Paging
原数据暂且不动,复制出来一份,在copy上进行数据修改。数据修改完成后,最后将指针从原数据指向copy,最后的指针变化,被认为是原子操作。
它比Commit logging更加简单,但涉及隔离性和并发琐时,它的事物并发能力有限,因此高性能数据库中应用不多。
Commit Logging 存在一个巨大的先天缺陷:决不允许在事务提交之前就修改磁盘上的数据.
Write-Ahead Logging 提前写入
Undo Log 回滚日志 注明修改了哪个位置的数据、从什么值改成什么值,等等
在事务回滚或者崩溃恢复时根据 Undo Log 对提前写入的数据变动进行擦除
Redo Log 重做日志 此前记录的用于崩溃恢复时重演数据变动的日志就相应被命名为 Redo Log
Global Transaction 单服务多数据源
JTA Java Transaction API
XA 将事务提交拆分成为两阶段过程:准备阶段,提交阶段
分布式事务 多服务多数据源
CAP 定理(Consistency、Availability、Partition Tolerance Theorem)
三个特性最多只能同时满足其中两个
追求最终一致性的柔性事务:
可靠事件队列
那顺序就应该安排成最容易出错的最先进行,即:账号扣款 → 仓库出库 → 商家收款。
只许成功,不许失败
TCC 事务
它是“Try-Confirm-Cancel”三个单词的缩写。
不考虑隔离性的话,有可能发生超售的问题。
如果业务需要隔离,那架构师通常就应该重点考虑 TCC 方案,该方案天生适合用于需要强隔离性的分布式事务中。在具体实现上,TCC 较为烦琐,它是一种业务侵入式较强的事务方案,要求业务处理过程必须拆分为“预留业务资源”和“确认/释放消费资源”两个子过程。
好处:TCC 在业务执行时只操作预留资源,几乎不会涉及锁和资源的争用,具有很高的性能潜力。
坏处:更高的开发成本和业务侵入性,意味着有更高的开发成本和更换事务实现方案的替换成本。
SAGA 事务
必须保证所有子事务都得以提交或者补偿,但 SAGA 系统本身也有可能会崩溃,所以它必须设计成与数据库类似的日志机制(被称为 SAGA Log)以保证系统恢复后可以追踪到子事务的执行情况,譬如执行至哪一步或者补偿至哪一步了。另外,尽管补偿操作通常比冻结/撤销容易实现,但保证正向、反向恢复过程的能严谨地进行也需要花费不少的工夫,譬如通过服务编排、可靠事件队列等方式完成,所以,SAGA 事务通常也不会直接靠裸编码来实现
幂等性 让消息带上一个唯一的事务 ID
========================================================================
什么是 banner?
当你执行程序时,控制台中打印出来的图形标志就是bannder。你将一个banner.txt放在 路径(src/main/resources)下面,执行程序就可以了。
下面有一个编辑图形的网站,挺有意思,大家可以尝试自己的bannner:
https://devops.datenkollektiv.de/banner.txt/index.html
type可以选择 banner3
========================================================================
什么是 StopWatch?
它是Spring提供的计时器,StopWatch对于秒、毫秒为单位方便计时的程序,尤其是单线程、顺序执行程序的时间特性的统计输出支持比较好。也就是说假如我们手里面有几个在顺序上前后执行的几个任务,而且我们比较关心几个任务分别执行的时间占用状况,希望能够形成一个不太复杂的日志输出,StopWatch提供了这样的功能。而且Spring的StopWatch基本上也就是仅仅为了这样的功能而实现。
ADemo05 demo = new ADemo05(); StopWatch clock = new StopWatch(); clock.start("bruce"); System.out.println(demo.minPathSum(ss)); clock.stop(); System.out.println(clock.prettyPrint());
结果:
StopWatch '': running time = 708201 ns --------------------------------------------- ns % Task name --------------------------------------------- 000708201 100% bruce
界面效果还是很好的,省去手动打时间戳的麻烦了。
Stopwatch介绍摘自:
https://blog.csdn.net/ioe_gaoyong/article/details/22788789
========================================================================
to be continued...