Mysql的分库分表

一、单Mysql节点

假如一主一从

为什么不能无限读?

瓶颈分析:

  1. 资源限制: 如CPU、内存、磁盘I/O、网络带宽等。随着读请求的增加,服务器的负载将会增加,甚至可能导致系统崩溃。

  2. 连接数限制: MySQL有最大连接数的限制。超出限制抛异常。

  3. 锁和并发控制: 大量读请求可能导致锁的争用。SELECT ... FOR SHARE或者SELECT ... LOCK IN SHARE MODE

  4. 缓存频繁失效: 数据库有查询缓存功能,高并发读请求会导致缓存失效

调用方的直观感觉:

  1. 响应增加
  2. 数据库链接失败

为什么不能无限写?

瓶颈分析:

  1. 主从复制延迟: 大量的写入操作可能会增加复制的延迟,导致从库数据同步滞后。(主从延迟耗时超过1秒告警)

  2. 磁盘空间问题: 大量写入操作可能导致磁盘空间迅速耗尽(需要有70%红线预警)

  3. 无限读的那4个瓶颈。

调用方的直观感觉:

  1. 由于读的是从库,由于主从延迟,会一直读不到最新的数据。
  2. 响应增加
  3. 数据库链接失败

最佳实践:单库读超过 1WQPS、写超过5000 就要预警

二、一主多从

目的:

  1. 为了应付更多的读写请求

将Mysql设置1主8从,每2个从节点放到一个机房,后续同机房的服务流量能降低延迟。

三、分库分表

路由规则

  • 表 shard 规则:table_num =  分表字段 % 1000
  • 库 shard 规则:db_num = table_num / (1000 / 10)。
单表拆分1000个表,
1000个表分布在10个库,每个库放100个表

db0 放 tb_[0-99]
db1 放 tb_[100-199]
db2 放 tb_[200-299]
...
db9 放 tb_[900-999]

比如商品table根据门店id分段,
假如门店id是 123456789,那么就分到了
table_789 (门店id % 1000)
table_789 是放到 db7 里面 (门店id % 10)


---
int dbCount = 10; // 10个库
int tbCount = 1000; // 1000个表

int poiId = 123456789;
int tbNum = poiId % tbCount; // 计算表编号 789
int dbNum = tbNum / (tbCount / dbCount); // 计算库编号 7

System.out.println("Table: tb_" + tbNum + ", Database: db" + dbNum);

四、数据迁移过程

1、双写新老库

思考问题:

  1. insert老table失败,insert新table成功怎么办?(先写老table,失败直接抛Exception,不走后面的写新table,接口返回失败)
  2. insert老table成功,insert新table失败 (则捕获异常,记录log并发消息给MQ,或者存到mysql 某个table,后续处理,接口返回成功)
  3. update同上

2、存量数据复制

  1. 新增情况采用insert ... ignore.. (避免因错误或异常数据导致这一批次插入丢失,如果主键id 数字单调递增,基本不会出现这个情况)
    1. copy过程准备插入数据 row1,row2,row3到新库,但是新库存在row2
    2. 此时由于 ignore,于是插入了 row1,row3
    3. 但是row2的数据其实是脏的,那么就出现脏数据
  2. update过程中发生脏数据
    1. copy线程复制了数据,还没写入(假如就是延时或者刚好发生了gc导致停顿)
    2. a线程先update老库,然后update新库的时候,由于数据还没写入,那么会update row = 0,然后copy线程
    3. copy线程写入数据到新库,此时新库的数据是过时的,属于脏数据更新操作丢失
  3. delete过程同上,老库已经删了,新库又给插了一条进去。删除操作丢失

3、数据检查

  1. 批量读取老库数据,比如每次一千条(注意深分页问题,别一味 limit page,size )
  2. 与新库数据进行对比(一切以老库数据为准)
    1. 如果新库缺数据,那么就insert
    2. 如果新库存在数据,但是数据不一致,那么更新新库数据(ctime、utime看情况可以不比对,可以忽略)
    3. 如果存在新库存在老库不存在的数据,那么直接删除

