分库分表之sharding-jdbc_分库分表shardingjdbc-程序员宅基地

技术标签: sharding-jdbc  java  中间件  数据库  

分库分表之sharding-jdbc

背景:

随着mysql越来越成熟以及去IOE的大势下,mysql被互联网公司运用的炉火纯青的同时,也被带进金融行业。但金融行业有其特殊属性,对数据的要求非常高,而相对轻巧mysql数据库往往需要辅助工具来解决某些严苛的使用场景。而因为mysql的轻巧等因素,导致其单机比较容易出现性能瓶颈,而成熟的oralce单机性能强悍。但是对比成熟且昂贵的oracle来说,开源免费的特性配合成熟的生态使得越来越被企业选用,但相应的运维能力要求也水涨船高。

以金融业的某银行为例,其新建设的网络信用贷款系统采用分布式架构,数据库存储采用mysql。系统架构之初将应用按照业务粒度拆分,同时为每个应用设计一个数据库,专库专用,但所有的库都集中在一台机器上。新系统刚上线业务量不大,而迁移过来的数据量也不大,单机跑也问题不大。但随着后续接入的产品越来越多,业务上来后,存储的数据达到千万级别后,单机瓶颈会突显,cpu占用高,io读写速度慢,数据占用磁盘巨大等噩需解决的棘手问题。此时可进行多种方案将单机性能瓶颈上移,比如拆库,采用中间件分库分表等。但无论采用哪种方案,风险都在,效果也不相同。

有没有一种相对不需要太高运维能力的技术,达到分库分表呢?当当网开源的sharding-jdbc就很适合,只需要引入一个jar包,加上配置即可。对开发透明,也无需多加中间件机器,大大减少运维难度,达到单库变多库,单表变多表,从而达到提升系统性能等优势。

分库分表:

分库:分为水平分库和垂直分库。水平分库简单理解就是一个库复制几个一摸一样的库,垂直分库简单理解就是将原本一个库按业务或者其它维度拆分成多个库。

分表:分为水平分表和垂直分表。简单理解跟分库差不多,水平分表即复制几个一摸一样的表,垂直分表就是将原本一个表的字段以业务或者其它规则拆分成几个表。

分库分表带来如下问题:

事务一致性:

由于分库分表把数据分布在不同库甚至不同服务器,不可避免会带来分布式事务问题。

跨关联节点查询:

在没分库前,查询关联表,直接关联就行。分库后,关联表可能不在一个库,甚至不在一台机器上,以往查询一次的情况,可能需要查询两次。

跨界点分页排序:

跨节点多库进行查询时,limit分页、order by排序等问题,就变得比较复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序。

主键避重:

在分库分表环境中,由于表中数据同时存在不同数据库中,主键值平时使用的自增长将无用武之地,某个分区数据库生成的ID无法保证全局唯一。因此需要单独设计全局主键,以避免跨库主键重复问题。

公共表:

实际的应用场景中,参数表、数据字典表等都是数据量较小,变动少,而且属于高频联合查询的依赖表。可以将这类表在每个数据库都保存一份,所有对公共表的更新操作都同时发送到所有分库执行。

由于分库分表之后,数据被分散在不同的数据库、服务器。因此,对数据的操作也就无法通过常规方式完成,并且它还带来了一系列的问题。好在,这些问题不是所有都需要在应用层面上解决,市面上有很多中间件可供选择,其中Sharding-JDBC使用流行度较高,了解下它。

Sharding-jdbc

简介:

它定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种 ORM框架。 Sharding-JDBC的核心功能为数据分片和读写分离,通过Sharding-JDBC,应用可以透明的使用jdbc访问已经分库分表、读写分离的多个数据源,而不用关心数据源的数量以及数据如何分布。

与jdbc性能对比:

性能损耗测试:服务器资源充足、并发数相同,比较JDBC和Sharding-JDBC性能损耗,Sharding-JDBC相对 JDBC损耗不超过7%。

性能对比测试:服务器资源使用到极限,相同的场景JDBC与Sharding-JDBC的吞吐量相当。

性能对比测试:服务器资源使用到极限,Sharding-JDBC采用分库分表后,Sharding-JDBC吞吐量较JDBC不分 表有接近2倍的提升。

入门:

需求:

使用sharding-jdbc对借据表(注:演示用,字段列举几个)进行水平分表,通过入门程序开发,快速体验sharding-jdbc使用方法。

环境准备:

操作系统:win10

数据库:mysql5.7

Jdk:64位1.8

