热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

从小流量到高并发:开发者眼中的LNMP架构

本篇从单台机器架构开始,然后会遇到了哪些瓶颈,哪些坑,如何解决等,是一个典型的LNMP架构网站的架构演变。希望对大家有价值。

本篇从单台机器架构开始,然后会遇到了哪些瓶颈,哪些坑,如何解决等,是一个典型的LNMP架构网站的架构演变。希望对大家有价值。

  有一天,我突发奇想创建了一个站点,基于 LNMP 架构,起初只有我自己访问,后来因为我点儿正,访问量越来越大,所以最终导致下面说的架构演变。

  单台机器

  单台机器因为只是一个小网站,访问量一天也没有多少UV(100以内),所以用一台1核1G内存的机器就够了。机器上安装的是 CentOS 系统,然后搭建了 nginx+php-fpm+mysql 的环境。

  两台机器

  

  访问量越来越大,日UV突破5000,单台机器不够了,本可以增加机器配置编程4核8G,但是考虑到还要换机器,所以直接添置一台数据库服务器单独跑 MySQL服务。

  原来的服务器只需要跑 Nginx+PHP-FPM,新加服务器跑 MySQL 服务。 在这里,往往会遇到一个问题,就是如何在多台机器上编译安装 LNMP 环境,在单台机器上编译都没有问题,PHP 放在最后,因为它依赖 MySQL,但我们这里需要把 MySQL 放到另一台机器,所以编译肯定会报错。解决这个问题,其实很简单,即使 Web上不需要 MySQL,我们也要安装一下,因为编译 PHP 的时候依赖它。

  增加memcached

  

  访问量持续增加,UV上万了,DB 服务器和 WEB 服务器压力越来越大,这时候我们需要加一个缓存来缓解 DB 服务器的压力。同样是两台机器,只不过 Web机器配置需要升级了,原来的1核1G内存不够用了,不仅要加 CPU 还要加内存,因为在 Web 上我们需要运行 memcached 服务,同时 PHP 也需要安装memcache 扩展。

  增加Web服务器,MySQL主从分布

  访问量又扩大了,UV到了5W,数据库服务器因为一开始配置就挺高,所以没有压力,但是 Web 服务器负载有点高了,在高峰期可以感觉到网站访问变慢。所以,这时候不得不考虑要加一台 Web 服务器。另外,数据库是单点,如果磁盘损坏,可能会带来意想不到的后果,所以我们有必要加一台从 DB 服务器,作为数据备份用。

  

  在这里,两台 Web 服务器并没有做负载均衡。主要是为了节省资源,暂时先不去购买服务器做负载均衡。

  我们使用 DNS 轮询的方法来把用户的请求分发到两台机器上,但这种该架构有个问题,一旦一台 Web 机器宕机,将会有一半的用户访问不到业务。

  还有一个问题,我们也需要考虑到,如何保证 Web 服务器上的数据一致,比如用户可能会上传图片到 Web 服务器上,假如他上传到了 Web1 上,那 WEB2 是不存在这个图片的。所以我们需要做一个共享存储让 Web1 和 Web2 同时可以访问,所以在这里我把 WEB1 的一个目录使用 NFS 共享出来,让 Web2 去挂载。

  还有一个问题就是memcached服务如何分配,在这里,我是把 memcaced 服务分别安装到两台 Web 上的,自己用自己的 memcached 服务。

  MySQL读写分离

  访问量持续上升,UV已到了数十万。网站在高峰期总是会卡顿那么一段时间。经排查,发现在 MySQL 服务器上有很多慢查询,经过各种调优依然没有太明显效果,最后决定做读写分离。

  做读写分离有两种方案,第一可以借助程序来实现,把所有的写操作指向到主 MySQL ,所有的读操作指向到从 MySQL。对于这种方案,机器数量和环境不用做任何调整,唯一要做的是程序代码要改一下。第二可以借助 mysql-proxy 来实现,不用修改代码,节省开发成本,但需要增加一个角色。架构是这样的,如下图:

  

  负载均衡

  两台 Web 服务器因为有一台配置比较老,因此在高峰期时,终究是没有能扛住而挂掉。结果影响了一半的用户访问不到网站了,这就是所谓的单点故障。经过此次事故,我又开始修改架构,尽量避免单点故障,在 Web 前端设置了负载均衡设备,并且做了高可用。

  

  在这里我拿 Nginx 做了负载均衡器,并没有使用 LVS和HAProxy,我觉得 Nginx 更容易操作,更好控制。

  为了节省成本,我并没有单独把 mysql-proxy 摘出来作为独立服务器,因为那样的话,也得为它考虑单点问题。在这个架构中,其实还有一个缺陷,就是 NFS 服务端也是有风险的,更加保险的做法是单独搞一台服务器做NFS服务。

  继续扩展

  UV上升到100万,两台 Web 服务器明显不够用了,而瓶颈并不在 MySQL 上。所以,只增加 Web,同时把 NFS 服务器单独摘出来,并做一个备用 NFS 服务器。

  

  引入NoSQL

  UV近1000万,三台 Web 服务器也早已不够,增加到5台。而 MySQL 服务器压力逐渐变大,针对 MySQL 的慢查询,发现压力主要体现在个别 SQL 语句上,该优化的已经优化到极致,对于这几个查询,其实是可以使用 NoSQL 的。

  于是,我找懂PHP开发的朋友修改了程序,把一些访问量大的数据存储到Redis,从而减少了对 MySQL 服务器的压力。 而 Redis 为了防止单点也做了主从。

  

  MySQL架构演变

  假设一个网站(Discuz)从最开始访问量很小做到日PV千万,我们来推测一下它的MySQL服务器架构演变过程。

  第一阶段

  网站访问量日PV量级在1W以下。单台机器跑Web和DB,不需要做架构层调优(比如,不需要增加memcached缓存)。此时,数据往往都是每日冷备份的,但有时候如果考虑数据安全性,会搭建一个MySQL主从。

  第二阶段

  网站访问量日PV达到几万。此时单台机器已经有点负载,需要我们把Web和DB分开,需要搭建memcached服务作为缓存。也就是说,在这个阶段,我们还可以使用单台机器跑mysql去承担整个网站的数据存储和查询。如果做 MySQL 主从,目的也是为了数据安全性。

  第三阶段

  网站访问量日PV达到几十万。单台机器虽然也可以支撑,但是需要的机器配置要比之前的机器好很多。

  如果经费允许,可以购买配置很高的机器来跑mysql服务,但是并不是说,配置翻倍,性能也翻倍,到了一定阶段配置增加已经不能带来性能的增加。

  所以,此阶段,我们会想到做MySQL服务的集群,也就是说我们可以拿多台机器跑MySQL。但是,MySQL集群和Web集群是不一样的,我们需要考虑数据的一致性,所以不能简单套用做Web集群的方式(lvs,nginx代理)。

  可以做的架构是,MySQL主从,一主多从。为了保证架构的健壮和数据完整,主只能是一个,从可以是多个。

  还有一个问题,我们需要想到,就是在前端Web层,我们的程序里面指定了MySQL机器的ip,那么当机器有多台时,程序里面如何去配置?Discuz其实有一个功能,支持MySQL读写分离。即我们可以拿多台机器跑MySQL,其中一台写,其他多台是读,我们只需要把读和写的 IP 分别配置到程序中,程序自动会去区分机器。当然,如果不使用 discuz 自带的配置,我们还可以引用一个软件叫做 mysql-proxy, 使用他来实现读写分离。它支持一主多从的模式。

  第四阶段

  网站访问量日PV到几百万。之前的一主多从模式已经遇到瓶颈,因为当网站访问量变大,读数据库的量也会越来越大,我们需要多加一些从进来,但是从的数量增加到数十台时,由于主需要把bin-log全部分发到所有从上,那么这个过程本身就是一件很繁琐的事情,再加上频繁读取,势必会造成从上同步过来的数据有很大延迟。

  所以,我们可以做一个优化,把MySQL原来的一主多从变为一主一从,然后从作为其他从的主,而前面的主只负责网站业务的写入,而后面的从不负责网站任何业务,只负责给其他从同步bin-log。这样还可以继续多叠加几个从库。

  第五阶段

  网站访问量日PV到1千万的时候,我们发现,网站的写入量非常大,我们之前架构中只有一个主,这里的主已经成为瓶颈了。所以,需要再近一步做出调整。比如,我们可以把业务分模块,把用户相关的单独分离出来,把权限、积分等也可以分离出来单独跑一个库,然后再做主从,也就是所谓的分库。

  当然也可以换一个维度,把访问量或者写入量大的表单独分离出来,跑在一台服务器上,也可以把一个表分成多个小表。这一步操作,涉及到一些程序上的改动,所以需要事先和开发同事做好沟通和设计。

  总之,这一步要做的就是分库分表。

  小结

  再往后发展,继续把大表分小表即可。 比如阿里淘宝网站的数据量是巨量的,他们的数据库全部都是 MySQL,他们的 MySQL 架构就是遵循分库分表这个原则的,只不过他们划分规则会有很多维度,比如可以根据地域划分,可以根据买家、卖家划分,可以根据时间划分等。


