大厂计划 | MySQL 高频面试题04:主从复制、读写分离与分库分表

目录

谈谈你对主从(从服务器=备库,二者概念一样)复制的了解?

主备延迟、主备同步延迟是什么?怎么产生的?如何解决?

谈谈你对读写分离的了解?

谈谈你对分库分表中的分表切分的了解?

分库分表后的 ID 是怎么生成的?


 

谈谈你对主从(从服务器=备库,二者概念一样)复制的了解?


MySQL 的主从复制,就是将 MySQL 主数据库上的数据复制到从数据库中去。

主从复制的目的是为了实现数据库的读写分离:写操作和实时性较强的读操作则访问主数据库;读操作则访问从数据库。从而使数据库具有更强大的访问负载能力,支撑更多的用户访问。

它的原理是:当应用程序客户端发送一条更新命令到数据库的时候,数据库会把这条更新命令通过 Binlog 线程同步记录到 Binlog 中,然后通过网络通信的方式将它发送到从服务器,从服务器将其写到自己的中转日志 Relay log 中,然后由从服务器的 SQL 执行线程从 Relay log 中读取这条新的日志,并把它重新执行一遍。

这样当客户端应用程序执行一个update命令的时候,这个命令会在主数据库和从数据库上同步执行,从而实现了主数据库向从数据库的复制,让从数据库和主数据库保持一样的数据。

主从复制主要涉及三个线程:

  • 主服务器的 binlog 线程 :在主服务器中,负责将主服务器上的数据更改写入到 binlog 日志文件中。

  • 从服务器的 I/O 线程 :在从服务器中,负责从主服务器上读取 binlog 日志 ,并写入从服务器的 Relay log 中转日志中。

  • 从服务器的 SQL 线程 :在从服务器中,负责读取中转日志,解析出主服务器已经执行的数据更改并在从服务器中重放执行。

主备延迟、主备同步延迟是什么?怎么产生的?如何解决?


是什么

所谓主备延迟,就是同一个事务,在备库执行完成的时间和主库执行完成的时间之间的差值。

怎么产生的

主备延迟最直接的表现是,备库消费中转日志(relay log)的速度,比主库生产 binlog 的速度要慢。造成的原因可能有:

  1. 备库所在机器的性能要比主库所在的机器性能差。

  1. 备库的压力太大:由于主库直接影响业务,大家使用起来可能会比较克制,但却忽视了备库的压力控制。结果备库上的查询耗费了大量的 CPU 资源,影响了同步速度,造成主备延迟。

  1. 主库上执行了大事务。如:一次性地用 delete 语句删除太多的数据,就会造成大事务,应该分批的删除,不能一次性删除;再者可能就是使用了在大表的 DDL(修改表结构) 导致了大事务。

如何解决

实际上主备延迟、主备同步延迟根本没有什么一招制敌的办法, 因为所有的 SQL 都必须要在备库里面再执行一遍,但是主库如果不断的有更新操作写入,那么一旦有延迟产生,那么延迟加重的可能性就会原来越大。当然,我们还是可以做一些缓解的措施。

  1. 因为主库主要负责更新操作,它对安全性的要求比备库高,所以应将 sync_binlog,innodb_flush_log_at_trx_commit 设为双1模式;但备库则不太需要这么高的数据安全,可以暂时地将备库的 sync_binlog 和 innodb_flush_log_at_trx_commit 设置为非双1模式来提高 SQL 的执行效率。当然,当备库赶上来后还是得将其设置回双1模式的,保证安全性。

  1. 另一个解决措施就是增加从服务器,这个目的还是分散读的压力, 从而降低服务器负载。

sync_binlog

sync_binlog = 1;表示每次事务提交后写到 binlog 日志文件到文件系统后就立即持久化到磁盘。磁盘 I/O 次数多,效率不高,但是安全,异常重启后可保证最多只有1个事务的数据丢失。

sync_binlog = 0;表示直到 binlog 日志文件在文件系统中写满后才持久化到磁盘。磁盘 I/O 次数少,效率高,但是不安全,如果异常重启,将会丢失多个事务的数据。

innodb_flush_log_at_trx_commit

innodb_flush_log_at_trx_commit = 1; 表示每次 redo log 从 redo log buffer 写到文件系统中,然后处于 prepare 阶段后就立即持久化到磁盘,而不会等到 commit 阶段经由每秒轮询刷到磁盘。磁盘 I/O 次数多,效率不高,但是安全。

innodb_flush_log_at_trx_commit = 2;表示每次 redo log 从 redo log buffer 写到文件系统中,然后处于 prepare 阶段后不会触发持久化磁盘的操作,而是到 commit 阶段经由每秒轮询刷到磁盘。磁盘 I/O 次数少,效率高,但是不安全,由于 redo log prepare 阶段后少了一次刷盘,异常重启后就算 binlog 写到磁盘了,那也无法恢复 redo log prepare 阶段之前 redo log 的数据,进而无法崩溃恢复。

谈谈你对读写分离的了解?


读写分离是指主服务器处理写操作以及实时性较高的读操作;而从服务器处理读操作。从而使数据库具有更强大的访问负载能力,支撑更多的用户访问。

读写分离依赖于从主复制。

读写分离能提高性能的原因在于:

  • 主从服务器负责各自的读和写,极大程度缓解了锁的争用;
  • 从服务器可以使用 MyISAM,提升查询性能以及节约系统开销;
  • 增加冗余,提高可用性。

读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。

谈谈你对分库分表中的分表切分的了解?


水平切分

水平切分又称为 Sharding,它是将同一个表中的记录拆分到多个结构相同的表中。

当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。

垂直切分

垂直切分是将一张表按列切分成多个表,通常是按照列的关系密集程度进行切分,也可以利用垂直切分将经常被使用的列和不经常被使用的列切分到不同的表中。

在数据库的层面使用垂直切分将按数据库中表的密集程度部署到不同的库中,例如将原来的电商数据库垂直切分成商品数据库、用户数据库等。

Sharding 策略

  • 哈希取模:hash(key) % N;
  • 范围:可以是 ID 范围也可以是时间范围;
  • 映射表:使用单独的一个数据库来存储映射关系。

Sharding 存在的问题

  1. 事务问题

使用分布式事务来解决,比如 XA 接口。

  1. 连接

可以将原来的连接分解成多个单表查询,然后在用户程序中进行连接。

  1. ID 唯一性
  • 使用全局唯一 ID(GUID)
  • 为每个分片指定一个 ID 范围
  • 分布式 ID 生成器 (如 Twitter 的 Snowflake 算法)

分库分表后的 ID 是怎么生成的?


这就涉及到分布式 ID 的生成方式了:有借助 MySQL 自增的、有借助 Redis 自增的、也有基于❄雪花算法❄自增的。

具体使用哪种方式要根据公司的技术栈决定了,一般使用 Redis 和基于雪花算法实现的比较多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值