应用框架:spring-boot-2.0.5.RELEASE,mybatis3.5

Sharding-JDBC:sharding-jdbc-spring-boot-starter-4.0.0-RC1

创建数据库:

create database loan;

创建表:

CREATE TABLE `loan_1` (

  `loan_id` bigint(20) NOT NULL COMMENT '借据号',

  `prd_code` varchar(50) DEFAULT NULL COMMENT '产品编码',

  `cert_code` varchar(32) DEFAULT NULL COMMENT '证件编码',

  `cert_type` varchar(10) DEFAULT NULL COMMENT '证件类型',

  PRIMARY KEY (`loan_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `loan_2` (

  `loan_id` bigint(20) NOT NULL COMMENT '借据号',

  `prd_code` varchar(50) DEFAULT NULL COMMENT '产品编码',

  `cert_code` varchar(32) DEFAULT NULL COMMENT '证件编码',

  `cert_type` varchar(10) DEFAULT NULL COMMENT '证件类型',

  PRIMARY KEY (`loan_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

引入maven依赖:

引入 sharding-jdbc和SpringBoot整合的Jar包:

<dependency>

         <groupId>org.apache.shardingsphere</groupId>

         <artifactId>sharding-jdbc-spring-boot-starter</artifactId>

         <version>4.0.0-RC1</version>

    </dependency>

编写程序:

分片规则配置是sharding-jdbc进行对分库分表操作的重要依据,配置内容包括:数据源、主键生成策略、分片策 略等。在application.properties中配置

分片规则配置:

 

 

  1. 首先定义数据源m1,并对m1进行实际的参数配置。
  2. 指定loan表的数据分布情况,他分布在m1.loan_1,m1.loan_2
  3. 指定loan表的主键生成策略为SNOWFLAKE,SNOWFLAKE是一种分布式自增算法,保证id全局唯一
  4. 定义loan表的分片策略,loan_id为偶数的数据落在loan_1,为奇数的落在loan_2,分表策略的表达式为 loan_$->{loan_id % 2 + 1}

程序如下:

Mapper文件

 

Test文件

输出

 

数据库

loan_1库

 

Loan_2库

 

从输出日志来看,sharding-jdbc解析了10条sql,按照设定的分片规则进行插入loan_1表和loan_2表。从表中的id来看,雪花算法生成的id如果为奇数,插入loan_2表,为偶数插入loan_1表,与预期一致。

总结:通过简单的快速入门案例,发现sharding-jdbc对开发人员只需要配置好,其它不用关心。操作简单,上手容易。当然,入门案例只是简单对插入数据观察,实际开发中使用更多的是查询,查询稍微复杂和注意事项多,待后续分享以及分库分表的另外一种比较流行的方案。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhangbingfa90/article/details/121572289

智能推荐

Python中with open...as的使用_python中with open as的用法-程序员宅基地

文章浏览阅读6.3k次,点赞2次,收藏21次。with open...as 语句是读写文件很好的语句。为什么要使用“with open...as”语句?“with...as”实际上替代了"try...finally"语句,从而能够自动释放资源。这个语句更加简洁。同时语句自动获取返回的对象,用起来更方便。#为什么使用“with open...as”语句?#“with...as”实际上替代了"try...finally"语句#从而能够..._python中with open as的用法

(附源码)计算机毕业设计ssm果蔬预约种植管理系统_ssm框架下的果蔬信息管理系统设计-程序员宅基地

文章浏览阅读686次。果蔬预约种植管理系统基于Web服务模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在不受时间、地点的限制来使用这个系统。果蔬预约种植管理系统工作原理图,如图4-1所示:图4-1 系统工作原理图4.2。_ssm框架下的果蔬信息管理系统设计

android:hintText与android:inputType详解-程序员宅基地

文章浏览阅读1.5k次。android:hintText为空时显示的文字提示信息,可通过textColorHint设置提示信息的颜色android:inputType设置文本的类型,用于帮助输入法显示合适的键盘类型。 android:hintText="这里提示你该输入什么内容" android:inputType="none" android:inputType="text" _hinttext

Morton码-程序员宅基地

文章浏览阅读1.6w次,点赞13次,收藏56次。版权声明:本文为博主原创文章,转载请注明原文出处!写作时间:2019-07-08 17:11:27Morton码的计算Morton码是对栅格格网进行编码的一种算法,在Google中搜索Morton,搜索结果第一位是Wikipedia的Z-order Curve,这是因为Morton码编码结果展现为一种Z形的填充曲线。下面简要说一下如何计算四进制和十进制的Morton码。四进制Morto..._morton码

OpenLayers教程一:OpenLayers概述-程序员宅基地

文章浏览阅读10w+次,点赞49次,收藏213次。目录一、OpenLayers简介二、OpenLayers的特征三、OpenLayers的框架结构一、OpenLayers简介 OpenLayers是一个用于开发WebGIS客户端的JavaScript包,最初基于BSD许可发行。 OpenLayers是一个开源的项目,其设计之意是为互联网客户端提供强大的地图展示功能,包括地图数据显示与相关操作,并具有灵活的扩展机..._openlayers

MyBatis学习笔记(3)-动态SQL_"select id=\"finduserlist\" parametertype=\"uservo-程序员宅基地

文章浏览阅读186次。动态SQL是MyBatis最核心的功能和最强大的特性之一,在使用原生JDBC进行连接数据库时,若要完成SQL语句拼接,程序员需要小心翼翼地完成代码,非常不方便,而MyBatis基于OGNL表达式的动态SQL机制,对SQL语句进行灵活操作,通过表达式进行判断,对SQL进行灵活拼接、组装。总体说来mybatis 动态SQL 语句主要有以下几类:if 语句 (简单的条件判断) where (主..._"select id=\"finduserlist\" parametertype=\"uservo\" resulttype=\"usercustom"

随便推点

并发编程-01 os底层原理与JMM基础篇_osnj-程序员宅基地

文章浏览阅读5k次。操作系统底层原理与JMM模型一、操作系统底层原理1.1 冯诺依曼模型1.2 操作系统缓存与内存管理1.2.1 操作系统缓存1.2.2 操作系统内存管理1.3 线程与进程二、JMM模型2.1 JMM模型2.2 JMM存在的必要性2.3 数据同步八大原子操作2.4 并发编程三大特性2.4.1 原子性2.4.2 可见性2.4.3 有序性2.5 JMM如何解决原子性、可见性、有序性2.6 volatile特性一、操作系统底层原理想玩转并发编程,前提一定是对计算机底层模型有一定的了解。线程、进程、CPU、内存模型_osnj

两段文章清楚弄明白什么是异步IO、同步IO、同步阻塞IO、同步非阻塞IO、异步阻塞IO、异步非阻塞IO-程序员宅基地

文章浏览阅读739次。百科解释:https://baike.baidu.com/item/%E5%BC%82%E6%AD%A5IO/6018433?fr=aladdin先看2,再看你,会理解的更好!1.2.阻塞和非阻塞# 阻塞和非阻塞关注的是程序在等待调用结果时的状态# 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才返回# 非阻塞调用是指在不能立即得到结果之前,该调用不..._同步io

Android WebView详解:web解析与使用技巧-程序员宅基地

文章浏览阅读134次。MainActivity.javapackagecom.example.web;importandroid.app.Activity;importandroid.app.ProgressDialog;importandroid.content.Intent;importandroid.net.Uri;importandroid.os.Bundle;importandroid.view..._安卓webview请求数据解析

将本地的word文档转为markdown(带图片)发布到CSDN_word文字图片转markdown-程序员宅基地

文章浏览阅读3.3k次,点赞6次,收藏13次。word转为markdown,自动发布_word文字图片转markdown

二维数组及数组例题_二维数组存储地址例题-程序员宅基地

文章浏览阅读2.1k次。二维数组1.定义:二维数组本质上是以数组作为数组元素的数组,即“数组的数组”,类型说明符 数组名 [常量表达式][常量表达式]。于数学中的“矩阵”类似。2.二维数组的遍历,拷贝方式及其他用法上可完全延用一维数组的方法。例题1.键盘上获取不超过10位数字的整数1)求位数2)分别输出每一位的数字3)将整数逆序 public static void main(String [] arg..._二维数组存储地址例题

jvm-sandbox 源码阅读记录_jvm-sandbox-repeater 源码分析-程序员宅基地

文章浏览阅读299次。启动模块即调用@Command修饰的方法通过http 调用ModuleHttpServlet 的 doMethod方法, jvm-sandbox是同构jetty启动了一个http server, 通过http对外交互。增强字节码过程最后增强字节码的动作在 ModuleEventWatcher 的 watch()方法, 一般通过他的默认实现类DefaultModuleEventWatcher中的private int watch() 进行。IBuildingForBehavior的实现类Buil_jvm-sandbox-repeater 源码分析

推荐文章

热门文章

相关标签