大规模数据处理:分库分表与数据迁移最佳实践
什么是分库分表
分库分表是一种数据库架构优化策略,它将数据分散存储在多个数据库或表中,以此来提高系统的可扩展性和性能。
虽然分库分表能够提升系统的整体性能,但是也不要一上来就分库分表,如果系统在单表的情况下,能够正常运行,就使用单表即可;
当业务出现性能瓶颈时,我们可以考虑先使用分区的方式去优化,如果分区之后仍然不能满足性能要求,再考虑分库分表;
在单库单表下,如果表的数据量累积到一定的数量时(5000W 行或 100G 以上),数据库的性能会出现明显下降,即使我们使用索引优化或读写库分离,性能依然存在瓶颈。此时,如果每日数据增长量非常大,就应该考虑分表,避免单表数据量过大,造成数据库操作性能下降。
面对海量数据,在单库单表下,数据库连接数、磁盘 I/O 、网络吞吐、并发能力等都是有限的。所以,在一些大数据量且高并发的业务场景中,我们就需要考虑分库分表来提升数据库的并发处理能力,从而提升应用的整体性能。
如何分库分表
通常,分库分表分为垂直切分和水平切分两种。
垂直分库
垂直分库通常是根据业务模块将数据库中的表进行分类,每个业务模块的表存储在独立的数据库中。这种方式可以减少数据库的宽度,提高查询效率,并且有利于数据库的维护和扩展。
水平分库
水平分库是将同一个库的数据按照某种规则拆分到多个数据库中,每个数据库存储数据的一部分。这种方式可以有效地分散单个数据库的负载,提高系统的并发处理能力。
垂直分表
垂直分表是将一个表的列拆分到多个表中,通常将不常用的列或大字段拆分出来。这种方式可以减少表的宽度,提高查询性能。
水平分表
水平分表是将一个大表的数据按照某种规则(如哈希分片、范围分片)拆分到多个表中。这种方式可以有效地分散单个表的数据量,提高查询效率。
举例说明一下,如何确定分表数量
提成系统有个课消明细表,用来记录学生上课课时消耗详情,每月大概有 400 万条数据,一年就是 4800 万,假如我们保留 10 年,是48000 万。
假如计划单表存储 200 万数据,则分表数量等于 240。
因为我们要用学生维度去查询数据,所以shard 键选择用学生 ID。
分库分表后的问题
分布式事务问题
比如在电商业务中,当我们提交订单时,除了会创建订单,还会扣除相应的库存。而订单表和库存表由于垂直分库位于不同的库中,此时我们需要分布式事务来保证事务的完整性。
跨节点JOIN查询问题
用户在查询订单时,往往通过表连接获取到商品信息,而商品信息表可能存在其他的库中,这就涉及到了跨库的 JOIN 查询。
通常可以采用冗余表和冗余字段来优化跨库 JOIN 查询。
- 对于一些基础表,如商品信息表,可以在每一个订单分库中复制一张基础表,避免跨库 JOIN 查询;
- 对于一两个字段的查询,可以将少量字段冗余在表中,从而避免 JOIN 查询,也就避免了跨库 JOIN 查询。
跨节点分页查询问题
以订单表为例,通常都是使用 UserId 字段做 Hash 取模,对订单表进行水平分表;若考虑高并发时的订单处理能力,还可以考虑基于UserId 字段 Hash 取模实现分库分表。
当用户在订单列表中查询所有订单时,可以通过用户 ID 的 Hash 值来快速查询到订单信息,而运营人员在后台对订单表进行查询时,则是通过订单付款时间来进行查询的,这些数据都分布在不同的库表中,此时就存在一个跨节点分页查询的问题了。
此时可以采用两套数据来解决跨节点分页查询问题。
- 基于分库分表的用户单条或多条查询数据;
- 基于 Elasticsearch 存储的订单数据,主要用于运营人员根据其它字段进行分页查询;
为了不影响提交订单的业务性能,一般使用异步消息来实现 Elasticsearch订单数据的新增和修改。
全局主键ID问题
在分库分表后,需要单独设计全局主键,避免不同的库和表中的主键重复问题。
有以下几种策略
UUID
UUID 是实现全局 ID 是最方便快捷的方式,即随机生成一个 32 位 16 进制数字,可以保证唯一性,水平扩展能力以及性能都比较高。但 UUID 最大的缺陷就是,它是一个比较长的字符串,连续性差,如果作为主键使用,性能相对来说会比较差,不建议使用。
redis分布式锁
基于 Redis 分布式锁实现一个递增的主键 ID,这种方式可以保证主键是一个整数且有一定的连续性,但分布式锁存在一定的性能消耗。
雪花算法
基于 Twitter 开源的分布式 ID 生产算法——snowflake 解决全局主键 ID 问题,snowflake 是通过分别截取时间、机器标识、顺序计数的位数组成一个 long 类型的主键 ID。这种算法可以满足每秒上万个全局 ID 生成,不仅性能好,而且低延时。
扩容问题
随着用户的订单量增加,以 UserId Hash 取模的分表中的数据量也在增加,此时需要考虑动态增加表,就涉及到了数据迁移问题。
在最开始设计表数据量时,尽量使用 2 的倍数来设置表数量。在扩容时,也同样按照 2 的倍数来扩容,这种方式可以减少数据的迁移量。
有 4 张表,分别为 t0,t1,t2,t3,UserID的哈希值4、8、12、16,则这几个的UserID % 4 = 0,都会存到 t0 表中
假如现在扩容到 8 张表,则 UserID为 4 和 12 的,被迁移到 t5,其他两个不动;
假如现在扩容到 6 张表,则 UserID为 4 和 8 和 16 的,都需要迁移,只有UserID为12 的不需要迁移。
双写数据迁移方案介绍
数据迁移前,上游业务应用是通过旧的服务访问旧的数据的。
步骤1:服务升级双写
首先,需要对旧服务升级,对旧库的增删改,在新库上也同样执行。
步骤2:数据迁移
开发一个数据迁移工具,负责将旧库中的数据迁移到新库中
到目前为止,还是旧库在提供服务,所以丝毫不影响我们的业务。
步骤3:数据校验
在数据迁移完成之后,需要使用数据校验的小工具,将旧库和新库中的数据进行比对,完全一致则符合预期,如果出现不一致的情况,则以旧库中的数据为准。
步骤4:流量切换
数据完全一致之后,将流量切到新库,完成平滑数据迁移。
订单分库分表流程图
假如现在有一个订单表,没有做分库分表,现在呢,我们要把订单进行分库分表,怎么在不停机的前提下,平滑迁移数据到新表呢?
按照上面的双写迁移方案,流程图如下:
当数据比对完全一致后,修改服务配置,只写入分库分表中间件就可以了。
相关文章:

