第七章分布式共享内存
- 格式:doc
- 大小:2.08 MB
- 文档页数:8
前言面向对象中间件体系结构a)主机基础设施中间件:封装socket,线程等不同主机的实现,形成统一的接口。
如java,ACEb)分布式中间件:连接管理,内存管理,整编,解编,端点和请求的多路分离,同步,多线程等,使程序员象开发独立应用程序一样开发分布式应用程序。
分布式中间件的核心是ORB(Object Requests Broker对象请求代理),如:COM+,JAVA RMI,CORBA 1通信设计空间1.1面向连接协议需要做出如下设计:●数据成帧策略●连接多路复用策略1.链接多路复用:多个线程复用同一个TCP链接2.非多路复用:多个进程使用多个链接。
系统开销大1.2同步和异步消息交换1.3消息传递与共享内存消息传递:消息中间件共享内存:●本地共享内存:shmget(),shmat(). 内存映射文件●分布式共享内存:虚拟内存,是本地共享内存的一种抽象。
2SOCKET API 概述3ACE Socket wrapper façade3.1ACE_Addr运算符== , !=addr_type, addr_size3.2ACE_INET_Add3.3ACE_IPC_SAP为其他ACE对象提供了基本的“I/O”句柄操作能力enable()disable()get_handle()set_handle()3.4ACE_SOCK继承自ACE_IPC_SAP,get _local_addr()set_local_addr()open()close()get_remote_addr()set_option()get_option()3.5ACE_SOCK_Connecter主动连接模式,是一个工厂类。
发起一个连接,并在连接成功后初始化一个ACE_SOCK_Stream对象。
可以通过“阻塞”“非阻塞”“定时”方式发起。
以下是非阻塞模式以下是非阻塞模式3.6ACE_SOCK_Stream数据传输角色的实现。
第六章分布式共享存储器在第一章中,我们看到存在着多处理机和多计算机这样两种多处理机系统。
在多处理机系统中,两个或更多的CPU共享一个存储器。
任何处理机上的任何进程只需将数据移入移出就可读写共享存储器中的数据。
而在多计算机系统中,每个CPU有各自的存储器,并不共享。
以农业为例,一个多处理机可以看作这样一个系统:一群猪(进程)用一个食槽(共享存储器)进食。
而多计算机则是每只猪拥有自己的食槽。
以教育为例,多处理机就是教室前面的一块黑板,所有学生都可以看到,而多计算机则是每个学生看自己的笔记本。
尽管这种区别看起来微不足道,其影响却是深远的。
其结果涉及到软件和硬件两个方面。
首先看看对硬件的影响。
设计一种使多个处理机同时使用同一存储器的机器是非常困难的。
如1.3.1节所述, 由于总线会成为一种瓶颈, 基于总线的多处理机总数就最多只能有几个。
1.3.2节介绍的交换式多处理机可应用于大系统,但相比之下过于昂贵、缓慢、复杂以及难维护。
相反,大的多计算机系统更易于建立。
单主板计算机(包含一个CPU,一个存储器,一个网络接口)可以相互连接在一起,而不受数量的限制。
许多生产商都提供包含数以千计处理机的多计算机系统。
从硬件设计者的角度看,多计算机系统比多处理机系统更优越。
现在看看它对软件的影响。
用于多处理机编程的技术很多。
为实现通信,一个进程把数据写到存储器,其它进程将之读出。
为保持同步,可以使用临界区(critical region),信号量或管程(monitor)提供必要的互斥。
很多文章都讨论了在共享存储器的计算机上实现通信与同步的问题。
在过去的20年中,每一本操作系统的教科书都有几个章节讨论这个问题。
简而言之,大量的理论和实践知识可用于多处理机编程。
对多计算机系统,情况正好相反。
通信一般使用消息传递,这使输入/输出更为抽象。
消息传递带来了许多复杂的问题,包括:流控制,信包丢失,缓冲区设置和拥塞。
尽管已提出了不同的解决方案,但消息传递的编程仍很复杂。
分布式感知方法分布式感知是指在分布式计算系统中,各个节点通过交换信息和相互通信,共同感知系统中的状态和变化。
下面是关于分布式感知方法的10条详细描述:1. 共享内存:分布式系统中的节点可以通过共享内存来感知其他节点的状态。
节点可以读取和写入共享内存中的数据,从而获得其他节点的状态信息。
2. 消息传递:节点通过传递消息来感知其他节点的状态。
节点可以发送消息给其他节点,并接收其他节点发送的消息,从而获得其他节点的状态信息。
3. 事件广播:节点通过广播事件来感知其他节点的状态。
当一个节点的状态发生变化时,它可以通过广播事件的方式通知其他节点,从而让其他节点感知到它的状态变化。
4. 心跳检测:节点通过定期发送心跳消息来感知其他节点的状态。
每个节点都会定期向其他节点发送心跳消息,如果某个节点长时间没有收到心跳消息,就可以判断该节点已经故障。
5. 图算法:节点通过图算法来感知系统中的状态。
节点可以将分布式系统中的节点和通信链路建模为图,利用图算法来分析节点和通信链路的状态,从而感知系统中的整体状态。
6. 位图算法:节点通过位图算法来感知系统中的状态。
每个节点都维护一个位图,位图中的每一位表示与其他节点的连接状态,节点可以通过比较位图来判断其他节点的状态。
7. 一致性协议:节点通过一致性协议来感知系统中的状态。
一致性协议可以保证分布式系统中的节点达成一致,节点可以通过检查一致性协议的进程来获得其他节点的状态信息。
8. 集群监控:节点通过集群监控系统来感知系统中的状态。
集群监控系统可以监测和收集各个节点的状态信息,并提供查询接口供节点访问和获取其他节点的状态。
9. 分布式锁:节点通过分布式锁来感知系统中的状态。
每个节点可以尝试获取分布式锁,如果获取成功,则可以认为其他节点处于正常状态;如果获取失败,则可以认为其他节点出现故障。
10. 验证算法:节点通过验证算法来感知系统中的状态。
验证算法可以检查节点发送的消息的合法性和正确性,从而判断其他节点的状态信息是否可信。
分布式系统与并行计算介绍随着科技的不断进步,计算机系统的规模和性能需求也在不断增加。
传统的单机计算已经无法满足大规模数据处理和高性能计算的需求,因此分布式系统和并行计算成为了解决方案。
本文将介绍分布式系统和并行计算的概念及其应用领域,并探讨其在未来的发展。
一、什么是分布式系统分布式系统是由多个相互独立的计算节点组成的计算网络。
每个计算节点都有自己的处理器和内存,它们通过通信网络相互连接,并通过共享数据实现协同工作。
这些计算节点可以是物理机器,也可以是虚拟机或容器。
分布式系统的优势在于它们能够通过增加计算节点的数量来提高性能和可靠性。
当系统面临大量计算任务时,可以将这些任务分解成更小的子任务,并将子任务分配给不同的计算节点并行执行。
此外,分布式系统还具备容错能力,即当某个节点出现故障时,其他节点仍可以继续执行任务。
二、分布式系统的应用领域分布式系统广泛应用于各个领域。
其中一个重要的应用领域是云计算。
云计算平台利用分布式系统的能力,将计算、存储和网络资源集中管理,提供按需分配和弹性伸缩的服务。
这使得用户可以按需使用计算资源,大大降低了成本并提高了灵活性。
另一个应用领域是大数据处理。
随着互联网的快速发展,海量的数据需要被高效地存储、处理和分析。
分布式系统通过将数据分散存储在多个节点上,以及并行地执行计算任务,能够高效地处理大规模数据,并提供实时的分析结果。
此外,分布式系统还被应用于分布式数据库、分布式文件系统、分布式存储系统等领域,为用户提供高性能、高可用性的服务。
三、什么是并行计算并行计算是指将一个大规模计算任务分解成多个子任务,并将子任务同时执行以加速计算过程的计算模型。
每个子任务可以在不同的处理器上并行执行,以减少计算任务的执行时间。
并行计算主要有两种形式:共享内存并行和分布式并行。
共享内存并行是通过共享内存来实现多个线程或进程之间的数据共享和通信。
而分布式并行则是通过网络连接多台计算节点,每个节点独立执行子任务,并通过消息传递进行通信。
基于Java平台共享内存的实现与应用 (张华杰 郑州广播电视大学 河南 郑州 450007 ) 【摘要】:
在java 开发环境中,没有涉及共享内存这个概念,但是在某一些应用中,“共享内存”确实非常有用。在java语言的分布式应用系统中,存在着大量的分布式共享对象,很多时候需要查询这些对象的状态,如果采用网络通信的方式,会增加应用的额外负担;如果采用共享内存的方式,则可以直接通过共享内存查看对象的状态数据和统计数据,减少了一些不必要的麻烦。
【关键字】:共享内存、java
一、 共享内存对应用开发的意义:
IPC(InterProcess Communication)基本包括共享内存、信号灯操作、消息队列、信号处理等部分,是开发应用中非常重要的必不可少的工具。其中共享内存IPC机制的关键,对于数据共享、系统快 速查询、动态配置、减少资源耗费等均有独到的优点。对应UNIX系统来说,共享内存分为一般共享内存和映像文件共享内存两种,而对应 Windows,实际上只有映像文件共享内存一种。所以java应用中也是只能创建映像文件共享 内存。
二、 共享内存在java中的实现 在jdk中提供的类MappedByteBuffer为我们实现共享内存提供了较好的方法。该缓冲区实际上是一个磁盘文件的内存映像。二者的变化将保持同步,即内存数据发生变化会立刻反映到磁盘文件中,这样会有效的保证共享内存的实现。将共享内存和磁盘文件建立联系的是文件通道类:FileChannel。该类的加入是JDK为 了统一对外部设备的访问方法,并且加强了多线程对同一文件进行存取的安全性。例如读写操作统一成read和write。这里只是用它来建立共享内存用,它建立 了共享内存和磁盘文件之间的一个通道。 打 开一个文件建立一个文件通道可以用RandomAccessFile类中的方法getChannel。该方法将直接返回一个文件通道。该文件通道由于对应的文件设为随机存取文件,一方面可以进行读写两种操作,另一方面使用它不会破坏映像文件的内容。这里如果用 FileOutputStream和FileInputStream则不能理想的实现共享内存的要求,因为这两个类同时 实现自由的读写操作要困难得多。 一下过程实现了如这种功能; RandomAccessFile RAFile = new RandomAccessFile(filename,"r");// 获得一个只读的随机存取文件对象 FileChannel fc = RAFile.getChannel();// 获得相应的文件通道 int size = (int)fc.size();// 取得文件的实际大小,以便映像到共享内存 MappedByteBuffer mapBuf = fc.map(FileChannel.MAP_RO,0,size); // 获得共享内存缓冲区,该共享内存只读 RAFile = new RandomAccessFile(filename,"rw");// 获得一个可读写的随机存取文件对象 fc = RAFile.getChannel();// 获得相应的文件通道 size = (int)fc.size();// 取得文件的实际大小,以便映像到共享内存 mapBuf = fc.map(FileChannel.MAP_RW,0,size); // 获得共享内存缓冲区,该共享内存可读写 mode = mapBuf.getInt();// 获取头部消息:存取权限 如果多个应用映像同一文件名的共享内存,则这多个应用共享了同一内存数据。这些应用对于文件可以具有同等存取权限,一个应用对数据的刷新会更新到多个应用中。为了防止多个应用同时对共享内存进行写操作,可以在该共享内存的头部信息加入写操作标志。该共享内存的头部基本信息至少有: int Length; // 共享内存的长度。 int mode; // 该共享内存目前的存取模式。 共享内存的头部信息是类的私有信息,在多个应用可以对同一共享内存执行写操作时, 开始执行写操作和结束写操作时,需调用如下方法: public boolean StartWrite() {if(mode == 0) { // 标志为0,则表示可写 mode = 1; // 置标志为1,意味着别的应用不可写该共享内存 mapBuf.flip(); mapBuf.putInt(mode); // 写如共享内存的头部信息 return true;} else { return false; // 指明已经有应用在写该共享内存,本应用不可写该共享内存}} public boolean StopWrite() {mode = 0; // 释放写权限 mapBuf.flip(); mapBuf.putInt(mode); // 写入共享内存头部信息 return true;} 这里提供的类文件mmap.java封装了共享内存的基本接口,读者可以用该类扩展成自己 需要的功能全面的类。如果执行写操作的应用异常中止,那么映像文件的共享内存将不再能执行写操作。为了在应用异常中止后,写操作禁止标志自动消除,必须让运行的应用获知退出的应用。在多线 程应用中,可以用同步方法获得这样的效果,但是在多进程中,同步是不起作用的。方法可以采用的多种技巧,这里只是描述一可能的实现:采用文件锁的方式。写共享内存应用在获得对一个共享内存写权限的时候,除了判断头部信息的写权限标志外,还要判断一个临时的锁文件是否可以得到,如果可以得到,则即使头部信息的写权限标志为1也可以启动写权限,其实这已经表明写权限获得的应用已经异常退出,这段代码如下: // 打开一个临时的文件,注意同一共享内存,该文件名要相同,可以在共享文件名后加后缀“.lock”。 RandomAccessFile fis = new RandomAccessFile("shm.lock","rw"); // 获得文件通道 FileChannel lockfc = fis.getChannel(); // 获得文件的独占锁,该方法不产生堵塞,立刻返回 FileLock flock = lockfc.tryLock(); // 如果为空,则表明已经有应用占有该锁 if(flock == null) {...// 不能执行写操作} else {...// 可以执行写操作} 该锁会在应用异常退出后自动释放,这正是该处所需要的方法。
- 176- . 分布式共享内存 第 - 176 - 页 第7章 分布式共享内存
在本章中,我们研究实现分布式共享内存(distributed shared memory简称DSM)。 7.1 引论
传统上,分布式计算是基于消息传递模型,在这种模型下进程们经由以消息形式交换数据来彼此互相交互和共享数据。Hoare的通讯顺序进程(communicating sequential processes),客户-服务器模型和远程过程调用都是这种模型的例子。 分布式共享内存(Distributed shared memory简称DSM)系统是分布式操作系统的一个资源管理成分,它实现在没有物理地共享内存的分布式系统中的共享内存模型。见图7.1。
图7.1分布式系统中的共享内存模型 这个共享内存模型提供一个虚拟地址空间,使得被在一个分布式系统中所有结点(计算机)之间共享。
7.2 体系结构和动力
具有分布式共享内存,程序访问在共享地址空间中的数据正如同访问在传统的虚存中的数据一样。在支持分布式共享内存的系统中,数据既在辅存和主存之间也在不同结点的主存之间移动。 每个结点可以拥有存贮在共享地址空间中的数据,并且当数据从一个结点移到另一个结点时,拥有关系可以改变。当一个进程访问在共享地址空间中的数据时,一个映照管理者(mapping manager) 映照共享内存地址到物理存储,这个物理存储可以是本地或远程的。 映照管理者是一个或者实现在操作系统内核中或者作为一个运行时库例程的软件层。 为了减少由于通讯误而带来的延迟,当共享内存地址映照到在在一个远程结点上的一个物理内存位置时,分布式共享内存可以移动在共享内存地址中的数据从一个远程结点到正在访问数据的结点。在这样情况下,分布式共享内存利用底层通讯系统的通讯服务。 分布式共享内存 .-177. 第 - 177 - 页 7.2.1 分布式共享内存的优点 在消息传递模型中,程序通过明显的消息传递使共享数据可供使用。换句话说,程序员需要意识到进程之间数据移动。程序员不得不明显地使用通讯原语(例如SEND和RECEIVE),放一个重要的负担在它们身上。 相反,分布式共享内存系统隐藏这个明显的数据移动并且提供一个较简单的程序员已经精通的共享数据抽象。因此,利用分布式共享内存比通过明显的消息传递更容易地设计和编写并行算法。 在消息传递模型中,数据在两个不同的地址空间之间移动。这使得它难以在两个进程之间传递复杂的数据结构。而且传递由“引用”的数据和传递包含指针的数据结构一般是困难的和贵的。相反,分布式共享内存系统允许传递由“引用”的复杂的数据结构,于是简化了对分布式应用的算法的开发。 仅移动规定的所引用的数据片来代替由移动整块或包含所引用的引用场点的数据页,分布式共享内存利用程序所显示的引用局部性,因此削减了在网络上的通信开销。 分布式共享内存系统比紧偶合多机系统更便宜。这是因为分布式共享内存系统可以利用货架上的(off-the-shelf)硬件建立不需要复杂的接口把共享内存连接到处理机。 在一个分布式共享内存系统所有结点中可供使用物理内存组合在一起是巨大的。这个大的内存可以用于有效地运行要求大内存的程序而不用招致由于在传统的分布系统中对换引起的磁盘延迟。这个事实也由处理机速度相对于内存速度预料的增加和非常高速网络出现所支持。 在具有单个共享内存的紧偶合多机系统中主存经由一个公共总线访问,这限制多机系统为几十个处理机。分布式共享内存系统没有这个缺点,并且可以容易地向上扩充。 为共享内存多处理机写的程序原则上可以不加改变地运行在分布式共享内存系统。至少这样的程序可以容易地移到分布式共享内存系统中。 本质上,分布式共享内存系统努力克服共享内存机器体系结构的限制并且减少在分布系统中写并行程序。所需的努力。
7.3 实现分布式共享内存的算法 实现分布式共享内存的中心课题是: 如何追踪远程数据的位置; 当访问远程数据时,.如何克服.通信延迟和在分布系统中通信协议的执行相联的开销; 为了改善系统性能,.如何使共享数据在几个结点上并发地可供访问。 现在我们描述实现分布式共享内存的四个基本算法。 中央服务器(Central-Server)算法 迁移算法 读复制(Read-Replicatin)算法 完全复制算法
7.3.1 中央服务器(Central-Server)算法
在中央服务器(Central-Server)算法中,一个中央服务器维护所有的共享数据。它服务从其它结点或者客户来的读请求,返回数据项给它们(见图7.2)。在客户写请求时,它更新数据并返回表示收到的消息。 在表示收到的消息失效情况一个超时(timeout)可以被采用来重发请求。重复的写请求可以由写请求所伴随的顺序号检测。在几次重新传输而又无响应后一个失败的条件被返回到企图访问共享数据的应用。 - 178- . 分布式共享内存 第 - 178 - 页 虽然中央服务器算法其实现是简单的,但中央服务器可能变成一个瓶颈。为了克服这个问题,共享数据可以分布在几个服务器上。在这种情况下,客户必须能够对每次数据访问定位适当的服务器。 多点广播式的数据访问请求是不希望的,因为与中央服务器方案相比,它并不减少服务器的负载。分布数据的一种较好的方法是按地址划分共享数据并且利用一个映照函数定位适当的服务器。
图7.2中央服务器算法 7.3.2 迁移算法
在中央服务器算法中,每个数据访问请求被发送到数据的位置,与之相比,在迁移算法中的数据被转移到数据访问请求的地点,允许随后的对该数据的访问被本地地执行(见图7.3)。 迁移算法每次仅允许一个结点访问一个共享数据。 在中央服务器算法中,每个数据访问请求被发送到数据的位置,与之相比,在迁移算法中的数据被转移到数据访问请求的地点,允许随后的对该数据的访问被本地地执行。
图7.3迁移算法 典型地,包含数据项的整个页或块迁移以代替单个请求项。这个算法利用由程序所展示的引用的局部性把迁移的费用分摊到多个访问迁移数据上。但是这种途径对抖动(thrashing)敏感,其中页频繁地在结点间迁移,而仅服务少数请求。 为了减少抖动,Mirage系统使用一个可调的参量决定一个结点可以拥有一个共享数据项的期间。这允许在页被迁移到另一结点之前一个结点对该页作若干次访问。Munin系统力求采用适合不同的数据访问模式的协议来减少数据移动。 分布式共享内存 .-179. 第 - 179 - 页 迁移算法提供了一个机会把分布式共享内存与运行在单个结点上操作系统所提供的虚存集成在一起。当分布式共享内存所用的页大小是虚存页大小的倍数时,一个本地掌握的共享内存页可以被映照到一个应用的虚地址空间并且利用正常的机器指令访问。 在一个内存访问失效时,如果内存地址映照到一个远程页,在映照页到进程的地址空间之前,一个页失效处理程序将迁移该页。在迁移一页时,该页从所有在以前结点被映照到的地址空间移开。注意,几个进程可以共享在一个结点上的一页。 为了定位一个数据块,迁移算法可以利用一个服务器追踪页的位置或者通过在结点上所维持的提示。这些提示指向搜寻当前占有该页的结点。另外,一个询问可以广播来定位一页。 7.3.3 读复制(Read-Replicatin)算法
在前面途径中仅仅在一个结点上的进程可以在如何时刻访问一个共享数据。读复制(Read-Replicatin)算法扩充了迁移算法,即复制数据块并且允许多个结点具有读访问或一个结点具有读写访问(多个读者-一个作者协议)(见图7.4)。
图7.4读复制 由允许多个结点并发地访问数据,读复制可以改善系统性能。但是,写操作是昂贵的,因为一个共享块在各种结点上的所有副本将或者不得不是无效的,或者用当前值来更新以维护共享数据块的一致性。 在读复制算法中分布式共享内存必须追踪所有数据块副本的位置。在IVY系统中,一个数据块的拥有者结点追踪具有该数据块的一个副本的所有结点。在PLUS系统中,一个分布式链接列表用来追踪具有该数据块的一个副本的所有结点。 然而,当读对写的比例是大的时候,读复制有减少读操作平均费用的潜力。在节描述在IVY系统中实现的许多读复制算法。 7.3.4 完全复制算法
完全复制算法是读复制算法的一种扩充(见图7.5)。读复制算法它允许多个结点具有对共享数据块的读和写两种访问(多个读者-多个作者协议)。由于许多结点可以并发地写共享数据,对共享数据的访问必须被控制以维持它的一致性。 维持一致性的一个简单方法是利用一个无间隙的顺序器(gap-free sequencer)。在这种方案下,所有希望修改共享数据的结点将发送修改给一个顺序器。这个顺序器将赋予一个顺序号并且多点广播这个修改及顺序号到所有具有该共享数据项副本的结点。 - 180- . 分布式共享内存 第 - 180 - 页 每个结点以顺序号次序处理修改请求。在一个结点上一个修改请求的顺序号和期待的顺序号之间的间隙指示一个或多个修改已被遗漏。在这种情况下结点将被请求重新传送已经遗漏的修改。这蕴涵在某个结点保留修改的日记。在第5节将讨论若干其它维护共享数据的一致性的协议。
图7.5完全复制算法 7.4 存储一致性(Memory coherence)
为了改善性能分布式共享内存系统依赖复制共享数据项和允许在许多结点上并发访问。但是,如果并发访问不仔细地加以控制,内存访问可能以不同于程序员所期望的次序被执行。非正式讲,一个内存是一致的,如果由读操作返回的值总归是程序员所期望的值。 例如,对一个程序员期待一个读操作返回一个最近写操作所存贮的值是相当自然的。 因此,为了维护共享数据项的一致性,一个控制或同步访问的机制是必要的。同样为了写正确的程序,程序员需要理解如何进行对共享内存的并发更新。允许的内存访问次序集合构成了存储一致性模型。字一致性用于说明一种特殊类型的一致性。 存储一致性最直观语义是严格一致性(strict consistency),其定义如下:一个读返回最近写的值。严格一致性要求具有决定最近写的能力,依次它蕴涵请求的全序。由于比一个程序可能实际需要更多的数据移动和同步要求,请求的全序导致非有效性(请参考[4])。 为了解决这个问题,某些分布式共享内存系统企图由提供不严格的一致性语义来改善性能。下列是几种内存一致性形式: 顺序的一致性(Sequential consistency) 一般一致性(General Consistency) 处理机一致性(Processor consistency) 弱一致性(Weak consistency) 释放一致性(Release consistency)