发布时间:2023-06-05
浏览次数:0
往期热门文章:
3、爽啊!Intellij IDEA 神器居然还藏着这些实用小技巧 !
来源:https://juejin.im/post/6844903992909103117
数据库困境
不管是IO困境还是CPU困境,数据库的活跃连接数最终都会减少,接近甚至达到数据库能够承载的活跃连接数的阈值。 从商业的角度来看,
即,可用的数据库连接很少或没有,连接时可想而知(并发、吞吐量、崩溃)。
IO困境,CPU困境,横向分库
3、场景:系统绝对并发增加,分表不能从根本上解决问题,垂直分库没有明显的业务归属。
4.分析:库多了,io和cpu的压力自然可以成倍降低
水平表
3、场景:系统的绝对并发没有增加,但是单表数据量过大,影响了SQL效率,增加了CPU负担,从而成为进退两难的局面。 可以考虑水平分表。
4、分析:单表数据量减少,单条SQL执行效率高,自然减轻CPU负担。
垂直分库
3、场景:系统的绝对并发增加,可以可视化一个单独的业务模块。
4、分析:至此,基本可以面向服务了。 比如:随着业务的发展,公共配置表、字典表等越来越多,这时候可以把这类表拆分成一个单独的库,甚至可以面向服务。 此外,随着业务的发展,也孵化出了一套商业模式。 这时候可以把相关的表拆成一个单独的库,甚至可以服务化。
垂直表
3.场景:系统绝对并发没有增加,表中记录不多,数组多,热数据和非热数据在一起,单行需要的存储空间数据大,使得数据库中缓存的数据行减少,查询时,回家读取c盘的数据形成大量的随机读IO,形成IO困境。
4.分析:可以用列表页和详情页帮助理解。 垂直分表的分表原则是将热点数据(可能被频繁查询的数据)放在一起作为主表,将非热点数据放在一起作为扩展表,这样可以缓存更多的热点数据,从而减少随机读IO。 拆解之后,如果要获取所有的数据,需要关联两个表来获取数据。
但是切记不要使用join,因为Join会减少CPU负担但是会将两个表耦合在一起(必须在一个数据库实例上)。 关联数据要在层进行,分别获取主表和扩展表的数据,然后使用关联数组将所有数据关联起来。
分库分表工具分库分表引起的问题
分库分表可以有效缓解单机单表带来的性能困境和压力,突破网络IO、硬件资源、连接数的困境。 同时,也带来了一些问题。 下面将描述此类问题和解决方法。
事务一致性问题
分布式事务
当更新内容同时存在于不同库中时intellij idea 数据库关系图,必然会造成跨库事务问题。 跨分片交易也是分布式交易,没有简单的解决方案。 通常可以使用“XA契约”和“两阶段提交”进行处理。
分布式事务可以最大化数据库操作的原子性。 但是,提交事务时需要多个节点协调,延误了提交事务的时间点,延长了事务的执行时间,增加了事务访问共享资源时发生冲突或死锁的概率。 随着数据库节点的增加,这些趋势会越来越严重,从而成为系统在数据库层面水平扩展的桎梏。
最终一致性
对于性能要求高但一致性要求低的系统,系统的实时一致性往往不是很关键,只要在允许的时间段内达到最终一致性即可,可以采用事务补偿的方式。 不同于事务执行过程中发生错误时立即回滚的形式,事务补偿是一种事后检测和修复的措施。 一些常见的实现方式包括:数据的对账检测、基于日志的比对、定期与标准数据源同步比对等。
跨节点关联查询加入问题
拆分前,系统中很多列表、明细表的数据可以通过join完成,拆分后,数据可能分布在不同的节点上。 这时候join带来的问题就比较麻烦了。 考虑到性能,尽量避免使用 Join 查询。 一些技巧来解决:
全局表
全局表,也可以看作是“数据字典表”,是系统中所有模块都可能依赖的一些表。 为了防止 join查询,可以在每个数据库中保存一份这样的表。 这种数据一般很少改动,不用怕一致性问题。
阵列冗余
典型的反范式设计使用空间换取时间并避免连接查询以提高性能。 比如保存订单表的时候,也会保存一份冗余的副本,这样就可以通过顺表查询订单明细找到用户名,而不用去查询卖家的用户表。 但是这些技术适用的场景也比较有限,比较适合依赖数组比较少,冗余数组的一致性很难保证的情况。
数据组装
在系统业务层面,查询分为两次。 第一次查询的结果集找到关联数据id,然后第二次根据id发起者请求关联数据,最后将得到的结果组装成一个数组。 这是一种比较常用的技术。
ER碎片
在关系型数据库中,如果表之间的关系(比如订单表和订单明细表)已经确定,并且这些相关的表记录存储在同一个分片上,这样可以更好的避免跨分片的分片问题joinintellij idea 数据库关系图,join可以在一个slice内进行。 在1:1或者1:n的情况下,一般会根据主表的ID进行字段切分。
跨节点分页、排序、功能问题
跨节点、多数据库查询时,会出现limit分页、排序等问题。 分页需要按照指定的数组进行排序。 当排序后的数组作为分页的主键时,更容易通过分片规则定位到指定的分片; 当排序数组不是分片数组时,它更复杂。
需要先对不同分片节点上的数据进行排序返回,然后对不同分片返回的结果集进行汇总重新排序,最后返回给用户如右图所示:
上图只取了首页的数据,对性能影响不是太大。 而如果获取的page数量很大,情况就复杂很多,因为每个shard节点的数据可能是随机的。 为了排序的准确性,需要对所有节点的前N页的数据进行排序合并,最后再进行整体排序。 这样的操作会消耗大量的CPU和显存资源,所以页数越大,系统性能就越差。
在使用Max、Min、Sum、Count等函数进行估算时,也需要先在每个分片上执行相应的函数,然后再汇总每个分片的结果集进行重新估算。
全局场回避问题
在分库分表环境下,由于表中的数据同时存在于不同的数据库中,通常使用的自减字段值将无用,难以保证全局唯一性分区数据库的自生成 ID。 所以需要单独设计全局字段,防止跨库字段重复。 以下是一些策略:
UUID
UUID标准方法为32个16位补码,分为5段,方法为8-4-4-4-12的36个字符。
UUID 是最简单的解决方案。 本地生成,性能高,无网络时长。 但是,它也有明显的缺点,占用大量的存储空间。 此外,将索引构建为字段并根据索引进行查询也存在性能问题,尤其是在引擎下。 顺序性会导致索引位置频繁变化,造成分页。
结合数据库维护字段ID表
在数据库中建表:
CREATE TABLE `sequence` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`stub` char(1) NOT NULL default '',
PRIMARY KEY (`id`),
UNIQUE KEY `stub` (`stub`)
) ENGINE=MyISAM;存根数组设置为唯一索引,同一个存根值在表中只有一条记录,可以同时作为多个表的全局ID。 通过改用引擎实现了更高的性能。 使用了表锁,表的读写是串行的,在并发时不用害怕读取同一个ID两次。 当需要全局唯一标识时,执行:
REPLACE INTO sequence (stub) VALUES ('a');
SELECT 1561439;这种方案比较简单,但是缺点比较显着:存在单点问题,对DB的依赖性强。 当DB异常时,整个系统不可用。 配置主从会降低可用性。 另外,性能困境仅限于单个Mysql的读写性能。
还有一种字段生成策略,类似表方案,更好的解决了单点和性能困境的问题。 本方案的总体思路是:搭建2台以上的服务器进行全局ID的生成,每台服务器上只部署一个数据库,每个数据库都有一张表用于记录当前的全局ID。
表中递减步长为库数,起始值依次错开,这样ID生成可以hash到每个库
这些方案在两台机器上平均分配ID生成的压力,并提供系统容错。 如果第一台机器出现错误,可以手动切换到第二台机器获取ID。 但是也有几个缺点:系统增加机器,横向扩展比较复杂; 每获取一个ID,都要读取一次DB,对DB的压力还是很大的,只能通过堆机来提升性能。
分布式自增ID算法
该算法解决分布式系统生成全局ID的需求,生成64位Long数。 这些组件是:
数据迁移和扩容问题
当业务快速发展,面临性能和存储困难时,就会考虑分片设计。 这时候就不可避免地要考虑历史数据的迁移。 通常的做法是先读取历史数据,然后按照指定的分片规则将数据写入各个分片节点。 据悉,还需要根据当前数据量、QPS、业务发展速度进行容量规划,预估大概需要的分片数量(一般建议单表数据量在一个单个分片不超过1000W)。
什么时候考虑分库分表
不是所有的表都需要分片,主要看数据缩减的速度。 分割在一定程度上增加了业务的复杂性。 除非万不得已,不要使用分库分表的“大招”,杜绝“过度设计”和“过早优化”。 分库分表前尽量优化:升级硬件、升级网络、读写分离、索引优化等。当数据量达到单表困境时,考虑分库分表。
这里的运维是指:数据库备份,如果单表太大,备份需要大量的c盘IO和网络IO。 在对大表做DDL时,MYSQL会锁住整张表,时间会很长,而且这段时间业务不能访问这张表,影响很大。
大表被频繁访问和更新,更容易出现锁等待。
这里我就不举例了。 实际业务中可能会遇到,一些不经常访问或不经常更新的数组要从大表中分离出来。
随着业务的快速发展,单表的数据量会不断减少。 当性能接近困境时,就要考虑水平切分,做分库分表。
往期热门文章:
1、《历史文章分类导读列表!精选优秀博文都在这里了!》
2、万亿级数据应该怎么迁移? 3、从应用到底层 36张图带你进入Redis世界 4、写代码有这16个好习惯,可以减少80%非业务的bug 5、顺丰快递:请签收MySQL灵魂十连
6、一个基于SpringBoot + MyBatis + Vue的代码生成器 7、Redis 分布式锁使用不当,超卖了100瓶飞天茅台!!! 8、如何设计订单系统?这篇写得太好了! 9、如果MySQL磁盘满了,会发生什么?还真被我遇到了! 10、阿里开源的27个项目,值得收藏! 如有侵权请联系删除!
Copyright © 2023 江苏优软数字科技有限公司 All Rights Reserved.正版sublime text、Codejock、IntelliJ IDEA、sketch、Mestrenova、DNAstar服务提供商
13262879759
微信二维码