进程
虽然进程构成了分布式系统中的基本组成单元,但是操作系统提供的用于构建分布式系统的进程在粒度上还是太大了,而就粒度而言,将每个进程细分为若干控制线程的形式则更加合适。
为了程序执行的需要,操作系统创建多个虚拟处理器,每个虚拟处理器运行一个程序。为了保持对这些虚拟处理器的跟踪,操作系统中有一张进程表。其包含的条目中存储着CPU寄存器值、内存映像、打开的文件、统计信息、特权信息等。
操作系统特别注意确保独立的进程不会有意或无意地破坏其他独立进程运行的正确性。也就是说,多个进程并发地共享同一个CPU以及其他硬件资源这样一个事实是透明的。一般来说,操作系统需要硬件支持来实现这种隔离。要得到这种并发透明性需要付出相对较高的代价。例如:每次创建一个进程的时候,操作系统必须分配一个完整的独立地址空间。空间分配意味着要对内存段进行初始化,比尔先对数据段清零,然后将相关的程序复制到文本段中,随后为临时数据建立堆栈等。
在两个进程之间切换CPU的开销同样会比较大,除了要保存CPU环境(包括寄存器值、程序计数器、堆栈指针等)以外,操作系统还必须修改内存管理单元的寄存器,并且将位于转换后备缓冲器中的地址转换缓存内容标记为无效,另外,如果操作系统支持同时运行的进程数目超出主存容纳能力,则必须在切换进程之前现在主存和磁盘之间进行交换。
非分布式系统中的线程用法
多线程最显著的好处来自以下事实:那就是在只拥有单线程的进程中,一旦执行了造成阻塞的系统调用,整个进程就被阻塞了。
多线程技术在大型应用程序上下文中也是很有用的。这种应用程序一般是作为一组写作的程序开发出来的,其中每一个程序都通过独立的进程进行。例如UNIX系统,程序间写作是通过进程间通信(IPC)机制实现的。这套机制中通常包括已命名管道、消息队列以及共享内存段。左右IPC机制都有一个主要的缺陷,就是其中的通信需要开销庞大的上下文切换:
由于IPC需要内核干预才能进行,因此,要进行IPC的进程一般首先要从用户模式切换到内核模式,需要改变MMU中的内存映像,同时还要刷新TLB。在内核中进行进程上下文的切换,随后就可以从内核模式切换回用户模式以使得通信的另一方能够激活。后一次切换也同样需要改变MMU映像并且刷新TLB。
一般采用用户级线程和内核级线程的混合模式(LWP),LWP运行在单个重量级进程的上下文中,每个进程可以包含多个LWP,除了LWP外,系统还提供用户级线程包,向应用程序提供了创建和销毁线程等普通操作。另外,包中还提供了用于线程同步的工具,比如互斥变量和条件变量。重要的是,线程包完全在用户空间中实现的。也就是说,执行这些线程操作不需要内核的干预。
分布式系统中的线程
1、多线程客户
在广域网上构建的分布式系统需要隐藏较长的进程间消息传播的时间。在广域网中,传输的延迟很容易达到上百毫秒,甚至几秒。
在很多情况下,Web文档是由HTML文件组成的,HTML文件中包含有纯文本文件以及图像组、图标等。为了获得Web文档中每一个组成部分,浏览器必须建立TCP/IP连接,读取输入数据并将数据传递给显示组件。首先将文本显示出来以便用户查看,并且提供页面滚动之类的功能,同时继续获取组成页面的其他文件,比如图像等。在收到这些文件之后再显示它们。用户不必等待浏览器取得整个页面的所有组件就能够查看页面。
以多线程客户的模式来开发浏览器可以显著地使问题简化。每个线程都与服务器简历一个独立连接以获取数据。在使用多线程客户的时候,可以与不同服务器副本建立连接,这样就可以并行地进行数据传输了,并且确保整个Web文档完全显示出来所需的时间与使用无复制的服务器的情况相比要短得多。
2、多线程服务器
考虑一下文件服务器的组织结构,该文件服务器可能会偶尔由于等待磁盘操作而阻塞。文件服务器一般等待输入的文件操作请求,随后执行该请求,最后送回应答。下图中,有一个称为分发器(dispatcher)的线程,由它来读取文件操作请求。客户发送请求到服务器的某个已知端点。在对请求进行检查以后,服务器选择一个空闲的(也就是阻塞的)工作着线程,由它来处理该请求。
工作者线程在本地文件系统上执行阻塞的read调用,执行该调用将会导致该线程被挂起直到数据从磁盘上读出为止。如果该线程被挂起了,就选择另一个线程接着执行。
简单总结下服务器集群。
简单说,服务器集群只是一组经网络连接的机器,每台机器运行一个或多个服务器,这里所讲的服务器集群是特指经局域网连接的机器,能提供高带宽和低延迟。
大多数情况下,服务器集群逻辑上由三层组成,第一层是一个逻辑上的交换机,由它分配客户请求给服务器。在功能上比如:传输层交换机接收TCP连接请求,再转发给集群中的某个服务器。
就像所有的多层客户-服务器体系结构一样,很多服务器集群也包含了专用于应用处理的服务器。在集群计算中,这通常是运行在高性能硬件上专用于提供计算能力的服务器。然而,在企业服务器集群中,应用程序可能只需运行在相对低端的机器上,因为在这里的平静不是计算能力而是数据存取。 当然现在的诸如Hadoop分布式计算框架已经不是三层结构,每台机器都有自己的本地存储,把应用和数据处理集成在单个服务器中。
第一层:一个重要的服务器集群设计目标是隐藏有多个服务器的事实。也就是说,运行在远程机器上的客户应用程序不应该需要知道集群的内部组织结构。这种存取透明性通过单个访问点来实现(就好比你调用spark的thriftserver服务,传入一个sql,并返回结果给你,你并不知道是由几个节点运算的)。
一个标准的存取服务器集群的方式是简历一个TCP连接,在这之上应用级别的请求可作为一个会话的一部分来发送。通过撤除连接可结束会话。在传输层交换机的情况下,交换机接受到来的TCP连接请求,转发一些请求给一台服务器。