分布式系统概念和设计——分布式共享内存

分布式系统概念和设计

分布式共享内存

分布式共享内存是在不共享物理内存的计算机之间实现数据的共享的一个抽象。

有一个底层运行的系统保证其透明性,但是进程还是根据内存的分布处理物理内存的分布式能力

DMS最关键点:

  • 不需要关心数据的通信,消息传递能力是巨大的底层支持。
  • 生存周期比访问的任意进程都长,并且不同进程组能够长期的访问和共享

在这里插入图片描述

  • 缓存策略和处理器——内存快速互联的方法,目标是获得较快的内存访问和较大的吞吐量的同时,增加处理器数目。
  • 在处理器和内存模块通过普通总线链接的系统,因为处理器需要竞争总线的原因,处理器数目限制在10-20之间,否则系统的执行性能会明显下降。
  • 共享内存的处理器通常是4个一组,通过一个电路板上的总线共享内存。
  • 在非一致内存访问(NUMA)结构的主板上,系统可以支持多达64个处理器。
  • 是一种层次结构,其中系统使用高性能的开关或高一级的总线将多个拥有4个处理器的主板链接起来。
  • 但是其中处理器访问本主板上内存的延迟时间比访问其他主板上内存的延迟时间少——体系结构名称的来源
    • 不同节点之间内存访问延迟的不同导致了内存访问的非一致性。因此,如果处理器访问本主板上的内存,访问的延迟时间就会比访问其他主板上的内存的延迟时间短,因为本地内存的延迟时间更短。这种设计方式的好处是可以在一定程度上提高系统的可伸缩性,同时减少节点间的通信,避免节点争用共享总线的瓶颈问题。但也要注意处理器访问的内存是否在同一节点,需要优化处理器访问内存的局部性,避免访问不必要的内存数据,提高计算效率。

在分布式内存的多处理器结构中,处理器不共享内存,但是通过高速网络链接起来。

DSM和多处理器结构所面临的一个核心问题是:

  • 共享内存算法和其相关软件知识能否直接应用于更大规模的分布式共享内存系统

需要开发新的算法和协议来维护分布式系统中的数据一致性和协同计算任务。例如,需要设计新的分布式共享内存结构和分布式锁机制来确保各个节点之间的数据状态一致。此外,还需要研究分布式共享内存系统的调度策略,以优化任务分配和处理器间的通信,提高计算效率。

消息传递机制和DSM比较
  • 编程模型

    • 使用消息传递模型的时候,当一个进程向另一个进程发送数据的时候,发送方必须对数据变量进行编码,接收进程对数据变量解码。使用共享内存的系统可以直接共享变量而无需编解码。不需要单独的通信操作。
    • 大多数DSM系统可以以访问非共享变量的方式对存储在DSM中的变量进行命名和访问
    • 使用消息传递的好处
      • 通过进程的私有地址区域,使通信进程的数据得到保护
    • 在共享内存中可能会因为某个进程修改了共享数据导致其他进程崩溃
    • 在异构通信中,通信可以在不同的系统中不同的处理方式,共享内存无法达到这一点
    • 在DSM中进程的同步是通过通常内存共享内存程序使用的同步机制实现,其中包括锁和信号量
    • 分布式需要不同的同步机制
    • 因为DSM是可以持久的,通过DSM通信的进程的生命周期并不能重叠,一个进程可以在随意的节点上的进程留下数据
    • 而另一个进程可以在自己的运行时读取到该数据
    • 通过消息传递机制进行通信的进程必须同时运行
  • 效率

    • 关于实现的方式可以有效的减少通信的时间但也有很多挑战
DSM的实现
  • 硬件
    • 基于NUMA体系结构的共享内存处理器依赖于特殊的硬件能提供一致性共享内存怒
    • 通过与远程的内存模块和缓存模块通信来处理LOAD和STORE,这些内存和缓存存储有所需的数据
    • 这种通信建立在一种与网络通信类似的高速连接上进行
  • 分页虚拟内存
    • 许多系统将DSM实现为一个虚拟分页内存,这个虚拟内存区域在每个参与进程内占据同样的范围(内存预规划技术)
  • 中间件
    • 通过在客户和服务器上的用户级支持层之间的通信来实现共享的内存的机制。
    • 当进程发出数据访问DSM,对支持层发出调用,通过相互通信维持一致性多进程之间。
