分库分表学习1
2023-08-24 01:15:13 0 举报
AI智能生成
这是一篇分库分表的学习。这是一篇分库分表的学习。这是一篇分库分表的学习。这是一篇分库分表的学习。这是一篇分库分表的学习。
作者其他创作
大纲/内容
https://mp.weixin.qq.com/s/J_zVlrR9cDX9Vrg6YVjUiA
参考自
水平分表:将表数据按记录分到多个表(涉及分片策略)
垂直分表:将表数据按字段分到多个表
怎么分
都有同库分表、既分库又分表
假设每张分表能放2kw行数据。那user0就放主键id为1~2kw的数据。user1就放id为2kw+1 ~ 4kw,user2就放id为4kw+1 ~ 6kw, userN就放 2N kw+1 ~ 2(N+1)kw
假设现在有条数据,id=3kw,将这个3kw除2kw = 1.5,向下取整得到1,那就可以得到这条数据属于user1表。于是去读写user1表就行了。这就完成了数据的路由逻辑,我们把这部分逻辑封装起来,放在数据库和业务代码之间。
是什么
数据少的时候 表也少,数据增多的时候表会慢慢增多
支持无限扩展
优点
根据id范围去做分表,因为id是递增的,那新写入的数据一般都会落到某一张表上,如果你的业务场景写数据特别频繁,那这张表就会出现写热点的问题
缺点
id范围分表
一个id=31进来,我们一共分了5张表,分别是user0到user4。对31%5=1,取模得1,于是就能知道应该读写user1表
新写入的数据都是实实在在的分散到了多张表上
如果想要扩展表的个数,比如从5张表变成8张表。那同样还是id=31的数据,31%8 = 7,就需要读写user7这张表。跟原来就对不上了。这就需要考虑数据迁移的问题
id取模
id范围+id取模
分表策略
第三方orm库,放在客户端侧(需要根据不同的语言实现不同的代码库,常用组件有sharding-jdbc)
在mysql和业务代码之间加个proxy服务(不需要关心上游服务用的是什么语言,常用组件有MyCat)
路由策略
上面分表策略用了id这一列作为分表的依据,这其实就是所谓的分片键。实际上我们一般也是用的数据库主键作为分片键。但很多情况下,我们的查询又不是只查主键,如果我的数据库表有一列name,并且加了个普通索引。由于name并不是分片键,我们没法定位到具体要到哪个分表上去执行sql。于是就会对所有分表都执行上面的sql,当然不会是串行执行sql,一般都是并发执行sql的。如果我有100张表,就执行100次sql。如果我有200张表,就执行200次sql。随着我的表越来越多,次数会越来越多,这就是所谓的读扩散问题。
背景
主键是分片键,而普通索引列并不分片
问题核心
单独建个新的分片表(这个新表里的列就只有旧表的主键id和普通索引列,而这次换普通索引列来做分片键。)
例子:为name列建个新表(nameX),以name为新的分片键
需要维护两套表,并且普通索引列更新时,要两张表同时进行更改。有一定的开发量。
怎么解决
上面的方案,则通过引入一个新表,倒过来,先用name查到对应的id,再拿id去获取具体的数据。这其实就像是建立了一个新的索引一样,像这种,通过name列反查原数据的思想,其实就很类似于倒排索引
分析
使用es,es天然分片,而且内部利用倒排索引的形式来加速数据查询
ES+MySQL。通过开源工具 canal 监听mysql的binlog日志变更,再将数据解析后写入es
方案
更优解
这是个分布式数据库。它通过引入Range的概念进行数据表分片,比如第一个分片表的id在0~2kw,第二个分片表的id在2kw~4kw。这是根据id范围进行数据库分表。它支持普通索引,并且普通索引也是分片的,这是不是又跟上面提到的倒排索引方案很类似。
使用tidb
更更优解
读扩散问题
1 mysql在单表数据过大时,查询性能会变差,因此当数据量变得巨大时,需要考虑水平分表
2 水平分表需要选定一个分片键,一般选择主键,然后根据id进行取模,或者根据id的范围进行分表
3 mysql水平分表后,对于非分片键字段的查询会有读扩散的问题,可以用普通索引列作分片键建一个新表,先查新表拿到id后再回到原表再查一次原表。这本质上是借鉴了倒排索引的思路
4 如果想要支持更多维度的查询,可以监听mysql的binlog,将数据写入到es,提供近实时的查询能力
5 用tidb替换mysql也是个思路
总结
分库分表学习1
0 条评论
下一页