4、灰度切读与观察

5% 10% 20% ... 100%

有问题就回滚,切换开关

5、全量切读与观察

建议持续个一两周,最后再下掉~

6、停双写,数据迁移完成

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/194342.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker:深入解析Nexus技术构建可靠的软件仓库管理系统

1、简述 在现代软件开发中,有效的软件仓库管理是确保项目成功的关键一环。Nexus Repository Manager作为一种流行的仓库管理系统,为开发人员提供了强大的工具,用于存储、检索和管理软件构建。本文将深入解析Nexus技术,探讨其关键…

GPIO的使用--操作PF09 PF10 PF08实现呼吸灯、跑马灯、警报闪烁灯

先来个呼吸灯演示 呼吸灯 目录 一、GPIO的介绍 1.含义 2.控制原理 3.控制流程 二、LED控制 1.呼吸灯 操作代码 烧录结果 2.蜂鸣器红绿灯交替 操作代码 3.红绿灯交替闪烁 操作代码 一、GPIO的介绍 1.含义 GPIO(general porpose intput output),通用输入输出端口。…

应用密码学期末复习(2)

目录 第二章 2.1数论与密码基础-数论基本概念 2.1.1几个基本概念 2.1.2辗转相除法 2.1.3解一次周余式 2.2密码基础-单表密码 2.2.1单表密码体制 2.2.2单表密码的统计分析 2.3密码基础-多表密码 2.4密码基础-置换密码 第二章 2.1数论与密码基础-数论基本概念 2.1.1几…

window关于下载anaconda 2023年以后的版本,jupyter notebook闪退,没有内核的问题

这种问题的解决办法: 下载anaconda较早版本,比如我下载的是:2022年5月的版本。 下载之后,打开jupyter好像也会没有内核和闪退。 下面解决步骤: 1.注意:打开anaconda powershell prompt 2.重点来了&#xf…

IDEA 2022.1 同一个 spring boot main类运行多个实例

普通的 Java 项目 运行多个实例是非常简单的,直接点击 run 多次即可,但在 spring boot 中默认情况下,是不允许把同一个 web 项目改完端口后多次运行的,如下会显示让你先停止当前实例后再启动: 开启运行多个实例的的方法…

Redis面试题:哨兵模式相关问题,以及脑裂问题

目录 面试官:怎么保证Redis的高并发高可用 面试官:你们使用redis是单点还是集群,哪种集群 面试官:redis集群脑裂,该怎么解决呢? 面试官:怎么保证Redis的高并发高可用 候选人:首先…

WordPress:构建强大的网站和博客的完美选择

WordPress:构建强大的网站和博客的完美选择 一、WordPress 简介1.1 WordPress 介绍1.2 WordPress 优势 二、部署LNMP环境2.1 前提条件2.2 关闭防火墙和SELinux2.3 安装Nginx2.4 安装MySQL2.5 安装PHP2.6 配置Nginx2.7 配置MySQL2.8 配置PHP2.9 测试访问LNMP平台 三、…

【九章斩题录】Leetcode:面试题 01.03. URL化(C/C++)

精品题解 🔥 《九章斩题录》 👈 猛戳订阅 面试题 01.03. URL化 📚 题目:URL化。编写一种方法,将字符串中的空格全部替换为%20。假定该字符串尾部有足够的空间存放新增字符,并且知道字符串的“真实”长度。…

【每日一题】子数组的最小值之和

文章目录 Tag题目来源题目解读解题思路方法一:贡献法单调栈 写在最后 Tag 【贡献法】【单调栈】【数组】【2023-11-27】 题目来源 907. 子数组的最小值之和 题目解读 计算整数数组的连续子数组中最小值的和。 解题思路 本题朴素的解决思想是求出所有的连续子数组…

微软重磅更新:Bing Chat全线改名Copilot,用户可免费使用GPT4!(文末附Copilot使用教程)

原创 | 文 BFT机器人 微软在2023年的Ignite大会上宣布了许多新产品和功能。其中最引人注目的是Bing Chat更名为Copilot,Copilot基于最新的OpenAI模型,包括GPT-4和DALL・E 3,为用户提供文本和图像生成功能。也就是说,只要你拥有微…

