当前位置: 首页 > news >正文

高性能(二)

三、读写分离和分库分表

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!

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

相关文章:

高性能(二)

三、读写分离和分库分表 1.读写分离 1.1 概述 将数据库的读写操作分散到不同的数据库节点上 通常一主多从一台主数据库负责写,多台从数据库负责读。 主库和从库之间会进行数据同步,以保证从库中数据的准确性。 1.2 问题及解决 1.2.1 问题 主从同…...

Allegro如何实现同一个屏幕界面分屏显示操作指导

Allegro如何实现同一个屏幕界面分屏显示操作指导 在做PCB设计的时候,会需要分屏显示,比如一边是放大的视图,另外一边是缩小的视图,Allegro支持同一个屏幕界面下进行分屏显示,如下图 而且会实时同步起来 如何分屏,具体操作如下 点击View...

前后端一些下载与配置(第二篇 第10天过后)nuxt banner redis 短信服务

NUXT 应该是不用怎么装? 有现成的 axios 还需要在npm吗 好像已经有现成的了 banner banner 笔记汇总P396 Redis Linux安装redis tar -xzvf redis-6.2.6.tar.gz cd redis-6.2.6 照着他做 然后 cd /usr/local/redis/bin ./redis-server /usr/local/redis…...

OSG三维渲染引擎编程学习之四十八:“第五章:OSG场景渲染” 之 “5.6 多重纹理映射”

目录 第五章 OSG场景渲染 5.6 多重纹理映射 5.6.1 多重纹理映射介绍 5.6.2 多重纹理映射示例...

对Node.js 的理解?优缺点?应用场景?

一、是什么 Node.js 是一个开源与跨平台的 JavaScript 运行时环境 在浏览器外运行 V8 JavaScript 引擎(Google Chrome 的内核),利用事件驱动、非阻塞和异步输入输出模型等技术提高性能 可以理解为 Node.js 就是一个服务器端的、非阻塞式I/…...

Bean的生命周期

所谓的生命周期指的是一个对象从诞生到销毁的整个生命过程,我们把这个过程就叫做一个对象的生命周期~~ Bean的生命周期分为以下五大部分: 实例化(为 Bean 分配内存空间) 设置属性(Bean对象注入/装配) 初…...

Python学习-----函数2.0(函数对象,名称空间,作用域-->全局变量与局部变量)

目录 前言: 1.函数对象 (1)函数对象的引用 (2)函数可以放到序列里面 (3)函数可以作为参数 , 传递给另一个函数 2.名称空间 3.作用域 (1)作用域的理解 …...

Java中Json字符串和Java对象的互转

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。诞生于 2002 年。易于人阅读和编写。同时也易于机器解析和生成。JSON 是目前主流的前后端数据传输方式。 JSON 采用完全独立于语言的文本格式,但是也使用了类似于 C 语言家族的…...

代码随想录NO42 | 动态规划_Leetcode70. 爬楼梯 (进阶) 322. 零钱兑换 279.完全平方数

动态规划_Leetcode70. 爬楼梯 (进阶) 322. 零钱兑换 279.完全平方数70. 爬楼梯 (进阶) 在原题基础上,改为:一步一个台阶,两个台阶,三个台阶,…,直到 m个台阶…...

【C++从入门到放弃】初识C++(基础知识入门详解)

🧑‍💻作者: 情话0.0 📝专栏:《C从入门到放弃》 👦个人简介:一名双非编程菜鸟,在这里分享自己的编程学习笔记,欢迎大家的指正与点赞,谢谢! C基础…...

企业工程项目管理系统源码+spring cloud 系统管理+java 系统设置+二次开发

工程项目各模块及其功能点清单 一、系统管理 1、数据字典:实现对数据字典标签的增删改查操作 2、编码管理:实现对系统编码的增删改查操作 3、用户管理:管理和查看用户角色 4、菜单管理:实现对系统菜单的增删改查操…...

【GPLT 三阶题目集】L3-016 二叉搜索树的结构

二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分…...

核心交换机安全多业务高性能万兆交换机

RG-S5750-24SFP/12GT交换机是锐捷网络推出的融合了高性能、高安全、多业务的新一代三层交换机。RG-S5750-24SFP/12GT 交换机能够提供灵活的介质接口,满足网络建设中不同介质的连接需要。全千兆的端口形态,加上可扩展的高密度万兆端口,提供1&a…...

Android APK 签名打包原理分析(三)【静默安装的实现方案】

背景 小编目前从事的系统定制类工作,有客户提出了,需要后台“静默安装”他们的app,也就是悄无声息的安装,而且特别强调,不可以跳出任何安装引导页面,他们的app下载完成之后,后台调用公开的android install代码,系统就后台完成安装,安装完成之后,重新打开应用就可以。…...

mulesoft MCIA 破釜沉舟备考 2023.02.14.05

mulesoft MCIA 破釜沉舟备考 2023.02.14.05 1. Refer to the exhibit.2. A Kubernetes controller automatically adds another pod replica to the resource pool in response to increased application load.3. An XA transaction Is being configured that involves a JMS c…...

结构体的三种定义方法、结构体类型名(可选标志符)什么时候可以省略

结构体的三种定义方法 一、单独定义: 先定义结构体类型,再定义变量   定义结构体的格式如下:    struct 结构体名 {    若干数据项;    } ;   其中,struct为关键字; 结构体名是用户定…...

cgo静态编译不能用glibc,用musl

Golang 的一个动态链接依赖问题 upx 是一个压缩二进制的工具,如上图,经过压缩之后,这些 binary 的体积都减少了 46%。 静态链接 CGO 的依赖 如果使用 glibc 的是,是不能静态链接的: rootf88271a666f9:/workspace# g…...

​力扣解法汇总1124. 表现良好的最长时间段

目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 给你一份工作时间表 hours,上面记录着某一位员工每天的工作小时数。…...

12- 降维算法 (PCA降维/LDA分类/NMF) (数据处理)

数据降维就是一种对高维度特征数据预处理方法。降维是将高维度的数据保留下最重要的一些特征,去除噪声和不重要的特征,从而实现提升数据处理速度的目的。PCA算法有两种实现方法: 基于特征值分解协方差矩阵实现PCA算法基于SVD分解协方差矩阵实…...

QT+ OpenGL学习

文章目录QT OpenGLQOpenGLWidget:不需要GLFWQOpenGLFunction_X_X_Core:不需要GLAD你好,三角形顶点输入顶点着色器片段着色器链接着色器本节代码元素缓冲对象EBOQT交互GLSLGLSL支持的类型输入输出Uniform纹理纹理单元纹理环绕纹理过滤多级渐远纹理QT OpenGL 本篇完整…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...