erlang/OTP 平台(学习笔记)(三)

分布式 Erlang

借助于语言属性和基于复制的进程通信,Erlang程序天然就可以分布到多台计算机上。要问为什么,且让我们来看两个用Java或C++这类语言写成的进程,它们运作良好并以共享内存为通信手段。假设你已经搞定了锁的问题,一切精准而高效,但就在你试图将其中一个线程挪到另一台机器上时,问题出现了。或许是为了利用更高效的计算能力和内存,或许是为了预防两个线程在硬件故障造成的宕机中同时挂掉,无论如何,这一刻降临时,程序员往往被迫重新设计代码结构,以便配合新的分布式环境中迥异的通信机制。显然,这将耗费大量的开发成本,而且很可能会引入数年才能彻底清除的bug。
Erlang程序却不受这些问题的影响。Erlang规避了数据共享并通过复制进行通信,这使得Erlang代码可以直接分布到多台机器上。在命令式语言里用线程编程时,各部分代码往往会因数据共享引入复杂的依赖关系;这类问题在Erlang中则很少见。今天能跑在你的笔记本上,明天就能跑在集群上。
Erlang应用通常可以直接分布到多个网络节点上,这同时意味着伸缩性问题也简化为一个数量级。你仍然需要考虑好各类进程的职能,每类进程需要运行多少个实例,在哪些机器上运行,怎样均衡负载以及怎样管理数据;但至少以下这类问题不用再劳你费心了:“我到底该怎么切分现有的程序才能搭建出冗余的分布式系统?”,“它们之间该怎么通信?”,还有“我该怎样得体地处理故障?”。

Erlang运行时系统和虚拟机

标准Erlang实现的核心是一个称作Erlang运行时系统(ERTS)的应用:这是一大块用C语言写成的代码,负责Erlang中所有底层的玩意儿。通过它你才能跟文件系统和终端打交道,它还处理内存,实现Erlang进程的也是它。ERTS知道如何将这些进程分布到现有的CPU资源上才能充分发挥计算机硬件的能力。同时,哪怕你只有一个单核CPU它也能实现Erlang进程的并发执行。ERTS还负责处理进程间的消息传递,并使处在不同机器上运行在各自的ERTS中的进程能够像身处同一台机器上一样进行通信。Erlang中所有需要底层支持的东西都由ERTS处理,所以ERTS移植到哪个平台Erlang就能在哪个平台上跑。
ERTS中特别重要的一个部分就是Erlang的虚拟机模拟器:这是执行Erlang程序经编译后产出字节码的地方。这个虚拟机也就是Bogdan Erlang抽象机(BEAM ) ,它非常高效:虽然我们也可以将Erlang程序编译为本地机器码,但一般没有那个必要,因为BEAM模拟器已经够快的了。注意虚拟机和ERTS之间并没有明确的界线;通常人们(包括我们自己)口中的Erlang VM指的就是模拟器加上运行时系统。
运行时系统中有许多有趣的特性,若不在文档中挖地三尺或是长期浸淫于Erlang邮件列表,你是不会知道的。它们正是Erlang能同时处理那么多进程的精要之所在,也是Erlang如此特别的原因之一。Erlang语言的基本哲学加上实现者所采取的务实方案,共同为我们带来了异常高效、面向生产的稳定系统。

我们将讨论促成了Erlang的强大和高效的3个重要方面:

调度器——处理运行中的Erlang进程,令所有就绪的进程共享可用的CPU资源,并在新消息到达或发生超时的时候唤醒相应的睡眠中的进程;

IO模型——′防止系统在进程与外部设备通信时阻塞,令系统平稳运行;

垃圾回收器——回收不再使用的内存。
 

1.调度器

经过多年的演进,ERTS的进程调度器提供了其他平台无法比拟的灵活性。它最初的设计目标是在单CPU上并发运行轻量级Erlang进程,而不是关心底层用什么操作系统。ERTS运行的时候通常就是单个操作系统进程(在操作系统的进程列表中一般名为beam或werl),就跑着管理所有Erlang进程的调度器。
随着线程在大多数操作系统中的普及,ERTS也有所变化,开始将I/O系统这类东西从运行Erlang进程的线程中拿出来,放到独立的线程中去,但完成主体工作的线程仍然只有一个。如果你用的是多核系统,就必须在同一台机器上运行多个ERTS实例。Erlang/OTP第11版中增加了对称多处理器( SMP)支持。这是一项重大突破,令Erlang运行时系统可以在内部使用不止一个进程调度器,每个占用一个独立的操作系统线程。
这意味着现在Erlang进程可以以n :m的方式映射到操作系统线程。每个调度器处理一个进程池。可并行运行的Erlang进程最多能有m个(每个调度器线程执行一个),但同一池内的进程仍像之前所有进程共用一个调度器那样分时运行。在此基础之上,进程可以在进程池之间迁移以便维持可用调度器上的负载均衡。在最新的Erlang/OTP发布版中,甚至可以根据机器上CPU的拓扑情况将进程绑定到特定的调度器上,从而更好地利用硬件的缓存架构。这意味着,大多数时候,作为一名Erlang程序员你不用担心手头有多少CPU或有多少个核:你只要中规中矩地写程序,并尽量将程序切分为尺寸适中的并行任务就好,负载均衡之类的事情就让Erlang运行时系统去操心吧。不管是单核还是128核——都一样,只会更快。

