大型网站架构(2)--分布式系统&中间件从入门到精通(四)

2022-07-29 14:04:12 浏览数 (1)

上篇文章说了当数据量大,并且访问量大的时候,可以把业务和DB分开放在不同的服务器,这时候会出现session问题,可以通过负载均衡器来解决session问题,保证同一个会话每次都发在同一个服务器上,也可以通过单独的服务保存sesion。

大型网站架构(1)--分布式系统&中间件从入门到精通(三)

数据库读写分离

当业务和DB分离之后,还存在服务器瓶颈,这时候可以考虑读写分离模式,可以增加一个读库,这个数据库不承担写的工作。这时候会出现两个问题:1、两个数据源的复制问题。2、应用对于数据源的选择问题。

我们首先要把数据复制到读的库里,目前数据库系统都有复制的功能,比如mysql的主从复制,但对于复制,我们要考虑到延迟性,如果用户修改了数据,而查出来的是未复制的数据,用户会误以为自己没修改成功。

Mysql在5.5之前是异步复制的,所以会有延迟,并提供完全镜像方式复制。而mysql在5.5之后加入了对semi-syn的支持,从数据安全来说,他比异步好,不过还是有延迟问题。Oracle接触的主要是data cuard方案,这个主要解决容灾、数据库的保护以及故障恢复等场景,该方案又分为物理备份(物理standBy)和逻辑备份(逻辑standBy)。

对应应用层面来说,增加了一个读库,即影响使用哪个数据源来读,我们需要根据不同的场景选择不同的数据源,写操作主要走主库。简单来说,读写分离就是增加了一个读库,分担写的压力,因此增加了个读源。

搜索引擎就是一个读库

所以我们常用的搜索引擎就是一个读库,我们举个例子,交易网站需要根据商品的标题来查找,想到的可能是like功能,但这种实现方式代价很大,这时候我们可以使用搜索引擎倒排序表达方式,它能够大大提升索引速度。

缓存解决数据库压力

缓存就是我们常说的cache,在日常开发中,缓存主要就是为了解决数据库读的压力,这就是前面说的分库和搜索引擎功能类似。

通常我们使用都会通过key-value的形式吧数据存在缓存中,一般存放的是热数据,而不是全部的数据库数据,举个例子,当数据在缓存中不存在,则会去数据库中查询,再放入缓存。还有一种做法就是把所有数据全部放入缓存中,这样会有一个要求,需要根据数据库变化去更新缓存的代码,理解业务逻辑。

弥补关系型数据库不足,引入分布式存储系统

在之前介绍的存储数据只要是数据库,但有些场景下,数据库彬彬哥不是很适合。

常见的分布式存储系统有分布式文件系统、分布式key-value系统和分布式数据库。文件系统大家都知道,就是在分布式环境下,由多个接地那组成的功能与单机文件系统一样的系统,他是弱格式,内容的格式需要自己组织。分布式key-value系统则会更加格式化一些。分布式数据库则是最格式化的方式。

分布式存储系统自身起到了存储作用,也就是提供数据库的读写支持,相对于读写分离中的读“源”,分布式系统更多的是直接代替主库。是否需要引入分布式系统则需要根据具体场景来选择。

当我们采用了读写分离的方式,增加缓存的方式还遇到了数据库的瓶颈,这时候我们就需要考虑专库专用,数据垂直拆分。

垂直拆分就是把数据库从不同的业务拆分到不同的数据库中,比如业务有商品,交易和用户,则把这些东西都拆分到不同的数据库。

当垂直拆分还有瓶颈的时候,就可以考虑吧数据库水平拆分,吧同一个表的数据拆分到两个数据库中。水平拆分的原因可能是某个业务的数据表数据量太大或者更新到达了单个数据的瓶颈,这时候就可以吧表拆分成两个或者多个到数据库中,数据水平拆分和读写分离的区别是,读写分离解决的是压力大的问题,对于数据量大后者更新量大的情况不起作用。经过垂直拆分后,用户表和交易表,商品表不在同一个数据库中,如果数据量或者更新量大,可以进一步拆分到不用的两个数据源中,他们有一模一样的用户表,每个表中只涵盖一部分数据。一旦完成拆分,这时候可以很好的应对数据量增长情况,但是也会遇到更多问题,比如分页问题,主键不能保证唯一性问题等。

应用拆分

数据库问题通过分库分表,垂直拆分,水平拆分,数据源如搜索引擎、缓存解决读的压力后,接下来可以看看应用拆分。

随着业务的发展,应用功能越来也多,我们该考虑如何不让应用持续变大,就应该需要把应该拆分开,从一个应用变成两个甚至多个应用。

我们可以根据业务的特性吧应用拆开,比如前面的例子,我们有商品,交易,和用户。可以原来一个应用拆分称为两个,一个放商品和用户,一个放交易和用户,因为他们都涉及到用户。

我们还可以按照用户注册、用户登入、用户信息维度等拆分,使他们变成三个系统。不过拆分之后会有很多相似的代码,这时候就需要解决代码的复用性。

服务化路

让商品中心、用户中心、交易中心,都独立连接各种的DB数据库,然后在用户访问页面的额时候,单机内部方法调用,引入远程服务调用。这样可以有效解决代码冗余,实现高复用。通过服务化,无论是web前端还是服务应用,都可以由固定的团队来维护系统,这样可以保证稳定性。需要做到服务化,需要一些基础的组件来实现,这些在后面会具体介绍。

0 人点赞