从软硬件以及常见框架思考高并发设计

目录

文章简介

扩展方式

横向扩展

纵向扩展

站在软件的层面上看

站在硬件的层面上看

站在经典的单机服务框架上看

性能提升的思考方向

可用性提升的思考方向

扩展性提升的思考方向


文章简介

先从整体,体系认识,理解高并发的策略,方向。以及从现有的经典单机服务框架上去分类学习其中优秀的架构设计,以及高并发背景之下的高性能,高可靠,可扩展这三大方向它们是怎么做到的。目前小杰只有浅显的认识和理解。所以此篇文章,只是通过提出问题,然后从多角度思考三高的提升方向,策略。然后结合现有的经典服务框架去实践学习。

个人想法:的确这些靠近架构的设计,偏向技术专家该研究和解决的问题,对于我们尚没有工作经验的学生或者说应届毕业生过于遥远。但是,我个人决定也许今天,明天,明年,甚至在工作的前三年。我们可能都不一定有机会将这些思想融入实践,真正转换为自身的硬技能。但是深入了解加这些,一是培养我们对技术的追求信仰,二是有个梦想和盼头,万一将来就用得上呢?我知道大多数人会说,现在学了没有用,过不了多久就会遗忘。不假,经过一年考研的代码空窗期,遗忘对我来说真是太有发言权了。但是,我非常感激三年前自己做出的决定,那就是用心记录自己的学习笔记,写成博客。因为自己写的东西是最容易理解的,也是最快可以回忆起来的。所以这也是维护文档和养成博客习惯的好处吧。

其次我还想跟大家分享下学习方法,我觉得任何知识,技能的熟练和掌握起码要三遍。不重复,这些难以理解的技术是永远不能真正变成我们自身的思想的。第一遍,通过音频,视频,体系文章快速的了解,理解新的技术点,设计思想,为什么会出现这种技术,它的出现是为了解决什么问题。还有就是体系化,想要真正掌握任何新的技术,我们绝不能有急于求成是想法。我们应该是静下心来,寻找成体系的书籍,或者是带文档的大佬音频(极客时间,慕课...)去成体系的先快速理解这个知识点,这个技术点。然后在理解的基础之上仔细阅读文档,在纸上精简提取文档中的精华。最后一步,将其持久化到博客之上。真的,碎片化的文章无法帮助我们建立记忆体系,必须要有体系化的去学习,高级的问题解决策略永远是站在无数个基础方法点之上的。最快的学习方法就是一开始很慢,但成体系。体系一旦建立,你会在具体实例的学习上不断的重复体系中的关键基础技术点,巩固记忆,最终形成深刻理解。

持久化的自己的博客一定要反复阅读,我个人就是需要面试前就开始读这些自己写的博客,会发现如同跨时空的对话,真的能够帮助我们快速回忆并且反复思考。

扩展方式

横向扩展

通俗理解:

单兵能力提升到一定程度之后,再想扩展比较困难。这种情况下硬件继续升级,可能性价比不高。所以采用普通配置的军团模式。进行横向扩展,用数量达到更高的并发处理,性能等能力。

增加实例个数。增加更多的计算节点(服务器、实例或节点)来扩展系统的容量和性能。可以通过负载均衡器将请求分发到不同的节点上,以实现负载的均衡。

实际案例:

  • 增加指令流水线的数目,更多条流水线并行运算,提高计算能力。
  • 双核和多核技术,将多个CPU核心压在一个芯片上,大大提高CPU的并行处理能力。
  • 横向增加Redis实例的个数. 比如使用3个8GB内存, 50GB磁盘的实例来达到24G内存, 150GB磁盘的效果。
  • 消息队列服务:在消息队列系统中,可以通过增加更多的消息队列节点来处理更多的消息并提高系统的吞吐量。

纵向扩展

通俗理解:

提升单兵作战能力,提高单节点处理数据,流量的能力。

可以通过硬件层面升级硬件,优化算法提高单节点处理能力。

