假设你对项目管理、系统架构有兴趣,请加微信订阅号“softjg”。增加这个PM、架构师的大家庭
近期看了非常多公司架构的演变的文章。发现当中的基本思路和架构演变都非常类似。这里也总结一下数据库架构的演变以及演变背后的思路。
单主机
最開始站点一般都是由典型的LAMP架构演变而来的,一般都是一台linux主机,一台apacheserver。php运行环境以及mysqlserver。普通情况下。这些都在一台虚拟主机上,简称单主机模式。
单主机模式缺点:
1 webserver和mysqlserver公用一台主机,共享硬件资源。可能存在某一方资源征用太大,导致整个应用产生瓶颈
2 当业务增长之后。没有办法做到横向扩展。
3 容错性太差,一旦主机存在问题,整个应用不可用
独立主机
随着业务的发展,能够把mysqlserver和webserver主机分开,分别部署,就是独立主机模式。
独立主机模式下。webserver和mysql不再共享硬件资源。分别部署。没有把鸡蛋放在一个篮子里面,添加了容错性。
假设仅仅是mysqlserver故障。那么对于web上不訪问server的应用是不会受到影响的。并且webserver能够做到横向扩展,假设webserver性能不够。能够添加多台webserver。进行负载均衡,分散webserver的压力。
独立主机模式的缺点:
1 可扩展性问题:尽管webserver能够做到横向扩展,可是mysqlserver是没有办法做到横向扩展的。
2 可用性问题:mysqlserver存在单点问题,一旦mysqlserver宕机,对影响的影响非常大
3 性能问题:单台mysqlserver可以支撑的服务是有限的。
读写分离
随着业务的不断发展,数据库的压力会越来越大,单数据库慢慢的就不能满足需求了,一些站点对数据实时性要求不高,就会慢慢发展读写分离模式,对于普通的查询请求,分配到读库(也能够说是备库)。对于改动请求。在主库上完毕。
对于读库。因为是无状态的。能够做到横向扩展。
对于写库,还仅仅能是单台主机
这样的模式事实上有限制的。要依据业务的类型来考虑。主库的数据是最新的,可是同步到读库会有时延。所以应用必须可以容忍短暂的不一致性。对于一致性要求很高的场景是不适合的。
这样的模式的存在的问题:
1 可扩展性:尽管读库可以做到横向扩展,可是写库还不行,读库不可以横向扩展
2 可用性:读库成为单点,一旦故障,影响全部的写操作业务
业务垂直拆分
随着业务的发展,一台写库显然不能够满足高并发的情况,可是考虑到写库是有状态的,不能简单的横向扩展,如果有两台写库,那么随机更新一台的数据,就会导致还有一方数据存在问题。出现一种数据两个不同版本号,显然是无法接受的。在写库上,能够考虑依照业务来垂直进行分库。因为我们这里讨论的是数据库架构。对于web层来说,事实上也是能够依照业务垂直拆分的。
在依照业务垂直拆分以后。系统在性能上有了非常高的提升,仅仅须要把业务上分成垂直部分。分的越细,系统的总体扩展能力就越强。
这样的模式下。存在下面几个问题
1 可用性:如果一个完整的业务流程P訪问的数据库被拆分为A、B、C、D、E 五个库。如果每一个写库可用性为99%。那么这个业务流程P的可用性就为99%*99%*99%*99%*99%=95%,库拆分的越多,对系统的总体可用性挑战就越大。
2 性能:因为垂直业务库每一个库的负载可能不一样,如果交易库负载非常高。一个交易写库肯定不可以满足需求。这个情况下。交易库成为整个系统的瓶颈。
3 可扩展性:单个节点的可扩展性没有得到改善。交易库不能单独进行扩展。
单业务库水平、垂直拆分
在上一种情况,如果交易库是整个系统的瓶颈,须要对交易库进行单独的扩展。能够考虑交易的水平拆分或者垂直拆分。有可能同一时候进行两种方式拆分。
水平拆分一般依据业务无关的keyword进行拆分。横向扩展性比較好。可是对于查询的挑战比較大
垂直拆分一般依据业务来拆分,可是可能导致数据不均匀以及拆分不够灵活。对于查询来说,相对照较友好
拿交易库举个样例,能够先交易的类型进行业务上的垂直分库,在依照订单号进行水平分库。
如果能够分成M*N个库。那么单个库的故障会影响1/M*N 的交易。可是如果每一个库可用性为99% ,那么交易数据库故障概率为 (99%)的(M+N)次方。如果数据库拆分的越多。发生单个数据库故障概率就越高。
这样的方式存在的问题:
1 尽管单个节点故障影响的用户非常少,可是总体可用会减少。
2 数据库管理上带来复杂的挑战,如果交易库表结构变更,须要运行M×N次脚本变更。
3 因为发生单个数据库故障的概率比較高。dba会非常苦逼的,预计常常性要救火
4 开发和測试起来会很苦逼,开发和測试成本会变高,查询很复杂。
5 单个节点假设发生问题,没有失败检測而且切换机制
6 分库还不能在水平方向做到无限扩展。我们的算法是事先分配M个库,假设加入一个库基本上不可行
随机分库
对于第六个问题。在水平方向的无线扩展,能够考虑一种机制,在insert数据的时候,申请一个数据库编号。然后把数据库的编号作为一个字段保存或者在把这个编号加入到已经字段上。
比如如果我们申请insert数据库,得到一个数据库编号为1000,那么我们能够构造出来一个订单号为1000_tradeno,订单号前面是分库编号,订单号后面是实际tradeno,这样攻克了水平无线扩展的问题。这样的就是随机分库模式。
可是这一种方式的局限性非常大。
随机分库的缺点:
1 分库算法和业务耦合在一起,比較适合特定的场景,适用范围比較窄
2 对于insert操作,比較easy,对于update操作。必须有分库编号,也就是说。仅仅能依据特定的字段来进行更新
3 不适合批量查询的场景,查询功能限制比較大,这也是分库带来的问题
单数据库备份以及失败切换
对于单个数据库,假设发生问题,会影响业务。可是是否能在发生问题的时候进行切换。尽管能够实现,可是会存在一定的问题。须要特定场景进行特定的分析。这一块比較复杂,说起来能够在写一篇文章,就简单的介绍一下
以上就是总结的数据库的架构演变。数据库的演变须要非常多基础技术做支撑,主要包含
1 强大的分布式数据库的管理中间件。主要屏蔽底层的数据库路由以及数据管理功能
2 强大的数据运维团队以及监控体系,可以检測出每一个节点的数据库状态
3 强大的数据库管理管理团队,可以维护这么的数据库集群
4 强大的业务架构能力和技术架构能力,可以掌控这么复杂的业务场景。
假设你对项目管理、系统架构有兴趣,请加微信订阅号“softjg”,增加这个PM、架构师的大家庭