Java面试题034:一文深入了解MySQL(6)

Java面试题029:一文深入了解MySQL(1)

Java面试题030:一文深入了解MySQL(2)

Java面试题031:一文深入了解MySQL(3)

Java面试题032:一文深入了解MySQL(4)

Java面试题033:一文深入了解MySQL(5)

1、分库分表简介

        随着业务规模的扩大和系统复杂度的增长,数据量和访问量也同时增加,关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严重。单个服务的磁盘空间是有限制的,并发压力下,所有的请求都访问同一个节点,肯定会对磁盘IO造成非常大的影响。此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间。

        分库:将一个库的数据按照一定规则拆分到多个库中
        分表:把一个表的数据按照一定规则放到多个表中

        当单个库太大时,先要看一下是因为表太多还是数据量太大,如果是表太多,则应该将部分表进行迁移(可以按业务区分),这就是垂直切分。如果是数据量太大,则需要将表拆成更多的小表,来减少单表的数据量,这就是水平拆分

2、四种实现形式

(1)垂直分库:是指在一个系统中的按照不同业务进行拆分,将不同的业务数据存放到不同的数据库中。典型的案例是微服务架构中不同的业务微服务可以将自己的业务数据存放到自己的数据源中,以服务的形式向系统提供数据查询。

(2)垂直分表:一般是表中的字段较多时,按照业务需要将列字段拆分为多个表。

        垂直分库(表)是将不同的数据进行分别存放,每个库或表存放的数据差别很大。

        当一个应用难以再细粒度的垂直切分,或切分后数据量行数巨大,存在单库读写、存储性能瓶颈,这时候就需要进行水平切分了,可以理解为负载均衡。

(3)水平分库:每个库(表)的结构都一样,数据都不一样。它们的并集就是全量数据。

(4)水平分表:每个库(表)的结构都一样,数据都不一样。它们的并集就是全量数据。

3、分库分表规则

(1)根据数值范围range

        按照时间区间或ID区间来切分。例如:按日期将不同月甚至是日的数据分散到不同的库中;将userId为1~9999的记录分到第一个库,10000~20000的分到第二个库。

优点:

  • 单表大小可控
  • 便于水平扩展,后期想对集群扩容时,只需添加节点即可,无需对其他分片的数据进行迁移
  • 使用分片字段进行范围查找时,连续分片可快速定位分片,有效避免跨分片查询的问题。

缺点:

  • 热点数据成为性能瓶颈。连续分片可能存在数据热点,例如按时间字段分片,有些分片存储最近时间段内的数据,可能会被频繁的读写,而有些分片存储的历史数据,则很少被查询。

  某些系统中使用的“冷热数据分离“,将一些使用较少的历史数据迁移到其他库中,业务功能上只提供热点数据的查询,也是类似的实践。

(2)根据数值取模Hash

        对字段值进行哈希运算后取余分区,适用于数据分布均匀的场景。

        例如:将 Customer 表根据 cusno 字段切分到4个库中,余数为0的放到第一个库,余数为1的放到第二个库,以此类推。这样同一个用户的数据会分散到同一个库中,如果查询条件带有cusno字段,则可明确定位到相应库去查询。

优点:

  • 数据分片相对比较均匀,不容易出现热点和并发访问的瓶颈

缺点:

  • 后期分片集群扩容时,需要迁移旧的数据(使用一致性hash算法能较好的避免这个问题),否则会导致历史数据失效。

  • 容易面临跨分片查询的复杂问题。比如上例中,如果频繁用到的查询条件中不带cusno时,将会导致无法定位数据库,从而需要同时向4个库发起查询,再在内存中合并数据,取最小集返回给应用,分库反而成为拖累。

4、实现方式

        分库分表的开源框架中常用的就是sharding-sphere和Mycat。

        sharding-sphere和Mycat后续会有专门单独的章节进行梳理。

        一般分库分表步骤分为:根据容量(当前容量和增长量)评估分库或分表个数 -> 选key(均匀)-> 分表规则(hash或range等)-> 执行(一般双写)-> 扩容问题(尽量减少数据的移动)。

(1)Mycat