TDA4开发环境Docker化

文章目录 背景1. TDA4X Linux SDK编译环境镜像构建1.1 安装SDK1.2 验证制卡1.2.1 出现的问题:1.3 验证编译1.3.1 出现的问题2. TDA4X Linux-RT SDK编译环境镜像构建2.1 安装SDK2.2 出现的问题参考背景 开始阅读本篇前,假设你已经对docker有了一定了解,且有过docker换件搭建…

在龙蜥 anolis os 23 上 源码安装 PostgreSQL 16.1

在龙蜥 OS 23上,本来想使用二进制安装,结果发现没有针对龙蜥的列表: 于是想到了源码安装,下面我们列出了PG源码安装的步骤: 1.安装准备 1.1.创建操作系统组及用户 groupadd postgres useradd -g postgres -m postgr…

Windows全系列 本地密码暴力破解

首先 咱们要准备两个工具: 第一个是 pwdump-master 第二个是 saminside_softradar-com.exe这两个工具 我会一并上传 需要的同学 可以自取本文章操作思路是: 第一步 首先把我刚刚提到的两个软件 以某种手段放置于机器中 如果是真实机 就用U盘 拷贝到真实机…

sCrypt 现已支持各类主流前端框架

sCrypt 现已支持各类主流前端框架,包括: ReactNext.jsAngularSvelteVue 3.x or 2.x bundled with Vite or Webpack 通过在这些支持的前端框架中集成sCrypt开发环境,你可以直接在前端项目里访问合约实例和调用合约,方便用户使用Se…

c++容器详解Vector、deque、list、set、multiset、map、multimap、queue、stcak、Array

容器 数据结构描述实现头文件向量(vector)连续存储的元素<vector>列表(list)由节点组成的双向链表,每个结点包含着一个元素<list>双向队列(deque)连续存储的指向不同元素的指针所组成的数组<deque>集合(set)由节点组成的红黑树,每个节点都包含着一个元素,…

Java自定义一个线程池

线程池图解 线程池与主线程之间通过一个阻塞队列来平衡任务分配&#xff0c;阻塞队列中既可以满足线程等待&#xff0c;又要接收主线程的任务。 线程池实现 使用一个双向链表实现任务队列 创建任务队列 //阻塞队列 public class BlockingQueue<T> {//双线链表private …

Mysql数据库多表数据查询问题

1、背景 线上某个业务数据分表存储在10个子表中&#xff0c;现在需要快速按照条件&#xff08;比如时间范围&#xff09;筛选出所有的数据&#xff0c;主要是想做一个可视化的数据查询工具&#xff0c;给产研团队使用。 2、实践 注意&#xff1a;不要在线上真实数据库操作&am…

使用Docker compose方式安装Spug,并结合内网穿透实现远程访问

文章目录 前言1. Docker安装Spug2 . 本地访问测试3. Linux 安装cpolar4. 配置Spug公网访问地址5. 公网远程访问Spug管理界面6. 固定Spug公网地址 前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、文件…

【Docker】python flask 项目如何打包成 Docker images镜像 上传至阿里云ACR私有(共有)镜像仓库 集成Drone CI

一、Python环境编译 1、处理好venv环境 要生成正常的 requirements.txt 文件&#xff0c;我们就需要先将虚拟环境处理好 创建虚拟环境&#xff08;可选&#xff09;&#xff1a; 在项目目录中&#xff0c;你可以选择使用虚拟环境&#xff0c;这样你的项目依赖将被隔离在一个…

3D点云目标检测:VoxelNex解读(带源码/未完)

VoxelNext 通用vsVoxelNext一、3D稀疏卷积模块1.1、额外的两次下采样1.2、稀疏体素删减 二、高度压缩三、稀疏池化四、head五、waymo数据集训练六、训练自己的数据集bug修改 通用vsVoxelNext 一、3D稀疏卷积模块 1.1、额外的两次下采样 使用通用的3D sparse conv&#xff0c;…