面试官又问我分库分表,这次我准备好了!

108 阅读3分钟

在开始文章之前,先对分库分表的含义做一个大概的解释。

分库: 把数据拆分到不同的mysql库中

分表: 把数据拆分到同一库的多张表里面

分片: 切分数据,片是一个基本的单元,我理解为逻辑单位。在mysql中我们可以把数据表分成数据库或数据表,在kafka中我们可以把数据切分成不同的分区。

为什么要进行分库分表?

最初的架构都是单机数据库,当数据越来越多,需要使用数据库集群,将主库的数据同步到从库,将数据库的写操作和读操作进行分离,使用多个从库副本负责读,使用主库负责写,从库可以水平扩展,解决更多的读请求。因为大部分系统都是读多写少的状态,所以使用这种方法进行读写分离。

当用户量级增多,加主库不能解决根本问题,因为要保证数据一致性,写操作在两个 之间同步,更加复杂。

可以概括为以下两种情况:

  1. 数据量太大查询慢

查询是指 事务中的查询和更新操作,只读的查询可以通过缓存和主从分离来解决,解决查询慢,可以减少每次查询的数据总量,即使用分表来解决问题查询数据过大。

  1. 高并发

一个数据库实例支撑不住高并发,把并发请求分散到多个实例。即使用分库来解决高并发。

在这种情况下,会使用分库分表来解决问题。
但是需要注意,分库分表的原则就是能不拆就不拆

有哪几种切分方法?

选择一个合适的列或属性作为分表的依据,这个属性即sharding key。选择sharding key重要的参考因素是 我们的业务如何访问数据?

垂直切分

垂直切分针对业务,分担io性能,但不能解决单表数据过大的问题。

水平切分

按照 某个字段的某个规则将数据分散到多个库,理论上突破单机数据量的瓶颈。

具体的切分策略

  1. 按范围分片,如时间范围、地域范围。对查询比较友好,适合数据量大但并发量小的系统,但数据存放不均匀,容易形成热点问题。

  2. 哈希分片算法。但扩容时需要大量数据迁移。

  3. 整体按照范围分片,范围内按照取模分片,保证扩容时数据不需要迁移,且每个范围内数据分布大致均匀。

需要根据业务场景,灵活定制分片策略。

分库分表后会出现什么问题?

  1. 事务支持

分库分表后,就成为分布式事务,如果依赖数据库本身的分布式事务管理功能去执行事务,开销较大;如果由应用程序协助控制,形成程序逻辑上的事务,代码量较大。

  1. 跨库跨表join

每个节点只包含部分结果,如何归并结果?需要跨库跨表join,导致之前一次查询能够完成的业务,分库后可能需要多次查询才能完成。

分库分表现有的较为优秀的开源产品如ShardingSphere,以后有机会写篇文章介绍介绍。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 16 天,点击查看活动详情

参考

zq99299.github.io/note-book/b…

www.bilibili.com/video/BV1vd…