Mycat是一个强大的数据库中间件,不仅仅可以用作读写分离、以及分表分库、容灾备份,而且可以用于多租户应用开发、云平台基础设施、让你的架构具备很强的适应性和灵活性,借助于即将发布的Mycat智能优化模块,系统的数据访问瓶颈和热点一目了然,根据这些统计分析数据,你可以自动或手工调整后端存储,将不同的表映射到不同存储引擎上,而整个应用的代码一行也不用改变。

        Mycat的原理中最重要的一个动词是“拦截”,它拦截用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。

        Mycat典型的应用场景:

  • 单纯的读写分离,此时配置最为简单,支持读写分离,主从切换;

  • 分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片;

  • 多租户应用,每个应用一个库,应用程序只连接Mycat,不改造程序本身,实现多租户化;

  • 报表系统,借助Mycat的分表能力,处理大规模报表的统计;

  • 替代Hbase,分析大数据;

  • 作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择。

Mycat高可用方案

        Mycat系统的高可用涉及到Mycat本身的高可用以及后端MySQL的高可用,大多数情况下,建议采用标准的MySQL主从复制高可用性配置。

        MySQL节点开启主从复制的配置方案,并将主节点配置为Mycat的dataHost里的writeNode,从节点配置为readNode,同时Mycat内部定期对一个dataHost里的所有writeHost与readHost节点发起心跳检测,正常情况下,Mycat会将第一个writeHost作为写节点,所有的DML SQL会发送给此节点,若Mycat开启了读写分离,则查询节点会根据读写分离的策略发往readHost(+writeHost)执行,当一个dataHost里面配置了两个或多个writeHost的情况下,如果第一个writeHost宕机,则Mycat会在默认的3次心跳检查失败后,自动切换到下一个可用的writeHost执行DML SQL语句。

        Mycat自身的高可用性,官方建议是采用基于硬件的负载均衡器或者软件方式的HAproxy,HAProxy相比LVS的使用要简单很多,功能方面也很丰富,免费开源。(HAproxy+Mycat集群+MySQL主从所组成的高可用性方案)

(2)sharding-sphere

        Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar这3款相互独立的产品组成。

        ShardingSphere-JDBC 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。

  • 适用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC;
  • 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, HikariCP 等;
  • 支持任意实现 JDBC 规范的数据库,目前支持 MySQL,PostgreSQL,Oracle,SQLServer 以及任何可使用 JDBC 访问的数据库。

        ShardingSphere-Proxy 定位为透明化的数据库代理端,通过实现数据库二进制协议,对异构语言提供支持。 目前提供 MySQL 和 PostgreSQL 协议,透明化数据库操作,对 DBA 更加友好。

        通过混合使用 ShardingSphere-JDBC 和 ShardingSphere-Proxy,并采用同一注册中心统一配置分片策略,能够灵活的搭建适用于各种场景的应用系统。

        数据分片

        指按照某个维度将存放在单一数据库中的数据分散地存放至多个数据库或表中以达到提升性能瓶颈以及可用性的效果。 数据分片的有效手段是对关系型数据库进行分库和分表。ShardingSphere 基于底层数据库提供分布式数据库解决方案,可以水平扩展计算和存储。

        ShardingSphere通过YAML 配置方式,实现数据分片,在 YAML 文件中配置数据分片规则,包含数据源、分片规则、全局属性等配置项,然后调用 YamlShardingSphereDataSourceFactory 对象的 createDataSource 方法,根据配置信息自动完成ShardingSphereDataSource 对象的创建。