实际案例:

  • 对单条流水线进行硬件升级等优化手段,降低单个任务的加工时间,提高单条流水线效率。进而提高处理能力。
  • 在CPU芯片的纵向扩展中,指的是通过增加单个CPU核心的性能来提高整个芯片的性能。这包括增加单个核心的时钟频率、增加核心的处理能力以及增加核心的缓存大小等。
  • 升级单个Redis实例的资源配置,增加内存容量,磁盘容量,更高配置的CPU。直接用24GB内存,150GB磁盘的单个Redis实例。

这两货尤其重要,几乎是所有的高并发策略都是站在这两货的宏观思想之上设计出来的。理解这两货,很多解决问题的策略都可以触类旁通,举一反三了。

站在软件的层面上看

  1. 负载均衡(横向扩展)算法。应用:数据库集群、分布式缓存、分布式文件系统
  2. 纵向扩展(垂直扩展): 单点性能优化。
  •  对于计算密集型应用,可以通过优化算法、提高代码效率等方式来提高单个节点的处理能力。
  • 对于数据库等服务,可以通过优化查询语句、增加索引、提高数据库参数配置等方式来提高单个节点的性能。

站在硬件的层面上看

有哪些提高并发量的硬件技术,它们需要搭配哪些软件技术?

  1. 高性能网卡:搭配 epoll IO多路复用,AIO 技术。
  2. 多核CPU:多线程/多进程 + CPU亲缘性
  3. 快速存取设备:块读取(一整块读取)+内存映射
  4. 大内存容量:本地应用缓存技术,分布式缓存技术(Redis、Memcached)

站在经典的单机服务框架上看

  • 单进程异步框架:redis
  • 多线程异步框架:memcached
  • 多进程异步框架:nginx
  • one request one process 框架:Apache
  • 微进程框架:skynet
  • 协程框架:libco

性能提升的思考方向

性能判定标准:QPS(Queries Per Second)和 TPS(Transactions Per Second)是衡量系统性能的指标,它们分别表示每秒钟能够处理的查询数和事务数

如何提高读取性能?     缓存策略   

如何提高写入性能?     消息队列 

缓存策略

  • 使用缓存技术将经常访问的数据存储在内存中,减少对磁盘的访问次数。这可以大大提高读取性能,尤其是针对热点数据或频繁访问的数据。
  • 常见的缓存方案包括使用内存缓存(如Redis、Memcached)、文件系统缓存、数据库查询结果缓存等。

消息队列

  • 使用消息队列来实现异步写入,将写入操作放入消息队列中,由后台服务异步处理。这可以降低写入操作对主线程的影响,从而提高系统的写入性能。
  • 常见的消息队列系统包括Kafka、RabbitMQ、ActiveMQ等。

性能优化几大原则:

  • 不能盲目、过度的提前设计(增加系统复杂度),一定要遵循问题导向。(一开始应该重业务实现轻量系统设计。)

在软件开发中,应该遵循适度的原则,而不是过度设计或过度实现。这意味着在开始设计系统之前,应该先理解业务需求并实现核心功能,然后根据实际需要逐步进行系统设计和优化。

在实现核心功能之后,可以逐步进行系统设计和优化。这包括对系统架构、数据库设计、性能优化、安全性设计等方面的优化。

通过逐步迭代的方式进行系统设计,可以根据实际情况调整和优化系统设计,避免过度设计和浪费资源。

  • 八二原则 20% 的精力解决 80% 的问题 [抓住主要矛盾]。优先优化主要性能瓶颈点。
  • 要测试,要有数据支撑,寻找拐点。
  • 优化过程要持续不断的迭代。

当并行的任务数较多时,系统会因为争抢资源而达到性能上的拐点,系统处理能力不升反降。

在系统设计中,性能提升拐点是指系统在不同负载下性能提升的速度逐渐减缓,并最终达到一个临界点,在此点之后性能提升的效果迅速降低甚至停滞。性能提升拐点通常与系统的架构、资源利用率、算法复杂度等因素密切相关。

