关于大型web服务器的设计思路

jopen 5年前

大型网站,比如门户网站,在海量用户访问、高并发请求方面,基本的解决方案是以下几点:
  1、高性能的数据库(oracle/db2/mysql...)
  2、高性能的Web容器(weblogic/apache...)
  3、高效率的编程语言(java/C#)
  4、使用高性能的服务器(小型机、PC服务器)
  5、集群分布式运行(比如上百台小型机器在线运行)

但是在在线用户上百万,日点击量超亿,而数据达几十T,甚至日数据量就达到T级别这种情况下还是难以解决
大型网站面临的高负载和高并发问题。
   本人也经常关注这方面的解决方案,结合自己的经验。总结了一部分常用的设计,希望各位多多指点。

一、设计上有足够弹性
  这是在前期架构设计师要足够考虑到的。最终目的是通过物理设备的线性投入来应付业务量的增长,而不止于受到技术框架应用部署的限制,甚至推到重来,这样的结构设计就是弹性的设计,当然这里还包括业务上的弹性设计(目前的开发模式、架构设计在很大程度上也是为了解决这个问题)。
  一般企业也是极力避免这种情况的发生,否则失去的不仅是成本投入还包括了客户资源。

二、页面静态化
  即静态html格式,这样避免了对数据资源的访问,同时也大大降低了应用的CPU消耗。如果能静态页面的信息尽量静态化。

、无状态
  这里说的无状态是服务器尽量设计成无状态的与客户端通讯,避免了占用大量内存的情况,但这也不是绝对的。部分应用中的状态保留也能大大减少IO流量与数据库的访问压力。看具体情况而定。

四、数据库集群、横向/纵向切分
    数据库集群能缓解数据库的压力,但节点过多又会引起写入同步消耗过大。
    数据库横向切分也就是把一个业务数据按不同属性(比如地域归属、用户名hashcode)来平均的分到各个数据库上。这样控制分库的粒度也就是控制了数据库的分布,能大大缓解单个数据压力过大访问受限的情况,不利的情况是经常要跨库访问,这样情况可能会变得比较复杂。
    数据库纵向切分也就是按业务内容来分不同的数据库,比如客户资料是一个数据库保存,而商品订单资料又分一个数据库保存,这样也能把数据库压力分解一部分。
    通过数据库的切分也能大大减少单个故障点的影响范围。

五、异步批量处理
    对于非紧急数据,可以采用异步批量处理,安排在非高峰时刻也能提高应用的使用效率。同时批量本身在实现上效率也高于单笔业务处理。

六、表的分区分段分表设计
    这是针对一个数据库的情况下,防止单表数据过大,采用分段分区把一张表分解到不同的物理设备上,提高查询速度,而可以按业务性质把一张表分成多张表,分区分表可以组合应用,这样在DB维护上也非常有益。同时分表也能有效降低I/O锁情况。

七、分历史数据库
    对于很多网站来说海量的历史数据是很少用到的,可以按照业务性质,把不修改的数据迁移到专门的历史数据库上归档,比如三个月以前的交易订单、用户的资料修改记录等。对于需要查询历史数据的情况,可以单独提供这类应用来查询历史数据库。这样能避免不断增加的交易数据带来的性能压力。

八、分活动和非活跃用户
    这是按照用户的优先级别分别存储访问,对于少量的活跃用户提供高速的访问(比如通过缓存),这样实际上大大提高了大部分用户请求的处理速度,实际上也大幅度降低应用压力提高并发能力,而对于非活跃用户继续保留了完整的请求服务,客户基本不会产生使用上的差异。

九、分布式的应用
   包括前台服务器和中间件(其实包括前面描述的多个数据库),把压力尽可能的均匀地分布到很多服务器上,而服务器可以是上百台的线性增加。

十、使用 Epoll/IOCP 来提高并发性能
    这些在游戏类网站上非常有用,能大大提高单台应用服务器的处理能力。结合多线程多进程多服务器处理可以解决高并发请求的情况。

十一、建立专门的文档服务器
    包括的页面图片、软件、文档等数据,由于IO流量大,比较占用应用服务器,必要的时候单独建立服务器存放。这种对于有大量图片的应用比如淘宝商品应该是非常有效的。

十二、分查询与更新业务数据库
   对于更新类关键业务提供强有力的高效保证(这类业务相对查询量应该比较少),而对于查询库则可以提供廉价的数据库服务。

十三、缓存
   其实所有的应用都或多或少的使用到了缓存,缓存包括 CPU /内存 /硬盘/网络/客户端的缓存,客户端可以缓存js/图片等信息,而不用频繁的访问应用,内存缓存是非常有效的方式,可以把静态的数据放到应用内存上,而不是频繁访问数据库查询,对于简单数据库其实还可以使用专业的缓存应用,比如memcache。

十四、海量数据使用非关系数据库
   对于访问记录等数据结构简单可靠性要求不高的数据持久化,可以不用关系数据库,因为数据库提供的食物访问一致性、隔离性、关系维护消耗了绝大部分资源,而这些功能对不是应用的要点。所以可以考虑使用文件方式或者其他号称NOSQL的方式来存储使用。

    本人认为应用通过分布式并发负载均衡运行可以解决应用服务器的性能问题(通过良好的设计来保证当业务持续增加的时候通过服务器的线性增加就能解决),关键点是数据库的唯一一致性要求(一份数据只能保存在一个地方,更新查询都以它为基础)决定了数据库的成本是非常高的,甚至于无法用资金来解决(大型机也不见得能保证海量数据的访问处理),所以只要解决了数据库的存放问题也就能解决高性能网站的主要问题
   上边说了这么多基本上还是把数据对象分开存放、尽量减少对于数据库的访问的原则提出解决方案的。
     对于系统的高可用性这里也总结出几条:
         A、良好成熟的框架设计(并不一定是非常先进),优秀的业务模型,高内聚低耦合的模块功能。
         B、优化部署配置,包括数据库的优化。
         C、预防为主,有专门的监控负责人,能定期分析系统健康负载情况。在问题爆发前能及时预警。
         D、有良好的单点控制与应急措施,比如当发帖非常耗性能的时候,单独关掉“发帖”,
               保证大部分的游览功能。 保证客户应用的最大化
         E、有效专业的开发管理团队与规范的制度