架构模式介绍

文章介绍了高性能数据库架构的几种模式,包括读写分离以分散访问压力,分库分表以解决存储压力,以及使用NoSQL如Redis、MongoDB和ES提升性能。同时,讨论了分库分表带来的问题,如join操作和事务管理的挑战,以及路由算法的选择。
摘要由CSDN通过智能技术生成

序言

本文章借鉴李运华老师<<从0开始学架构>>课程

1.高性能架构模式

1.1读写分离

1.1.1介绍

在这里插入图片描述
在这里插入图片描述

高性能数据库集群的第一种方式是“读写分离”,其本质是将访问压力分散到集群中的多个节点,但是没有分散存储压力;第二种方式是“分库分表”,既可以分散访问压力,又可以分散存储压力。

1.1.2复制延迟

在这里插入图片描述

1.1.3分配机制

  • 程序代码封装
  • 中间件封装(sharding-jdbc)

由于数据库中间件的复杂度要比程序代码封装高出一个数量级,一般情况下建议采用程序语言封装的方式,或者使用成熟的开源数据库中间件。如果是大公司,可以投入人力去实现数据库中间件,因为这个系统一旦做好,接入的业务系统越多,节省的程序开发投入就越多,价值也越

1.2分库分表

1.2.1介绍

  • 背景

读写分离分散了数据库读写操作的压力,但没有分散存储压力,当数据量达到千万甚至上亿条的时候,单台数据库服务器的存储能力会成为系统的瓶颈,主要体现在这几个方面:数据量太大,读写的性能会下降,即使有索引,索引也会变得很大,性能同样会下降。数据文件会变得很大,数据库备份和恢复需要耗费很长时间。数据文件越大,极端情况下丢失数据的风险越高(例如,机房火灾导致数据库主备机都发生故障

  • 分库

    在这里插入图片描述

  • 分表
    在这里插入图片描述

1.2.2问题

1.join 操作问题 业务分库后,原本在同一个数据库中的表分散到不同数据库中,导致无法使用 SQL 的 join 查询。例如:“查询购买了化妆品的用户中女性用户的列表”这个功能,虽然订单数据中有用户的 ID
信息,但是用户的性别数据在用户数据库中,如果在同一个库中,简单的 join 查询就能完成;但现在数据分散在两个不同的数据库中,无法做
join 查询,只能采取先从订单数据库中查询购买了化妆品的用户 ID 列表,然后再到用户数据库中查询这批用户 ID
中的女性用户列表,这样实现就比简单的 join 查询要复杂一些。
2. 事务问题 原本在同一个数据库中不同的表可以在同一个事务中修改,业务分库后,表分散到不同的数据库中,无法通过事务统一修改。虽然数据库厂商提供了一些分布式事务的解决方案(例如,MySQL

XA),但性能实在太低,与高性能存储的目标是相违背的。例如,用户下订单的时候需要扣商品库存,如果订单数据和商品数据在同一个数据库中,我们可以使用事务来保证扣减商品库存和生成订单的操作要么都成功要么都失败,但分库后就无法使用数据库事务了,需要业务程序自己来模拟实现事务的功能。例如,先扣商品库存,扣成功后生成订单,如果因为订单数据库异常导致生成订单失败,业务程序又需要将商品库存加上;而如果因为业务程序自己异常导致生成订单失败,则商品库存就无法恢复了,需要人工通过日志等方式来手工修复库存异常。
4. 成本问题 业务分库同时也带来了成本的代价,本来 1 台服务器搞定的事情,现在要 3 台,如果考虑备份,那就是 2 台变成了 6 台。

1.2.3路由

水平分表后,某条数据具体属于哪个切分后的子表,需要增加路由算法进行计算,这个算法会引入一定的复杂性

范围路由:选取有序的数据列(例如,整形、时间戳等)作为路由的条件,不同分段分散到不同的数据库表中。以最常见的用户 ID
为例,路由算法可以按照 1000000 的范围大小进行分段,1 ~ 999999 放到数据库 1 的表中,1000000 ~ 1999999
放到数据库 2
的表中,以此类推。范围路由设计的复杂点主要体现在分段大小的选取上,分段太小会导致切分后子表数量过多,增加维护复杂度;分段太大可能会导致单表依然存在性能问题,一般建议分段大小在
100 万至 2000 万之间,具体需要根据业务选取合适的分段大小。范围路由的优点是可以随着数据的增加平滑地扩充新的表。例如,现在的用户是
100 万,如果增加到 1000 万,只需要增加新的表就可以了,原有的数据不需要动。范围路由的一个比较隐含的缺点是分布不均匀,假如按照
1000 万来进行分表,有可能某个分段实际存储的数据量只有 1000 条,而另外一个分段实际存储的数据量有 900 万条。 Hash
路由:选取某个列(或者某几个列组合也可以)的值进行 Hash 运算,然后根据 Hash 结果分散到不同的数据库表中。同样以用户 ID
为例,假如我们一开始就规划了 10 个数据库表,路由算法可以简单地用 user_id % 10 的值来表示数据所属的数据库表编号,ID 为
985 的用户放到编号为 5 的子表中,ID 为 10086 的用户放到编号为 6 的字表中。Hash
路由设计的复杂点主要体现在初始表数量的选取上,表数量太多维护比较麻烦,表数量太少又可能导致单表性能存在问题。而用了 Hash
路由后,增加子表数量是非常麻烦的,所有数据都要重分布。Hash 路由的优缺点和范围路由基本相反,Hash
路由的优点是表分布比较均匀,缺点是扩充新的表很麻烦,所有数据都要重分布。
配置路由:配置路由就是路由表,用一张独立的表来记录路由信息。同样以用户 ID 为例,我们新增一张 user_router 表,这个表包含
user_id 和 table_id 两列,根据 user_id 就可以查询对应的
table_id。配置路由设计简单,使用起来非常灵活,尤其是在扩充表的时候,只需要迁移指定的数据,然后修改路由表就可以了。配置路由的缺点就是必须多查询一次,会影响整体性能;而且路由表本身如果太大(例如,几亿条数据),性能同样可能成为瓶

1.3高性能NoSQL

1.3.1背景

在这里插入图片描述
在这里插入图片描述

1.3.2 redis

在这里插入图片描述

1.3.3MongoDB

在这里插入图片描述

1.3.4ES

在这里插入图片描述

1.4高性能缓存架构

在这里插入图片描述

1.4.1问题

  • 缓存击穿
  • 缓存雪崩
  • 缓存热点
    解决方案这里不在详述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫果冻

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值