以下是一些可能导致性能提升拐点的因素:

  1. 硬件资源瓶颈

    • 当系统的性能受限于硬件资源(如CPU、内存、磁盘I/O等)时,性能提升拐点可能出现在硬件资源达到饱和的临界点。此时,再次增加硬件资源并不能显著提升系统性能。
  2. 并发度限制

    • 当系统受到并发度限制时,即使增加了更多的处理单元或线程,也无法进一步提高系统的并发处理能力。这可能是由于锁竞争、资源竞争或分布式系统中的一致性等原因导致的。
  3. 算法复杂度

    • 在某些情况下,系统性能的提升受到算法复杂度的限制。当系统采用的算法复杂度达到一定水平时,进一步优化算法可能会变得非常困难,从而导致性能提升效果减弱。
  4. 系统架构限制

    • 系统架构设计的合理性也会影响性能提升的拐点。当系统架构存在瓶颈或不合理之处时,再怎么优化也无法进一步提高系统的性能。
  5. 外部依赖限制

    • 系统的性能也可能受到外部依赖的限制,例如数据库性能、网络带宽等。在某些情况下,性能提升受限于外部依赖的性能。

在遇到性能提升拐点时,进一步的性能优化可能需要更深入的系统分析、重新设计架构、采用更高效的算法、优化硬件配置等措施。需要综合考虑系统的整体架构、负载特征、资源使用情况等因素,以寻找性能提升的新突破点。

可用性提升的思考方向

如何完成容灾,有哪些容灾策略? 通过备份来容灾。

啥叫可用性:可以使用的程度,究竟是全年无损,还是 三五宕机(无法服务)。

可用性:无故障运行能力(容灾能力,自动恢复能力)。

可用性度量:

MTBF (Mean Time Between Failure):平均无故障时间(两次故障的时间间隔)

MTTR (Mean Time To Repair):平均恢复时间

可用性(Availability)

  • 可用性指的是系统在特定时间范围内处于可用状态的概率,通常以百分比(%)表示。例如,如果系统的可用性为 99.9%,则表示系统在一年中有 99.9% 的时间处于可用状态。

  • 可用性可以用以下公式计算:

可用性与 MTBF 和 MTTR 相关,通过提高 MTBF 和缩短 MTTR 可以提高系统的可用性。

高可用系统的设计思路

  1. Failover(故障转移):主备节点之间,系统出现故障或不可用情况下,自动将服务从一个节点(通常是主节点)切换到另一个备用节点的过程。这样可以确保系统在出现故障时仍然能够保持可用性和持续运行。 (设计一个选举问题,选择那个备用节点成为主节点)
  2. 超时控制(规避延迟,避免阻塞导致资源占用得不到释放引发的服务崩溃)为避免因大量阻塞导致服务端崩溃,需要对系统进行合理的设计和优化。这包括采用非阻塞的并发模型、合理设置超时时间、优化资源管理、限制并发请求数量
  3. 服务降级(牺牲非核心业务)降级是为了保证核心服务的稳定而牺牲非核心服务的做法。
  4. 服务限流(限制每秒访问量,超出系统范围返回错误)

扩展性提升的思考方向

系统中存在哪些服务会成为制约系统扩展的重要因素呢? 思考扩展的方向

高峰期如何通过扩展的方式来平稳扩度过?

有哪些常用扩展方式?

(截取高并发系统设计40讲中的案例)

其实,无状态的服务和组件更易于扩展,而像 MySQL 这种存储服务是有状态的,就比较
难以扩展。因为向存储集群中增加或者减少机器时,会涉及大量数据的迁移,而一般传统的
关系型数据库都不支持。这就是为什么提升系统扩展性会很复杂的主要原因。

除此之外,从例子中你可以看到,我们需要站在整体架构的角度,而不仅仅是业务服务器的
角度来考虑系统的扩展性 。所以说,数据库、缓存、依赖的第三方、负载均衡、交换机带
宽等等都是系统扩展时需要考虑的因素。我们要知道系统并发到了某一个量级之后,哪一个
因素会成为我们的瓶颈点,从而针对性地进行扩展。

