MPI是高性能计算常用的实现方式,它的全名叫做Message Passing Interface。顾名思义,它是一个实现了消息传递接口的库。MPI作为编程库很丰满,作为计算框架很骨感。它的好处在于一切自己动手,不利也在于一切全靠自己。 本文的目的不是探讨如何使用MPI,MPI标准是这方面最有参考价值的文档。本文笔者仅仅讨论它在并行编程上的特点,帮助用户决定何时或在何种场景下使用MPI。 什么是MPI? MPI是一个跨语言的通讯协议,支持高效方便的点对点、广播和组播。它提供了应用程序接口,包括协议和和语义说明,他们指明其如何在各种实现中发挥其特性。从概念上讲,MPI应该属于OSI参考模型的第五层或者更高,他的实现可能通过传输层的sockets和Transmission Control Protocol (TCP)覆盖大部分的层。大部分的MPI实现由一些指定的编程接口(API)组成,可由C, C++,Fortran,或者有此类库的语言比如C#, […]
系统架构面面观
在计算密集型或者数据密集型的应用场景,多机并行处理是提升性能的常用方法。并行编程不仅仅是一个编程问题,它涉及到数据访问、多机通信和资源调度,应用开发人员不可能从头造轮子解决所有问题,借助于编程框架是不可避免的趋势。究竟框架如何提升并行处理的效能呢?本篇我们聊聊这个话题。 并行如何提升计算效率? 分而治之是王道 计算机算法中常常将一个大问题分解成若干个小问题来解决,这就是所谓的分治法(Divide-Conquer)。如果不同的小问题可以交由单台机器的N个CPU(泛指逻辑CPU,包括CPU、核或者超线程),或者更进一步交给多台机器的N个CPU,理想情况下期望的运行时间可能缩短到1/N。之所以说是理想,是因为实际运行时间由下面几个因素决定: 由上述公式可知,如果系统中必须有50%的代码串行执行,那么系统的最大加速比为2。 计算机体系提升并行的方式 分布式计算是从并行计算机的时代演化来的。我们花点时间介绍一下传统并行计算机的实现模式,以此为基础理解分布式并行计算会有帮助。笔者认为并行的基础是数据并行。这个数据指文件,也可以是内存或者寄存器的数据。如果没有数据并行,那意味着操作之间或者毫无关系(从而直接分解),或者必须严格串行。如果是后者,就不可能有并行可言。 在传统的计算机体系中,数据并行有两种实现路径: 在分布式并行处理的场景中,我们会看到类似SIMD和MIMD的模式。 资源瓶颈驱动问题分解 […]
容错是大规模数据系统和计算系统的必备功能,不能容错的分布式系统基本没有可用性。大家可能觉得高质量的系统错误率没有那么高,实质上系统的故障率总是随着系统规模和复杂程度增加。笔者读书的时候曾经听过一位参与过先进飞行控制系统设计的专家讲课。这位专家有一句原话是说飞机大多是带故障飞行的。笔者很多研究无人机的师兄们都有意无意的避免坐飞机。笔者坐飞机也会再三确认购买保险 🙂 这不是吓唬大家,只是为了说明容错与我们息息相关。本篇我们来聊聊系统容错的方方面面。 1. 可靠性从哪里来? 1.1 安全、可靠与可用 安全(safety)、可靠(reliable)和可用(available)是我们常用的几个词汇。安全通常指避免灾难的能力,可靠指的是无故障提供指定功能的能力,可用指的是某个时间段系统能够正常运行。安全与可靠容易区分。举个例子来说,一架飞机坏了停在地上,它是安全的,因为它不可能引发灾难,但是不可靠,因为它无法完成飞行任务。可靠和可用的区别是什么呢?再举一个例子,你把钱存在银行里,晚上银行下班了,你没法通过柜台取钱。你的资产没有问题,银行具备可靠的保管你的资产的能力,但是它的服务不是7 x 24 […]
有句成语说“工欲善其事必先利其器”,系统问题纷繁复杂,需要完善的工具、方法和系统来帮助定位和解决。操作系统级别的机制和工具是首要条件,是后续分析和自动化的基础。打铁先得锤子硬。本篇笔者结合自己的经验,和大家聊聊分析系统问题的工具和方法。 工具只提供数据不提供答案 无论是通过命令行手动分析,还是运维系统自动分析,包括玄之又玄的智能运维(AIPOS),基础都是数据。差别只是做分析和决策的是人还是程序。在真实的数据密集型和计算密集型的生产环境中,任何机制或者工具都不可能采集系统所有的事件,所以数据不是日志,它在本质上是系统行为和状态在某个层次的粗粒化。例如iostat看硬盘设备的读写带宽和占用率,返回的是一个时间段的宏观统计值,使用者需要根据经验或者系统的实现机制去分析潜在的原因。 事件、状态或性能? 分析目的不一样,采用的工具、方法和代价各不相同: 数据采集对系统的影响 数据收集的首要问题是数据收集的代价,即数据收集对生产系统的影响程度如何。不同工具因为其实现方式不一样,对系统造成的影响各不相同。iotop或者iostat等工具的数据收集在目标代码段执行过程中,或者状态切换的时候进行,代价较小,但是提供的信息粒度相对固定。dtrace或者systemtap 等工具支持用户插入自己的分析代码,会给系统造成一定程度的性能影响。这些工具通常提供选项控制采样频率或者尺度,使用者需要根据具体情况选择。 Linux提供了哪些工具? Linux系统集成了大量的监控和分析工具帮助用户解决问题,大家根据需要自行选择服用。这些都是开发、调试、运维、杀人、放火必备技术。 […]
IT江湖上流传有一种说法,说的是“编译器和操作系统是计算科学的皇后”(不好意思,两个皇后)。编译器追求的是编程艺术,无数先贤发明编程语言获得图灵奖。如果说编译器是珠峰上的明珠,那笔者认为操作系统就是喜马拉雅山的垫脚石。操作系统没有编译器那么高大上,没有特别高级的算法,也没有让人眼前一亮的漂亮功能。它只是为所有可能的程序提供高效稳定的运行环境。单想做到这一点就足以耗尽无数系统程序猿的心血,却往往换不来一句好评。 刚入行时,听一位老司机说:“我们搞计算机的和木匠瓦匠是一回事,都是手艺人”。计算机科学与物理化学不一样,本质上不发现自然界的未知规律,它的目标是用已有的工具或者创造新工具解决已知的问题。它更像是经济学,追求的是解决问题的效率。在计算机领域的所有手艺中,系统开发(泛指操作系统内核、存储、计算基础架构等系统级工程)是“两头堵”的艺术,系统程序猿们整天忙着拆东墙补西墙,众口难调调众口。 写了很多编程宝典的侯捷说:“源码之前,了无秘密”。笔者想说,这句话可能不适用于系统软件。系统软件一旦运行,往往展现出复杂的动态行为,万“相”丛生,非“代码”两字足以囊括。笔者借用一个名词,称它是动力系统,说明其动态演化的特点。笔者在本篇和大家聊聊这些动态系统的机制,以及它们对真实的计算系统或者业务的决定性影响。 不会看病的程序猿不是好员工 任何一个产品交付给用户使用后,自然形成一个责任边界,即哪些责任由产品提供商负责,哪些责任由用户负责。实际情况是怎么样的呢?供需不平等决定了甲乙双方地位实质上不对等,用户往往进行有罪推定,而产品提供方则需要自证清白。基础架构产品(存储或者计算),他们对应用程序的运行时行为有间接但是决定性影响,责任边界更难划分。做系统的工程师都得会两手:一手给自己找茬(程序的Bug到底在哪里?),一手替别人看病(这是你的问题,不是我的Bug)。如果问题出在企业的生产环境,工程师更得如履薄冰,小心翼翼。 线上运维之“悬丝诊脉” 我们从小说和影视剧中常常可以看到“悬丝诊脉”的情节。神医把丝线的一头搭在贵妃的手腕上,另一头则由自己掌握。神医必须凭借着从悬丝传来的手感猜测、感觉脉象,诊断疾病,因为男女授受不亲,贵妃的身体更是碰不得。企业生产环境的应用跟贵妃一样,乙方能不碰是尽量不去碰的。例如用户一个典型的组装植物基因组的程序,经常得跑上几个星期,疯狂使用内存或者存储。如果跑到第十天还没有结束,用户会理直气壮地问“为什么还没有结束啊?系统出问题了吧?”。这个时候我们的工程师就得上去诊断。用户的程序是不可能停的,也不能调整配置做实验,或者调试一下存储。如果用户的程序被你弄挂了,就更说不清楚了。工程师们既要帮用户解决问题,还得离这个程序远远的。这就是典型的悬丝诊脉嘛。 当然也有乙方是比较生猛的。我们曾经在一个公有云的大厂上跑一个流程,运行了几天,程序卡住了。原因很简单,从两个不同的机器看一个目录,内容不一样。做过分布式存储的同志们都知道,这是数据不一致了,大概率是分布式锁的问题。乙方上去折腾了几天,搞不定。最后他们的支持工程师来了个猛的,提出把挂载点umount/mount解决问题,我们直接就傻眼了:“2B的工程师们不可以这么生猛吧?”。这显然不是典型的系统工程师啊。 学会当系统工程师 系统工程师这个说法笔者刚开始参加工作的时候从一个洋人大老板那里听来的,大体意思是从硬件到软件,从内核到用户态程序,从代码到脚本都得精通。这个系统的所有问题都是你的,需要你去搞定。当时觉得老板你真会忽悠人干活。后来自己参与存储创业,才明白了这个道理。为什么对工程师这么要求呢?因为一个存储或者计算系统是一个端到端的全栈解决方案。存储不等同于硬件,计算不等同于调度。用户的应用出了问题,你没法直接说问题不是你的。你得上去从头到脚的分析,直到证明这是应用程序自己的问题。在这个过程中,还要保证应用不受影响。 […]
无论是基于虚拟化的公有云还是基于容器的容器云(例如架在公有云上的k8s),都不是天然为HPC或者计算类业务优化的基础架构。那么“云”和“计算”理想的结合是什么呢?笔者认为应该是计算云。大家如果认为笔者前两篇文章是在挑刺的话,那这篇文章就尝试开个药方。 计算云是什么? 笔者所谓的计算云指的是为计算业务优化的类云基础架构,它强调用云的方式解决计算问题,而不是将“计算”搬到现有的公有云或者容器云上。目前公有云或者容器云(例如k8s)上的HPC解决方案本质上都是将现有的HPC方案虚拟化或容器化,以虚拟机或容器替代物理机。这些做法是为了将公有云资源卖给计算用户,并没有改进计算业务本身。 从用户的角度说,计算云是什么样的呢?笔者认为计算云应该具备下面几个特征。 1. 计算即服务 计算云提供的应该是端到端的计算服务,而不是资源服务。以一个传统环境下的HPC用户举例。HPC集群各个计算节点挂载了分布式文件系统,用户(或者系统管理员)将计算程序安装到分布式文件系统。用户登录到集群的登录节点,通过qsub投递一个单机计算任务,或者通过mpiexec提交一个MPI计算任务。调度系统(例如SGE、PBS、Slurm等)分配合适的计算资源,完成用户的计算任务。如果把HPC集群搬到云上或者容器里,使用方式仍然类似。系统管理员拉起一个HPC集群,普通用户登录集群使用计算服务。 现在问题来了。如果这个用户需要混合使用MPI、Hadoop、Tensorflow怎么办呢?系统管理员需要拉起三套集群,分别做三种计算。用户需要登录到三套不同的系统中提交任务。这三套系统的使用频率、负载程度不一样,系统管理员不可能实时动态管理集群来确保资源利用率。系统管理员以容器云的方式将HPC集群容器化是一种计划经济,没有市场经济的效率。计算应该由用户主导,按需分配。按需分配意味着程序化自动调度。基于k8s的Volcano解决问题的方式是让普通用户使用k8s模版提交任务。MPI用户需要提交服务模版去启动一组运行sshd服务的容器,然后启动一个运行mpiexec程序的容器。这种方式将系统管理员的工作转移到了用户身上,用户需要学习使用k8s。用户真正关心的是他自己的MPI程序,不是k8s,也不是运行sshd容器。造成这个问题的原因是k8s只是一个PaaS解决方案,本质上提供的是资源服务,不是计算服务。 真正的计算即服务要求用户不需要做与自己计算无关的事情。计算集群提供一些登录容器或者服务器,用户登录服务器安装软件到分布式文件系统,或者将软件打包成容器。用户根据自己的需要在登录节点通过qsub或者mpiexec提交作业,指明作业需要的资源和数据。计算云根据任务的类型,按需分配资源,构建HPC、Hadoop或者Tensorflow集群完成计算。计算过程中的资源如何分配,集群如何部署和销毁,数据如何共享是计算云内置的服务,不应该有用户参与。用户只需提交数据和程序到计算云,然后等待计算结果。 2. […]
理解了云计算的实质,Kubernetes就好理解了,它提供的是容器云。在私有数据中心,服务运行在物理主机的Host OS上,云计算场景下运行在虚拟机上,k8s场景下应用运行在容器内,容器替代了虚拟机。 容器是什么? 相对虚拟化,容器是更轻量级的技术,它将应用软件及依赖打包在一起,便于部署和迁移。如果说Java语言实现了一次编译,处处运行,那么容器实现了一次安装,多次运行。在Linux上,容器技术的底层实现机制是Linux Kernel的Control Group(CGroup)。它维护各种各样的名字空间(进程ID,IPC,网络等等),并按照Group管理系统资源分配和释放。可以在每个CGroup上施加限制(CPU、内存、IO等等),确保资源的使用配额。所有的容器可以有自己的资源和文件系统镜像,但是共享内核。容器比虚拟机开销小,性能上占优势。虚拟机比容器隔离性(isolation)好,更容易保证不同租客不相互影响。 容器技术有多种选择,Docker和Singularity是两种比较流行的选择。它们的底层机制是共通的,但是在镜像管理上有差别。Docker通过层(Layer)与层的叠加优化镜像空间的利用率,通过Overlay2文件系统实现只读共享和写时拷贝。Singularity采用不同的文件格式(SIF),通过压缩技术优化空间利用率,镜像主体部分只读共享。无论Docker和Singularity都不适合容器内部大量读写,所以容器需要和外部存储结合使用,容器镜像承载只读的二进制程序和软件包,外部存储承载程序的数据读写。 k8s从哪里来? k8s源于Google的开源项目Kubernetes。尴尬的是Google内部真正使用的系统叫Borg,不是k8s。有一种野史说法是,Google将Borg中的一些边缘技术通过Golang实现,变成了Kubernetes。当然Google的说法是Kubernetes吸取了Borg的优秀理念。Google将一个自己并不使用的技术开源给大家使用,可谓“纯粹的奉献”。 大家了解Google是因为它闻名遐迩的三件套GFS、MapReduce和BigTable。大概从2003年开始,这三件套发表了论文,但没有开放源代码,大家只闻其名,不见其形。后来有位工程师Doug […]
云计算是很大的话题,这个领域的玩家都是巨头,个个都财雄势大,每人都有一家之言。本文只从用户角度,看看云和计算结合都有些什么问题。 云计算的起源与初衷 云计算是近些年炒的厉害的概念,也是生物技术相关企业常被推销的解决方案。究其起源,云计算发端于IBM的IT外包服务(IT outsourcing),简单的说就是企业把自己全套IT基础设施托管在IBM的数据中心,后者负责运维。亚马逊(Amazon)后来居上,提供了ECS、S3等等云服务。Amazon的“中国化”就产生了现在的阿里云、腾讯云、华为云等。 云计算带来了什么新技术呢?云计算不带来什么新技术,它是一种商业模式上的创新,即将企业的一次性固定成本转化为运营成本。云计算最适合的运用场景是解决峰值需求。用户平常只需要5台机器,某个星期需要几千台机器,可以去租用云服务商的机器,避免投入千台机器的成本。云服务商通常就是那些已经买了大量机器的企业。亚马逊、阿里、京东都是电商。反正已经投入了这么多机器,忙的时候自己用,闲的时候租给你用。那么非峰值场景企业用不用云服务呢?答案取决于你对成本和安全这两个核心问题的考虑。成本问题自己可以算,安全问题很简单:云计算是异地计算,所有数据和服务都在云服务提供商手里,都在他们的运营人员手里。所以该怎么决策?算算你的成本是否划算,摸摸你的后背是否觉得安全。现在很多人说云计算是趋势,是政治正确。抛开这两个问题谈趋势,只能是忽悠。 云上安全吗? 我们再闲话几句安全问题。安全是一个很大的问题,我们这里只能扯一扯和云计算相关的安全问题。云计算的安全问题本质是信任问题,不等于安全技术。因为所有的服务和数据都在远端,我们需要确信它们是安全的。我们常用的安全技术例如加密解密,只能保证数据在传输过程中,或者数据落盘之后的安全。前提是数据在云上的整个环节都执行了严格的安全标准。感兴趣的同志们可以研究研究美国的HIPPA标准,它制定出来保护病人隐私数据。亚马逊有它的实现指南,规定了网络服务要怎么样,数据库要怎么样,存储要怎么样等等。国内的法规如何呢?我们都不知道。笔者曾经请教RSA的专家云安全的问题,为什么不能和用户签署一份服务质量协议(Service Level Agreement),承诺用户安全?他回答说“NO”,事情不是这样子做的。没有人能证明系统是安全的,你永远只能证明系统不安全。当然也无法承诺安全,你只能承诺系统的行为是按照期望那样发生的。你永远只能用技术去保证你的服务只会在哪台机器运行,这台机器所有的操作日志都存留一下,进入机房的人员都有签字录像,等等等等。你把每件事都记下来,交给客户和可信第三方来审计,说看吧,我能做到这些,你相信自己安全吗?。至于我们的可信第三方和审计怎么样?自己去想想。 笔者亲身经历了Amazon云上的安全事件。当时我们公司在Amazon(美国地区)部署了一个网站,是一个Twiki服务,仅仅开放80端口。没有任何意外(当时很意外),我们的网站被攻击了,变成了少儿不宜视频服务,Google搜索发现成千上万的链接指向我们。其实攻击的方式很简单,利用了Twiki搜索框的漏洞。一个星期后,Amazon给我们发了邮件,报告我们的虚拟机在试图攻击别人的虚拟机。这个指责毫无疑问是正确的,因为我们的虚拟机已经不“属于”我们了。我们向Amazon投诉,它的回答是“我们只是提供虚拟机,虚拟机里面由用户自己负责”。这当然是有道理的,它涉及到云厂商和用户在基础架构服务(IaaS)的权责划分。但是它暴露了一个问题:用户上云可以将IT成本减少到什么程度? […]