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