2.I/O与调度

很多并发语言都有的一个毛病就是它们没怎么拿I/O当回事儿。单个进程进行IO时,它们几乎都存在整个系统或大半系统阻塞的问题。这真是既恼人又没有必要,尤其是Erlang早在二十年前就已经解决了这个问题。在前一节,我们曾讨论过Erlang的进程调度器。除了处理进程调度,调度器还替系统优雅地处理了IO问题。在系统的最底层,Erlang以事件驱动的方式处理所有IO,当数据进出系统时,程序可以以非阻塞方式完成数据处理。这降低了连接建立和断开的频次,还避免了OS层面上的加锁开销和上下文切换。
这是一种高效的IO处理方法。可惜,程序员往往难以分析和理解这种技术,这也是为什么只有在明确要求高可靠性和低延迟的系统中才能见到这种技术。早在2001年,Dan Kegel就在他的论文The C10K Problem中描述过这个问题,虽然现在已经略显过时,但这篇文章仍然很值得一读。它针对这个问题及可能的解决方案给出了良好的综述。这些方案实现起来全都既复杂又痛苦,·这正是Erlang运行时系统替你包办这些问题的原因。Erlang在进程调度器中整合了基于事件的I/O系统。事实上,你一点儿都不用操心就能享受一切便利。这让用Erlang/OTP构建高可靠性系统变得轻松了很多。

3.进程隔离与垃圾回收器

虽然实现相对简单,Erlang程序却不太会像其他语言开发的系统那样在GC时遭受停顿。这主要因为Erlang进程之间的隔离:每个进程所使用的内存都是自己的,随进程的创建和结束而分配和释放。听起来好像没什么要紧,实则不然。首先,这意味着垃圾回收器可以在不影响其他进程运行的前提下单独暂停目标进程。其次,单个进程占用的内存通常较小,遍历可以快速完成。(也有内存占用量大的进程,但这些进程一般不用做出快速响应。)再次,调度器知道每个进程最后一次运行的时间,如果某个进程自上次垃圾回收后什么也没干,调度器会跳过它。正是这些因素让Erlang既可以轻松使用垃圾回收器,又可以保证较短的停顿时间。除此以外,有时候进程自派生到完工,再到退出,根本就没有触发过垃圾回收。这种情况下,进程的作用相当于一块昙花一现的内存,除自动分配和释放外,没有任何额外的开销。

本节所描述的运行时系统的特性使Erlang程序能够充分利用可用的CPU来运行大量进程、执行IO操作,并自动回收内存,与此同时还能维持软实时响应能力。了解了平台这些方面的知识,便可更好地理解自己的系统自启动后的各种行为。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/621660.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言整型常量的表示方法

整形常量就是整常数,在c语言中,使用的整常数有八进制,十进制和十六进制三种 1)十进制常数:十进制常数没有前缀,其数码为0~9。 以下各数是合法的十进制整常数: 237、-568、65535、1627&#xf…

leetcode206.反转链表

https://leetcode.cn/problems/reverse-linked-list/description/ 题目 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入&am…

中国政企客户,需要什么样的云服务?

0. 前言和目录 我前段时间写了一篇《技术服务工作的呼吁和推演》,文中感叹,几乎没有云厂商重视技术服务工作。很意外也很庆幸,这篇文章起到了抛砖引玉的效果,我收到了一些高价值反馈。我的感叹有些肤浅,国内政企云行业…

ssm基于Vue的健身房会员管理系统+vue论文

摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱,出错率高,信息安全性差&#x…

【车载开发系列】AutoSar当中的DcmDspSecurity容器

【车载开发系列】AutoSar当中的DcmDspSecurity容器 AutoSar当中的DcmDspSecurity容器 【车载开发系列】AutoSar当中的DcmDspSecurity容器一. DcmDspSecurity容器位置二. 关于对安全等级理解三. 关于安全等级的定义1)Extendedsecuritylevel2)Programmings…

软件设计不是CRUD(10):低耦合模块设计理论——业务抽象:从需求中提取业务维度

接上文《软件设计不是CRUD(9):低耦合模块设计理论——设计落地所面临的挑战》 2、什么是业务抽象 业务抽象是一种将需求落地成模块功能的设计思想,是对业务需求和技术设计进行转换、隔离的一种分析方法。经过业务抽象后的业务模块一般具有较高的业务屈服度,能更大程度满…

Envoy

一、Envoy简介 Envoy 是一款由Lyft开源的高性能服务代理软件,使用现代C语言(C11及C14)开发,提供四层和七层网络代理功能。2017年,Envoy 被捐赠给 CNCF 基金会,最终成为继Kubenetes利Prometheus 之后第3个 …

