为什么要分库分表?你用过哪些分库分表的中间件?
不同的分库分表中间件有什么优缺点?
你们具体是如何对数据库如何进行垂直拆分或者水平拆分的?
在系统承受高并发压力的情况下,数据库中数据量巨大,磁盘读写效率降低。为了降低数据库的压力,我们采用分库分表的设计,
分表:
单表都几千万数据量量,数据量太大,会影响sql执行的性能。将一个表中的数据拆分成多个相同的表。
分库:
拆分为多个库,承受并发增加了多倍
分库分表的中间件:
Sharing-jdbc属于client层技术方案,不用单独部署,性能高,不需要二次转发。每个系统模块都要耦合sharding-jdbc的依赖
mycat属于proxy层方案,需要单独部署,升级方便,只需部署中间件就ok
垂直拆分:
将一个表的字段拆分成多个表,每个表拥有之前一张大表的不同字段,用外键进行关联,将经常查询的字段喝不经常查询的字段分成两张表,
水平拆分的意义就是方便扩容,降低并发压力。
水平拆分:
将一张表横向切割,比如一张拥有100万数据的表,分成三张,每张表拥有的字段是相同的,只是将数据量分开。一张表可能只拥有原表的1/3。
分库分表的两种方式:
range:按照时间范围来分配,比如某一个时间段来决定插入哪个数据库中。容易产生热点问题,可能大的访问量全部都打在了最新更新的数据上。
hash:通过hash算法,将某个字段的值进行hash均匀的分散。平均分配数据库和压力,扩容麻烦,涉及到数据迁移问题。之前的数据需要重新计算 hash 值重新分配到不同的库或表。
如何不停机进行分库分表迁移?
停机分库分表数据迁移
老的做法是在系统访问时间最低峰的时候将系统停机,后台开启多个进程,读取老的数据库中的数据,将老数据库中的数据写入分库分表中间件,让中间件写入新的分库分表的数据库中,然后将老系统代码更改不再写入老的数据库,将后面的数据全部写入消息中间件中,插入数据到分库分表中。
缺点:停机,访客无法访问网站,一旦出现问题无法解决就需要回滚老的系统版本,消耗人力。可能造成损失
不停机分库分表方案:
双写方案,
就是将线上代码改为老库和新库都写到方案,同时写两个库,系统部署后再开启数据迁移进程将老库中的数据读取写入新的库中,读取插入的时候如果出现唯一id一样的数据,就比较数据库中的时间戳,根据时间戳的时间对比哪个是新数据哪个是老数据,只允许新数据覆盖老数据,
一轮数据迁移之后可能出现数据不一致的情况,程序自动做校验检查,再次读写,直到数据一致为止。
然后将线上系统代码改为只对新库做操作。
|
|