分布式系统与一致性
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.1 拆分是解决大规模应用问题的本质

互联网应用的架构是非常复杂多变的,具有不同用户访问量和数据量的互联网应用的系统架构有着非常大的差异。当系统访问量和数据量不大时,系统架构相对简单,往往一台应用服务器加上一台数据库服务器就可以解决问题。早期的互联网应用基本上就是这样的架构。在互联网发展初期,互联网用户还不是很多,不管是什么类型的应用,基本上一台机器就可以搞定。

但是互联网的发展是快速的,这样的架构很快就不能满足需求了,大量的访问用户给服务器带来了巨大的压力。当服务器不能承载时,在架构上就开始采用具有更强处理能力的CPU、容量更大的内存、容量更大的存储设备。昂贵的小型机和存储设备成为互联网的首选,IOE(IBM的服务器、Oracle的数据库、EMC的存储设备)架构也成为主要的解决方案。

为了获得更好的用户体验,对应用服务器可以进一步做一些系统架构优化,比如将从数据库取到的结果缓存在应用服务器的内存当中,下次处理同一个用户的同一类请求时,就可以直接将内存中的结果返回给用户,减少了访问数据库这一步骤。这缩短了用户请求响应时间,同时也降低了数据库的压力,便于承载更大的用户访问量。此外,甚至可以做进一步的优化,将某些数据直接保存在应用服务器的本地磁盘中,而不保存到数据库中。

互联网的发展是惊人的,随着访问量的进一步增长,单台应用服务器最终将出现瓶颈,不能再依靠替换更强的服务器继续支撑。因为不是一种可以持续发展的架构,并且IOE的昂贵收费也让这种架构变得不可接受,这种依赖提高单机处理能力的垂直扩展架构走到了尽头。互联网从业者开始尝试采用增加应用服务器的数量来处理增长的访问请求这种架构,也就是采用水平扩展的方式来解决问题。在水平扩展架构中,在应用服务器前可以增加一层负载均衡,比如使用Nginx或LVS这样的软件负载服务器,或者F5这样的硬件负载服务器,把用户的访问请求分散到多台应用服务器上,让多台应用服务器访问同一台数据库服务器。这种架构不再依赖单台服务器的处理能力,随着访问量的增长,只需要不断地增加应用服务器即可,具有无限的水平扩展能力。应用服务器也不再是昂贵的IBM小型机,普通的PC服务器就可以。

与此同时,不能再像单台应用服务器阶段那样对缓存进行优化,因为某个用户的数据被缓存在某台应用服务器的内存中,或者被保存在某台应用服务器的硬盘中,当这个用户的请求被负载均衡到其他服务器时,将找不到缓存在内存中和保存在硬盘中的数据。对于那些之前缓存的数据,可以通过再次从数据库中读取的方式来解决,但是保存在硬盘中的数据就没办法解决了。所以这个阶段的应用服务器往往被设计成无状态的服务器,也就是说,在应用服务器上不保存任何数据,数据都被保存在数据库中,每次处理用户请求时,都去数据库中获取最新的数据。为了提高性能,添加了一台专门的缓存服务器,如Redis或者Memcache,所有的应用服务器都把本来缓存在自己内存中的数据保存在缓存服务器中。把应用服务器设计成无状态的好处是水平扩展非常方便,所有的应用服务器都是一样的,水平扩展只是在负载均衡层后面添加一台服务器,可以将用户请求发给任意一台应用服务器,而无须发给缓存了这个用户数据的那台服务器。

但无状态的应用服务器并不能解决全部的问题,随着用户访问量的继续增长,数据库的处理能力或者缓存服务器的处理能力逐步达到上限,数据库和缓存这一层同样需要一种可以水平扩展的架构。对于这个问题,相应的办法是对应用进行拆分,把原来一个大应用,按照领域拆分成多个应用。比如电子商务应用,一般都会拆分成订单子系统、交易子系统、用户子系统、商品子系统等,每个子系统都有自己独立的数据库服务器,这样就解决了单台数据库服务器的瓶颈问题。这种将一个应用拆分成多个子系统的方法也被称为领域拆分,每个领域相对比较独立。领域拆分仍然是互联网行业解决大规模应用问题所采用的主要技术手段,被应用得淋漓尽致。比如在大型电子商务应用中,甚至一个商品详情页面就是一个独立的子系统,由多层应用服务器、多层缓存机制、多个数据库组成,并且由一个庞大的部门独立维护着。