高性能(二)

三、读写分离和分库分表

1.读写分离

1.1 概述

将数据库的读写操作分散到不同的数据库节点上

在这里插入图片描述

  • 通常一主多从一台主数据库负责写,多台从数据库负责读。

  • 主库和从库之间会进行数据同步,以保证从库中数据的准确性。

1.2 问题及解决

1.2.1 问题

主从同步延迟

主库写完数据后同步到从库之前主从数据不一致

1.2.2 解决

(1)强制将读请求路由到主库处理

  • 适合将必须获取最新数据的读请求都交给主库处理

  • 方案:Sharding-JDBC
    通过Sharding-JDBC的HintManager分片键值管理器强制使用主库

HintManager hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();
// 继续JDBC操作

(2)延迟读取

  • 适合对数据比较敏感的场景,在写请求后避免立即读操作
    如:支付成功后跳转到一个支付成功页面,点击返回后才返回自己的账户。

1.3 如何实现读写分离

1.3.1 常规步骤
(1)部署一主多从数据库
(2)主从复制

保证主从数据库之间的数据是实时同步的

(3)主库处理写请求,从库处理读请求
1.3.2 项目实现方式
(1)代理方式

在这里插入图片描述

  • 应用和数据中间加一个代理层,并处理应用程序所有的数据请求

  • 代理层负责读写请求,将他们路由到对应的数据库中

  • 中间件
    MySQL Router(官方)、Atlas(基于 MySQL Proxy)、Maxscale、MyCat。

(2)组件方式

引入第三方组件处理读写请求(推荐)

如:sharding-jdbc,引入jar包即可使用,非常方便且节省很多运维成本

官方链接:
sharding-jdbc 关于读写分离的操作

1.4 主从复制原理

1.4.1 概述
  • MySQL binlog(binary log 即二进制日志文件)主要记录了MySQL数据库中数据的所有变化(数据库执行的所有 DDL 和 DML 语句)

  • 根据主库的 MySQL binlog 日志就能够将主库的数据同步到从库中。

备注: binlog 还能帮助我们实现数据恢复。

1.4.2 步骤

在这里插入图片描述

(1)主库将数据库中变化写入到binlog中
(2)从库链接主库
(3)从库创建一个I/O线程向主库请求更新的binlog
(4)主库会创建一个binlog dump线程来发送binlog,从库的I/O线程负责接收
(5)从库的I/O线程将接收的binlog写入到relay log中
(6)从库的SQL线程读取relay log同步到本地数据库(执行SQL)
1.4.3 延伸

(1)阿里开源canal
实现MySQL数据库之间或与其他数据源如elasticsearch之间的数据同步,底层也是依赖binlog,原理模拟MySQL主从复制过程

(2)Redis也是通过主从复制实现读写分离

详见我另一篇博客,链接:
数据库及缓存之Redis(一)




2.分库分表

解决数据库存储数据量过大问题

2.1 分库

2.1.1 概念

将数据库中的数据分散 到不同的数据库中

2.1.2 分类
(1)垂直分库
  • 把单一数据库按照业务划分,不同业务使用不同的数据库

  • 举例
    将数据库中的用户表、订单表、商品表分别单独拆分为用户数据库、订单数据库、商品数据库

在这里插入图片描述

(2)水平分库
  • 把同一个表按一定规则拆分到不同的数据库中,每个库可以位于不同的服务器上,实现水平扩展,解决单表的存储和性能瓶颈问题

  • 举例
    订单表数据量太大,订单表水平切分后的2张表分别放在不同数据库

在这里插入图片描述

2.2 分表

对单表的数据进行拆分

在这里插入图片描述

2.2.1 垂直拆分
(1)对数据列拆分,把一张列比较多的表拆分为多张表
(2)举例

将用户信息表中一些单独列抽出来作为一张表

2.2.2 水平拆分
(1)对数据行拆分,把一张行比较多的表拆分为多张表,解决单一表数据量过大的问题。
(2)举例

将用户信息表拆分为多个用户信息表,避免单一表数据量过大造成性能下降

备注: 为了提升性能,通常会选择拆分后的多张表放在不同数据库中,即水平分表和水平分库结合

2.3 分库分表的场景

(1)单表的数据达到千万级别以上,数据库读写速度比较缓慢。
(2)数据库中的数据占用的空间越来越大,备份时间越来越长。
(3)应用的并发量太大

2.4 常见的分片算法

分片算法主要解决了数据被水平分片之后,数据究竟该存放哪个表的问题。

2.4.1 哈希分片

