分库分表设计方案

2023-11-11

一、为什么要分库分表?
随着业务的不断发展,数据量不断增加,因此数据操作,如增删改查的开销也会越来越大,原来基于单库单表的设计已经不能满足存储需求,数据库随时面临爆库风险;

再加上物理服务器的资源有限(CPU、磁盘、内存、IO 等)。最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

二、如何解决?
1、增加存储这只能暂时缓解,但也可能是一种性价比比较高的方案

2、数据实现动静分离,定时备份到达终态数据,缓解存储压力

例:

热数据:3个月内的订单数据,查询实时性较高;(mysql中分库分表)

冷数据A:3个月 ~ 12个月前的订单数据,查询频率不高;(es中)

冷数据B:1年前的订单数据,几乎不会查询,只有偶尔的查询需求;(hive)

3、数据库分表可以解决单表海量数据的查询性能问题,分库可以解决单台数据库的并发访问压力问题。有时候,我们需要同时考虑这两个问题,因此,我们既需要对单表进行分表操作,还需要进行分库操作,以便同时扩展系统的并发处理能力和提升单表的查询性能,就是我们使用到的分库分表。

三、分库分表的实现方案
拆分的方式有两种,一种是水平拆分,一种是垂直拆分,分库分表是对数据库拆分的解决方案;根据分库分表方案中实施切片逻辑不同,我们将分库分表的实现方案分成三大类:客户端,代理分片,分布式数据库

1、客户端
客户端分片就是使用分库分表数据库的应用层直接操作分片逻辑,分片规则需要在同一应用的多个模块进行同步,每个应用嵌入一个操作分片的逻辑实现,一般都通过依赖jar实现,具体的实现方式分为三种:一种在应用层直接实现,第二通过ORM框架实现;第三通过定制JDBC协议实现;

应用层实现:
       这是一种通用的简单的实现方案,直接在应用层读取分片规则实现路由逻辑,然后应用层自己决定访问那个实例,那个库,那个表,那个字段等等。

 架构如下:

在这里插入图片描述

这种方案虽然侵入了业务,但是实现比较简单,适合快速上手,出问题也比较好查,目前有一些开源实现dbsplit方案

ORM框架实现:
通过定制ORM框架中或者通过框架的扩展机制来实现分库分表的逻辑,现在很多公司通过mybatis配置文件的SQL中的表索引的参数来实现分片;

在这里插入图片描述

mybatis实现分库分表方式:

在这里插入图片描述

在这里插入图片描述

此方案也是推荐方案

JDBC协议实现:
我们通过定制JDBC协议来实现,针对业务提供JDBC一致的接口,让业务方无需关系分库分表的实现,让分库分表规则在JDBC内部实现,对业务方透明;

架构如下:
在这里插入图片描述
在这里插入图片描述

ShardingSphere-JDBC体系结构

这种解决方案对业务透明,不侵入业务,让开发人员更大限度聚焦在逻辑实现上,但开发人员需要理解并使用JDBC协议;现在流行的框架:shardingsphere,前身是sharding-jdbc由当当开发,现目前已经交给apahce了

https://github.com/apache/incubator-shardingsphere

使用限制:

对于部分SQL语法不支持,比如:having,union,or,批量插入insert into values(v1,v2),(v3,v4),distinct,不支持子查询

2、代理分片
代理层是在应用层和数据库层增加一个代理层,把分片规则配置在代理层,代理层对外提供与JDBC兼容的接口给应用层,业务也不用关系分片规则

在这里插入图片描述

这种方案的优点是对业务透明,缺点是增加一层网络代理,对性能有损失;

在这里插入图片描述

3、分布式数据库
通过将分片功能在DB内部实现来实现分布式存储,对业务透明;

架构如下:
在这里插入图片描述

业界的开源实现,阿里的OceanBase,开源的tidb和度小满nesiodb

四、案例分析
1、billing模块t_bill_record数据超两千万条

在这里插入图片描述

水平拆分,以周为单位,提前建好两年的表t_bill_record_yyyymmdd
新增数据根据当前时间进入对应的表中
查询数据根据时间跨度,联合查询的表数据
数据迁移(尽量不要影响正在使用中的表,如果有影响,对于insert/update/delete,每次处理1000行数据,执行commit,之后sleep 1秒。对于select,每次查询2000行数据,之后sleep1秒)

