使用HAProxy、PHP、Redis和MySQL支撑每周10亿请求
状态
平台
背景
为了满足他们扩展到下一个市场的需求,架构师必须使用可扩展理念进行设计。首先,我们审视了他们的基础设施:
前端网站通过REST API与服务交互,响应则基于JSON格式。为了简单起见,我们没有选择SOAP,一个开发者比较无爱的协议,因为谁都不愿意解析一堆的XML。
带来的好处:
- 独立子系统(服务)可以便捷的在不同团队中开发,开发者互不干涉,效率理所当然提升。
- 身份验证和会话不会通过它们来管理,因此它们造成的扩展问题不翼而飞。
- 业务逻辑被区分,不同的前端网站不会再存在功能冗余。
- 显著地提高了服务的可用性。
共生的缺点:
为系统管理员带来更大的工作量。鉴于服务都使用了独立的基础设施,这将给管理员带来更多需要关注的地方。
应用程序层
着眼请求工作流,第一层是应用程序。HAProxy负载均衡器、Varnish和Symfony2应用程序都在这一层。来自前端网站的请求首先会传递给HAProxy,随后负载均衡器将把他分给不同的节点。
应用程序节点配置
Symfony2应用程序
应用程序本身基于Symfony2建立,这是一个PHP全堆栈框架,提供了大量加速开发的组件。作为基于复杂框架的典型REST服务可能受到很多人质疑,这里为你细说:
- 对 PHP/Symfony 开发者友好。客户端IT团队由PHP开发者组成,添加新技术将意味必须招聘新的开发者,因为业务系统必须做长时间的维护。
- 清晰的项目结构。 PHP/Symfony虽然从来都不是必需品,但却是许多项目的默认选择。引入新的开发者将非常方便,因为对他们来说代码非常友好。
- 许多现成的组件。遵循DRY思想……没有人愿意花力气去做重复的工作,我们也不例外。我们使用了大量的Symfony2 Console Component,这个框架非常有利于做CLI命令,以及应用程序性能分析(debug工具栏)、记录器等。
应用程序分析与监控
我们使用Symfony2工具来监视应用程序,在收集指定方法执行时间上表现的非常不错,特别是那些与第三方网络服务交互的操作。这样一来,我们可以发现架构中潜在的弱点,找出应用程序中最耗时的部分。
- Debug,可能会发生的事情。比如,请求信息在调用前会传送给一个外部Web服务;事情发生后从API调用响应。
- Error,当错误发生时请求流并未被终止,比如第三方API的错误响应。
- Critical,应用程序崩溃的瞬间。
扩展性
扩展平台的应用程序层并不困难,HAProxy性能并不会在短时间耗尽,唯一需要考虑的就是如何冗余以避免单点故障。因此,当下需要做的只是添加下一个应用程序节点。
数据层
我们使用Redis和MySQL存储所有的数据,MySQL更多作为三级缓存层,而Redis则是系统的主要数据存储。
Redis
- 大部分我们执行的操作都具有 O(1)或O(N)复杂性, N是需要检索键的数量,这意味着keyspace大小并不会影响性能。
- 通常情况下会使用MGET命令行同时检索100个以上的键,这样可以尽可能的避免网络延时,而不是在循环中做多重GET操作。
“期满”键数量越接近0情况越危险,这个时候管理员就需要考虑适当的分片或者是增加内存。
我们如何进行监控?这里使用Icinga check,仪表盘会显示数字是否会达到临界点,我们还使用了Redis来可视化“丢失键”的比率。
在一年后,我们已经爱上了Redis,它从未让我们失望,这一年系统从未发生任何宕机情况。
MySQL
MySQL的高可用性
在纵向扩展失效后进行的必然是横向扩展,值得高兴的是,项目开始时我们就为数据准备了一个易于分片的结构:
在MySQL上,结构化的表格非常易于向另一台服务器上迁移——同样基于记录类型(表格)。当然,一旦基于记录类型的分片不再奏效,我们将转移至哈希。