分布式系统
特点:
1.系统各组件分布于网络上多个计算机上
2.我们部署的各功能组件彼此之间仅仅通过消息传递来通信,达到协调行动的目的。
满足这两点,你的系统就是分布式系统
分布式系统存在的意义:
向上扩展达到瓶颈:
1.即单机上无论你增加内存,磁盘,CPU个数,其性价比很难再提不上去了。
2.性能达到临界点后,性能将不升反降。
3.单点故障无法避免,故障后一切扩展都将不可用。
基于冯诺依曼的计算机架构,对于当前来说已经无法从单机上得到更好的整体系统性能。摩尔定律说计算机硬件技术会每18个月更新一次,在当今世界也在改变,硬件的提升会逐渐达到提升瓶颈,而数据则会在18个月后翻一倍,所以我们已经进入一个大数据的时代。另外,摩尔定义也向我们说明了一个问题,今天你花多大的价钱买的硬件,在一年半(18个月)后都会落后。
多CPU:
硬件技术进步,让单机计算能力出现了太多空闲,因此多线程编程技术就成为了最佳的提高性价比的方式。
多线程编程模型:
1. 互不通信的线程模型: 这些模型的性能是最好的,执行效率也是最高效的,但实用性可能不高。
2. 基于共享容器协同工作的模型:
A线程运行过程中,需要从B线程哪里获取一个结果,才能继续运行,若此时A线程直接去启动B线程,
这其实是相当麻烦的事,若借助中间容器,这里指队列,A线程通过将请求发给队列,然后,B线程
从队列中获取请求,执行结束后将结果再放回队列中,A线程从队列中获取结果后,就可以继续执行了。
这种就是共享容器模型,它可以实现让多个线程并行协同运行。
为了使这种共享容器模型在多线程并行时,访问数据更加安全,它又分为两种类型:
a. 线程安全
指A线程修改了共享容器中的A数据,而C去访问A数据或修改A数据也一样可以,它们之间都是
互相独立,互不干扰的,这种就称为线程安全的模型。
b. 线程不安全
指A线程修改了共享容器中的A数据,而C线程此时也去修改A数据,就可能导致A数据损坏,这种
就称为线程不安全。 对于线程不安全的类型,通常使用加锁的机制 或 Copy on Write(COW)
的方式来保障数据安全,在使用加锁的机制时,若并发线程数很多时,通常会使用互斥锁。
这种方式中线程之间是需要互相通信的,因此就会造成等待结果的一方将不能继续运行,所以这其实
就会降低多线程并行执行的效率了。
3.通过事件协调的多线程模型
B的某个执行流程依赖于A完成了某种特定操作之后才能进行。那么A就需要在某个特定操作完成之后,
触发一个事件,这个事件可以通知给B,所以B拿到这个事件后,就可以继续运行了,所以在A触发这个
事件之前,B就只能处于等待事件的状态。
多线程 和 多进程模型的区别:
线程之间是可共享父进程内部的很多资源,如:父进程打开的文件句柄,内部信号等等。
进程之间是互相隔离的,它们仅能通过进程间通信模式进行交互通信,所以多进程模型比多线程模型,在资源控制方面更为简单。
这些模型的出现,主要是为了使用多CPU,因为,单个CPU已经不能通过提升频率来提升其性能,目前芯片厂商都是通过增加CPU的核心数,借助于多线程编程,来解决单机上面性能的提升问题。但多线程编程又非常复杂,若程序员不能很好的利用多核心来编程,对于多核来说效益是很小的。
网络I/O:
1.通过阻塞模型,即一个请求过来,在处理它时,其它请求都被阻塞等待第一个请求处理完才能被接入进来进行处理,所以这种模型目前已不在使用。
2.多进程模型,即每个进程响应一个请求;
3.多线程,多进程,即每个进程生成多个线程,每个线程响应一个用户请求。
4.多线程,每个线程直接响应多个请求。
但是无论是那种方式,每一个请求进来都需要有一个对应的套接字。
基于socket实现网络通信开发,其实现方式主要有三类:
BIO: Blocking IO,即阻塞式IO:一个Socket套接字需要一个进程或一个线程来处理,那么连接的建立读数据写数据的过程都有可能产生阻塞,这种机制就是每进程 或 每线程响应一个请求的模式。
缺点:每个连接都要占用一个套接字. 【注:套接字有两种:连接和监听套接字】
NIO: Nonblocking IO,非阻塞I/O,它是基于事件驱动(Linux是epoll实现事件驱动的.)的思想,采用Reactor模式,实现响应。
优点: 一个套接字分配个一个线程,而一个线程可以处理多个套接字相关的工作。
AIO:异步IO模式,它也是基于事件驱动的思想,但它采用Proactor模式
如何把应用从单机扩展到多机?
输入、输出设备如何变化?
控制器如何变化?