NUMA

共享内存在处理器间共享数据时,通常会使用共享总线来实现。这样的设计可以大大简化通信协议和数据一致性的维护。一般而言,将处理器组成4个一组共享内存更适合于中小型的计算任务。因此,当需要在多个处理器间共享数据时,这种设计方式可以提高计算效率。

但是,当系统需要支持更多处理器时,使用共享总线进行内存访问会变得非常复杂和慢。为了解决这一问题,非一致性内存访问架构(NUMA)被提出。在NUMA中,处理器被分成多个节点,每个节点拥有自己的本地内存和I/O总线。与共享内存不同的是,NUMA允许节点之间的内存访问是非一致性的,也就是说,不同节点的内存访问速度可能不同。

使用NUMA的好处是可以处理更大规模的计算任务,并提高系统的可伸缩性。由于每个节点拥有自己的本地内存,节点之间的内存访问瓶颈被大大减少,同时可以通过在各节点之间移动内存数据来优化访问速度。因此,NUMA通常用于高性能计算领域和大型服务器系统。

设计问题和实现问题

一致性模型是指DSM系统中的各种数据模型应该在特定的条件下遵从一致性规则,以确保数据的正确性和一致性。一致性模型的设计思想主要是通过事务处理、锁定机制和版本控制来防止多个用户同时对数据进行修改和访问,并确保数据在不同节点之间的传输和存储是一致的。在具体的实现过程中,一致性模型可以采用多种技术,例如分布式事务、分布式锁、多版本并发控制等。在设计和实现一致性模型时,需要考虑系统的复杂性、性能、可扩展性、容错性等因素,以满足不同用户的需求。同时,还需要使用适当的工具和技术来测试和验证系统的正确性和可靠性。

主要面临问题
  • DSM中的数据和结构问题
  • 应用层一致访问DSM的同步模型
  • DSM的一致性模型,一致性模型管理不同计算机访问的数据的一致性
  • 计算机之间交互所写信息的更新选项
  • DSM实现中的共享粒度以及颠簸问题
结构
  • 每一个应用程序进程都拥有一些抽象的对象集合,集合内存概念。可以被不同的访问方式访问。
面向字节的

访问虚拟内存一样访问数据类型,DSM是一组连续的字节。

应用程序在共享内存上实现所需的数据结构。

这些共享是直接可寻址的内存位置。

LOAD,STROE(读写操作)

面向对象的
  • 由一系列语言级的对象如栈,字典等组成。
  • 应用程序只能通过调用对象才能改变这些对象的内存共享值
  • 不能通过直接访问对象的共享内存地址直接改变
  • 利用对象的语义能够加强一致性
对象共享方式

共享对象的方式:

有几种方式可以实现对象共享:

  1. 静态变量:

静态变量是类级别的变量,多个对象可以共享同一个静态变量。可以在类的任何地方访问静态变量,并且只有一个副本在内存中被创建。

Java中使用static关键字来定义静态变量。

  1. 单例模式:

单例模式是一种设计模式,它确保一个类只有一个对象实例,并提供全局访问点。

单例对象可以通过静态方法访问,在这个方法内可以控制对象的创建并确保只创建一个对象。

  1. 共享内存:

共享内存是一种进程间通信方式,多个进程可以共享同一块内存。这种方式需要特殊的加锁机制来控制并发访问,以及确保数据一致性。

  1. 引用计数:

引用计数是一种内存管理技术,它跟踪内存中对象的引用次数。当一个对象被多个其他对象引用时,只需要创建一个对象实例,并记录每个引用的计数。当所有引用计数都变为零时,对象就可以被释放。

一致性语义设计在编程语言层面

