当前位置: 首页 > 后端技术 > Java

【数据库篇】垂直拆分、水平拆分、分库分表策略、主从复制、读写分离

时间:2023-04-01 18:02:02 Java

1.垂直拆分1.1垂直拆分垂直拆分就是把表分成不同的功能模块在数据库中,如果你的系统是分布式微服务架构,就更好理解了。通常,一个微服务对应一个或多个数据库。比如电商系统一般有用户中心、订单、商品等。用户中心数据库存与用户信息相关,产品数据库存是所有与产品相关的数据,订单数据库与存储的订单相关。1.2垂直分表垂直分表是将一个数据表的字段拆分成两条或两条以上的数据进行存储。这样做的目的之一是避免一张表中存储的字段过多,单条数据的数据量大,不仅会占用较多的物理内容,还会降低查询性能。而有的字段查询的不是很频繁,有的字段查询的很频繁,那么我们可以把经常查询和不经常查询的字段分开存放。这样可以避免不必要的磁盘IO,提高系统的性能。我们一般将经常查询的字段放在主表中,将不经常查询的、不是很重要的字段放在扩展表中。主表和扩展表是一对一的关系,用主键来关联它们。1.3垂直拆分优缺点优点:解决业务系统层面的耦合,业务清晰。类似于微服务的治理,也可以对不同业务中的数据进行分层管理、维护、监控和扩展。在并发场景下,垂直切分可以在一定程度上改善IO、数据库连接、单机硬件资源等瓶颈。缺点:部分表无法join,只能通过接口聚合解决,增加了开发的复杂度。分布式事务处理很复杂。仍然存在单表数据过多的问题(需要横向切分)。2.水平拆分当应用被垂直拆分后,数据库或数据表的粒度已经被拆分到最小,但是单表的数据行数巨大,读取时存储性能仍然会很差并编写数据库。这时候就需要水平拆分。水平拆分又分为分库分表和分库分表。在进行横向分表时,需要根据表中存储的数据之间的逻辑关系进行拆分。可以根据表中的某个字段获取分数,比如userid。也可以按时间来划分,比如一个月一次。这些分表策略的最终目的是让单表中的数据变小,从而降低读写数据表的IO压力。2.1数据库中的子表数据库中的子表是指数据库中的某个表。当数据行数达到数据库读写性能瓶颈时,将数据均匀分布到数据表结构相同的数据表中,达到了减少单表数据,提高读写性能的目的的数据表。2.2分库分表分库分表只是解决了数据库中单表的压力,但是如果查询比较频繁的话,分库分表的数据库整体性能是还是很容易达到瓶颈。因为物理机的CPU、内容、网络IO都是有限的,所以需要多个库来分担单个库的IO压力。分库分表就是将原来单库的数据表划分到各个数据库中,目的是降低单库的IO性能压力,俗话说人多力量大。3.分表策略3.1splitbyrange根据ID范围进行分表。例如:将userId1~9999分配给第一库,将userId10000~19999分配给第二库,以此类推。从某种意义上说,一些系统采用的“冷热数据分离”,将一些使用较少的历史数据迁移到其他库中,只提供业务功能的热数据查询,也是一种类似的做法。优点:单表大小可控。横向扩展自然很容易。如果以后要扩展整个shard集群,只需要增加节点,不需要从其他shard迁移数据。使用分片字段进行范围搜索时,连续分片可以快速定位分片进行快速查询,有效避免跨分片查询问题。缺点:热数据成为性能瓶颈。连续分片可能会有数据热点,比如按时间字段分片。有些分片存储的是最近一段时间的数据,可能会被频繁读写,而有些分片存储的是很少被查询到的历史数据。3.2取模与分表这种分表策略在项目中被广泛使用。字段值取模分表的算法是利用某个字段的值进行取模,即key%n。如果计算数据属于哪个库,那么n就是数据库的总数。如果统计数据属于哪个表,n就是数据表的总数。Key是您需要用来获取模字段的值。这个一般可以根据你项目的业务来定义。比如key是userId,那么这个人的数据必然会落入同库。需要注意的是,必须保证这个key是一个全局唯一的id。优点:数据分片比较均匀,不易出现热点和并发访问瓶颈。缺点:后期分片集群扩容时,需要迁移旧数据(使用一致性哈希算法可以更好的避免这个问题)。很容易面对跨分片查询的复杂问题。3.3时间表按时间分为表。该表的拆分周期将作为表的后缀名。比如按月分表,表名一般会跟在这个表的年月之后。通常,时间分割的粒度是根据数据量的大小来确定的。从小数据量到大数据量的拆分粒度是小时、天、月、年。一般按照时间切分的数据一般是日志数据。这种数据一般查询一些创建时间比较近的数据,历史数据不容易查询到。优点:单表大小可控,横向扩展自然方便。如果以后要扩展整个sharding集群,只需要增加节点,不需要从其他shards迁移数据。使用分片字段进行范围搜索时,连续分片可以快速定位分片进行快速查询,有效避免跨分片查询问题。缺点:热数据成为性能瓶颈。连续分片可能会有数据热点,比如按时间字段分片。有些分片存储的是最近一段时间的数据,可能会被频繁读写,而有些分片存储的是很少被查询到的历史数据。表查询困难。以上总结了几种常用的分库分表策略,还有其他的分库分表策略,有兴趣的可以自行学习。没有最好的分库分表策略。需要根据自己的业务场景选择使用哪种分库和分表策略。现在流行的分库分表中间件有几种:shardingJDBC、mycat等,掌握一种就够了。基本原则是相同的。总结起来就是拦截SQL语句,然后根据你配置的分库分表策略重写SQL,路由到对应的数据库。4、主从复制以mysql为例。对master数据库进行数据修改操作后,数据库执行后,会在本地记录执行日志,保存在二进制文件中,也就是我们所说的bin-log。假设主从数据配置为主从关系,实时修改master的数据,主库会通过网络通过3306端口同步bin-log到从库。slave执行的不是binarylog,因为它是从master的binarylog复制过来的,并不是自己的数据库变化产生的。感觉是relaylog,这里叫relaylog,即中继日志。这就是所谓的mysql复制,即MYSQL复制。可以发现,通过上面的机制,可以保证master和slave的数据库数据是一致的,但是时间上肯定有一个延迟,也就是MYSQL-B的数据滞后。即使不考虑任何网络因素,master的数据库操作可以并发执行,但slave只能从relaylog中读取一个entry并执行。所以master的写操作很频繁,slave可能跟不上。对于主从复制,你只需要知道它的原理即可,因为主从复制的配置有点偏向于运维。有专门的运维人员会做这些,开发不需要关心。5、读写分离在数据库集群架构中,主库负责处理事务性查询,而从库只负责处理select查询,这样可以明确两者分工提高数据库的整体读写性能。当然,主库的另一个功能是负责将事务查询引起的数据变化同步到从库,即写操作。这就是数据库的读写分离。优点:分担服务器压力,提高本机系统处理效率,增加冗余,提高服务可用性。当一台数据库服务器宕机时,可以从数据库中调出另一台,以最快的速度恢复服务。**我觉得写的不错,可以一键三下。想了解更多,或者想直接获取我的后续内容。Gong#Zhong#Hao:Java干货仓库,送【亿级系统设计】。**后续文章目录大纲: