F5社区-F5技术交流中心

博文精选 | 亿级流量架构之服务器扩容思路及问题分析

2022-04-22 15:45:59

F5小安

PHPWord

文章速览:

 

行业:互联网

 

关键字:流量、架构、服务器、扩容、组件、分布式

 

摘要:说人话就是, 无论如何优化性能,能达到的最大值是一定的,对于一个用户量大的应用,可以对服务器进行各种优化,诸如限流、资源隔离,但是上限还是在那里,这时候就应该改变我们的硬件,例如使用更强的 CPU、更大的内存。

 

阅读时长:8分钟

 

 

以下文章来源于InfoQ!作者:互联网架构师小马

 

 

为什么要扩容

说人话就是, 无论如何优化性能,能达到的最大值是一定的,对于一个用户量大的应用,可以对服务器进行各种优化,诸如限流、资源隔离,但是上限还是在那里,这时候就应该改变我们的硬件,例如使用更强的 CPU、更大的内存,在前文中举了一个学生食堂打饭的例子,如果学生多了,可以通过令牌桶算法优先给高三学生令牌打饭,但是如果高三的学生还是很多呢?那就只有增加窗口或者食堂的数量,也就是硬件上的扩容。


扩容策略

扩容策略可以分为两种, 一种是对单机整体扩容,也就是机器内部包含 CPU、内存、存储设备等,另一种是扩容对应的组件,例如扩内存、扩磁盘、扩 CPU。


整机硬件

整机扩容的好处是,有很多专业的服务器硬件供应商,例如 IBM、浪潮、DELL、HP 等,专业的硬件供应商,他们组装以及搭配方面可能经验更加丰富,另外有些公司会对组件进行一些优化,从而服务器更加稳定,可以类比为买电脑,有的人可能选择买淘宝卖家已经组装好的台式,有的人可能自己买各种硬件自己回家组装,对于一般人而言,选择前者是较为靠谱的选择,因为你即使懂硬件的一些参数,也难保自己搭配的机器是否能发挥各个部件最大性能。


组件

对于一些技术能力强悍的公司,更多的是自己买各种组件组装,这样成本更低,因为节省了组装等费用,并且可以根据业务个性化定制,例如有的公司是计算密集型的,那么主要是更换更强的 CPU,有的 IO 密集型,那么扩容的应该是内存等,有的公司需要存储大量的数据,那么可能扩容的是硬盘等存储设备。


组件包含:


cpu


Intel、Amd ,参考频率、线程数等


网卡


百兆->千兆 -> 万兆


内存


ECC 校验


磁盘


SCSI HDD(机械)、HHD(混合)、SATA SSD、PCI-e SSD、 MVMe SSD


AKF 拆分原则

在 Redis 集群拆分原则之 AKF 中,详细介绍了 AKF 拆分原则的详情,这儿简单回顾一下:


对于一个应用,如果单机不足以支撑服务请求,那么可以建立诸如主主、主从等模式的集群:



这个叫 AKF 原则 X 轴扩展,目的是将请求分流在多台机器上,但是多台机器中间要解决数据同步性的问题,越多的机器数据不同步的可能性越大,这也就意味着没法无限整体复制扩容。所以可以整理搜集服务器内热点的业务请求,将业务分离出来,只对热点业务进行扩容,这就是 AKF 原则的 Y 轴拆分:



对业务拆分之后,某个业务还可能太热点,也就是 Y 轴拆分后水平复制还是不足以支撑数据请求,那么可以将业务的数据进行拆分, 具体来说就是,某个业务的数据,可以放在多个地方,例如在湖北、北京、上海部署机房,各地的人们需要请求数据时,由离得近的服务器提供服务。


拆分扩容后存在的问题

随着业务的增长,系统变得越来越庞大, 根据系统功能拆分成独立而又互通的项目, 比如交易系统、财务系统、生产流程系统、物流系统、网站系统等等,但是分布式结构会存在很多问题。对于这些问题每一个都值得深入探讨,这儿简单的提一下,后面再开篇幅。


数据共享问题

所有的服务之间数据如何共享同步,这是一个需要考虑的问题,微服务架构中,数据不可能只有一份,没法避免机器损坏等原因造成的数据丢失,多份数据之间如何同步?目前可供参考的解决思路是建立数据中心、搭建数据库集群。

接口调用问题

