1。数据库瓶颈无论是IO瓶颈还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,逼近甚至达到数据库能够承载的活跃连接数的阈值。从业务服务的角度来看,可用的数据库连接很少或没有。那你可以想象一下(并发、吞吐量、崩溃)。1.第一类IO瓶颈:磁盘读IO瓶颈,热数据太多,数据库缓存放不下,每次查询都会产生大量IO,降低查询速度->分库垂直分表。第二种:网络IO瓶颈,请求数据过多,网络带宽不足->分库。2、第一类CPU瓶颈:SQL问题,比如SQL包含join、groupby、orderby、非索引字段条件查询等,增加CPU运算->SQL优化,建立合适的索引,创建合适的索引在业务服务层做业务计算。第二种:单表数据量过大,查询时扫描行过多,SQL效率低,增加CPU运算的操作->水平分表。二、分库分表1、横向分库的概念:以字段为基础,按照一定的策略(hash、range等),将一个数据库中的数据拆分到多个数据库中。结果:每个库的结构都是一样的;每个库的数据不同,没有交集;所有库的联合就是全量数据;场景:系统绝对并发增加,分表很难从根本上解决问题,而且还是垂直分库没有明显的业务归属。分析:库多了,io和cpu的压力自然可以成倍增加。2、水平分表的概念:以字段为基础,将一张表中的数据按照一定的策略(hash、range等)拆分成多张表。结果:各表结构相同;每个表的数据不同,没有交集;所有表的并集就是全量数据;场景:系统绝对并发没有增加,但是单表数据量过大,影响SQL效率,增加CPU负担,成为瓶颈。分析:表数据量减少,单条SQL执行效率高,自然减轻了CPU的负担。3、数据库垂直划分的概念:以表为基础,根据不同的业务隶属关系,将不同的表拆分到不同的数据库中。结果:每个库的结构都不一样;每个库的数据也不一样,没有交集;所有库的联合就是全量数据;场景:系统绝对并发增加,可以抽象出单独的业务模块。分析:至此,基本可以面向服务了。比如随着业务的发展,公共配置表、字典表等越来越多,这时候可以把这些表拆分成一个单独的库,甚至可以面向服务。此外,随着业务的发展,已经孵化出了一套商业模式。这时候可以把相关的表拆成一个单独的库,甚至可以服务化。4、垂直分表的概念:以字段为基础,将表中的字段根据字段的活跃度拆分成不同的表(主表和扩展表)。结果:每个表的结构都不一样;每个表的数据也不一样。一般来说,每个表的字段至少有一个列交集,通常是主键,用来关联数据;所有表的并集是全量数据;场景:系统的绝对并发没有增加。表中记录不多,但字段多,热数据和非热数据在一起,单行数据需要的存储空间大。导致数据库缓存中的数据行减少,查询时会读取磁盘数据,导致大量随机读IO,造成IO瓶颈。分析:可以使用列表页和详情页来帮助理解。垂直分表的原理是将热点数据(可能冗余,经常一起查询的数据)放在一起作为主表,把非热点数据放在一起作为扩展表。这样可以缓存更多的热点数据,从而减少随机读IO。拆解后,如果要获取所有的数据,需要关联两个表来获取数据。但是切记,千万不要使用join,因为join不仅会增加CPU负担,还会将两个表耦合在一起(必须在一个数据库实例上)。对于关联数据,应该在业务服务层做文章,分别获取主表和扩展表的数据,然后使用关联字段将所有数据关联起来。3、分库分??表工具sharding-sphere:jar,原sharding-jdbc;TDDL:jar,淘宝分布式数据层;Mycat:中间件。注:该工具的优缺点请自行研究,官网和社区优先。4、分库分表的步骤根据容量(当前容量和增长)评估分库或分表的数量->选择key(uniform)->分表规则(hash或range等).)->执行(一般是双写)->扩展问题(最小化数据移动)。五、分库分表问题1.非分区键查询问题(水平分库分表,拆分策略是常??用的hash方法)。除了partitionkey,最后只有一个non-partitionkey作为conditionalquerymappingmethodGene方法注:写的时候,genetic方法生成user_id,如图。关于xbit基因,比如有8个表,23=8,所以x取3,即3bit基因。基于user_id查询时,可以直接取模块,路由到对应的分库或分表。基于user_name查询时,首先通过user_name_code生成函数生成user_name_code,然后建模路由到对应的分库或分表。id生成常用的雪花算法。除了终端上的partitionkey之外,使用多个非partitionkey作为条件查询的映射方法冗余方法注:根据order_id或buyer_id查询时,路由到db_o_buyer数据库,查询时根据seller_id,它被路由到db_o_seller数据库。有点颠倒的感觉!还有什么好的方法吗?改变技术堆栈怎么样?后台除了partitionkey还有各种非partitionkey组合条件查询NoSQL方法冗余方法2.非partitionkey跨库跨表分页查询问题(横库分表,拆分策略为常用的hash方法)注:使用NoSQL方案(ES等)。3.扩容问题(横向分库分表,拆分策略是常??用的hash方式)数据库横向扩容(升级自数据库方式)注:扩容成倍。横向扩展表(双写迁移方式)Step1:(同步双写)应用配置双写、部署;第二步:(同步双写)将旧数据库中的旧数据复制到新数据库中;第三步第一步:(同步双写)在旧数据库的基础上校对新数据库中的旧数据;第四步:(同步双写)申请解除双写部署;注意:双写是一种通用的解决方案。6.分库分表总结分库分表,首先要知道瓶颈在哪里,然后才能合理拆分(分库还是分表?水平还是垂直?怎么分?许多?)。分库分表不能拆分。选择key很重要,不仅要考虑偶数拆分,还要考虑非分区键查询。只要能满足要求,拆分规则越简单越好。7、分库分表示例GitHub地址:https://github.com/lc-study/study-sharding.git
