高并发系统—高扩展

文章出自:阿里巴巴十亿级并发系统设计(2021版)

链接:https://pan.baidu.com/s/1lbqQhDWjdZe1CBU-6U4jhA 提取码:8888 

从架构设计上来说,高可扩展性是一个设计的指标,它表示可以通过增加机器的方式来线性提高系统的处理能力,从而承担更高的流量和并发。

你可能会问:“在架构设计之初,为什么不预先考虑好使用多少台机器,支持现有的并发 呢?”这个问题我在“03 | 系统设计目标(一):如何提升系统性能?”一课中提到过, 答案是峰值的流量不可控。一般来说,基于成本考虑,在业务平稳期,我们会预留 30%~50% 的冗余以应对运营活动或者推广可能带来的峰值流量,但是当有一个突发事件发生时,流量可能瞬间提升到 2~3 倍甚至更高,我们还是以微博为例。

鹿晗和关晓彤互圈公布恋情,大家会到两个人的微博下面,或围观,或互动,微博的流量短时间内增长迅速,微博信息流也短暂出现无法刷出新的消息的情况。

那我们要如何应对突发的流量呢?架构的改造已经来不及了,最快的方式就是堆机器。不过 我们需要保证,扩容了三倍的机器之后,相应的我们的系统也能支撑三倍的流量。有的人可能会产生疑问:“这不是显而易见的吗?很简单啊。”真的是这样吗?我们来看看做这件 事儿难在哪儿。

为什么提升扩展性会很复杂

在上一讲中,我提到可以在单机系统中通过增加处理核心的方式,来增加系统的并行处理能力,但这个方式并不总生效。因为当并行的任务数较多时,系统会因为争抢资源而达到性能 上的拐点,系统处理能力不升反降。

而对于由多台机器组成的集群系统来说也是如此。集群系统中,不同的系统分层上可能存在一些“瓶颈点”,这些瓶颈点制约着系统的横线扩展能力。这句话比较抽象,我举个例子你就明白了。

比方说,你系统的流量是每秒 1000 次请求,对数据库的请求量也是每秒 1000 次。如果流量增加 10 倍,虽然系统可以通过扩容正常服务,数据库却成了瓶颈。再比方说,单机网络带宽是 50Mbps,那么如果扩容到 30 台机器,前端负载均衡的带宽就超过了千兆带宽的限制,也会成为瓶颈点。那么,我们的系统中存在哪些服务会成为制约系统扩展的重要因素呢?

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

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

针对这些复杂的扩展性问题,我提炼了一些系统设计思路,供你了解。

高可扩展性的设计思路

拆分是提升系统扩展性最重要的一个思路,它会把庞杂的系统拆分成独立的,有单一职责的模块。相对于大系统来说,考虑一个一个小模块的扩展性当然会简单一些。将复杂的问题简单化,这就是我们的思路。

但对于不同类型的模块,我们在拆分上遵循的原则是不一样的。我给你举一个简单的例子, 假如你要设计一个社区,那么社区会有几个模块呢?可能有 5 个模块。

  1. 用户:负责维护社区用户信息,注册,登陆等;
  2. 关系:用户之间关注、好友、拉黑等关系的维护;
  3. 内容:社区发的内容,就像朋友圈或者微博的内容;
  4. 评论、赞:用户可能会有的两种常规互动操作;
  5. 搜索:用户的搜索,内容的搜索。

而部署方式遵照最简单的三层部署架构,负载均衡负责请求的分发,应用服务器负责业务逻 辑的处理,数据库负责数据的存储落地。这时,所有模块的业务代码都混合在一起了,数据也都存储在一个库里。

1. 存储层的扩展性

无论是存储的数据量,还是并发访问量,不同的业务模块之间的量级相差很大,比如说成熟社区中,关系的数据量是远远大于用户数据量的,但是用户数据的访问量却远比关系数据要大。所以假如存储目前的瓶颈点是容量,那么我们只需要针对关系模块的数据做拆分就好 了,而不需要拆分用户模块的数据。所以存储拆分首先考虑的维度是业务维度。