2、亿级订单系统设计
订单表为例,在订单表中,订单id肯定是不可重复的,因此将该字段当做shard key 是非常适合的,其他表类似。
例:单张order表分为10个库,每个库100个表
中间变量 = shard_key / (库数量*单个库的表数量)
库序号 = 取整(中间变量/单个库的表数量)
表序号 = 中间变量 % 单个库的表数量,

如果shard_key 不是整数类型,可以先hash 在进行取模,

例如: hash(shard_key) % 库容量

数据迁移(双写迁移方案)
就是在线上系统,之前所有写库的地方,增删改操作,除了对旧库增删改,都加上对新库的增删改,这就是所谓双写 — 同时写俩库(旧库和新库)
同时起一个job,同步旧库数据到新库,接着当数据完全一致了,上线所有操作到新库服务

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

分库分表设计方案 的相关文章

  • 如何在远程 WebSphere 上进行 JNDI 查找期间解决 sun/io/MalformedInputException

    我使用 WebSphere 8 5 来托管我的应用程序 并在应用程序服务器上配置了一些 JDBC 资源 我还使用瘦客户端运行时库开发了一个客户端应用程序 当按以下方式执行 JNDI 查找时 env put Context INITIAL C
  • 从 Grib 天气模型中提取数据

    我已经下载了grib1模型数据来自GFS http en wikipedia org wiki Global Forecast System 我使用的是 Mac OS X 并且能够构建wgrib2文件来自NOAA http en wikip
  • 请参阅 Java EE eclipse 调试中的 POST 参数

    我在调试 Java EE 方面没有经验 我更像是一个 javascript 人 我需要查看哪些 HTTP POST 参数到达服务器端 我在表单将其操作指向的 jsp 文件中放置了一个断点 现在我在调试变量窗口中找不到 POST 内容 他们在
  • 如何拦截 REST 端点以接收所有标头?

    我当前的代码是 Path login RequestScoped public class LoginResource GET SecurityChecked public Response getUser HeaderParam AUTH
  • Java Microsoft Excel API [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 有多少种方法可以将位图转换为字符串,反之亦然?

    在我的应用程序中 我想以字符串的形式将位图图像发送到服务器 我想知道有多少种方法可以将位图转换为字符串 现在我使用 Base64 格式进行编码和解码 它需要更多的内存 是否有其他可能性以不同的方式做同样的事情 从而消耗更少的内存 现在我正在
  • 异步迭代器

    我有以下代码 while slowIterator hasNext performLengthTask slowIterator next 由于迭代器和任务都很慢 因此将它们放入单独的线程中是有意义的 这是对迭代器包装器的快速而肮脏的尝试
  • MySQL 将表从 Latin1 转换为 utf8

    我需要将包含大量数据的表从 Latin1 转换为 utf8 以便它可以接受韩语字符 如何更改该表而不损坏其中的数据 我的 SQL 语句是什么 最好的方法是什么 ALTER TABLE database name table name CON
  • Java:java.util.ConcurrentModificationException

    我正在制作 2D 目前正在研究用子弹射击 子弹是一个单独的类 所有项目符号都存储在称为项目符号的数组列表中 当它超出屏幕一侧 Exception in thread main java util ConcurrentModification
  • 带有 OpenId 提供程序的 Java Spring 安全性

    我有一个 spring MVC 应用程序 另一个客户端应用程序想要使用 open id connect 访问我的 spring 应用程序 如何在服务器端实现开放ID提供商 请帮忙 MITREid 连接 OpenID Connect Java
  • 如何使用 Mysql Python 连接器检索二进制数据?

    如果我在 MySQL 中创建一个包含二进制数据的简单表 CREATE TABLE foo bar binary 4 INSERT INTO foo bar VALUES UNHEX de12 然后尝试使用 MySQL Connector P
  • 使用 secp256r1 曲线和 SHA256 算法生成 ECDSA 签名 - BouncyCastle

    我正在尝试使用带有 secp256r1 曲线 P256 的 ECDSA 和用于消息哈希的 SHA256 算法生成签名 我也在使用 Bouncy Castle 库 下面的代码 public class MyTest param args pu
  • Java:由 HTTP 连接创建的等待连接线程存活时间很长

    我有一个服务器端代码 用于检查 SOAP 服务是否已启动 代码如下 String response while response length 0 try final URL url new URL DummySoapServiceURL
  • 使用 JAD 反编译 java - 限制

    我正在尝试使用 Java 中的 JAD 反编译几个 jar 文件 我也尝试过 JD GUI 但运气更差 但出现了很多错误 一种类型 易于修复 似乎是内部类 但我也发现了这段代码 static int SWITCH TABLE atp com
  • 无法使用 wget 在 CentOS 机器上安装 oracle jdk

    我想在CentOS上安装oracle java jdk 8 我无法安装 java jdk 因为当我尝试使用命令安装 java jdk 时 root ADARSH PROD1 wget no cookies no check certific
  • 摩尔斯电码 至 英语

    我现在的问题是让 摩尔斯电码转英语 正常工作 将英语转换为莫尔斯电码的第一部分工作正常 我知道以前已经有人问过这个问题 但我不知道我做错了什么 我知道我需要在某个地方进行拆分 但我只是不确定将其放在代码中的何处 现在 莫尔斯电码到英语的部分
  • WHERE NOT EXIST 附近的语法错误

    我在堆栈中搜索 但没有一个达到最终答案 我的查询是这样的 INSERT INTO user username frequence autoSend VALUES feri2 3 1 WHERE NOT EXISTS SELECT FROM
  • 更改mysql数据库表中的日期格式

    大家早上好 只是一个简单的问题 在我现有的 MySql 数据库中 我几乎没有包含日期 的列 目前这些是年 月 日格式 但现在我需要将其全部更改为年 月 日格式 我试过了select date format curdate d m Y 但它不
  • 如何在不同版本的Google App Engine中使用自定义域名?

    我使用谷歌应用程序引擎作为我的 Android 和 Web 应用程序的服务器 我使用 Android Studio 开发了 Android 应用程序 并使用 Eclipse 开发了 Web 应用程序 我在应用程序引擎中部署了两个版本 第一个
  • Java、Spring、Hibernate找不到org.springframework.orm.hibernate3.LocalSessionFactoryBean

    我正在尝试制作 spring hibernate ant 项目 目前我收到此错误 HTTP Status 500 type Exception report message description The server encountere

随机推荐

  • 出现command 'gcc' failed with exit status 1 解决方案

    在centos7 上用pip 安装psutil的时候很不幸的出现了如下错误 pip install psutil Collecting psutil Using cached psutil 5 3 1 tar gz Installing c
  • python 角度判断_大牛带你打牢Python基础,看看这10语法

    都说Python简单 易懂 但是有时候却又很深奥 许多人都觉的自己学会了 却老是写不出项目来 对很多常用包的使用也并不熟悉 学海无涯 我们先来了解一些Python中最基本的内容 1 数值 数值包括整型和浮点型 分别对应整数和浮点数 后者精度
  • Python3 列表笔记

    列表 使用 括起来的一个个元素的集合 1 列表的元素使用 进行分割 2 列表的元素可以是任意数据类型 1 创建列表 list huarzil 32 3 14 True zhuangsan lisi 32 29 30 name height
  • linux学习笔记--网络编程

    目录 概念 协议 网络应用设计模式 分层模型 协议格式 TCP状态 网络名词 socket编程 套接字 字节序 函数 socket bind listen accept connect C S模型 server client 封装 高并发服
  • iview 数据表格 固定列拉倒底部后刷新出现错行问题

    很多小伙伴肯定遇到过这个组件问题 下面只需要一行即可搞定 vue方法 首先我们在mixin js里封装一个方法 pageSizeChange pageSize 每页显示数量变更 this searchParams limit pageSiz
  • C#中,浮点数的比较和decimal

    浮点数 C 的浮点数类型 float double 当我们定义一个浮点数可以 可以使用var 关键字 可以做类型推断 定义float类型 数字末尾需要加上 F或者是f 定义一个double类型 double a1 1 1 var a2 1
  • <转>企业应用架构 --- 分层

    系统架构师 基础到企业应用架构 分层 上篇 一 前言 大家好 接近一年的时间没有怎么书写博客了 一方面是工作上比较忙 同时生活上也步入正轨 事情比较繁多 目前总算是趋于稳定 可以有时间来完善以前没有写完的系列 也算是对自己这段时间工作和生活
  • 程序流程图是什么?基本流程图讲解

    程序流程图是什么 程序流程图是流程图的其中一种分类 又称程序框图 指用特定图形符号加上对应的文字描述表示程序中所需要的各项操作或判断的图示 程序流程图除了说明程序的流程顺序外 着重于说明程序的逻辑性 一 程序流程图特点 当程序流程中有较多循
  • 动态规划经典例题-国王的金矿问题

    金矿问题 问题概述 有一位国王拥有5座金矿 每座金矿的黄金储量不同 需要参与挖掘的工人人数也不同 例如有的金矿储量是500kg黄金 需 要5个工人来挖掘 有的金矿储量是200kg黄金 需要3个工人来挖 掘 如果参与挖矿的工人的总数是10 每
  • 转:FindBugs,第 2 部分: 编写自定义检测器

    FindBugs 第 2 部分 编写自定义检测器 如何编写自定义检测器以查找特定于应用程序的问题 FindBugs 是一种可以扩展和定制以满足自己团队独特要求的静态分析工具 在本系列的第 2 部分中 高级软件工程师 Chris Grinds
  • odoo12 用户(users) 权限管理界面分析

    起因 由于需要了解 odoo的权限管理 去看了下 odoo 是如何给用户赋权限的 发现好多不能理解 因此 打算从 user 的xml开始 看里面到底是什么意思 第一步 肯定查看user的xml 找user源码 odoo odoo addon
  • delphi xe 10.3 访问 linux 7 mysql 5.7.20

    下载 https cdn mysql com archives mysql 5 7 mysql 5 7 34 win32 zip 解压 并复制lib目录下的所有文件到 X Program Files x86 Embarcadero Stud
  • MySQL崩溃修复案例

    问题描述 研究MySQL源代码 调试并压测MySQL源代码时 MySQL崩溃了 问题是它竟然崩溃了 而且还损坏了InnoDB文件 还好是在调试环境下发生的 赶紧看看如何解决这个问题 经过一系列的查阅资料 验证 对比 MySQL源码调试跟踪
  • 单线程的Redis为什么这么快

    一 为什么Redis是单线程的 Redis 是基于内存的操作 而CPU 不是 Redis 的瓶颈 Redis 的瓶颈最有可能是机器内存的 大小或者网络带宽 同时 单线程的实现更加简单和经济 采用单线程可以使指令串行 不用额外 维护锁机制 避
  • java通过反射创建对象的两种方式

    我个人觉得我自己是个比较粗心的人 所以各位大佬发现有什么不对的地方还请留言告知 在java中 通过反射创建对象有两种方式 使用Class对象的newInstance 方法来创建对象 具体步骤是 1 获取类的Class对象 有三种方式可以获取
  • 深度学习系列:阿里DIN模型的原理和代码实现

    一 前言 今天介绍阿里巴巴的DIN网络 不得不说 阿里妈妈的大佬是真的多 经常都会更新非常多的创造性的东西 比如DIN中使用的自适应正则化技术以及Dice激活函数以及注意力机制的使用 并且值得注意的是DIN网络中使用的注意力机制还挺多的 哈
  • C语言中不定参数函数

    在我们平常调用函数的时候 会进行传参 调用的函数也会有参数去接收 数量和类型都是对应的 而不定参数函数是指对一个函数传参 参数的个数可以不确定 接下来 我就简单的叙述一下不定参数函数的原理及应用 在我们刚学C语言的时候 大多会首先接触pri
  • 可变长参数 VS C++11 可变长模板

    转 https blog csdn net zj510 article details 36633603 C 可变长参数 VS C 11 可变长模板 2014年07月03日 13 50 32 阅读数 10437 有些时候 我们定义一个函数
  • fine-tuning(微调)的理解

    fine tuning 介绍 什么情况下使用微调 微调指导事项 不同数据集下使用微调 涉及到的其他知识 学习率 learning rate 卷积神经网络的核心 迁移学习与微调 什么是迁移学习 为什么要迁移学习 详细解释 自己的理解 不知道对
  • 分库分表设计方案

    一 为什么要分库分表 随着业务的不断发展 数据量不断增加 因此数据操作 如增删改查的开销也会越来越大 原来基于单库单表的设计已经不能满足存储需求 数据库随时面临爆库风险 再加上物理服务器的资源有限 CPU 磁盘 内存 IO 等 最终数据库所