这是一个大问题:)我们正在运行一个 LAMP 不大的网站,5 个具有 LVS 负载平衡的 Web 服务器,3 个具有复制和读写分离的 MySQL 服务器,我们使用 Memcached 进行缓存和一些全文搜索工具。到目前为止,它运行良好,因为我们目前没有大量流量。
但是当用户快速增长时,我们将不得不扩展我们的架构以满足需求。也许会引入分布式文件系统和数据库(以及并行计算?),以及一些集群和维护技术(如 Gearman 和 Pshell)。
网上有一些文章我可以浏览一下。但我确实需要一些实践经验来切实有效地为这个问题做准备。
有许多方法可以扩展 Web 应用程序和支持的基础设施。Cal Henderson 写了一本关于这个主题的好书,叫做“构建可扩展的网站”。这是基于他在 Flickr 上的经历。除非您成长缓慢,否则您将遇到许多其他人看到的相同类型的成长问题。与许多其他主题一样,扩展是一个旅程,而不是一个目的地。
第一步是让一切都可重复、可衡量和可管理。可重复我的意思是使用 FAI 或 kickstart 之类的工具来安装操作系统,并在安装基本操作系统后使用 puppet 或 cfengine 之类的工具来配置机器。可衡量的意思是使用仙人掌、蟋蟀或神经节之类的东西来监控你的集群现在的表现。不仅要衡量平均负载之类的东西,还要衡量呈现页面或服务请求所需的时间。刚开始时,这些似乎都不重要,但应该在您的系统因负载崩溃之前告诉您,并且可以使一次添加 10 或 100 台机器变得简单。将您的增长计划基于数据而不是猜测。
可管理意味着将工具放在适当的位置,以便您尽可能多地自动生成和测试配置。从你所拥有的开始并发展它。如果您将机器信息存储在数据库中,那就太好了。如果没有,您可能有一个可以导出的电子表格。如果您还没有,请将您的配置放入某种源代码控制中。从您的数据库中自动创建配置可以让您以更小的压力成长。在它们在您的服务器上上线之前对其进行测试可以使您免于因拼写错误或其他错误而无法启动服务。
水平方法假设您可以适当地重复事情。想想你的应用程序。哪些领域值得拆分?哪些领域可以由多台机器并行处理?延迟是否会影响您的应用程序。您遇到连接限制或其他瓶颈的可能性有多大?您是否要求您的 Web 服务器也处理邮件传递、数据库或其他杂务?
我曾在拥有数百台 Web 服务器的环境中工作过。对于不同类型的负载,事情应该得到不同的划分。如果您拥有大量很少更改的数据文件,则将它们与主动更改的“内容”分开可能会为提供静态和动态数据提供更多空间。不同的工具适用于不同的负载。Apache 和 Lighttpd 在某些方面效果很好,而 Nginx 在其他方面效果更好。
查看代理和缓存。在您的用户和应用程序之间以及在应用程序的各个部分之间。我读到您已经在使用 memcache,这很有帮助。根据您的应用程序流量,在您的负载均衡器和 Web 服务器之间放置一个像 perlbal 或 pound 这样的反向代理可能是有意义的。
在某些时候,您可能会发现 MySQL 主 <-> (N * 从) 复制没有跟上,您需要对数据库进行分区。对数据库进行分区可能涉及设置另一层数据管理。许多人使用另一个带有 memcache 的数据库来进行这种管理。在我工作的一个地方,我们使用 master <-> master 复制对来处理大多数数据,另一对使用 10 个读取从属设备作为指向数据的指针。
这只是对我在拥有数百台机器的站点中遇到的一些问题的非常简单的描述。从几台机器慢慢增长到几百台的事情是没有止境的。我敢肯定,增长到数千人也是如此。
最近出现了很多关于这个主题的优秀文献。从High Scalability开始,很多最好的东西都是从那里开始的。您可以查看Digg 的技术博客,了解我们如何做事,还可以联系 SAGE 等资源 - SAGE 列表中的人是一个很好的资源。
大多数 Web 应用程序用户群的高速增长要求开发人员在 DB 前使用 memcache。应计算数据并将其保存在缓存中。这将有助于减少根据用户请求向页面提供数据所需的时间。