rules:
- !SHARDINGtables: # 数据分片规则配置<logic_table_name> (+): # 逻辑表名称actualDataNodes (?): # 由数据源名 + 表名组成(参考 Inline 语法规则)databaseStrategy (?): # 分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一standard: # 用于单分片键的标准分片场景shardingColumn: # 分片列名称shardingAlgorithmName: # 分片算法名称complex: # 用于多分片键的复合分片场景shardingColumns: # 分片列名称,多个列以逗号分隔shardingAlgorithmName: # 分片算法名称hint: # Hint 分片策略shardingAlgorithmName: # 分片算法名称none: # 不分片tableStrategy: # 分表策略,同分库策略keyGenerateStrategy: # 分布式序列策略column: # 自增列名称,缺省表示不使用自增主键生成器keyGeneratorName: # 分布式序列算法名称auditStrategy: # 分片审计策略auditorNames: # 分片审计算法名称- <auditor_name>- <auditor_name>allowHintDisable: true # 是否禁用分片审计hintautoTables: # 自动分片表规则配置t_order_auto: # 逻辑表名称actualDataSources (?): # 数据源名称shardingStrategy: # 切分策略standard: # 用于单分片键的标准分片场景shardingColumn: # 分片列名称shardingAlgorithmName: # 自动分片算法名称bindingTables (+): # 绑定表规则列表- <logic_table_name_1, logic_table_name_2, ...> - <logic_table_name_1, logic_table_name_2, ...> defaultDatabaseStrategy: # 默认数据库分片策略defaultTableStrategy: # 默认表分片策略defaultKeyGenerateStrategy: # 默认的分布式序列策略defaultShardingColumn: # 默认分片列名称# 分片算法配置shardingAlgorithms:<sharding_algorithm_name> (+): # 分片算法名称type: # 分片算法类型props: # 分片算法属性配置# ...# 分布式序列算法配置keyGenerators:<key_generate_algorithm_name> (+): # 分布式序列算法名称type: # 分布式序列算法类型props: # 分布式序列算法属性配置# ...# 分片审计算法配置auditors:<sharding_audit_algorithm_name> (+): # 分片审计算法名称type: # 分片审计算法类型props: # 分片审计算法属性配置# ...- !BROADCASTtables: # 广播表规则列表- <table_name>- <table_name>

配置示例:

dataSources:ds_0:dataSourceClassName: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.DriverjdbcUrl: jdbc:mysql://localhost:3306/demo_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword:ds_1:dataSourceClassName: com.zaxxer.hikari.HikariDataSourcedriverClassName: com.mysql.jdbc.DriverjdbcUrl: jdbc:mysql://localhost:3306/demo_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8username: rootpassword:rules:
- !SHARDINGtables: # 数据分片规则配置t_order: # 逻辑表名称actualDataNodes: ds_${0..1}.t_order_${0..1}  # 由数据源名 + 表名组成(参考 Inline 语法规则)tableStrategy: # 分表策略,缺省表示使用默认分表策略,以下的分片策略只能选其一standard:shardingColumn: order_idshardingAlgorithmName: t_order_inlinekeyGenerateStrategy:column: order_idkeyGeneratorName: snowflakeauditStrategy:auditorNames:- sharding_key_required_auditorallowHintDisable: truet_order_item:actualDataNodes: ds_${0..1}.t_order_item_${0..1}tableStrategy:standard:shardingColumn: order_idshardingAlgorithmName: t_order_item_inlinekeyGenerateStrategy:column: order_item_idkeyGeneratorName: snowflaket_account:actualDataNodes: ds_${0..1}.t_account_${0..1}tableStrategy:standard:shardingAlgorithmName: t_account_inlinekeyGenerateStrategy:column: account_idkeyGeneratorName: snowflakedefaultShardingColumn: account_idbindingTables:- t_order,t_order_itemdefaultDatabaseStrategy:standard:shardingColumn: user_idshardingAlgorithmName: database_inlinedefaultTableStrategy:none:shardingAlgorithms:database_inline:type: INLINEprops:algorithm-expression: ds_${user_id % 2}t_order_inline:type: INLINEprops:algorithm-expression: t_order_${order_id % 2}t_order_item_inline:type: INLINEprops:algorithm-expression: t_order_item_${order_id % 2}t_account_inline:type: INLINEprops:algorithm-expression: t_account_${account_id % 2}keyGenerators:snowflake:type: SNOWFLAKEauditors:sharding_key_required_auditor:type: DML_SHARDING_CONDITIONS- !BROADCASTtables:- t_addressprops:sql-show: false
YamlShardingSphereDataSourceFactory.createDataSource(getFile("/META-INF/sharding-databases-tables.yaml"));

分片键

        用于将数据库(表)水平拆分的数据库字段。 例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。 SQL 中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,Apache ShardingSphere 也支持根据多个字段进行分片。

