ShardingSphere数据分片、读写分离、数据屏蔽教程

news2024/11/19 7:47:50

本文不讨论框架实现原理以及源码分析,只做功能使用案例说明

数据分片:

表分可以帮助评论应用程序更有效地管理其不断增长的评论表,提高性能和可扩展性,同时还使备份和维护任务更易于管理

 Apache ShardingSphere 有两种形式:

  1. ShardingSphere-JDBC是一个轻量级的Java框架,在Java的JDBC层提供额外的服务。
  2. ShardingSphere-Proxy是一个透明的数据库代理,提供了一个数据库服务器,封装了数据库二进制协议来支持异构语言。

本文主要针对ShardingSphere-JDBC 的数据分片。

依赖项:

org.apache.shardingsphere:shardingsphere-jdbc-core:5.3.2

org.apache.shardingsphere:shardingsphere-cluster-mode-core:5.3.2

org.apache.shardingsphere:shardingsphere-cluster-mode-repository-zookeeper:5.3.2

org.apache.shardingsphere:shardingsphere-cluster-mode-repository-api:5.3.2

建议使用ShardingSphere的版本是5.X版本,最好是非spring boot 的 starter版本,这样会更加灵活

配置项:

ShardingSphere-JDBC配置主要有两种方式:YAML配置和Java配置。本文选择了YAML配置方式

application.yaml

spring:
  datasource:
    username: my_user
    password: my_password
    url: jdbc:mysql://localhost:3306/reviews-db?allowPublicKeyRetrieval=true&useSSL=false
    tomcat:
      validation-query: "SELECT 1"
      test-while-idle: true
  jpa:
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect
    open-in-view: false
    hibernate:
      ddl-auto: none

我们指定用于数据源的驱动程序将是ShardingSphereDriver并且url应该根据此文件选择sharding.yaml

dataSources:
  master:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:3306/reviews-db?allowPublicKeyRetrieval=true&useSSL=false
    username: my_user
    password: my_password
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 65
    minPoolSize: 1

mode:
  type: Standalone
  repository:
    type: JDBC

rules:
  - !SHARDING
    tables:
      reviews:
        actualDataNodes: master.reviews_$->{0..1}
        tableStrategy:
          standard:
            shardingColumn: course_id
            shardingAlgorithmName: inline
    shardingAlgorithms:
      inline:
        type: INLINE
        props:
          algorithm-expression: reviews_$->{course_id % 2}
          allow-range-query-with-inline-sharding: true
props:
  proxy-hint-enabled: true
  sql-show: true

现在让我们分析配置中重要的属性:

  • dataSources.master– 这是我们主数据源的定义。
  • mode– 既可以是standalone with JDBCtype,也可以是cluster with Zookeepertype(推荐用于生产),用于配置信息持久化
  • rules– 在这里,我们可以启用各种ShardingSphere功能,例如 –!SHARDING
  1. tables.reviews– 在这里,我们根据inline语法规则描述实际的表,这意味着我们将有两个表reviews_0并按reviews_1列分片course_id
  2. shardingAlgorithms– 在这里,我们通过一个 groovy 表达式来描述手动内联分片算法,该表达式告诉评论表根据列分为两个表course_id
  • props– 在这里,我们启用了拦截/格式化 sql 查询(可以禁用/注释 p6spy)。

重要提示: 在开始我们的应用程序之前,我们需要确保创建了我们定义的分片,因此我在我的数据库中创建了两个表:reviews_0reviews_1( init.sql)。

请求调试:

现在我们准备启动我们的应用程序并执行一些请求

POST http://localhost:8070/api/v1/reviews/
Content-Type: application/json

{
  "text": "This is a great course!",
  "author": "John Doe",
  "authorTelephone": "555-1234",
  "authorEmail": "johndoe@example.com",
  "invoiceCode": "ABC123",
  "courseId": 123
}

我们可以看到如下日志:

INFO 35412 --- [nio-8070-exec-2] ShardingSphere-SQL: Actual SQL: master ::: insert into reviews_1 (created_at, last_modified_at, author, author_email, author_telephone, course_id, invoice_code, text, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) ::: [2023-04-17 15:42:01.8069745, 2023-04-17 15:42:01.8069745, John Doe, johndoe@example.com, 555-1234, 123, ABC123, This is a great course!, 4]

如果我们要使用不同的负载执行另一个请求:

INFO 35412 --- [nio-8070-exec-8] ShardingSphere-SQL: Actual SQL: master ::: insert into reviews_1 (created_at, last_modified_at, author, author_email, author_telephone, course_id, invoice_code, text, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) ::: [2023-04-17 15:43:47.3267788, 2023-04-17 15:43:47.3267788, Mike Scott, mikescott@example.com, 555-1234, 123, ABC123, This is an amazing course!, 5]

现在我们可以根据course_id

GET http://localhost:8070/api/v1/reviews/filter?courseId=123

GET http://localhost:8070/api/v1/reviews/filter?courseId=124

并在日志中观察我们两个表之间的路由是如何发生的。

INFO 35412 --- [nio-8070-exec-9] ShardingSphere-SQL: Actual SQL: master ::: select review0_.id as id1_0_, review0_.created_at as created_2_0_, review0_.last_modified_at as last_mod3_0_, review0_.author as author4_0_, review0_.author_email as author_e5_0_, review0_.author_telephone as author_t6_0_, review0_.course_id as course_i7_0_, review0_.invoice_code as invoice_8_0_, review0_.text as text9_0_ from reviews_1 review0_ where review0_.course_id=? ::: [123]

INFO 35412 --- [nio-8070-exec-5] ShardingSphere-SQL: Actual SQL: master ::: select review0_.id as id1_0_, review0_.created_at as created_2_0_, review0_.last_modified_at as last_mod3_0_, review0_.author as author4_0_, review0_.author_email as author_e5_0_, review0_.author_telephone as author_t6_0_, review0_.course_id as course_i7_0_, review0_.invoice_code as invoice_8_0_, review0_.text as text9_0_ from reviews_0 review0_ where review0_.course_id=? ::: [124]

第一个select针对reviews_1表,第二个针对reviews_0-正在运行的分

分片进阶操作:

默认分片策略是对配置文件中的shardingColumn进行algorithm-expression配置规则运算,如果有些定制化的场景需求,那么也可以自己实现分片计算逻辑
sharding.jdbc.config.sharding.tables.reviews.actual-data-nodes= master.reviews_$->{0..1}
sharding.jdbc.config.sharding.tables.reviews.table-strategy.standard.sharding-column=course_id
sharding.jdbc.config.sharding.tables.reviews.table-strategy.standard.precise-algorithm-class-name=com.demo.shardingjdbc.PreciseShardingDBAlgorithm
sharding.jdbc.config.sharding.tables.reviews.table-strategy.standard.range-algorithm-class-name=com.demo.shardingjdbc.RangeShardingDBAlgorithm

自定义精确匹配策略实现:

主要用于where、in

public class PreciseShardingDBAlgorithm implements PreciseShardingAlgorithm<String> {
   @Override
   public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> preciseShardingValue) {
        
    }
}

自定义范围匹配的策略实现:

public class PreciseShardingDBAlgorithm implements RangeShardingAlgorithm<String> {
   @Override
   public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> preciseShardingValue) {
        
    }
}

读写分离:

现在让我们想象另一个问题,评论应用时间可能会在高峰时段承受高压力,从而导致响应时间变慢并降低用户体验。针对这个问题,我们可以实现读写分离来平衡负载,提高性能。

ShardingSphere 为我们提供了读写分离的 解决方案。读写分离涉及将读取查询定向到副本数据库,将写入查询定向到数据库,确保读取请求不会干扰写入请求并优化数据库性能。

在配置读写分离解决方案之前,我们必须对数据库架构进行一定变更(主从模式)

读写分离数据源配置:

dataSources:
  master:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:3306/reviews-db?allowPublicKeyRetrieval=true&useSSL=false
    username: my_user
    password: my_password
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 65
    minPoolSize: 1

  slave0:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:49922/reviews-db?allowPublicKeyRetrieval=true&useSSL=false
    username: my_user
    password: my_password
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 65
    minPoolSize: 1

  slave1:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.jdbc.Driver
    jdbcUrl: jdbc:mysql://localhost:49923/reviews-db?allowPublicKeyRetrieval=true&useSSL=false
    username: my_user
    password: my_password
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 65
    minPoolSize: 1

读写分离规则:

- !READWRITE_SPLITTING
  dataSources:
    readwrite_ds:
      staticStrategy:
        writeDataSourceName: master
        readDataSourceNames:
          - slave0
          - slave1
      loadBalancerName: readwrite-load-balancer
  loadBalancers:
    readwrite-load-balancer:
      type: ROUND_ROBIN

我们指定写入数据源名称为master读取数据源指向我们的 slaves:slave0and slave1; 我们选择了一种round-robin 负载均衡器算法

重要提示: 最后要进行的更改是关于分片规则,它对新配置的读写分离规则一无所知并直接指向 master:

分片数据源变更:

sharding.jdbc.config.sharding.tables.reviews.actual-data-nodes=readwrite_ds.reviews_$->{0..1}

我们可以启动我们的应用程序,运行相同的 POST 请求并观察日志:

INFO 22860 --- [nio-8070-exec-1] ShardingSphere-SQL: Actual SQL: master ::: insert into reviews_0 (created_at, last_modified_at, author, author_email, author_telephone, course_id, invoice_code, text, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) ::: [2023-04-17 16:12:07.25473, 2023-04-17 16:12:07.25473, Mike Scott, mikescott@example.com, 555-1234, 124, ABC123, This is an amazing course!, 7]

这里分片仍然有效,并且查询发生在master数据源(写入数据源)中。但是如果我们要运行几个 GET 请求,我们将观察到以下内容:

INFO 22860 --- [nio-8070-exec-2] ShardingSphere-SQL: Actual SQL: slave0 ::: select review0_.id as id1_0_, review0_.created_at as created_2_0_, review0_.last_modified_at as last_mod3_0_, review0_.author as author4_0_, review0_.author_email as author_e5_0_, review0_.author_telephone as author_t6_0_, review0_.course_id as course_i7_0_, review0_.invoice_code as invoice_8_0_, review0_.text as text9_0_ from reviews_0 review0_ where review0_.course_id=? ::: [124]

INFO 22860 --- [nio-8070-exec-4] ShardingSphere-SQL: Actual SQL: slave1 ::: select review0_.id as id1_0_, review0_.created_at as created_2_0_, review0_.last_modified_at as last_mod3_0_, review0_.author as author4_0_, review0_.author_email as author_e5_0_, review0_.author_telephone as author_t6_0_, review0_.course_id as course_i7_0_, review0_.invoice_code as invoice_8_0_, review0_.text as text9_0_ from reviews_0 review0_ where review0_.course_id=? ::: [124]

您可以观察读写分离的运行情况;我们的 写入 查询发生在master数据源中,但我们的读取查询发生在主副本(slave0slave1)中,同时保持正确的分片规则。

数据屏蔽:

关于我们的应用程序的另一个假想问题。想象一下,由于数据隐私法规,某些用户或应用程序可能需要访问客户电子邮件、电话号码和发票代码等敏感信息,同时对其他人保持隐藏状态。

为了解决这个问题,我们可以实施数据屏蔽解决方案,在映射结果时或在 SQL 级别屏蔽敏感数据。ShardingSphere在这里通过另一个易于启用的功能来解决——数据屏蔽

配置变更:

- !MASK
  tables:
    reviews:
      columns:
        invoice_code:
          maskAlgorithm: md5_mask
        author_email:
          maskAlgorithm: mask_before_special_chars_mask
        author_telephone:
          maskAlgorithm: keep_first_n_last_m_mask

  maskAlgorithms:
    md5_mask:
      type: MD5
    mask_before_special_chars_mask:
      type: MASK_BEFORE_SPECIAL_CHARS
      props:
        special-chars: '@'
        replace-char: '*'
    keep_first_n_last_m_mask:
      type: KEEP_FIRST_N_LAST_M
      props:
        first-n: 3
        last-m: 2
        replace-char: '*'

让我们看看这里有什么:

  • table.reviews– 我们为前面提到的每一列定义了三种掩码 算法
  • maskAlgorithms.md5_mask– 我们MD5为 invoice_code 指定了算法类型
  • maskAlgorithms.mask_before_special_chars_mask– 我们MASK_BEFORE_SPECIAL_CHARS为列配置了算法,这意味着@ author_email符号之前的所有字符都将替换为*符号。
  • maskAlgorithms.keep_first_n_last_m_mask– 我们KEEP_FIRST_N_LAST_Mauthor_telephone列配置了算法,这意味着只有电话号码的前 3 个和后 2 个字符保持不变;介于两者之间的所有内容都将被* 符号掩盖。

我们启动我们的应用程序并执行相同的 POST 请求

INFO 35296 --- [nio-8070-exec-1] ShardingSphere-SQL: Actual SQL: master ::: insert into reviews_0 (created_at, last_modified_at, author, author_email, author_telephone, course_id, invoice_code, text, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?) ::: [2023-04-17 16:26:51.8188306, 2023-04-17 16:26:51.8188306, Mike Scott, mikescott@example.com, 555-1234, 124, ABC123, This is an amazing course!, 9]
[
  {
    "text": "This is an amazing course!",
    "author": "Mike Scott",
    "authorTelephone": "555***34",
    "authorEmail": "*********@example.com",
    "invoiceCode": "bbf2dead374654cbb32a917afd236656",
    "courseId": 124,
    "id": 9,
    "lastModifiedAt": "2023-04-17T15:44:43"
  },
]

数据在数据库中保持不变,但在查询和传递时,根据我们在数据屏蔽规则中定义的算法屏蔽了电话、电子邮件和发票代码

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

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

相关文章

公众号推文添加附件秀米添加附件?三步轻松实现

很多人都不知道&#xff0c;其实公众号文章正文是支持添加附件的&#xff0c;只是需要借助一个叫做“文章附件”的网站来实现。公众号自身是不支持直接上传文件的&#xff0c;但是我们可以通过另外的方式来实现。 其实原理很简单&#xff0c;公众号文章中是可以添加小程序链接…

AOP(小卡拉米!!!)温故!

前面我们说了AOP底层是使用代理模式进行实现&#xff0c;spring写的接口是通过代理反射&#xff0c;实现方法&#xff0c;然后定义切入点&#xff1a; springAOP接口定义的方法有&#xff1a;被加强的方法前执行&#xff0c;被加强的方法后执行&#xff0c;出错了执行&#xf…

docker数据卷volume详细配置案例讲解

docker数据卷 文章目录 docker数据卷1.docker挂载宿主机数据卷1.2.具体配置1.3.挂载命令1.3.1访问页面 2.多端口的容器nginx配置2.1.创建目录位置2.2.访问结果 3.数据卷volume持久化配置3.1.语法格式3.2.详细参数3.3.操作案例3.4.数据改动3.5.查看卷的详细属性 4.与某个容器使用…

如何利用技术做到脱颖而出?亚马逊云科技泛娱乐高峰论坛为你揭秘

互联网技术的飞速进步与数字内容消费的蓬勃发展&#xff0c;使得泛娱乐市场越来越红火&#xff0c;用户对于高品质内容的个性化需求也在不断提升&#xff0c;这对技术底座也提出了更加严苛的要求&#xff0c;时代潮流已至&#xff0c;如何利用技术在一片红海中做到脱颖而出&…

【溯源反制】CDN域前置云函数-流量分析|溯源

文章目录 CDN隐藏C2地址环境搭建上传至威胁感知平台直接分析使用DNSQuerySniffer和Process Monitor定位进程网络流量分析文件属性(IDAPro Ollydbg) 域前置隐藏环境搭建威胁感知流量分析 云服务API网关/云函数云函数使用HTTPcs的流量可以简单的分为三个阶段 云函数使用HTTPS 总结…

kali Linux root密码修改

kali root 密码修改有时候是经常发生的,要么忘记,要么是必须限时要改的,今天记录下,修改方法,以便后续。 Kali Linux的前身是BackTrack Linux发行版。Kali Linux是一个基于Debian的Linux发行版,它被认为是最好的渗透测试的 Linux 发行版之一,而且名副其实。 作为一名从…

Vivado使用技巧:时钟的约束方法

时钟的基础知识 数字设计中&#xff0c;“时钟”表示在寄存器之间可靠地传输数据所需的参考时间&#xff1b;Vivado的时序引擎利用时钟特征来计算时序路径需求&#xff0c;通过计算时间裕量&#xff08;Slack&#xff09;的方法报告设计的时序空余&#xff1b;时钟必须…

C++11 -- 入门基础知识

文章目录 C11简介列表初始化std::initializer_list 变量类型推导nullptr范围for循环STL中的一些变化 C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了C98称为C11之前的最新C标准名称。不过由于C03(TC1)主要是对C98标准中…

怎么在照片上添加logo

怎么在照片上添加logo&#xff1f;现在是全面自媒体的时代&#xff0c;很多旅行博主或者摄影爱好者喜欢将自己拍摄的照片发布到各大平台上&#xff0c;分享自己的摄影作品&#xff0c;不过互联网属于一个开放平台&#xff0c;所以盗取照片的事情时有发生&#xff0c;很多不法分…

LabVIEWCompactRIO 开发指南16 有效使用网络共享变量的技巧