一致性语义是编程语言中非常重要的一部分,它确保程序在不同的线程或进程之间保持一致的状态,并且数据应该按照特定的顺序进行读写,以免出现竞争条件、死锁或者原子性问题。

以下是编程语言级别上的一致性语义的设计说明:

  1. 范式设计:

范式是一种编程语言设计模式,它包含数据结构和一组操作数据的函数。这种设计模式可以统一并简化程序的逻辑,使其易于理解和维护。

在保证一致性语义的设计中,采用范式设计可以使得程序的状态变化更加可控,对于不同的线程或进程之间的并发访问,可以更容易地保证其正确性。

  1. 内存管理:

内存管理是一项关键的任务,它包括分配和释放内存,管理内存的使用方式,以及在多线程或多进程环境下保证内存的一致性和正确性。

为了保证内存的一致性,编程语言通常会提供一些机制,例如内存模型、锁、信号量、条件变量等,以允许并发访问和防止访问冲突。

  1. 原子操作:

在多线程或者多进程环境下,确保数据的原子性是非常重要的,数据的原子性就是指一组相关的操作是无法被其他线程或进程中断的,从而保证了数据的一致性。

编程语言通常提供一些原子操作,例如原子变量、原子锁、原子信号量等,以支持原子操作。在一些语言中,原子操作还可以包含类似于自旋锁、读写锁等的机制,用于控制对共享资源的并发访问。

  1. 事务:

在保证一致性的设计中,事务是一种非常有用的机制。通过对一组相关的操作进行封装,事务可以保证这些操作要么全部执行成功,要么全部失败。一旦遇到任何失败情况,整个事务都会被回滚,以保持数据的一致性和正确性。

  1. 同步机制:

同步机制是一种有效的方法,用于控制对共享资源的访问。编程语言通常会提供一些同步机制,例如锁、信号量、条件变量、屏障等,用于协调线程或进程之间的操作。

在保证一致性的设计中,同步机制可以确保线程或进程按照指定的顺序访问共享资源,从而避免出现竞争条件、死锁和其他并发问题。

不变数据

不变数据项的集合,进程可以读取,删除,增加数据项,但不能更改。

元组空间设计

  • 通过一个元组空间方式共享元组数据
  • 当从元组中读取一个元组数据,进程提供一个元组规约
  • 系统从元组规约中获取符合规约的元组,这种规范是一种联合寻址
同步模型

许多应用程序会在共享内存存储的值上加上某些限制。

解决方法:

  • 将这一段代码设置为临界区
  • 这样可以保证在某一个时刻只有一个进程可以执行
内存临界区

内存临界区是指一段程序代码,在这段代码中访问共享内存的操作会导致数据竞争问题。当多个线程或进程同时访问同一片共享内存时,需要设计合理的临界区来保证数据的正确性。

下面是几种常见的内存临界区设计方式:

  1. 锁机制:采用锁机制来控制对共享内存的访问。在进入临界区之前,线程/进程必须先获取锁,执行完访问共享内存的操作后再释放锁。
  2. 信号量:通过信号量来控制对共享内存的访问。当需要访问共享内存时,线程/进程必须首先获取信号量,执行完访问操作后再释放信号量。
  3. 读写锁:当许多线程需要从共享内存读取数据而只有少量线程需要写入数据时,可以采用读写锁机制,允许多个线程同时读取共享内存,但只能有一个线程写入共享内存。
  4. 原子操作:某些编程语言提供了一些原子操作,可以将多个操作合并为一个原子操作,从而避免在共享内存上的数据竞争问题。
  5. 消息队列:通过消息队列来传递访问共享内存的请求和数据,在实际访问共享内存时只允许一个线程/进程进行访问,从而避免数据竞争问题。
一致性模型

内存一致性模型是指在共享内存环境中,多个处理器或线程之间的内存访问所遵循的规则。这些规则规定了对共享内存的访问顺序,保证了多个处理器或线程之间的内存访问是有序的,而不是随机的。