大规模数据处理:分库分表与数据迁移最佳实践
什么是分库分表 分库分表是一种数据库架构优化策略,它将数据分散存储在多个数据库或表中,以此来提高系统的可扩展性和性能。 虽然分库分表能够提升系统的整体性能,但是也不要一上来就分库分表,如果系统在单表的情况下࿰…...

TCP网络编程概述、相关函数、及实现超详解
文章目录 TCP网络编程概述1. TCP协议的特点2. TCP与UDP的差异3. TCP编程流程 TCP网络编程相关函数详解1. socket():创建套接字参数说明:返回值:示例: 2. connect():客户端连接服务器参数说明:返回值&#x…...

Cluade 3.5 Sonnet 提示词泄露
prompt 翻译: The notebook currently demonstrates support for a two agent setup. Support for GroupChat is currently in development....

git clone代码报错Permission denied (publickey)
git clone gerrit SSH的Clone with commit-msg hook代码连接,报错Permission denied (publickey). 一般在C:\Users\用户名.ssh文件夹下有一个id_rsa.pub文件 把文件里的内容复制 到gerrit网站上User Settings的SSH keys里 在New SSH key里粘贴刚刚复制的内容&…...

QT设计中文输入法软键盘DLL给到C#开发步骤
开发目的:本文提供解决触摸屏C#程序中无法输入中文问题,中文拼音采用开源的谷歌输入法程序、使用QT编译中文输入法界面和中文输入法接口给到C#使用。 开发步骤: 1、QT中设计字母和字符输入界面 2、QT中设计数字输入界面 3、QT中封装调用谷歌…...
使用 Rust 和 wasm-pack 开发 WebAssembly 应用
一、什么是 WebAssembly? WebAssembly 是一种运行在现代 Web 浏览器中的新型二进制指令格式。它是一种低级别的字节码,可以被多种语言编译,并在浏览器中高效运行。 1.1 WebAssembly 的背景与概念 高性能计算:WebAssembly 旨在提…...

