继续我们关于大型分布式网站解决方案的讨论。上一章节中,我们一起研究了应用与数据库分离、集群、读写分离、缓存这几种大型网站的解决方案,地址:https://blog.csdn.net/xulong_08/article/details/81359364。
经过上一章节的讨论,我们已经能够了解随着网站访问量的增加,如何逐步改造网站架构。
- 对于单机系统的处理能力无法满足需求时,需要多台服务器将应用和数据库分离开,减少服务器的负载压力。
- 访问量继续增加后,需要多台应用服务器共同提供服务,需要配置集群部署方式,但是需要引入负载均衡来解决让多台服务器共同提供服务,以及集群服务器间的Session共享问题。
- 多台应用服务器共同提供服务,这时我们的数据库压力变大,需要通过读写分离来减轻数据库压力,但是要处理好数据同步和数据源选择问题
- 网站快速响应可以提高用户体验,这是我们引入缓存服务器来存储一些热点数据,提高网站响应速度、减轻数据库压力。
至此为止我们网站已经能够应对一定量的并发请求,并且实现了快速响应等,接下来我们将讨论如何进一步增加网站的并发处理能力,以及服务优化等问题。
6、弥补关系型数据库的不足,引入分布式存储系统
之前我们的数据存储方式主要是数据库和缓存,数据库存储一些需要持久化的数据,缓存存储一些热点数据以及共享数据。随着业务发展,关系型数据库已经不能满足日益增长的业务需求,这时我们就需要分布式存储系统来实现数据、文件等的存储功能。
常见的分布式存储系统主要有:
- 分布式文件系统
- 我们的网站包含了大量的图片以及其他文件,集群的每一台机器需要访问这些文件,所以我们引入分布式文件系统,将文件统一存储,通过URL存取文件。
- 分布式缓存系统
- 一般指Key-value形式的存储系统。
- 分布式数据库
- 需要多台数据库服务器功能提供读写操作,已经讨论了如何实现读写分离,其他的方案将在下文中描述。
7、读写分离无法突破数据库瓶颈,采用数据拆分分担压力
尽管我们已经采取了读写分离、添加热点数据缓存等措施来减少数据库压力,但由于数据库中数据越来越多,存取操作也越来越频繁,查询速度越来越慢,导致网站无法提供高效的服务。基于以上问题,我们分析一下可能存在的问题,目前我们所有业务相关的变都存在一个库中,数据量越来越庞大,数据库变得臃肿、低效。我们需要使用多个数据库分离数据,将这些数据分担到多个库中,这样就能是每个数据库里存储适量的数据,提高整体效率。一般我们将数据拆分的方法有垂直拆分和水平拆分两种。
- 专库专用,垂直拆分数据
- 即将不同业务的数据存储到不同的数据库中,比如交易、商品、用户可以存储在三个数据库服务器中,每个数据库中的数据就变少了,数据库压力随之减少。
- 不同业务的数据存储到不同的数据库中后,需要考虑单机中跨业务的事务处理。即如何解决不同业务之间的数据关联查询
- 使用分布式事务,但是其性能上比较低。
- 优化代码,去掉跨业务的事务,需要根据不同业务去优化代码。
- 解决单表数据量过大,数据水平拆分
- 当单表数据量过大时,数据查询效率就会非常低,所以我们需要减少一张表中存储的数据量,即将一张表中的数据存储到多个数据库中,即设置一个数据记录数的上限,一旦达到这个限制,就保存到存的数据库中。
- 这样会带来很多问题,一是查询时如何才能知道在哪个数据库,二是主键如何保证不重复,自增如何处理,三是分页如果涉及到两个库中的数据,如何处理。关于这些问题需要很大的篇幅去介绍,我也将关于此事专门写一篇文章来介绍,敬请期待!
8、业务范围扩大、按模块拆分应用
数据库方面我们已经做足了工作,读写分离、分布式存储、数据拆分等,数据库已经有了很强的负载能力。我们的应用服务器却随着业务扩大,代码量变大,变得臃肿复杂,这时我们就需要将原有应用拆分开,分别部署到不同的服务器中。
我们可以根据业务功能去拆分应用,比如讲用户、交易和商品拆分成三个不同的应用。这样,拆分后的每个应用都可以有专门的团队去维护,代码变得简洁了,甚至我们还可以对小模块再次进行拆分,使之功能更加具体一点。但是这样我们会遇到以下问题
- 不同应用之前的调用问题
- 比如交易模块需要获取商品信息,也需要获取用户信息。这些信息的获取需要商品和用户模块对外暴露接口,提供给其他模块进行调用,我们可以通过RPC框架来进行应用间的信息交换以及数据处理。
9、使用面向服务架构改造系统
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的 面向服务架构(SOA) 是关键。SOA是将用访问层和服务层相分离,让用户访问层只接受用户请求,然后将请求发送给服务层处理,服务层暴露接口可由多个用户访问层调用。这时我们的服务层就相当于一个专门提供服务的服务中心。
这样改造后,我们系统不仅是单机内部的方法调用了,还引入了远程服务调用。共享的代码不用散落在不同的应用中了,二是统一交由服务中心去实现。做到服务化需要一些基础组件的支撑,我们将在下一章节介绍相关的Java中间件。
10、消息中间件
这一节我们先来研究一下消息中间件,消息中间件在分布式系统中有着重要的作用,在解耦和消息处理上有着无可比拟的优势。消息中间件是面向消息的系统,在分布式系统中完成消息的发送盒接收的基础软件。
消息中间件有着异步和解耦的作用,从上图中我们可以看出,应用A和B没有直接的联系,而是通过消息中间件来进行信息的传输,消息中间件可以将消息保存并记录,直到这条消息被接受。对于应用来说不用关心消息来得来源和去向,只需要向消息中间件中发送或者获取消息即可。
11、总结
至此为止,我们的网站可以支撑大量并发并提供稳定的服务了,整个网站系统变得高效、安全稳定。经历了应用和数据库分离、集群、读写分离、缓存、数据拆分、应用拆分、服务化的改造,相信我们已经对大型网站的架构有了一些初步的认识,但是详细的实现过程还需要我们一起去探索,下一章节我们将讲述Java中间件以及Java中间件的一些理论基础,会涉及到一些比较底层的东西,是时候展示真正的技术了。
由于文章写得比较仓促,可能存在部分遗漏或者出错的地方,还希望大家谅解。如果大家对我的文章有什么意见或建议,以及有任何疑问欢迎大家在文章下面评论,或者通过我的个人邮箱与我联系:[email protected]。