当前位置:首页 > 问答 > 正文

并行和分布式计算那些基本原理还有点复杂但挺关键的东西

并行和分布式计算里有些核心思想,乍一听有点绕,但确实是整个领域的基石,咱们抛开那些晦涩的术语,直接聊聊这些“有点复杂但挺关键的东西”。

最根本的一点是,为什么要并行或分布式? 答案很简单:一个人(一个处理器)干太慢,或者根本干不了,比如要分析全球的天气数据,一台机器算到明年也算不完,那就得找成千上万台机器一起算,但“一起算”不是简单地把活一分就完事了,这里就引出了第一个关键概念:“分”的策略和“合”的代价,你怎么把一个大任务拆成小任务?是平均分,还是按难度分?拆得太细,管理这些小任务的开销可能比干活本身还累;拆得太粗,有些机器忙死,有些闲死,更麻烦的是,这些小任务干完活之后,结果往往还得汇总起来,它们之间如果需要互相通信、等待,那就会产生巨大的协调成本,这就好比一个团队做项目,如果每个人都要不停地跟所有人开会同步进度,那真正干活的时间就少了,这个协调和通信的开销,是吃掉并行计算效率的主要“怪兽”。

一个无法回避的难题是同步与锁,想象一下,好几个计算单元都要去修改同一个数据,比如同一个银行账户余额,如果同时进行,结果肯定乱套,所以必须有个机制,让它们“排队”修改,这就是“锁”:一个单元用的时候,就把数据锁上,别人只能等着,但锁又会带来新问题:万一拿着锁的单元出故障了,或者等锁的单元太多,整个系统就可能卡死,这叫“死锁”,更头疼的是,为了安全而频繁加锁,又会把并行打回原形,变成变相的排队串行,高手们总是在设计更精巧的锁,或者干脆想办法设计不需要共享数据的计算方式,来避开这个泥潭。

在分布式计算中,另一个核心问题是故障是常态,一个由几千台普通电脑组成的集群,几乎每时每刻都有机器在出故障、掉线,你不能因为一台电脑死机,就让整个计算任务从头再来,这就要求系统必须具备容错能力,最常见的法宝是冗余:把同一份数据或者同一个计算任务,默默地复制好几份,放在不同的机器上,这样,坏了一两个副本,还有备份,但这又带来了数据一致性的新麻烦:如何确保所有备份的数据时刻都是一样的?如果为了强一致性,每次更新都要同步所有备份,那速度就慢;如果允许暂时不一致,那用户可能读到旧数据,这就是著名的“CAP原理”所揭示的困境:在分布式系统中,一致性、可用性、分区容错性三者难以兼得,你必须有所取舍。

还有一个深刻的思想叫“可扩展性”,它不仅仅是“能加机器”,而是指加了机器之后,性能是否能成比例地提升,理想情况是加一倍机器,速度就快一倍,但现实中,由于前面提到的通信、协调、同步等开销,加机器带来的收益会越来越低,甚至加多了反而变慢,一个好的并行或分布式系统设计,其核心目标就是让这些无法并行的、必须串行的部分尽可能小,让系统的规模可以平滑地扩大,这就像组织一个庞大的人群工作,如果规章制度(通信协议)和中间管理层(协调开销)过于臃肿,人越多反而效率越低。

这些原理——任务分解与协调开销、同步与锁的困境、故障常态下的容错与一致性权衡、以及可扩展性的本质——相互交织,构成了并行与分布式计算复杂性的内核,理解它们,就能理解为什么设计一个高效、可靠的大规模计算系统如此具有挑战性,也才能明白那些层出不穷的技术框架,本质上都是在用不同的方式应对这些根本性的难题。

(主要思想参考自Andrew S. Tanenbaum的《分布式系统:原理与范型》、Maurice Herlihy与Nir Shavit的《多处理器编程的艺术》以及Google关于MapReduce、BigTable等系统的经典论文中所阐述的基本原理)

并行和分布式计算那些基本原理还有点复杂但挺关键的东西