分片算法

        ShardingSphere 内置提供了多种分片算法,按照类型可以划分为自动分片算法、标准分片算法、复合分片算法和 Hint 分片算法,能够满足用户绝大多数业务场景的需要。此外,考虑到业务场景的复杂性,内置算法也提供了自定义分片算法的方式,用户可以通过编写 Java 代码来完成复杂的分片逻辑。

(1)自动分片算法

        自动分片算法的分片逻辑由 ShardingSphere 自动管理,需要通过配置 autoTables 分片规则进行使用。

  • 取模分片算法:MOD

  • 哈希取模分片算法:HASH_MOD

  • 基于分片容量的范围分片算法:VOLUME_RANGE

  • 基于分片边界的范围分片算法:BOUNDARY_RANGE

  • 自动时间段分片算法:AUTO_INTERVAL

(2)标准分片算法

用于处理使用单一键作为分片键的 =INBETWEEN AND><>=<= 进行分片的场景。

Apache ShardingSphere 内置的标准分片算法实现类包括:

  • 行表达式分片算法:提供对 SQL 语句中的 = 和 IN 的分片操作支持,只支持单分片键。
  • 时间范围分片算法

(3)复合分片算法

        用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。

        行表达式:简化数据节点配置工作量

        由两部分组成,分别是字符串开头的对应 SPI 实现的 Type Name 部分和表达式部分。

${['online', 'offline']}_table${1..3}

最终会解析为:

online_table1, online_table2, online_table3, offline_table1, offline_table2, offline_table3

(4)Hint 分片算法

        用于处理使用 Hint 行分片的场景。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基础教程(011):面向对象中的构造方法

10-面向对象-构造方法 构造方法也叫做构造器、构造函数。 作用&#xff1a;在创建对象的时候给成员变量进行初始化的。 ✅ 一、构造方法的特点特点说明与类同名构造方法的名称必须与类名相同没有返回类型构造方法没有返回值&#xff0c;甚至不能写 void自动调用使用 new 创建对…

Adobe Photoshop:数字图像处理的终极工具指南

Hi&#xff0c;我是布兰妮甜 &#xff01;Adobe Photoshop自1990年问世以来&#xff0c;已经成为数字图像处理领域的标杆和代名词。这款强大的软件不仅彻底改变了摄影、设计和艺术创作的方式&#xff0c;还深刻影响了我们消费和感知视觉内容的文化方式。从专业摄影师到社交媒体…

本期来讲讲什么是LVS集群?

集群和分布式 集群&#xff08;Cluster&#xff09;&#xff0c;解决某个问题将多台计算机组合形成的系统群。 常见的集群类型&#xff1a; 负载均衡(LoadBalancing&#xff0c;简称LB)&#xff1a;由多个相同配置的主机组成&#xff0c;每个主机经过调度承担部分访问&#…

JVM 类加载过程笔记

一、概述 JVM&#xff08;Java Virtual Machine&#xff09;在运行 Java 程序时&#xff0c;需要将 .class 字节码文件加载到内存中&#xff0c;并转换成可以被 JVM 执行的数据结构&#xff0c;这一过程就是 类加载过程&#xff08;Class Loading Process&#xff09;。 JVM 的…

基于爬虫技术的电影数据可视化系统 Python+Django+Vue.js

本文项目编号 25002 &#xff0c;文末自助获取源码 \color{red}{25002&#xff0c;文末自助获取源码} 25002&#xff0c;文末自助获取源码 目录 一、系统介绍二、系统录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状 六、核心代码6.1 查询数据6.2 新…

如何用 LUKS 和 cryptsetup 为 Linux 配置加密

在信息安全愈发重要的今天&#xff0c;为 Linux 系统盘配置全盘加密已经成为很多企业和个人的选择。LUKS&#xff08;Linux Unified Key Setup&#xff09;配合工具 cryptsetup 可以在不牺牲性能的前提下实现高强度加密。本文将通过一个故事化的场景&#xff0c;介绍整个配置过…

VIVADO技巧_BUFGMUX时序优化

1.版本说明日期作者版本说明2025xxxx风释雪初始版本 2.概述 基于VIVADO时序约束&#xff0c;BUFGMUX多路时钟选择原语的设计3.原语介绍 7系列FPGA/UltraSCale/UltraSCaleBUFGMUX_CTRL BUFGMUX_CTRL_inst (.O(O), // 1-bit output: Clock output.I0(I0), // 1-bit input: Cloc…

