我正在寻找有关如何以最佳方式(主要是硬件方面)设置高速负载平衡服务器集群的建议,该集群的预算(例如 2,000 - 3,000 英镑)用于在单个 IP 地址后面托管 Web 服务,由数据库服务器和通用文件系统支持。全部在 Linux 上。
对于 Web 服务器,我知道我想使用 Apache 设置 IPVS,但我不知道在硬件上花钱的最佳方式。我设想有一台机器(最好有备份)从互联网接收请求,并在 Apache 服务器阵列之间平衡这些请求。阵列中的每个服务器都共享对公共文件系统的访问权限。随着时间的推移,我会向阵列添加更多服务器以增加容量。
系统总是在负载平衡器处出现瓶颈。我需要什么样的机器才能支持非常高/不那么高的流量?哪个更重要——处理器/内存
对于 Apache 阵列中的机器,我需要什么 - 更多处理器、更快的处理器、更多 RAM 等 - 哪些是最重要的,如果我打算添加更多机器,这是否很重要
实现共享文件系统的最佳方式是什么,以便提供可扩展性(易于添加更多磁盘空间)和性能(因为它也是一个瓶颈)。在这里我需要软件和硬件方面的建议。
对每项不同任务的机器的成本/性能进行估算。
对于使用此设置可以为给定数量的机器提供何种流量,您有什么想法吗?
答案1
我最近不得不设计一些类似的东西。这是我的概念信封背面设计
负荷分配
我假设网络操作人员已经设置了冗余且高度可用的路由、防火墙和交换结构,以便将请求传递给负载均衡器。
(如果没有,我会选择使用 PF 或 IPtables 的状态 HA 设置,并使用 carp 或 keepalived 实现自动故障转移。)负载平衡器的规格将取决于 Web 应用程序负载分配方法和成本等指标。
根据预算,可以使用以下方式实现负载平衡 - 基于硬件的负载平衡器,通常价格昂贵 - 基于软件的代理,例如 HAProxy
负载均衡器必须具有高可用性,因此我会选择几个带有备用备份的活动负载(比如 2 个 HAProxy 实例,其中 2 个处于备用模式)。
我会让路由层将请求发送到负载均衡器。如果其中一个负载均衡器发生故障,则可以使用基于 keepalived 的解决方案无缝替换故障设备。
一旦负载均衡器接受请求,它们就会将其传递给缓存层。缓存层将处理:
- 静态内容请求。
- 具有 HTTP 标头表明尚未过期的内容。
- 压缩静态文本内容,例如 CSS 和 JS 文件。
缓存层可以使用反向代理中的 SQUID 或 NGINX 等解决方案来实现。通过这样做,我们将通过仅向 Apache/PHP 服务器发送动态请求来减少应用服务器的负载。
为了将成本降至最低,我会将 HAProxy 和 NGINX 放在同一个盒子里。
一种简单且可扩展的方法是通过网站的子域名提供 CSS、JS 和静态图像(比如http://cdn.myservice.com/static)。使用这样的设置,我们将来可以全局安装缓存实例,并让 DNS 将静态请求发送到最近的 CDN 实例。不过,最初 CDN 工作可以由这些 NGINX 实例处理,以降低成本。
处理层
处理层由针对 Apache/PHP 优化的服务器池组成。它们将从 NFS 或分布式文件系统共享加载配置文件,并通过处理来自另一个远程共享(NFS 或 DFS)的 PHP 脚本来满足它们的请求。使用这些远程共享可减轻维护和同步服务器配置的配置开销。
Apache 和 PHP 可以进一步优化,例如:
- 删除 PHP 和 Apache 中不需要的模块。
- 使用 PHP Opcode 缓存(例如 APC)来减少 PHP 编译开销。
- 优化 Apache 的设置,例如 MPM 和 keep-alive 设置。
还可以配置 memcache 服务器池来存储常见且昂贵的数据库查询的结果。如果从服务器不在 memcache 层中,则读取查询通常会发送到从服务器,然后缓存其结果。写入将发送到主服务器,并且可能涉及使 memcache 层中的数据无效。PHP 会话数据也可以通过 memcached 共享,这样如果任何单个 Apache/PHP 服务器发生故障,其余服务器可以从 memcache 中获取会话数据。
扩展处理池中的负载需要添加更多服务器并更新反向代理。服务器池可以划分为多个逻辑组。然后,逻辑组将使用通过 NFS 共享的通用配置,并且可以作为块进行升级。
然后可以监控升级,如果检测到问题,可以实施修复或回滚。逻辑组可以分布在不共享任何内容(电源、网络交换机等)的机架上,并由不同的成员组成(例如戴尔的服务器型号 A、B 和 C),以便块迁移测试是全面的。
数据库
对于数据库,我将在主服务器/多从服务器设置中运行 MySQL 服务器。主服务器将针对写入进行优化,并启用二进制日志记录以进行复制。这通常意味着我们将使用 MySQL 的常规优化,例如:
- 使用 RAID 10 和高 RPM 驱动器。
- 在 mysql 数据目录上禁用 atime/mtime。
- 调整 CPU 和 RAM 的 innodb 设置。
- 对表进行适当的索引和分区。
- 监控慢查询日志并使用 explain 来分析慢查询。
- 监控数据库性能。
从服务器将配置为读取,并需要使用 maatkit 的 mk-heartbeat 等实用程序不断监控复制滞后。滞后的服务器可能会从 PHP 读取集中删除,直到它赶上来。
如果发生主服务器故障:
- 从属设备将被提升为主设备。
- 将对 DNS 进行更改以指向新的主服务器。
- 网络中的解析器会重新加载以反映 DNS 更改。
- 其他从服务器自动从新的主服务器中选择(我们可以使主服务器和从服务器上的 binlog 位置和文件相同,以简化此迁移)
- 由于 DNS 解析器将返回新的主服务器,因此 Apache/PHP 服务器将自动写入新的主服务器。通过使用 DNS 循环和从属集的 A/AAAAA 记录,读取也将发送到正确的服务器。
DNS 的替代方法可能是将良好从属服务器列表存储在缓存中(例如 memcache),并对其进行适当更新。
最重要的是,我会有一两个工作站用于网络监控和报告汇总。我会使用 Munin/Zenoss 进行趋势分析,使用 syslog 服务器汇总服务器日志,使用自定义脚本进行日志分析和警报。Nagios 也可用于提供基础设施和警报的全局概览。
扩展
升级基础设施以承载更多负载将通过以下方式处理:
- 增加负载平衡器反向代理服务器来处理更多静态内容。
- 静态内容的地理分布。根据成本,CDN 工作可能会外包给 Amazon 的 cloudfront 等服务。
- 增加 Apache/PHP 服务器的数量以处理更多负载。
- 增加 MySQL 从属服务器的数量。
- 对主服务器和 MySQL 联合进行分片,以呈现分布在数据库服务器集群上的表的统一视图