本篇博客是一篇读书笔记和归纳
分布式系统介绍
分布式系统的定义
在很多的书和很多的博客里都没有找到一个准确和让人完全认同的定义,在国外的一本书里有这样一个定义:A distributed system is one in which component located at networked computers commucate and coordinate their actions by passing messages.
翻译一下就是:分布式系统就是组件分布在网络上,组件之间仅仅只通过消息传递来通信和协调工作。
分布式系统看起来就像一个超级计算机一样。
首先分布式系统一定是由多个节点组成的系统,一个节点可以简单理解为一台计算机。这些节点之间是可以互相通信的。从这个角度看,我们使用的互联网就是一个分布式系统。
使用分布式系统主相对于使用一个单独的系统的好处在于:
- 升级单机处理能力的性价比越来越低
- 单机处理能力存在瓶颈
- 稳定性和可用性上分布式系统更好
如何把应用从单机扩展到分布式
计算机之父冯罗伊曼,提出的计算机是由5个部分组成的,分别是:
- 输入设备
- 输出设备
- 运算器
- 控制器
- 存储器(包括内存和外存)
当应用从单机扩展到分布式之后,以上的部分都会有一些区别
名称 | 单机 | 分布式 |
输入设备 | 人机交互的输入,如鼠标键盘 | 来自与分布式系统中其他节点的输入+人机交互的输入 |
输出设备 | 人机交互的输出,如显示器 | 向其他节点传递的信息+人机交互的输出 |
运算器 | 具体的电子元件 | 多个节点的运算器组成 |
控制器 | CPU中的控制器 | 协调控制节点之间的动作和行为 |
存储器 | 内存+外存 | 把多个节点组织在一起,使得它们看起来像使用一个存储器 |
分布式系统的难点
缺乏全局时钟
在单机系统中,程序以单机的时间为准,控制时序比较容易。在分布式系统中,每个节点都有自己的时钟,在他们互相通信的时候再按照时序会比较难处理。
解决方案是通过一个集群来区分多个动作的先后顺序即可。
面对故障独立性
在分布式系统中,整个系统的一部分有问题而其他部分正常,称之为故障独立性。这种情况经常出现
处理单点故障
在分布式系统中,若某个功能只有某一台机器在支撑,那么这个节点称为单点,其发生的故障称为单点故障。
在分布式系统中应当尽可能避免出现单点。若无法避免,可以通过以下两种方式解决问题:
- 给这个单点做好备份
- 降低单点故障的影响范围
事务的挑战
相对来说,单一机器的事务简单许多,分布式系统解决事务问题是一个重要的部分。
大型网站架构演进过程
大型网站:访问量大+数据量大
单机负载:
集群
服务器压力变大后,让应用服务器从一台变为两台,通过负载均衡器解决服务器选择的问题
服务器变为集群之后的session问题
http协议是无状态的。session机制是:在会话开始时,分配一个唯一的会话标示-SessionId,通过cookie把这个标识告诉浏览器,以后每次请求的时候,浏览器都会带上这个sessionId来告诉web服务器请求是属于哪个会话的。
在web服务器上,各个会话有独立的存储,保存不同的会话信息。
遇到cookie禁用,一般做法是把这个sessionId放到url的参数中。如下:
集群服务器的session问题是指:由于session的数据是保存在每一个web服务器的单机上的,如果第一次访问网站时请求落到了某一个服务器上,那么session就创建和保存在那个服务器上了。如果不做任何处理,在接下来的请求中是无法保证每次请求都落在同一边的服务器上的。这就是session的问题。
解决方案:
1.Session Sticky
在负载均衡器上做一些改进,让它能每一次根据请求的sessionId进行请求转发
2.session replication
不在负载均衡器上做改进,在所有的web服务器之间建立session同步的一套机制。如果只有几台机器,可行。
3.session数据集中存储
和第二种方案类似,但是这里是直接把所有的session维护在了一个地方,让不同的web服务器都从这儿去取。
web服务器数量大时,这个方案优势比较明显
4.Cookie based。
不太推荐
服务器变为集群之后数据库压力大
读写分离
不同的数据库用不同的支持,如mysql支持Master(主库)+slave(备库)
若在读写分离之后又遇到瓶颈
读写分离之后-垂直拆分
把不同的业务数据拆分到不同的数据库
读写分离之后-水平拆分
把同一个表的数据拆到两个数据库
但是在拆分之后,应用也会面临一些挑战和问题
拆分之后的问题
分布式事务如何处理?
CAP理论
Consistency(一致性), 数据一致更新,所有数据变动都是同步的
Availability(可用性), 好的响应性能
Partition tolerance(分区容忍性) 可靠性
定理:任何分布式系统只可同时满足二点,没法三者兼顾。
忠告:架构师不要将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍。
采用的方式:保证A和P,对于C,保证最终一致,不保证数据变化后所有节点立刻一致,但是保证它们最终是一致的。
由此得出的解决方案:消息事务+最终一致性
所谓的消息事务就是基于消息中间件的两阶段提交,本质上是对消息中间件的一种特殊利用,它是将本地事务和发消息放在了一个分布式事务里,保证要么本地操作成功成功并且对外发消息成功,要么两者都失败,开源的RocketMQ就支持这一特性