从 0 开始学架构
李运华
网名“华仔”,前阿里资深技术专家(P9)
152571 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 66 讲
结束语 (1讲)
结课测试 (1讲)
从 0 开始学架构
15
15
1.0x
00:00/00:00
登录|注册

04 | 复杂度来源:高性能

针对单个任务进行扩展
简单的系统更容易高性能
分配算法
连接和交互
任务分配器
MPP
NUMA
SMP
进程间通信
线程
进程
任务分解
任务分配
多核处理器
操作系统
集群的复杂度
单机复杂度
复杂度来源之一:高性能

该思维导图由 AI 生成,仅供参考

周四,我为你讲了架构设计的主要目的是为了解决软件系统复杂度带来的问题。那么从今天开始,我将为你深入分析复杂度的 6 个来源,先来聊聊复杂度的来源之一高性能
对性能孜孜不倦的追求是整个人类技术不断发展的根本驱动力。例如计算机,从电子管计算机到晶体管计算机再到集成电路计算机,运算性能从每秒几次提升到每秒几亿次。但伴随性能越来越高,相应的方法和系统复杂度也是越来越高。现代的计算机 CPU 集成了几亿颗晶体管,逻辑复杂度和制造复杂度相比最初的晶体管计算机,根本不可同日而语。
软件系统也存在同样的现象。最近几十年软件系统性能飞速发展,从最初的计算机只能进行简单的科学计算,到现在 Google 能够支撑每秒几万次的搜索。与此同时,软件系统规模也从单台计算机扩展到上万台计算机;从最初的单用户单工的字符界面 Dos 操作系统,到现在的多用户多工的 Windows 10 图形操作系统。
当然,技术发展带来了性能上的提升,不一定带来复杂度的提升。例如,硬件存储从纸带→磁带→磁盘→SSD,并没有显著带来系统复杂度的增加。因为新技术会逐步淘汰旧技术,这种情况下我们直接用新技术即可,不用担心系统复杂度会随之提升。只有那些并不是用来取代旧技术,而是开辟了一个全新领域的技术,才会给软件系统带来复杂度,因为软件系统在设计的时候就需要在这些技术之间进行判断选择或者组合。就像汽车的发明无法取代火车,飞机的出现也并不能完全取代火车,所以我们在出行的时候,需要考虑选择汽车、火车还是飞机,这个选择的过程就比较复杂了,要考虑价格、时间、速度、舒适度等各种因素。
软件系统中高性能带来的复杂度主要体现在两方面,一方面是单台计算机内部为了高性能带来的复杂度;另一方面是多台计算机集群为了高性能带来的复杂度

单机复杂度

计算机内部复杂度最关键的地方就是操作系统。计算机性能的发展本质上是由硬件发展驱动的,尤其是 CPU 的性能发展。著名的“摩尔定律”表明了 CPU 的处理能力每隔 18 个月就翻一番;而将硬件性能充分发挥出来的关键就是操作系统,所以操作系统本身其实也是跟随硬件的发展而发展的,操作系统是软件系统的运行环境,操作系统的复杂度直接决定了软件系统的复杂度。
操作系统和性能最相关的就是进程线程最早的计算机其实是没有操作系统的,只有输入、计算和输出功能,用户输入一个指令,计算机完成操作,大部分时候计算机都在等待用户输入指令,这样的处理性能很显然是很低效的,因为人的输入速度是远远比不上计算机的运算速度的。
为了解决手工操作带来的低效,批处理操作系统应运而生。批处理简单来说就是先把要执行的指令预先写下来(写到纸带、磁带、磁盘等),形成一个指令清单,这个指令清单就是我们常说的“任务”,然后将任务交给计算机去执行,批处理操作系统负责读取“任务”中的指令清单并进行处理,计算机执行的过程中无须等待人工手工操作,这样性能就有了很大的提升。
批处理程序大大提升了处理性能,但有一个很明显的缺点:计算机一次只能执行一个任务,如果某个任务需要从 I/O 设备(例如磁带)读取大量的数据,在 I/O 操作的过程中,CPU 其实是空闲的,而这个空闲时间本来是可以进行其他计算的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