求指定key(如id)的哈希,然后根据哈希值确定数据应被放置在哪个表中。

适合随机读写而不适合经常需要范围查询的场景

2.4.2 范围分片

按照特性的范围区间(如时间、ID区间)来分配数据

  • 适合经常进行范围查找而不适合随机读写的场景
    因为数据未被分散容易出现热点数据的问题

  • 举例
    如将id 为 1~299999 的记录分到第一个库,300000~599999 的分到第二个库。

2.4.3 地理位置分片

根据地理位置(城市、地域)来分配数据

很多 NOSQL数据库都支持

2.4.4 融合算法

灵活组合多种分片算法

如将哈希分片和范围分片组合

2.5 分库分表问题

2.5.1 无法join操作
  • 同一个数据库中的表分布在不同的数据库中无法使用join操作

  • 需要在一个数据库中查询到一个数据再去另外一个数据库汇总查询对应的数据

2.5.2 事务问题
  • 同一个数据库中的表分布在不同的数据库中,单个操作涉及到多个数据库,数据库自带的事务无法解决
2.5.3 分布式ID
  • 分库后,数据遍布在不同服务器上的数据库中,数据库的自增主键已经没办法满足生成的主键唯一。

  • 需要引入分布式ID

2.5.4 其他
  • 需要更多的数据库服务器,成本上升了

2.6 分库分表方案

ShardingSphere 项目

在这里插入图片描述

(1)包括 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar,由京东数科巨佬维护
(2)功能完善

支持读写分离和分库分表、分布式事务、数据库治理等功能。

(3)生态体系完善

社区活跃,文档完善,更新和发布比较频繁

入门可以看看下面这篇文章:
《芋道 Spring Boot 分库分表入门》

2.7 分库分表数据迁移

2.7.1 停机迁移
  • 系统使用的人数非常少的时候,如凌晨 2 点,挂公告系统要维护升级预计 1 小时。

  • 再写个脚本老库的数据写到新库中

2.7.2 双写方案

针对不能停机迁移场景

原理如下:

(1)对老库的更新操作(增删改),同时也要写入新库(双写)
(2)还需要自己写脚本将老库中的数据和新库的数据做比对
  • 在迁移过程,双写只会让被更新操作过的老库中的数据同步到新库

  • 如果新库中没有,那咱们就把数据插入到新库

  • 如果新库有,旧库没有,就把新库对应的数据删除(冗余数据清理)

(3)重复上一步的操作,直到老库和新库的数据一致为止

备注:
项目中实施双写很麻烦很容易会出现问题,建议使用数据库同步工具 Canal 做增量数据迁移(还是依赖 binlog,开发和维护成本较低)。





上一篇跳转—高性能(一)


本篇文章主要参考链接如下:

参考链接1-JavaGuide


持续更新中…

随心所往,看见未来。Follow your heart,see light!

欢迎点赞、关注、留言,一起学习、交流!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"C高性能编程"是一本涉及高性能编程技术的PDF电子书。这本书涵盖了各种与高性能编程相关的主题,包括算法优化、并行编程、内存管理、网络编程和系统优化等。它旨在帮助程序员提升程序的性能,使其能够更好地满足用户的需求。 这本书的第一部分介绍了高性能编程的概念和原则。它解释了高性能编程的重要性,以及如何通过合理的设计和优化来提高程序的性能。此外,它还介绍了一些常见的性能优化技术和工具,如性能测试和性能分析。 第部分主要涵盖了算法优化和并行编程。它介绍了一些常见的算法和数据结构,以及如何通过优化算法来提高程序的执行效率。此外,它还介绍了并行编程的基本原则和技术,如多线程和分布式计算等。 第三部分讨论了内存管理和优化。它介绍了一些内存管理技术,如内存分配和回收机制,以及如何避免内存泄漏和内存碎片等问题。此外,它还介绍了一些内存优化的技巧,如缓存优化和内存对齐。 第四部分涵盖了网络编程和系统优化。它介绍了一些网络编程的基本知识和技术,如套接字编程和网络协议。此外,它还介绍了一些系统级优化技术,如优化IO操作和减少系统调用等。 总之,“C高性能编程”是一本涵盖了高性能编程相关主题的PDF电子书。通过学习这本书,我们可以了解高性能编程的基本概念和原则,掌握一些常见的性能优化技术和工具,以及学习如何优化算法、并行编程、内存管理、网络编程和系统优化等方面的知识。这将有助于我们提高程序的性能,使其能够更好地满足用户的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值