不用找了,大厂在用的分库分表方案,都在这了

  • 日期:07-26
  • 点击:(886)


作者:嘎嘎人

原文:

首先,数据库瓶颈

无论是IO瓶颈还是CPU瓶颈,它最终都会导致数据库的活动连接数量增加,从而接近甚至达到数据库可以托管活动连接的阈值。在业务服务视图中,可用的数据库连接较少或没有可用的连接。下一步是想象(并发,吞吐量,崩溃)。

1. IO瓶颈

第一种类型:磁盘读取IO瓶颈,热点数据过多,无法放置数据库缓存,每次查询都会生成大量IO,降低查询速度 - >子库和垂直子表。

第二种:网络IO瓶颈,请求的数据太多,网络带宽不足 - >子库。

2,CPU瓶颈

第一种类型:SQL问题,如SQL包含join,group by,order parts查询等,增加CPU操作的操作 - > SQL优化,在业务服务层建立合适的索引,业务计算。

第二种类型:单个表中的数据量太大,查询期间扫描的行数太多,SQL效率低,而CPU是第一个瓶颈 - >水平表。

二,子库表

1.水平子库

58e36578b5c8466d997a14408bbed7fb

1.概念:基于该领域,根据某种策略(散列,范围等),将一个库中的数据分成多个库。 2.结果:

每个图书馆的结构都是一样的;每个图书馆的数据不同,没有交集;所有库的联合是完整的数据量;

3.场景:系统具有绝对的并发量。从根本上解决问题很困难,并且没有明显的业务归属来垂直分配库。 4.分析:图书馆更多,io和cpu的压力自然可以缓解。

2.水平子表

80e996187b4a4dd3af385bb6ed61b070

1.概念:基于该领域,根据某种策略(散列,范围等),将一个表中的数据分成多个表。 2.结果:

每个表的结构是相同的。每个表的数据不同,没有交集;所有表的并集是完整的数据量;

3.场景:系统的绝对并发性没有出现,但是单个表中的数据量太多,这会影响SQL的效率并增?覥PU负担,这是一个瓶颈。 4.分析:表中的数据量很小,单个SQL执行的效率很高,这自然减轻了CPU的负担。

3,垂直子库

cd63c4b7e794492aaf9ef8836f4289b5

1.概念:基于表,根据不同的业务属性将不同的表分成不同的库。 2.结果:

每个图书馆的结构不同;每个图书馆的数据不同,没有交集;所有库的并集是完整数据;

3.场景:系统具有绝对的并发量,可以抽象出各个业务模块。 4.分析:此时,您基本可以服务。例如,随着业务的发展,有越来越多的常见配置表,字典表等,这些表可以拆分成单独的库甚至服务。此外,随着业务的发展,已经孵化了一组业务模型,并且可以将相关表分解为单独的库,甚至可以提供服务。

4,垂直子表

490ef4f6eaf54b16a3a9cb59bf6556e9

1. Concept: Based on the field, according to the activity of the field, the fields in the table are split into different tables (primary and extended). 2. Results:

The structure of each table is different; the data of each table is different. Generally speaking, the fields of each table have at least one column intersection, generally the primary key, used to associate data; the union of all the tables is the full amount of data;

3. Scenario: The absolute concurrency of the system does not come up. There are not many records in the table, but there are many fields, and the hot data and non-hot data are together. The storage space required for single-line data is large. As a result, the data cache of the database cache is reduced, and the disk data is read during the query to generate a large amount of random read IO, which causes an IO bottleneck.

4. Analysis: You can use the list page and the details page to help understand. The principle of splitting vertical partitions is to put together hotspot data (data that may be frequently queried frequently together) as a primary table, and non-hotspot data together as an extended table. This way more hot data can be cached, which reduces random read IO. After the disassembly, in order to get all the data, you need to associate two tables to fetch the data. But remember, don't use joins, because join not only increases the CPU load but also couples the two tables together (must be on a database instance). To associate data, you should make a fuss in the business service layer, obtain the main table and extended table data respectively, and then use the associated field to get all the data.

Third, the sub-library table tool

Sharding-sphere:jar, formerly sharding-jdbc; TDDL:jar, Taobao Distribute Data Layer; Mycat: middleware.

Note: The pros and cons of the tool, please research on your own, the official website and community priority.

Fourth, the sub-database sub-table steps

xx根据容量(当前容量和增长)评估子库或子表的数量 - >选择键(偶数) - >子表规则(散列或范围等) - >执行(一般双写) - >扩展问题(最小化数据移动)。

五,子库表问题

1,非分区键查询问题(水平子库表,常用哈希方法的拆分策略)

除了分区键之外,只有一个非分区部分查询映射方法

f34b8912fe814a54b643af7be380bac6

遗传方法

960e4fabb10d42bf81adaf6c81f6aaef

注意:写入时,gene方法会生成userid,如图所示。关于xbit基因,例如,有必要划分8个表,23=8,因此x取3,即3位基因。根据userid查询,可以直接调整到相应子库或子表的路由。根据用户名查询,首先通过用户名代码生成函数生成username_code,然后将其调制到相应的子库或子表。 Id生成常见的雪花算法。

除了分区键之外,还有多个非分区部分查询映射方法

40450a42f3534e9fab01dd9a6475e950

冗余方法

2af1306afc844fb78a254a2a108bf823

注意:根据orderid或buyerid进行路由时,它会路由到dbobuyer库,并根据sellerid查询路由到dbo_seller库。感觉有点颠倒!还有其他好方法吗?改变技术堆栈?

除了分区键之外,还有各种非分区部件来查询NoSQL方法。

6f36a7c860544442838a8bda73a272ff

冗余方法

f79c9c5ab88c4a4f8ebc1a62d8b61c20

2,非分区密钥跨数据库跨表分页查询问题(水平子库子表,常用哈希方法的分割策略)

注意:使用NoSQL方法解决(ES等)。

3,扩展问题(水平子库表,常用哈希方法的拆分策略)

1.水平扩展库(从库方法升级)

93cb6407051a4feb85e7eb5eea0f9ff9

注意:容量扩展加倍。

2.水平扩展表(双写迁移方法)

697eb035ffe94f109a484122ff260ce3

第一步:(同步双写)应用程序配置双写,部署;第二步:(同步双写)将旧库中的旧数据复制到新库中;第三步:(同步双写)到旧库中纠正新库中的旧数据;第四步:(同步双写)应用程序删除双写,部署;

注意:双重写作是一种通用解决方案。

6.子库表总结

首先,子库表必须知道瓶颈在哪里,然后可以合理地分割(子库或子表?水平或垂直?几个?)。它不能拆分为子数据库子表。考虑到统一拆分,以及非分区键的查询,选择密钥非常重要。只要满足要求,分割规则就越简单。

七,子库表示实例

示例GitHub地址: