面试官:聊聊你对分库分表的理解?

在 MySQL 集群架构中有两种主流的集群实现,一种是读写分离,而另外一种则是数据分片。所谓的数据分片其实就是今天要聊的分库分表技术。

分库分表技术不但是日常工作中用于解决数据库中的数据量会急剧增长,解决单库单表性能瓶颈的一种方案,更是面试中的高频知识点。

阿里巴巴的《Java 开发手册》中规定:当单表的数据超过 500 万,或单表的大小超过 2GB 时,就要考虑分库分表了。那么什么是分库分表呢?

1.分库分表

首先来说,“分库分表”不是一个技术,而是两个技术实现,它分为:

  1. 分库
    1. 垂直分库
    2. 水平分库
  2. 分表
    1. 垂直分表
    2. 水平分表

1.1 垂直分库

垂直分库是按照业务将不同的表拆分到不同的数据库中。例如,在一个电商数据库中的用户表和订单表分别存放到不同的数据库中,如下图所示:

alt

1.2 水平分库

水平分库是将数据按照一定的规则(如用户 ID 取模、哈希等)分布到不同的数据库中。比如,根据用户 ID 对 10 取模,将用户数据分布到 10 个不同的数据库中,每个数据库都保存着完整的数据表结构,如下图所示:

alt

1.3 垂直分表

垂直分表是将一张表按照列的相关性拆分成多张表。例如,将一个包含大量字段的用户表,拆分为用户基本信息表和用户扩展信息表,如下图所示:

alt

1.4 水平分表

水平分表是将一张表的数据按照行进行拆分。例如按照用户 ID 的范围或者哈希值将数据拆分到不同的表中。

alt

如果搞不清楚什么是垂直分表和什么是水平分表?可以参考一下这幅图思考一下:

alt

2.技术实现

分库分表的主流实现技术有以下两种:

  1. MyCat
  2. Apache Sharding Sphere

Sharding Sphere 相比于 MyCat 来说,它的优势是:

  1. 功能更多:除了读写分离和分库分表之外,还提供了数据加密、流量质量、数据迁移等功能。
  2. 社区更活跃度和生态更好:Sharding Sphere 拥有活跃的社区和丰富的文档,生态系统较为完善,有更多的用户和开发者参与。
  3. 灵活性和扩展性:Sharding Sphere 灵活性更高,扩展性也更好,它可以方便地与其他技术集成,这方便 MyCat 支持的比较有限。

3.Sharding Sphere

Sharding Sphere 最早是当当网的内部框架,后面捐献给了 Apache,目前也是分库分表的主流技术实现方案,在 Sharding Sphere 中有两种分库分表的技术实现:

  1. Sharding Sphere JDBC:定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。

alt

  1. Sharding Sphere Proxy:定位为透明化的数据库代理端,通过实现数据库二进制协议,对异构语言提供支持。 目前提供 MySQL 和 PostgreSQL 协议,透明化数据库操作,对 DBA 更加友好。

alt

它们的区别如下:

ShardingSphere-JDBCShardingSphere-Proxy
支持数据库 任意 MySQL/PostgreSQL
连接消耗数
支持语言 仅 Java 任意
性能 损耗低 损耗略高
无中心化

课后思考

Sharding Sphere JDBC 和 Sharding Sphere Proxy 使用场景分别是啥?ShardingSphere-JDBC 具体实现步骤有哪些?说说它的实现原理?

#java#
Java面试精讲 文章被收录于专栏

Java常见面试题、场景题、企业真题精讲。

全部评论

相关推荐

问题1:为什么会使用分库分表,到达了什么样的数据级别才会去加设计,是否对数据量有一个统计我的理解:看星哥之前写过 单表行数超 500 万行或者单表容量超过 2GB,推荐分库分表,但是面试的过程中怕被问自己写的项目会有这么大的数据量吗不要这么硬背,具体情况具体分析,有的表字段少,经常是条件等值查询,这样加个索引,一个亿也不用分表,有的字段多,还是范围查询,可能5000万就得分表,面试官问你你说是自己在学习分库分表应用到项目中,自己造了几千万的数据量问题2:基因法需要分表的一个数量和确定的一个东西(我的理解是分表的依据,例如大麦中是订单编号和用户id),但是正常的生产环境中是可能动态改变的,比如说需要动态扩容的话,怎么解决呢(例如当前有4个分表,但是现在需要扩充到8个分表),是使用双写吗?这个在扩容前就要考虑好能维持多少年内不需要再扩容。转转架构师在分库分表前,通过之前记录的数据增长量,做了256张表,能在7年内不需要再扩容,如果需要扩容的话,可以使用双写,新扩容表写的过程中,用新的分库分表算法问题3:如果在防止超卖的过程中,Redis不可用了,怎么解决我的理解:使用Redis集群和主从复制吗?因为Redis宕机的话数据库的数据也不能保证是最新的版本,所以得尽量保证Redis不宕机?肯定要使用redis集群模式,但可能会有主从延迟,导致从节点数据不是最新的,但关系不大。可以在用户生成订单后,修改数据库的座位和库存,然后用户支付后,再改数据库的座位和库存,每一步都做好验证。这样从节点的数据问题会降到最低。问题4:如果在当前的幂等验证逻辑中,有一个消息所对应的幂等标识符是不存在的,按照现有的逻辑是可以执行的,但是幂等验证之后的业务系统异常了,这个时候应该怎么处理呢(即通过了幂等的验证,但是后面的服务down掉了,比如说下游抛了一个异常出来)【没太明白应该回答什么,是指需要将幂等标识符重新进行设置吗】异常了就异常了呗,把这个请求的标识从redis中删除了,就像分布式锁时,业务异常也要执行解锁一样,让下一个请求进来正常执行,然后设置好标识位问题5:本地缓存为什么使用Caffine呢,为啥不用Guava因为caffine的性能要远高于Guava,没有其他复杂原因我的理解:查了下Caffine就是Guava改进而来的,可以这么说吗- Caffine在读写操作方面的性能更高,是基于异步的操作,将淘汰过期操作与读写进行分离- Caffine采用了一种结合 LRU、LFU的算法W-TinyLFU+,具有高命中率,低内存占用的特点
查看5道真题和解析
点赞 评论 收藏
分享
05-13 16:14
厦门大学 Java
查看12道真题和解析
点赞 评论 收藏
分享
评论
1
14
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务