vue -- 单页面应用和多页面应用区别及优缺点

Vue单页面应用(SPA)和多页面应用(MPA)是两种常见的前端应用架构模式,它们在开发方式、性能以及用户体验方面有着不同的特点。 单页面应用(SPA): SPA 是一种基于JavaScript的应用程序…

EI级 | Matlab实现VMD-TCN-BiLSTM变分模态分解结合时间卷积双向长短期记忆神经网络多变量光伏功率时间序列预测

EI级 | Matlab实现VMD-TCN-BiLSTM变分模态分解结合时间卷积双向长短期记忆神经网络多变量光伏功率时间序列预测 目录 EI级 | Matlab实现VMD-TCN-BiLSTM变分模态分解结合时间卷积双向长短期记忆神经网络多变量光伏功率时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基…

【AUTOSAR】RTE的基础概念和ETAS ISOLAR RTA-CAR配置指南(一)RTE简介

目录 前言 RTE简介 什么是RTE 软件组件 类型 组件类型和实例

Vue3-46-Pinia-获取全局状态变量的方式

使用说明 在 Pinia 中,获取状态变量的方式非常的简单 : 就和使用对象一样。 使用思路 : 1、导入Store;2、声明Store对象;3、使用对象。 在逻辑代码中使用 但是 Option Store 和 Setup Store 两种方式定义的全局状态变量…

检测射线与球体交点数量代码实现(C#代码Unity环境下测试通过)

上代码&#xff1a; int RayCrossSphere(Ray ray, Sphere sphere) {Vector3 originT0Center sphere.center - ray.origin;float sqrtRadius sphere.radius * sphere.radius;if (originT0Center.sqrMagnitude < sqrtRadius){return 1;}else{Vector3 project Vector3.Proj…

7 认证相关

认证相关 7 认证相关今日详细1. 代码整合2.通用认证组件2.1 处理访问记录2.2 登录之后才具有评论和发布 3.随意的接口结论&#xff1a;在serializer中可以调用request4.完善详细页面 总结1. 小程序1.1 申请账号APPID1.2 搭建开发者工具1.3 目录结构1.4 组件1.5 微信API1.6 事件…

全新小白菜QQ云端机器人登录系统源码 /去除解密授权学习版源码

源码介绍&#xff1a; 全新小白菜QQ云端机器人登录系统源码&#xff0c;是一款经过全面解密的授权学习版源码。 这款源码已解除了授权版的限制&#xff0c;然而许多人可能对其用途并不了解。实际上&#xff0c;该源码主要面向群机器人爱好者设计。它是一个基于挂机宝机器人框…

RT-DETR算法优化改进:多层次特征融合(SDI)结合PConv、DualConv、GSConv,实现二次创新 | UNet v2最新论文

💡💡💡本文独家改进:多层次特征融合(SDI)高效结合DualConv、PConv、GSConv等实现二次创新 1)替代原始的Concat; RT-DETR魔术师专栏介绍: https://blog.csdn.net/m0_63774211/category_12497375.html ✨✨✨魔改创新RT-DETR 🚀🚀🚀引入前沿顶会创新(CVPR…

Linux 脚本编程题库

1.在主目录下新建一个test.sh文件&#xff0c;脚本功能为查找某文件是否存在&#xff08;某文件名以参数形式传递&#xff09;&#xff0c;如果文件存在&#xff0c;则修改文件权限为用户主可读写&#xff0c;其他用户无任何权限&#xff0c;否则返回文件不存在&#xff01; #…

Java期末复习题库(封装,继承,抽象类,接口,GUI)

包与字符串 1.创建包的基本操作 在biology包中的animal包中有human类,它具有name,height,weight的属性,还具有eat(),sleep()和work()的行为,在biology包中的plant包中有flower类,它具有name,color,smell的属性,还具有drink()和blossom()的行为. 现在在一个school包中的garde…

20240113-确定两个字符串是否接近

题目要求 如果可以使用以下操作从另一个字符串获得一个字符串&#xff0c;则认为两个字符串是接近的&#xff1a; 操作1&#xff1a;交换任意两个现有字符。 例如&#xff0c;abcde -> aecdb操作2&#xff1a;将每个出现的一个现有字符转换为另一个现有字符&#xff0c;并…

Go语言开发小技巧易错点100例(十一)

往期回顾&#xff1a; Go语言开发小技巧&易错点100例&#xff08;一&#xff09;Go语言开发小技巧&易错点100例&#xff08;二&#xff09;Go语言开发小技巧&易错点100例&#xff08;三&#xff09;Go语言开发小技巧&易错点100例&#xff08;四&#xff09;Go…

优雅处理并发:Java CompletableFuture最佳实践

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;今天&#xff0c;小黑要和大家聊聊CompletableFuture&#xff0c;这个Java 8引入的强大工具。 在Java传统的Future模式里&#xff0c;咱们都知道&#xff0c;一旦开始了一个异步操作&#xff0c;就只能等它结束…