LabVIEWCompactRIO 开发指南16 有效使用网络共享变量的技巧 在使用网络共享变量进行编程时&#xff0c;可以遵循三个技巧来最大化性能并避免任何不需要的行为。图4.11显示了包含每个技巧的初始化过程。 技巧1:初始化共享变量 在应用程序开始时将共享变量初始化为已知值。如…

全文检索-Elasticsearch-整合SpringBoot

文章目录 前言一、整合检索服务1.1 创建 gulimall-search 模块1.2 配置 Maven 依赖1.3 搜索服务注册到注册中心1.4 新增 es 配置类1.5 测试 RestHighLevelClient 组件 二、存储数据到 ES2.1 测试 ES 简单插入数据2.2 测试 ES 查询复杂语句2.3 读入数据 前言 前面记录了 Elasti…

如何修复d3dcompiler_47.dll缺失?多种解决方法分享

在使用Windows操作系统的过程中&#xff0c;有时候会遇到d3dcompiler_47.dll缺失的情况。这个问题可能会导致某些应用程序无法正常运行&#xff0c;因此需要及时解决。本文将介绍如何修复d3dcompiler_47.dll缺失的问题。 一.什么是d3dcompiler_47.dll D3dcompiler_47.dll是Di…

Kali-linux查看打开的端口

对一个大范围的网络或活跃的主机进行渗透测试&#xff0c;必须要了解这些主机上所打开的端口号。在Kali Linux中默认提供了Nmap和Zenmap两个扫描端口工具。为了访问目标系统中打开的TCP和UDP端口&#xff0c;本节将介绍Nmap和Zenmap工具的使用。 4.4.1 TCP端口扫描工具Nmap 使…

revit的附着顶部/底部工具使用及CAD图纸转柱

一、revit的附着顶部/底部工具的使用 生活上&#xff0c;有很多建筑是斜屋顶的房子&#xff0c;像是一些别墅的装修&#xff0c;斜屋顶往往比平屋顶更有装饰感&#xff0c;也更有利于排水。 那么在Revit中&#xff0c;绘制带有斜屋顶的往往会遇到这样一个问题&#xff0c;屋顶之…

OpenCL编程指南-3.2OpenCL上下文

OpenCL上下文 上下文是所有OpenCL应用的核心。上下文为关联的设备、内存对象&#xff08;例如&#xff0c;缓冲区和图像&#xff09;以及命令队列&#xff08;在上下文和各设备之间提供一个接口&#xff09;提供了一个容器。正是上下文驱动着应用程序与特定设备以及特定设备之…

算法训练Day53:​ 1143.最长公共子序列 1035.不相交的线 53.最大子序和 动态规划

文章目录 最长公共子序列题解 不相交的线题解 最大子数组和题解 最长公共子序列 CategoryDifficultyLikesDislikesContestSlugProblemIndexScorealgorithmsMedium (64.94%)13110--0 Tags Companies 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子…

浏览csdn博客自动隐藏侧边栏并只看目录

背景 CSDN 总算做了点好事&#xff0c;能够隐藏大部分无关信息&#xff0c;只看博客内容本身。具体如图&#xff0c;还在测试版 以我的一篇博客为例&#xff0c;原始界面&#xff0c;花里胡哨一堆 点击隐藏侧栏后的清爽版 点击只看目录后的清爽版 前提提要 安装油猴脚本&…

使用VSCode创建Vue项目

Vue介绍 Vue.js是一个渐进式JavaScript框架&#xff0c;用于构建用户界面。它可以与其他库或现有项目集成&#xff0c;也可以作为单个组件使用。Vue.js的目标是提供一种简单、快速和灵活的方式来开发交互式Web应用程序。 Vue.js的核心特性包括&#xff1a; 响应式数据绑定&am…

http协议格式

HyperText Transfer Tansfer Protocol 超文本传输协议&#xff0c;是一种基于TCP的应用层协议&#xff0c;也是目前为止最为流行的应用层协议之一&#xff0c;可以说HTTP协议是万维网的基石。历经了0.9、HTTP/1.0、HTTP/1.1、HTTP/2几个版本(关于HTTP协议的历史&#xff0c;这里…

unity-物体rotation翻转180度后,OnPointerDown失效的问题

问题&#xff1a;今天碰到一个问题&#xff0c;就是把物体A进行水平翻转后&#xff0c;如下图&#xff0c;OnPointerDown 就失效了 》解决方案1&#xff08;使用Scale X来替代Rotation Y&#xff09;&#xff1a; 使用Scale改为-1来翻转&#xff0c;这样 OnPointerDown 就正常…