现代软件系统的高性能带来了复杂度的挑战,主要体现在单台计算机内部和多台计算机集群方面。在单机复杂度方面,操作系统的发展直接影响着软件系统的复杂度,而多台计算机集群的协同工作更是一个复杂的任务。为了解决这一挑战,任务分配和任务分解成为了常见的应对方式。然而,任务分解需要避免拆分得过细,以免增加系统间的调用次数,导致性能下降。因此,在设计和实现软件系统时,需要认真考虑和解决高性能带来的复杂度问题。同时,文章也指出了任务分解带来的性能收益是有一个度的,并非越细越好,对于架构设计来说,如何把握这个粒度就显得非常关键。因此,文章提供了对于软件系统高性能复杂度问题的深入思考和解决方案。文章通过深入分析了现代软件系统中高性能带来的复杂度挑战,强调了任务分配和任务分解在解决这一挑战中的重要性,并提出了相应的解决方案。文章内容丰富,对于软件系统设计和实现具有一定的指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《从 0 开始学架构》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(187)

  • 最新
  • 精选
  • loveluckystar
    之前我们的系统是all-in的单系统模式,虽然水平扩展了大量机器,但是仍然存在性能问题,比如类似秒杀之类的活动,几乎会在瞬间把整个系统的数据库连接耗尽,导致其他服务发生卡顿甚至不可用;并且全在一个业务系统中,开发部属效率极低,扩展性也存在问题。 于是我们将系统进行了拆分,起初是按照业务拆分成几个核心系统,同时针对不同业务的负载情况进行了合理的水平扩展,整个系统的性能得到了提升,扩展性得到了保证,并且开发部署效率也得到了极大的提高。 但是随着业务的发展,之前的系统拆分不能满足现有业务,同时随着公司很多老员工的离开,之前的架构设计思路没有人清楚,于是就变成了走一步看一步的推进模式,衍生出了各种独立的服务达40个左右,这样系统之间的边界越来越模糊,甚至出现了服务间的循环调用,白白浪费时间。而且一次调用链路过长,发生问题很难定位。 所以我觉得我们的系统就是一个活生生的,没有搞好架构设计的例子,前期是没有设计导致性能瓶颈,后期是过度设计导致系统复杂。

    作者回复: 典型案例,值得好好总结归纳一下

    2018-05-07
    8
    111
  • pavel
    感谢老师回复。我们系统的量,每天学到存储大概有2T,采用mysql和hbase做存储。我们是做网站统计的,类似cnzz。每天接到的pv请求会到十亿次以上。我们使用集群接收,Kafka做消息队列,storm实时消费。统计结果存储在mysql,行为数据等存储在hbase。由于实时性要求以及量大,存储性能实在是一个瓶颈,主从同步滞后也相对严重,现在都已经去掉从库了。针对这种IO场景,而且实时性要求较高,R如何来应对呢?之前有个方案是mysql采取大量的分表分库,总共20台服务器,ssd硬盘,这样是能支持,但是成本还是挺大的,是否有更好的,或者我应该从哪方便去考虑呢?

    作者回复: 1. 压缩 2. 合并:将多个数据合并为一个数据,可以在web端做 3. 采样:统计其实不需要精确值,例如1000000001和1000000002没有区别,可以用采样来推算原始值 你的系统复杂度就是大数据量(规模)和实时性,对结果其实不要求非常精确。

    2018-05-22
    69
  • Sean
    架构无处不在,生活中也有很多例子。就比如去快餐厅去吃饭,涉及的任务就有打饭,选菜,付款,找座位。 普通的快餐厅,比如**缘,就是单线程,所有必须排队进行,最原始的系统架构。所以你会发现效率低,通常会拍队列,体验就不好。 而去**王吃饭,进去就有一个引导员(负载均衡),提前帮你分配座位,发点餐单,而且有多个引导员同时工作(负载均衡集群),而且各种菜系可以同时进行(并行)。另外一些需要等待的菜,会让你边吃边等(异步)。所以看上去人好多,很少有在排队的现象。可见,这位老板也是位不错的架构师。

    作者回复: 666

    2018-10-16
    64
  • gevin
    我这边很多项目都是面向传统行业国企的,他们成熟的传统方案都和IT无关,先现在要向IT靠拢。通常用户那边的业务量、并发量小,企业不差钱,所以一般都是通过硬件层面的垂直扩展来提高性能的。对我们的用户而言,一方面喜欢性能强悍的硬件设备,另一方面,当我们给他们写软件开发的报告时,什么样的技术方案火,就要在报告里体现出什么样的技术(比如现在给用户的方案都要和向微服务靠拢),面子上的工作要做足,也很有意思~

    作者回复: 这就是你们项目的复杂度:如何以更低成本优雅的装逼😂

    2018-05-21
    7
    53
  • 小喵喵
    李老师,当一个系统分为很多子系统时,每个子系统都有独立的数据库,如何保证数据的一致性呢?比如我有一个业务需要在A库插入一跳数据,在B库也要插入了一跳数据,然后在C库修改一条数据。假设中间那个库操作失败了,如何做到这个数据的一致性呢?

    作者回复: BASE原理,最终一致性,后面会讲

    2018-05-06
    2
    25
  • 汪彬英
    我目前是一家中型互联网公司技术部平台组leader。我们,目前的架构其实是更接近第二种。做了微服务拆分。它在一定程度上解决了单系统时期面临的各种问题。但是就像文中说的,我觉得我们的拆分力度没有把握的很好。也导致了近2年开始出现,特别是大促的时候,机器增加比例比请求增加的比例大很多。一个完整的调用流程,调用链非常长。核心原因是当时做微服务拆分的时候,完全是基于数据库做拆分的,比如,所有跟用户信息有关的东西拆分成用户系统,跟你订单有关的东西拆分成订单系统,跟渠道有关的东西拆分成渠道系统等等。这样拆分之后,一个在用户看起来应该很连贯的操作,我们内部却需要调很多系统。想问一下老师,基于这种现状,有没有比较好的建议呢?

    作者回复: 分析核心流程的全链路性能消耗,找到消耗最大的1个或者几个服务进行优化,或者合并一些微服务,降低接口调用次数

    2021-06-15
    17
  • 清泉
    说说我的理解,不管是任务分配还是任务分解,都是通过分摊单台机器的流量来提高整个系统的处理性能。 对于任务分解,我认为不但没有性能上的收益,反而有性能上的损耗,本来可以在一个进程内部完成的交互,分解后却需要进行服务器间的网络交互。(分解前后业务逻辑不变的情况下) 不知道我这么理解对不对,但是与楼主说的任务分解一定程度上可以提高性能有些矛盾,求楼主指点迷津😊

    作者回复: 有性能损耗,但性能收益更多,举个简单例子,A功能和B功能在同一系统,A功能慢查询导致整个系统性能低,B功能性能同样被拉低。 我举例是告诉你说有慢查询,实际上很多系统隐藏的性能问题并不明显就能看出来。

    2018-05-05
    3
    17
  • 卡莫拉内西
    我们公司做的政府项目,没有高并发的场景,业务大多也是crud,高可用是有的,高扩展的场景较少,需求基本上是产品经理整理好的,一台ng,两台应用服务器,一主两从mysql,nas设备,redis都可以不用,请问这样业务场景的公司是否适合长期呆下去,还是说可以为了架构而架构,公司本身不差钱,给政府做项目几乎也是友情价,老板在乎的可能是数据

    作者回复: 职业选择不是本专栏的内容呢,看你个人追求什么了,有的人追求稳定,有的人追求兴趣,有的人追求回报

    2018-05-06
    2
    8
  • 新人小胖
    我们现在的系统是一个消息处理系统,主要的瓶颈在于消息的处理是必须要是顺序的,不能乱序,所以subscribe消息是单线程的,目前需要解决这个问题。

    作者回复: “顺序”有两种场景:1. 按先后顺序分配,2. 处理完前一条才能处理完后一条。 第一种情况按照简单的任务分配就可以实现高性能,第二种如果任务的处理比较复杂的话,可以用任务分解,将任务分解为多个步骤,采用流水线的架构设计达到高性能,如果任务很简单,单台机器做好优化性能也能做到比较高,例如redis就是单进程的

    2018-05-05
    3
    8
  • 马亮
    单台服务器性能打八折,这个数字怎么来的呢?经验值还是测算值?比较好奇

    作者回复: 经验值,而且很多时候还达不到这个值

    2019-02-26
    7
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部