服务器系统时间不准确怎么办?

服务器系统时间不准确可能会导致日志错乱、任务调度失败、SSL证书校验错误等问题。以下是解决办法&#xff1a;&#x1f310; 一、同步系统时间的方法1. 使用 timedatectl 命令&#xff08;适用于 systemd 系统&#xff09;timedatectl set-ntp true # 开启自动同步 timedatect…

零信任产品联合宁盾泛终端网络准入,打造随需而变、精准贴合业务的网络安全访问体系

零信任网络访问控制&#xff08;Zero Trust Network Access&#xff0c;ZTNA&#xff0c;文中零信任皆指 ZTNA&#xff09;基于“永不信任&#xff0c;持续验证”的理念&#xff0c;打破了企业基于传统网络边界进行防护的固有模式。在当前日趋复杂的网络环境下&#xff0c;内部…

【未限制消息消费导致数据库CPU告警问题排查及解决方案】

一、背景 某天下午&#xff0c;上游系统同一时间突然下了三个大合同数据&#xff0c;平均每个合同数据实例在6万以上的量级&#xff0c;短短几分钟内瞬间有20万左右的流量涌入系统。 而在正常情况下&#xff0c;系统1天处理的流量也不过2千量级&#xff0c;当时数据库指标监控告…

iOS开发 Swift 速记2:三种集合类型 Array Set Dictionary

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

Apache基础配置

一、Apache安装# 安装apache [rootwebserver ~]# yum install httpd -y# 在防火墙中放行web服务 [rootwebserver ~]# firewall-cmd --permanent --add-servicehttp success [rootwebserver ~]# firewall-cmd --permanent --add-servicehttps success# 开启服务 [rootwebserver …

Python100个库分享第37个—BeautifulSoup(爬虫篇)

目录专栏导读&#x1f4da; 库简介&#x1f3af; 主要特点&#x1f6e0;️ 安装方法&#x1f680; 快速入门基本使用流程解析器选择&#x1f50d; 核心功能详解1. 基本查找方法find() 和 find_all()CSS选择器2. 属性操作3. 文本提取&#x1f577;️ 实战爬虫案例案例1&#xff…

石子入水波纹效果:顶点扰动着色器实现

水面波纹的真实模拟是计算机图形学中一个经典且重要的课题,广泛应用于游戏、影视和虚拟现实等领域。本文将从技术原理和实现细节出发,系统介绍如何利用**顶点扰动(Vertex Displacement)**技术,结合多种辅助方法,打造既真实又高效的水面波纹效果。 一、顶点扰动的核心思想…

【FFmpeg 快速入门】本地播放器 项目

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 整体架构 详细流程 &#x1f4c1; 数据流向​ &#x1f4c1; 队列设计​编辑 &#x1f4c1; 线程设计 &#x1f4c1; 音视频同步 &#x1f4c1; 音频输出设计 &#x1f4c1; 视频输出设计 &#x1f4c1; 总结 …

Maven dependencyManagement标签 properties标签

dependencyManagement标签properties标签

前端埋坑之element Ui 组件el-progress display:flex后不显示进度条解决方案

项目适用场景&#xff1a; <divs style"display&#xff1a;flex"> <span>这里是进度条前标题说明</span> <el-progress :percentage"50"></el-progress> </div> 问题呈现&#xff1a; el-progress进度条没啦&#xf…

嵌入式学习-土堆PyTorch(7)-day23

损失函数的调用import torch from torch import nn from torch.nn import L1Lossinputs torch.tensor([1.0,2.0,3.0]) target torch.tensor([1.0,2.0,5.0])inputs torch.reshape(inputs, (1, 1, 1, 3)) target torch.reshape(target, (1, 1, 1, 3)) #损失函数 loss L1Loss…

【2025最新】使用neo4j实现GraphRAG所需的向量检索

学习笔记&#xff0c;比较混乱&#xff0c;介意慎点。 背景 在将UMLS或者LightRAG构造的数据库存入neo4j之后&#xff0c;我开始将知识图谱运用到实际场景的使用中、例如查询、推理。然而&#xff0c;由于字符串匹配导致大量术语在检索时出现缺失。导致检索效果不佳。我们需要…