提升高并发系统的扩展性有时候会很难,主要是因为系统中存在一些难以扩展或对扩展支持比较弱的瓶颈点。以下是一些可能导致扩展性受限的常见瓶颈点:

  1. 数据库瓶颈

    • 数据库通常是高并发系统的瓶颈之一。传统的关系型数据库(如MySQL)在水平扩展方面存在一定的局限性,特别是在处理大量读写请求时容易成为瓶颈。
    • 单个数据库实例的性能有限,无法满足系统的高并发需求。即使使用主从复制或分片等技术进行扩展,仍然可能遇到性能瓶颈和一致性问题。
  2. 缓存层瓶颈

    • 缓存层通常用于提高系统的读取性能和降低数据库负载。但是,当缓存层成为瓶颈时,可能会导致性能问题。
    • 如果缓存层无法有效地处理大量并发请求或缓存命中率较低,就会增加数据库负载,并影响系统的扩展性。
  3. 网络瓶颈

    • 网络通常是分布式系统中的一个关键瓶颈点。当系统规模扩大时,网络带宽和延迟可能成为限制因素。
    • 特别是在跨数据中心或跨地理位置的分布式架构中,网络延迟和可靠性问题会对系统的性能和可用性产生重大影响。
  4. 服务间依赖关系

    • 当系统中的各个服务之间存在较强的依赖关系时,扩展性可能会受到限制。如果某个关键服务无法扩展或出现故障,可能会影响整个系统的性能和可用性。
    • 合理的服务拆分和解耦可以减少依赖关系,提高系统的灵活性和扩展性。
  5. 技术选型和架构设计

    • 不恰当的技术选型和架构设计可能会限制系统的扩展性。如果系统采用的技术栈或架构模式无法满足日益增长的需求,就会导致扩展困难。
    • 例如,选择不适合高并发场景的数据库引擎、使用单体架构而非微服务架构等都可能影响系统的扩展性。

拆分是设计高可扩展系统的核心思想之一,它指的是将系统拆分成多个独立的组件或服务,以降低单个组件的复杂度,提高系统的灵活性和可扩展性。拆分可以分为水平拆分和垂直拆分两种方式。

  1. 水平拆分
    • 水平拆分是指将系统的数据或工作负载分散到多个节点上,每个节点负责处理部分请求或数据。这样可以通过增加节点来扩展系统的处理能力,提高系统的吞吐量和性能。
    • 例如,在电子商务系统中,可以根据用户的地理位置将用户数据分散到不同的数据中心,以降低跨地理位置的网络延迟,并提高系统的响应速度。
  2. 垂直拆分
    • 垂直拆分是指将系统的功能拆分成多个独立的模块或服务,每个模块负责处理特定的功能或业务流程。这样可以降低单个模块的复杂度,提高系统的灵活性和可维护性。
    • 例如,在社交网络系统中,可以将用户管理、消息推送、好友关系管理等功能拆分成独立的服务,每个服务负责处理特定的功能,从而降低系统的耦合度,并实现更好的水平扩展。

下面是一些帮助理解拆分思想的例子:

  1. 在线购物系统

    • 将用户管理、商品管理、订单管理等功能拆分成独立的服务,每个服务负责处理特定的功能。
    • 可以将订单管理服务水平拆分成多个节点,以应对订单数量的增加。
    • 可以将用户管理和商品管理服务垂直拆分成多个模块,以降低单个模块的复杂度。
  2. 大型社交网络系统

    • 将用户认证、消息推送、好友管理、内容管理等功能拆分成独立的服务。
    • 可以根据用户地理位置将用户数据水平拆分到不同的数据中心,以降低跨地理位置的网络延迟。
    • 可以将消息推送服务垂直拆分成多个模块,例如将即时消息推送和通知推送拆分成独立的服务。

通过适当的拆分,可以降低系统的复杂度,提高系统的灵活性和可扩展性,从而更好地应对系统的增长和变化。

  1. 针对性的扩展
  2. 高可扩展的设计思路  核心思想是拆分

三高:高性能,高可靠/用,高可扩展。是在高并发基础之上的。想一想,如果只是上百并发量实现三高。对比上百万并发量实现三高。自然是后者更难。所以哦我们是站在高并发的基础上去研究高性能,高可用,高可扩展技术的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小杰312

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

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

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

打赏作者

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

抵扣说明:

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

余额充值