拆分之后,这个简单的社区系统就有了用户库、内容库、评论库、点赞库和关系库。这么做还能隔离故障,某一个库“挂了”不会影响到其它的数据库。

章节小插曲:本篇只总结了"高并发系统设计"的一部分内容,还有更多资源正在整理中包含 JVM、Tomcat、MySQL、Spring、Mybatis、Redis、MongoDB、Mycat、Zookeeper Nginx、RabbitMq、RocketMq、Kafka、Dubbo、Docker 分布式(架构设计,事务场景策略,场景解决方案,任务调度场景实现) 高并发场景应对方案、性能调优实战、海量数据场景实现、消息服务总线MQ等。 不定期更新中获取可添加助理QQ:【2986706524】 备注:【Java】审核通过后私信:【资料】 即可获取。

按照业务拆分,在一定程度上提升了系统的扩展性,但系统运行时间长了之后,单一的业务数据库在容量和并发请求量上仍然会超过单机的限制。这时,我们就需要针对数据库做第二次拆分。

这次拆分是按照数据特征做水平的拆分,比如说我们可以给用户库增加两个节点,然后按照某些算法将用户的数据拆分到这三个库里面,具体的算法我会在后面讲述数据库分库分表时和你细说。 水平拆分之后,我们就可以让数据库突破单机的限制了。但这里要注意,我们不能随意地增加节点,因为一旦增加节点就需要手动地迁移数据,成本还是很高的。所以基于长远的考虑,我们最好一次性增加足够的节点以避免频繁地扩容。

当数据库按照业务和数据维度拆分之后,我们尽量不要使用事务。因为当一个事务中同时更 新不同的数据库时,需要使用二阶段提交,来协调所有数据库要么全部更新成功,要么全部 更新失败。这个协调的成本会随着资源的扩展不断升高,最终达到无法承受的程度。

说完了存储层的扩展性,我们来看看业务层是如何做到易于扩展的。

2. 业务层的扩展性

我们一般会从三个维度考虑业务层的拆分方案,它们分别是:业务纬度,重要性纬度和请求来源纬度

首先,我们需要把相同业务的服务拆分成单独的业务池,比方说上面的社区系统中,我们可 以按照业务的维度拆分成用户池、内容池、关系池、评论池、点赞池和搜索池。

每个业务依赖独自的数据库资源,不会依赖其它业务的数据库资源。这样当某一个业务的接口成为瓶颈时,我们只需要扩展业务的池子,以及确认上下游的依赖方就可以了,这样就大 大减少了扩容的复杂度。

除此之外,我们还可以根据业务接口的重要程度,把业务分为核心池和非核心池。打个比 方,就关系池而言,关注、取消关注接口相对重要一些,可以放在核心池里面;拉黑和取消 拉黑的操作就相对不那么重要,可以放在非核心池里面。这样,我们可以优先保证核心池的 性能,当整体流量上升时优先扩容核心池,降级部分非核心池的接口,从而保证整体系统的 稳定性。

最后,你还可以根据接入客户端类型的不同做业务池的拆分。比如说,服务于客户端接口的

业务可以定义为外网池,服务于小程序或者 HTML5 页面的业务可以定义为 H5 池,服务于 内部其它部门的业务可以定义为内网池,等等。

课程小结

本节课我带你了解了提升系统扩展性的复杂度以及系统拆分的思路。拆分看起来比较简单, 可是什么时候做拆分,如何做拆分还是有很多细节考虑的。