不同的服务器之间进行调用遵循远程调用协议 RPCJAVA RMI:Java 远程方法调用,即 Java RMI(Java Remote Method Invocation)是 Java 编程语言里,一种用于实现远程过程调用的应用程序编程接口。 它使客户机上运行的程序可以调用远程服务器上的对象。dubbo:提供了面向接口代理的高性能 RPC 调用

持久化数据雪崩问题

数据库分库分表,参考:MySQL 调优之分区表。资源隔离,参考:亿级流量架构之资源隔离思路与方法。缓存设定数据持久化策略:Redis 持久化之 RDB 和 AOF。

高并发问题缓存:诸如缓存击穿、穿透、雪崩等,参考 Redis 击穿、穿透、雪崩产生原因以及解决思路。数据闭环:为了便于理解,举个例子,对于淘宝而言,有网页版、IOS 版、安卓版、还有什么一淘等等,虽然客户端不一样,但是展示的商品信息是相同的,也就是一件商品,无论是哪个端用的数据是一样的,需要一套方案来解决并发下根据相同数据在不同端进行不同展示的问题,这就叫数据闭环。

数据一致性问题这是一个难点,大意就是多个服务器之间数据如何保证一致性,同样的商品在不同客户端服务端端价格应该是一样的, 通常使用分布式锁。


数据库扩容:集群

先简单说一下分布式与集群的区别,这两个词儿经常一起出现,但是意义却有所不同,分布式会缩短单个任务的执行时间来提升工作效率,而集群强调的是提高单位时间内执行操作数的增加来提高效率。更简单的来说,分布式是将步骤分到每台电脑上,不考虑依赖关系,集群方案是指几个任务同时在处理。


单一数据库存储难以满足业务需求时,采取集群的方式,将数据存储在不同的服务器,这可以是主主或者主从,主从中主负责写,从负责读,将与数据库有关的压力进行分解到多台机器上。


分布式 ID

在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。很容易想到的是利用自增,但是自增有很多问题,例如 ID 有太强的规律,可能会被恶意查询搜集,面对数据日渐增长,对数据分库分表后需要有一个唯一 ID 来标识一条数据或消息,这样数据库的自增 ID 显然不能满足需求;特别一点的如商品、订单、用户也都需要有唯一 ID 做标识。此时一个能够生成全局唯一 ID 的系统是非常必要的。概括下来,那业务系统对 ID 号的要求有哪些呢?


分布式 ID 要求

面对分布式 ID,需要满足下面的要求:


  1. 全局唯一性:不能出现重复的 ID 号,既然是唯一标识,这是最基本的要求。

  2. 趋势递增:在 MySQL InnoDB 引擎中使用的是聚集索引,由于多数 RDBMS 使用 B-tree 的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能。

  3. 单调递增:保证下一个 ID 一定大于上一个 ID,例如事务版本号、IM 增量消息、排序等特殊需求。

  4. 信息安全:如果 ID 是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定 URL 即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要 ID 无规则、不规则。


上述 123 对应三类不同的场景,但是 3 和 4 的需求是互斥的,也就是无法使用同一个方案满足。除了对 ID 号码自身的要求,业务还对 ID 号生成系统的可用性要求极高,想象一下,如果 ID 生成系统瘫痪,整个与数据有关的动作都无法执行,会带来一场灾难。由此总结下一个 ID 生成系统最少应该做到如下几点:


  1. 平均延迟和 TP999 延迟都要尽可能低;

  2. 可用性 5 个 9(这是美团的要求,有些企业例如阿里要求 6 个 9);

  3. 高 QPS。


分布式 ID 生成策略

目前业界常用的 ID 生成策略有很多,例如 UUID、雪花生成算法、Redis、Zookeeper 等,这儿只简单讲讲 UUID 以及 Snowflake,后面要开篇详谈。


UUID 生成算法

UUID(Universally Unique Identifier)的标准型式包含 32 个 16 进制数字,以连字号分为五段,形式为 8-4-4-4-12 的 36 个字符,示例:550e8400-e29b-41d4-a716-446655440000,到目前为止业界一共有 5 种方式生成 UUID,详情见 IETF 发布的 UUID 规范 A Universally Unique IDentifier (UUID) URN Namespace。


优点:


  • 性能非常高:本地生成,没有网络消耗。