推荐阅读
  • 我的读书清单(持续更新)201705311.《一千零一夜》2006(四五年级)2.《中华上下五千年》2008(初一)3.《鲁滨孙漂流记》2008(初二)4.《钢铁是怎样炼成的》20 ... [详细]
  • 本文详细探讨了在Web开发中常见的UTF-8编码问题及其解决方案,包括HTML页面、PHP脚本、MySQL数据库以及JavaScript和Flash应用中的乱码问题。 ... [详细]
  • PHP面试题精选及答案解析
    本文精选了新浪PHP笔试题及最新的PHP面试题,并提供了详细的答案解析,帮助求职者更好地准备PHP相关的面试。 ... [详细]
  • Redis:缓存与内存数据库详解
    本文介绍了数据库的基本分类,重点探讨了关系型与非关系型数据库的区别,并详细解析了Redis作为非关系型数据库的特点、工作模式、优点及持久化机制。 ... [详细]
  • centos 7.0 lnmp成功安装过程(很乱)
    下载nginx[rootlocalhostsrc]#wgethttp:nginx.orgdownloadnginx-1.7.9.tar.gz--2015-01-2412:55:2 ... [详细]
  • PHP环境下的ini配置详解:聚焦错误相关选项
    本文详细探讨了PHP环境中的ini配置,特别是与错误处理相关的配置项,旨在帮助开发者更好地理解和调整php.ini文件以适应不同的开发需求。 ... [详细]
  • 如何处理PHP缺少扩展的问题
    本文将详细介绍如何解决PHP环境中缺少扩展的问题,包括检查当前环境、修改配置文件以及验证修改是否生效的具体步骤,帮助开发者更好地管理和使用PHP扩展。 ... [详细]
  • 电商高并发解决方案详解
    本文以京东为例,详细探讨了电商中常见的高并发解决方案,包括多级缓存和Nginx限流技术,旨在帮助读者更好地理解和应用这些技术。 ... [详细]
  • Django与Python及其他Web框架的对比
    本文详细介绍了Django与其他Python Web框架(如Flask和Tornado)的区别,并探讨了Django的基本使用方法及与其他语言(如PHP)的比较。 ... [详细]
  • MySQL Administrator: 监控与管理工具
    本文介绍了 MySQL Administrator 的主要功能,包括图形化监控 MySQL 服务器的实时状态、连接健康度、内存健康度以及如何创建自定义的健康图表。此外,还详细解释了状态变量和系统变量的管理。 ... [详细]
  • Nacos 0.3 数据持久化详解与实践
    本文详细介绍了如何将 Nacos 0.3 的数据持久化到 MySQL 数据库,并提供了具体的步骤和注意事项。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • 在Linux系统中避免安装MySQL的简易指南
    在Linux系统中避免安装MySQL的简易指南 ... [详细]
  • CRZ.im:一款极简的网址缩短服务及其安装指南
    本文介绍了一款名为CRZ.im的极简网址缩短服务,该服务采用PHP和SQLite开发,体积小巧,约10KB。本文还提供了详细的安装步骤,包括环境配置、域名解析及Nginx伪静态设置。 ... [详细]
author-avatar
乖乖88918
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有