未做拆分的系统虽然可扩展性不强,但是却足够简单,无论是系统开发还是运行维护都不需要投入很大的精力。拆分之后,需求开发需要横跨多个系统多个小团队,排查问题也需要涉 及多个系统,运行维护上,可能每个子系统都需要有专人来负责,对于团队是一个比较大的 考验。这个考验是我们必须要经历的一个大坎,需要我们做好准备。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 要使用Python构建高并发扩展的学习系统,您可以考虑使用以下技术和框架: 1. 异步编程:使用asyncio库进行异步编程,以便同时处理多个并发请求。 2. 分布式任务队列:使用Celery或RabbitMQ等任务队列,将任务分发到多个工作节点,以便实现水平扩展。 3. 缓存系统:使用Redis或Memcached等缓存系统,以便缓存频繁请求的数据,减少对数据库的访问次数。 4. Web框架:使用Django或Flask等Web框架,以便快速搭建Web服务。 5. 数据库:使用MySQL或PostgreSQL等关系型数据库,以便存储和管理系统的数据。 6. 消息中间件:使用Kafka或ActiveMQ等消息中间件,以便异步处理系统中的事件和消息。 通过上述技术和框架的结合使用,您可以构建一个高并发扩展的学习系统。 ### 回答2: 要实现高并发扩展的学习系统,可以按照以下方法利用Python: 1. 使用异步编程:Python提供了诸如asyncio和aiohttp等库,可用于实现异步编程。通过使用异步I/O和协程,可以提系统的并发处理能力。 2. 使用分布式架构:将系统拆分成多个独立的服务模块,并将其部署在不同的服务器上。可以使用Python的一些开源分布式框架,如Celery或Pyro等来管理任务分发和节点通信,以实现系统的横向扩展能力。 3. 使用缓存和消息队列:将频繁读取的数据进行缓存,例如使用Redis作为缓存数据库。另外,可以使用消息队列(如RabbitMQ或Kafka)进行解耦和异步处理,以避免系统阻塞。 4. 使用负载均衡:通过将流量分发到不同的服务器上,可以实现请求负载的均衡,提系统的并发能力。可以使用Python实现的一些负载均衡器,如HAProxy或Nginx。 5. 使用性能的数据库:选择适合并发场景的性能数据库,如MongoDB或Elasticsearch。这些数据库具有良好的横向扩展性,可以在处理大量数据时提供更好的性能。 6. 使用监控和日志工具:为了追踪系统运行情况并进行性能优化,可以使用Python提供的监控和日志工具,如Prometheus和ELK(Elasticsearch + Logstash + Kibana)。这些工具可以帮助您定位系统的瓶颈和问题,并优化系统性能。 总体而言,使用Python编程语言可以轻松地实现高并发扩展的学习系统。通过合理选择和应用相关的库和工具,可以提系统的并发处理能力,支持大量用户的同时访问,并实现系统的横向扩展。 ### 回答3: 要实现一个高并发扩展的学习系统,可以使用Python编程语言,并采用以下几个方法: 1. 使用异步编程: Python提供了多个异步框架(如asyncio和Tornado),可以通过使用异步编程技术来处理并发请求。异步编程可以提系统的吞吐量,同时避免阻塞线程的情况。 2. 使用分布式架构: 使用Python的分布式系统框架(例如Celery或Pyro),可以将任务分发到多个节点或服务器上进行处理。这样能够提系统扩展性,分担服务器的负载,以应对大量并发请求。 3. 数据库优化: 对于学习系统来说,数据库是一个重要的组成部分。使用性能的数据库技术,如NoSQL(如MongoDB)或数据缓存(如Redis),可以加快数据库的读写速度,提系统的并发处理能力。 4. 使用缓存: 在学习系统中,有些数据是可以被缓存的,如用户信息、用户学习的课程等。使用缓存技术,如Memcached或Redis,可以将经常访问的数据存储在内存中,减少对数据库的访问,提系统的响应速度和并发能力。 5. 水平扩展: 当系统的负载逐渐增加时,可以考虑将系统进行水平扩展。使用负载均衡器,将请求分发给多个服务器处理,可以提系统的并发处理能力,并保持系统的可用性。 6. 异常处理和错误日志: 在高并发系统中,出现异常和错误是不可避免的。使用适当的异常处理机制,并记录详细的错误日志,有助于排查问题和改进系统性能。 总之,使用Python编程语言可以通过异步编程、分布式架构、数据库优化、缓存、水平扩展等技术手段来实现高并发扩展的学习系统。这些方法可以提系统的并发处理能力、响应速度和吞吐量,以满足大量用户同时访问的需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值