这本书主要讲的是分布式的架构原则在Azure上的实现。
关于这本书,可以看这个链接https://docs.microsoft.com/en-us/azure/architecture/patterns/
以下是书中部分模式的笔记
1, Cache-Aside Pattern: 如何保证缓存里的数据是最新的。
大部分商业的缓存系统都提供read-through, write-through, write-behind等策略来保证缓存是最新的。
如果某个service当前使用的缓存没有提供这个功能的话,应用可以自己实现read-through策略,实现的时候,尤其需要考虑的一下几点:
1), 缓存数据的生命周期,如何失效
2),缓存数据更新策略,当缓存大小满呢了时候,需要丢弃哪些数据,LRU换出
3),缓存初始化
关于缓存更新,可以参照这篇文章
2, Circuit Breaker Pattern: 链路中断模式,其实就是当网络上发生故障(timeout, failed)或者throttling时的策略
一般客户端应用会采用重试机制,但是这有可能反而加剧了服务端的负载,加剧了服务中断的严重性。
可以在客户端和服务之间加一个代理,对异常进行处理,拦截客户端请求。
主要需要考虑的几点:
1)异常类型以及异常处理
2)保证可以恢复
3)日志
3, Compensating Transaction Pattern: 补偿事务模式,或者叫回滚事务模式
在分布式系统中,分布式事务中间过程一旦出现错误,有些情况下,rollback会比较困难,
一种策略可以创建一个新的事务,用来rollback之前的事务,好处是可以用统一的事务管理来操作,比如回滚事务失败了,可以重试等等
难点是如何准确定义回滚事务的操作。
4,Competing Consumers Pattern: 服务竞争模式
现在基于scale out的设计考虑,部署在cloud上的服务一般都可以是多份的,根据实时负载情况可以动态增减服务实例的。
客户端需要发送请求给这类服务时,中间可以加一个message queue作为通信方式,好处是解耦了客户端应用和服务
需要注意的地方是:message queue本身的性能,可靠性,可扩展性,以及多个服务实例竞争获取请求,以及处理失败等case
另外还有就是message本身有没有顺序要求。
在microsoft azure里面,可以使用service bus queue, 服务从service bus queue里面获取消息时,可以通过PeekLock把这个消息锁住,其他服务实例将看不到这个消息,保证不会有重复处理同一个消息的情况,在服务正确处理完消息之后,可以把它从queue里面最终删除,另外还可以加一个超时时间,如果服务处理消息过程中发生错误,比如服务crash了,那么超时之后,其他服务可以重新处理这个消息。
5, Compute Resource Consolidation Pattern
根据SRP模式以及现在流行的microservice的概念,每个模块最好功能都是单一的,这样从实现以及维护上来说都是比较好的,
但是和其他情况一样,不能过度设计,过犹不及,尤其是从性能上,运行代价上等可能都会有问题
解决方案就是把多个任务集中在一起,对于cloud 计算单元来说,这些任务就是一个原子任务,一起扩展,一起缩减
所以在consolidate 多个任务的时候,要考虑以下方面:
任务的伸缩性是否相似
任务的生命周期是否相似
安全性,
错误容忍性等
总之和scale相关的问题都要考虑到。
6, Command and Query Responsibility Segregtion Pattern (CQRS)
传统的CRUD都是针对同一个数据源,这会导致以下的问题
1)读写数据不一致,可以参考数据库隔离级别,以及每种隔离级别的优缺点
2)安全性和权限控制的难处
解决方案可以是把读写分离,读写从不同的model或者数据源
需要注意的地方是:
1) 如何保证分离后读写的数据一致性,比如做到最终一致性: 写操作可以是append only的,事件驱动的
7 Event Sourcing Pattern
传统的CRUD模型有一些限制,比如: 不易于扩展;在跨域多用户同时更新的情况下,数据冲突很容易发生;历史操作信息会丢失
可以采用存储源事件模式,好处是:
1)事件是不变的,可以采用只追加操作,由此可以提高性能和扩展性
2)事件本身包含更多的信息被保留下来
3)解耦事件和操作,提高客户响应,降低延迟,适合异步操作
8 External Configuration Store Pattern
主要是一点,开发service的时候需要考虑到,哪些配置是允许实时修改,立即生效的
9,Leader Election Pattern
这个模式在云服务上使用特别广泛,云服务一般都是多实例,可动态扩展的,但是有些操作是互斥的,就需要有机制来选一个leader的服务实例执行此操作
主要需要考虑的是:
1)算法需要时健壮的,对于各种错误都能最终选出leader
2)使用shared distributed mutext有可能会导致服务对外部(提供分布式共享mutext的服务)有依赖,是否会导致有single point of failure
3)leader 不工作的时候,重新选择leader的延迟,这个延迟设计为多少
在Azure上,可以使用BlobDistributedMutext
- An example illustrating the Bully Algorithm.
- An example illustrating the Ring Algorithm.
其实就是数据分片的一种技术:水平分片,
另外还有垂直分片