在多核处理器或者多线程应用中,存在多个处理器或线程同时访问共享内存的情况。如果这些处理器或线程之间的内存操作没有按照规定的顺序执行,就会导致数据一致性问题,例如数据竞争、死锁等等。

为了避免这种问题,需要建立一种内存一致性模型,规范处理器或线程之间的内存读写操作。这个模型通常由处理器架构或操作系统制定,并且在硬件上实现。

常见的内存一致性模型包括:

1.顺序一致性模型:所有的内存读写操作都是串行执行的,且所有的处理器或线程看到的内存访问顺序都是一致的。

2.弱一致性模型:内存读写操作可以乱序执行,但是一定会保证最终的结果是正确的。

3.松散一致性模型:内存读写操作可以乱序执行,并且不一定要保证最终结果是正确的,但是会保证最终结果是相对一致的,也就是说每个处理器或线程看到的内存访问顺序是不同的,但是最终结果是相对一致的。

不同的处理器架构或操作系统会选择不同的内存一致性模型,应用开发者需要了解并遵循所选的模型规范,以确保程序正确性。

更新选项

一个进程向其它进程传递更新数据有两种方式

  • 写-更新

    • 进程进行的更新将改变本地数据并会组播其他具有此数据项的拷贝的副本管理器上,副本管理器收到通知后会立即更新本地进程的所读数据,进程可以读取本地副本数据而无需进行通信。
    • 在这里插入图片描述
  • 写-失效

    • 它通常用于多个读进程/单个写进程的共享环境中。
    • 通常一个进或多个进程以只读的方式来访问一个数据项,或者这一个数据项由唯一一个进程进行读写
    • 当前被只读方式访问的数据可以有多个副本。
    • 当有一个进程试图写这一数据项时,系统首先向这一数据的所有副本组播一个失效的消息
    • 并且在写操作执行之前收到来自副本的失效确认消息
    • 此时系统阻止其他进程读取这一数据项的过时数据——这一数据项不是最新的
    • 如果有一个其它进程正在写数据,那么系统将阻止其他进程对这一数据项的读取操作直到写入完成
粒度

在DSM中应该实现怎样粒度的共享单元?

当一个进程对DSM进行写操作后,为了保持其他地点的一致性,DSM运行时应该发送什么样的数据?

  • 硬件进行页为单位的地址交换
  • 主要是在页面中更新新的页面指针
  • 页面的大小最大8KB,当发生更新时,需要传输大量的数据
  • 在默认情况下,不管是整页更新,还是只更新了页的一个字节,整页都必须进行传输,页是最小单位
  • 当页很大的时候会大概率发生页数据竞争的情况
系统颠簸

写失效的一个潜在问题是系统颠簸?

  • 相对于DSM的正常工作时间而言,写失效和通信传输数据的时间可能更多。此时就会发生系统抖动
  • 当多个进程共享一个数据项,或者错误的共享数据时也会发生,
一致性模型

Zab协议(ZooKeeper Atomic Broadcast Protocol)是ZooKeeper使用的一种基于Paxos算法的原子广播协议,用于保证分布式环境下的一致性和可靠性。Zab协议实现了分布式系统中的原子广播,使得ZooKeeper集群中的所有节点都可以达成一致的状态,从而保证了系统的可靠性和一致性。

Zab协议将ZooKeeper集群中的所有节点分为两类:Leader和Follower。Leader节点负责接收客户端请求,并将请求广播给所有Follower节点。Follower节点接收请求并将其复制到本地存储中。当多数节点都成功复制请求后,Leader节点将请求标记为已提交,并将其广播给所有Follower节点。Follower节点接收提交请求并将其应用到本地存储中。

Zab协议的设计目标是保证原子性、顺序性、可靠性和高效性。它通过将ZooKeeper集群中的所有节点分为Leader和Follower两类,实现了分布式系统中的原子广播,使得ZooKeeper集群中的所有节点都可以达成一致的状态,从而保证了系统的可靠性和一致性。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

P("Struggler") ?

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值