缺点:


  • 不易于存储:UUID 太长,16 字节 128 位,通常以 36 长度的字符串表示,很多场景不适用。

  • 信息不安全:基于 MAC 地址生成 UUID 的算法可能会造成 MAC 地址泄露,这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。

  • ID 作为主键时在特定的环境会存在一些问题,比如做 DB 主键的场景下,UUID 就非常不适用:① MySQL 官方有明确的建议主键要尽量越短越好[4],36 个字符长度的 UUID 不符合要求。All indexes other than the clustered index are known as secondary indexes. In InnoDB, each record in a secondary index contains the primary key columns for the row, as well as the columns specified for the secondary index. InnoDB uses this primary key value to search for the row in the clustered index.If the primary key is long, the secondary indexes use more space, so it is advantageous to have a short primary key.


② 对 MySQL 索引不利:如果作为数据库主键,在 InnoDB 引擎下,UUID 的无序性可能会引起数据位置频繁变 动,严重影响性能。


雪花生成算法

这种方案大致来说是一种以划分命名空间(UUID 也算,由于比较常见,所以单独分析)来生成 ID 的一种算法,这种方案把 64-bit 分别划分成多段,分开来标示机器、时间等,比如在 snowflake 中的 64-bit 分别表示如下图(图片来自网络)所示:







41-bit 的时间可以表示(1L<<41)/(1000L360024*365)=69 年的时间,10-bit 机器可以分别表示 1024 台机器。如果我们对 IDC 划分有需求,还可以将 10-bit 分 5-bit 给 IDC,分 5-bit 给工作机器。这样就可以表示 32 个 IDC,每个 IDC 下可以有 32 台机器,可以根据自身需求定义。12 个自增序列号可以表示 212212 个 ID,理论上 snowflake 方案的 QPS 约为 409.6w/s,这种分配方式可以保证在任何一个 IDC 的任何一台机器在任意毫秒内生成的 ID 都是不同的。


这种方式的优缺点是:


优点:


  • 毫秒数在高位,自增序列在低位,整个 ID 都是趋势递增的。

  • 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成 ID 的性能也是非常高的。

  • 可以根据自身业务特性分配 bit 位,非常灵活。


缺点:


  • 强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。


弹性扩容

说人话,就是让集群根据计划在某一段时间自动对资源进行扩容,并在设置的计划还原时间时释放资源。这样能解决规律性的资源峰谷需求,达到充分合理利用资源的目的。

但是弹性扩容有一些问题:


第一,虚拟机弹性能力较弱。使用虚拟机部署业务,在弹性扩容时,需要经过申请虚拟机、创建和部署虚拟机、配置业务环境、启动业务实例这几个步骤。前面的几个步骤属于私有云平台,后面的步骤属于业务工程师。一次扩容需要多部门配合完成,扩容时间以小时计,过程难以实现自动化。如果可以实现自动化“一键快速扩容”,将极大地提高业务弹性效率,释放更多的人力,同时也消除了人工操作导致事故的隐患。


第二,IT 成本高。由于虚拟机弹性能力较弱,业务部门为了应对流量高峰和突发流量,普遍采用预留大量机器和服务实例的做法。即先部署好大量的虚拟机或物理机,按照业务高峰时所需资源做预留,一般是非高峰时段资源需求的两倍。资源预留的办法带来非常高的 IT 成本,在非高峰时段,这些机器资源处于空闲状态,也是巨大的浪费。


 

 

以上是针对服务器扩容的分享,希望对大家有帮助!

 

 

 

阅读原文

 

声明:本文章版权归原作者及原出处所有 。凡本社区注明“来源:XXX或转自:XXX”的作品均转载自其它媒体,转载目的在于传递分享更多知识,内容为作者个人观点,仅供参考,并不代表本社区赞同其观点和对其真实性负责。本社区转载的文章,我们已经尽可能的对作者和来源进行了注明,若因故疏忽,造成漏注,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本社区拥有对此声明的最终解释权。

发布评论 加入社群

发布评论

相关文章

博文精选 | 面向业务的高可用架构设计

F5小安

2022-05-31 14:25:53 324

博文精选 | 8 张图带你了解大型应用架构演进历程

F5小安

2021-10-29 10:09:11 517

博文精选 | 详解 | 大型分布式电商系统架构

F5小安

2021-10-12 11:00:11 831

Login

手机号
验证码
© 2019 F5 Networks, Inc. 版权所有。京ICP备16013763号-1