1. IP地址介绍
IP地址 一、网络概述1、网络类型2、网络组成、传输介质2.1 组成2.2 传输介质 二、IP地址1、IP地址的表示方法2、IP地址的组成3、IP地址的类型3.1 根据IP地址第一个字节大小来分3.1.1 单播地址 Unicast 3.2 根据IP地址的使用 三、子网掩码 netmask1、默认的子网掩码2、判断多个I…...

喜报来袭~又有一波优秀企业选择Smartbi
近期,大金(中国)武汉&广州分公司、中广核智能、新疆银行、四川省人民医院等多家知名企业/机构签约Smartbi,数智化建设再上新高度! Smartbi数10年专注于商业智能BI与大数据分析软件与服务,为各行各业提…...

Web端云剪辑解决方案,BS架构私有化部署,安全可控
传统视频制作流程繁琐、耗时,且对专业设备和软件的高度依赖,常常让企业望而却步,美摄科技凭借其强大的技术实力和创新能力,推出了面向企业用户的Web端云剪辑解决方案,为企业提供一站式、高效、便捷的视频生产平台。 B…...

AI 代码助手插件推荐
AI正在重塑我们的工作方式,软件开发也不例外。AI编码助手使开发人员能够比以往更快、更有效地编写代码。 在本文中,我们将比较几个个最好的AI编码助手,突出它们的独特功能和价格,以帮助读者找到完美的编码伙伴: 1、腾讯云 AI 代…...

word中的表格全部设置宽度100%
1、背景 我们用工具将数据库或其他的数据导出成word时,表格有的会大于100%,超过了边界。word没有提供全局修改的方法。如果我们想改成100%。 一种方式是通过宏,全局改。一种是手动改。 2、宏修改 如果表格多,可以通过这种方式。…...
JFinal整合Websocket
学习笔记,供大家参考 总结的不错的话,记得点赞收藏关注哦!导入JAR包 javax.websocket-api <dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.1&…...

(done) 声音信号处理基础知识(7) (Understanding Time Domain Audio Features)
参考:https://www.youtube.com/watch?vSRrQ_v-OOSg&t1s 时域特征包括: 1.幅度包络 2.均方根能量 3.过零率 振幅包络的定义:一个 frame 里,所有采样点中最大的振幅值 一个形象的关于振幅包络的可视化解释如下:…...

拓数派荣获上海数据交易所“数据治理服务商”认证
近期,杭州拓数派科技发展有限公司(以下简称“拓数派”)荣获上海数据交易所“数据治理服务商”认证,标志着拓数派正式加入上海数据交易所数商生态,成为上海数据交易所官方认证的数据治理服务商。拓数派企业发展部总监吴…...

【Redis】分布式锁之 Redission
一、基于setnx实现的分布式锁问题 重入问题:获得锁的线程应能再次进入相同锁的代码块,可重入锁能防止死锁。例如在HashTable中,方法用synchronized修饰,若在一个方法内调用另一个方法,不可重入会导致死锁。而synchroni…...
对象序列化
Data AllArgsConstructor NoArgsConstructor public class Product implements Serializable {public Long productId;public String productName;public Double productPrice;public String productImg;public Integer productStatus;public String productCategory; }为什么要…...

什么是专利开放许可?
专利作为技术创新的重要载体,其有效转化与应用成为推动社会进步和经济发展的关键力量。那么,专利开放许可究竟是何方神圣?它如何打破传统专利许可的壁垒,促进创新资源的广泛共享? 专利开放许可的定义 专利开放许可&am…...

地表最强开源大模型!Llama 3.2,如何让你的手机变身私人智能助理
你有没有想过,为什么现在的手机越来越像小型电脑?无论是拍照、看视频,还是用各种APP,甚至是AI助手,手机的功能几乎无所不能。其实,这一切的背后有一个技术正在悄悄改变我们的生活,那就是Llama 3…...
Pandas中DataFrame表格型数据结构
目录 1、DataFrame是什么2、创建一个dataframe3、获取dataframe的行、列索引4、获取dataframe的值 1、DataFrame是什么 series是有一组数据与一组索引(行索引)组成的数据结构,而dataframe是由一组数据与一对索引(行索引和列索引&…...
C++的智能指针
很久之前,我们说到了new和delete关键字。 new在堆上分配内存,需要delete来删除内存、释放内存,因为它不会自动释放内存。 智能指针是实现过程自动化的一种方式,即当我们调用new时,我们不需要调用delete关键字。 在很…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...