分布式数据访问服务之1—华山论剑篇

  业界主流的互联网架构中,分布式服务框架、分布式数据访问服务、消息队列服务、服务网关(API)、分布式事务等都是核心的组件和框架。

当我们的系统规模越来越大,从几台服务器扩展到几十台、几百台、上千台,传统的烟囱式的、大集中式系统架构,逐步演进为服务化SOA、分布式的系统架构:

在数据层面,应用层面,访问层面和查询方面,全都以分布式的结构来搭建,使整个系统不存在性能和横向扩展的瓶颈,实现系统的弹性伸缩和横向扩展,

以支撑我们超大规模的系统。

      最近研究了业界主流的分布式数据访问服务,做了一次横向对比和分析。基于对比做技术选型、验证,目的就是要设计一套.Net版本的分布式数据访问组件。

      搞了这么多年.Net,ORMapping(EF、Hibernate、MyBatis),有必要搞一个“分布式数据访问服务”的技术专题,作为总结和技术分享。

      这个系列的第一篇以"华山论剑" 开始吧,细数各门各派的看家本领(分布式数据访问服务框架),一较高低!

一、微软Azure SQL 

使用 Azure SQL 数据库的可缩放工具和功能,可以轻松地横向扩展数据库。特别是可以使用弹性数据库客户端库来创建和管理扩大的数据库。

此功能支持使用成百上千个 AzureSQL 数据库,轻松地开发数据分区应用程序。然后,可以使用弹性作业帮助简化这些数据库的管理。

它包含了三个核心组件:分片映射管理、数据路由、多分片查询

1. 分片映射管理器:分片映射管理器是一个特殊的数据库,它维护一个分片集中有关所有分片 (数据库)的全局映射信息。

2. 数据路由:使用查询中的数据将请求路由到相应数据库的功能

假设将一个请求传入应用程序。基于请求的分区键值,应用程序必须根据该键值判断正确的数据库。接着,它会与数据库建立连接来处理请求。借助数据依赖路由

能够通过对应用程序的分片映射的单个简单调用打开连接,进行数据操作:

3.  多分片查询:多分片查询用于诸如数据收集/报告等需要跨多个分片运行查询的任务。(相比之下,数据相关的路由会在单个分片上执行所有操作。)

当一个请求涉及多个(或所有)分片时,多分片查询将生效。多分片查询在所有分片或一组分片上执行相同的 T-SQL 代码。使用 UNION ALL 语义,

将参与分片中的结果合并到一个总结果集中。该功能是通过该客户端库处理多个任务公开的,其中包括连接管理、线程管理、故障处理和中间结果处理。

最多可以查询数百个分片

总结:微软的Azure SQL是一个PaaS层的数据访问服务,需要将本地数据库迁移到Azure SQL,即云端SQLServer中,

整个Azure SQL支持对SQLServer的横向扩展,在SDK层面简化屏蔽了分库分表带来的一些编程问题,如果采用Azure SQL的话,

分库分表的部署、管理、集成的确非常方便,原生支持。但是本地化私有云环境下,SQLServer的分库分表就需要自己搞了。

二、阿里分布式关系型数据库服务DRDS——云端数据库PaaS服务

DRDS 目前定位成一个中间件(前身是TDDL),在业务应用和RDS(关系型数据库服务器)之间,本身不承担数据存储,

只负责解决分布式情况下数据操作路由、执行、数据处理等功能。主要支持的数据库是MySQL。

DRDS的使用与MySQL非常接近,建实例、建库、建表、SQL操作,唯一比较大的区别在于水平拆分模式下,DRDS对于建表需要指定拆分字段(类似索引),

只要带上这个拆分字段,SQL只会在部分数据分片上执行,从而加速SQL执行速度。

DRDS有着比较完整的MySQL SQL兼容性

DRDS 对于单机事务完整支持,也就是业务中一个事务中的各个SQL最终都落到同一个数据库即可保障强一致,

对于跨数据库的分布式事务,DRDS提供最终一致分布式事务给业务使用,目前处于内测阶段。

1. DRDS基本原理-读写分离:

对于sql进行类型判定,如果判定为读取操作,则按照用户设置的读权重进行sql路由,到主实例或者到只读上进行sql操作。

2. DRDS基本原理-水平拆分

对于sql进行类型判定,如果判定为读取操作,则按照用户设置的读权重进行sql路由,到主实例或者到只读上进行sql操作。

DRDS中的数据是按照拆分字段值,加上特定的算法进行计算,根据结果存储数据到对应分片。

3. DRDS基本原理-SQL路由

当用户SQL到DRDS时,DRDS会解析整个SQL含义,然后按照拆分字段的值和执行策略将SQL路由到对应分区进行执行。

4. DRDS基本原理-数据合并:

如果一个SQL对应多个分片数据执行,DRDS会将各个分片返回的数据按照原始SQL语义进行合并。

5. DRDS支持的SQL语法

6. DRDS不支持的SQL语法:

    受限于分布式事务

  • 跨分片操作, UPDATE/DELETE [ORDER BY] LIMIT

  • 跨分片操作, UPDATE A,B set A.s = B.s+1 WHERE A.ID = B.NAME , 非拆分字段之间的跨库JOIN

  • 拆分键变更, UPDATE A SET A.ID = 1 WHERE XXX, ID为拆分字段

  • 跨分片操作, INSERT A SELECT B WHERE B.ID > XX , 跨库导入导出数据

  • 跨库事务, 比如两次UPDATE不在一个分片上

   子查询限制

  • 暂不支持非where条件的correlate subquery

  • 暂不支持sql中带聚合条件和correlate subquery

7. DRDS是否支持分布式join以及复杂SQL如何支持?

   不是所有的join都能够支持,例如对于大表之间的join,就因为执行代价过高,速度过慢而被DRDS限制,但大部分的join的语义,支持以最高效的方式完成。

   DRDS处理join的原则非常简单:尽可能让join发生在单机

   7.1. 按照同一个维度进行切分:如果能够让join物理上发生在单台机器上,那么任何一类的复杂查询都是可以直接支持的。一般而言,

这就意味着参与join的多张表按照同一个维度进行切分。例如,一个用户有多个商品,每个商品都有自己的商品特征。这时候,如果需要join,可以将所有数据按照用户,

或者按照商品进行切分,那么join就会物理上的发生在同一个机器上,DRDS能够很轻松的保证所有在单机发生的join查询,物理上都能够查出数据,

对于非常复杂的SQL,可以通过注释的方式,直接告知DRDS切分条件,这样就可以绕开SQL解析器进行查询。

  7.2. 小表复制(主数据复制同步):同时可以有选择的将一些不经常更新的,数据量比较小的元数据表复制到全部的节点上。

这样,大表join小表的时候,就从一个分布式join变为了本地join,当然,这种过程需要一定的代价,也就是元数据表内的数据更新,

可能在一小段时间(50~100ms)后才能在分库内看到。

  7.3. 在线查询与离线查询分离:对于复杂的大表和大表的分析和统计类查询,阿里内部推荐采取专门的分析引擎来获取报表数据,比如使用ODPS等,

这类查询使用传统数据库架构,在数据量非常巨大的时候,很可能会影响线上的应用,因此阿里建议将在线和离线查询分开。

总结:阿里的DRDS还是非常强大的,依靠MySQL原生的Replica技术+SQL路由解析+内存数据合并,日常的MySQL分库分表、读写分离等大部分场景都能支持。

三、当当Sharding-JDBC

Sharding-JDBC是当当应用框架ddframe中,关系型数据库模块dd-rdb中分离出来的数据库水平扩展框架,即透明化数据库分库分表访问。

从框架名字看,肯定是Java技术路线的,官方的说明中,Sharding-JDBC功能灵活且全面:

  • 分片策略灵活,可支持=,BETWEEN,IN等多维度分片,

  • 也可支持多分片键共用

  • SQL解析功能完善,支持聚合,分组,排序,Limit,OR等查询,并且支持Binding Table以及笛卡尔积的表查询。

  • 支持柔性事务(目前仅最大努力送达型)。

  • 支持读写分离

Sharding-JDBC定位于日常数据库CRUD操作,目前仅针对DQL和DML语句进行支持

编程示例:

ShardingRule shardingRule = ShardingRule.builder()

    .dataSourceRule(dataSourceRule)

    .tableRules(tableRuleList)

    .databaseShardingStrategy(new DatabaseShardingStrategy("sharding_column", new XXXShardingAlgorithm())) 

    .tableShardingStrategy(new TableShardingStrategy("sharding_column", new XXXShardingAlgorithm()))) 

    .build(); 

DataSource dataSource = ShardingDataSourceFactory.createDataSource(shardingRule); 

  String sql = "SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.user_id=? AND o.order_id=?"; 

    Connection conn = dataSource.getConnection(); 

    PreparedStatement preparedStatement = conn.prepareStatement(sql)) {           

      preparedStatement.setInt(1, 10); 

    preparedStatement.setInt(2, 1001); 

      ResultSet rs = preparedStatement.executeQuery();

      {

                while(rs.next()) {

                System.out.println(rs.getInt(1));  

                System.out.println(rs.getInt(2));

        } 

      }

对于复制的综合查询,咨询了当当的架构师团队,他们也在计划通过离线分析和大数据分析来实现,不过其实时性和数据的准确性是一个挑战。

四、Shark:分布式的MySQL分库分表中间件

此Shark非工作流Shark,是云集主要的分布式数据访问框架,也是Java技术路线,它是一个应用程序层的数据访问框架。

Shark的技术优点:

  • 完善的技术文档支持;

  • 动态数据源的无缝切换;

  • 丰富、灵活的分布式路由算法支持;

  • 非proxy架构,应用直连数据库,降低外围系统依赖所带来的宕机风险;

  • 业务零侵入,配置简单;

  • 站在巨人的肩膀上(springjdbc、基于druid的sqlparser完成sql解析任务),执行性能高效、稳定;

  • 提供多机sequenceid的API支持,解决多机sequenceid难题;

  • 缺省支持基于zookeeper、redis3.x cluster作为集中式资源配置中心;

  • 基于velocity模板引擎渲染内容,支持sql语句独立配置和动态拼接,与业务逻辑代码解耦;

  • 提供内置验证页面,方便开发、测试及运维人员对执行后的sql进行验证;

  • 提供自动生成配置文件的API支持,降低配置出错率;

同样,也有很多限制:

  • 不支持强一致性的分布式事务,建议在业务层依赖MQ,保证最终数据一致性;

  • 不建议、不支持多表查询,所有多表查询sql,务必全部打散为单条sql逐条执行;

  • sql语句的第一个参数务必是shard key;

  • shard key必须是整数类型;

项目的Git:https://github.com/gaoxianglong/shark,个人要支持一下,希望能继续增强改进。

五、总结

通过上面四个主要的分布式数据访问服务/框架的比较,我们深入研究了分布式数据访问技术,有以下收获分享给大家:

1. 分布式数据访问组件基于物理上的数据库分库分表,主要解决数据库的横向扩展问题

2. 业界主流的分布式数据访问组件主要面向CRUD操作,复杂查询的实现依赖于数据仓库、分析型数据库、大数据分析等技术来实现

3. Sharding策略和SQL路由是实现分库分表的关键技术,其中Sharding的粒度:主要有两种:Database(数据库) 和 Table(表),即分库和分表

4. Sharding策略主要有以下几种:时间范围、ID哈希、地理区域、Hash分区、枚举分区、表达式计算分区等等

5. 分区键的设计非常重要,阿里的实践值得借鉴:用户和商品两个维度,满足不同用户的需求

6. 分库分表后的复杂查询是一个大的技术挑战:需要解决跨库Join、跨多个Shard查询合并、存储过程、综合BI查询等等,可能需要引入数据仓库和大数据技术来实现

7. 还有分布式事务问题需要解决,阿里有个TXC,可以学习了解借鉴。

综合起来说,分布式数据访问服务是大规模分布式应用的必备中间件,技术复杂度和难度都很高,涉及的技术栈比较多,同时比较深,我们会继续深入研究,

目标是设计一套.Net版本的分布式数据访问服务。有兴趣的小伙伴,可以一起搞

原文地址:http://www.cnblogs.com/tianqing/p/6736320.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

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

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

相关文章

漫画:什么是快速排序?(完整版)

转载自 漫画:什么是快速排序?(完整版) 同冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的。 不同的是,冒泡排序在每一轮只把一个元素冒泡到数列的一端&a…

测试——《微服务设计》读书笔记

一.测试象限(Brain Marick) 二.测试金字塔(Mike Cohn) 1.单元测试 通常只测试一个函数或方法调用,通过TDD或者基于属性而写的测试就属于这一类,在UnitTest中,我们不会启动服务,对且对…

MyKtv点歌系统前台主要功能实现,内附数据库脚本,可以直接运行

C#开发工具:Visual Studio 2012 数据库:Sql Server Windows版本:Win10 分辨率:1366*768 文章的最后有KTV点歌系统的前后台源码下载链接。 在正式写代码之前先看一下运行效果图,如果觉得这个是你需要的,那么…

Java中“/”,“.”所代表的文件路径

转载自 Java中“/”,“.”所代表的文件路径 我们在开发的过程中,经常会去读、写文件。在读写文件的时候,就不得不写文件的路径,使用相对路径的方式有两种:”/”和 “.” 。在写文件的路径的时候,需要了解一…

Hibernate框架(1)

1.Hibernate框架简述 Hibernate的核心组件 在基于MVC设计模式的JAVA WEB应用中,Hibernate可以作为模型层/数据访问层。它通过配置文件(hibernate.properties或hibernate.cfg.xml)和映射文件(***.hbm.xml)把JAVA对象或PO(Persistent Object,持久化对象)映射到数据库中…

通过 Transifex 中文化开源软件

如果您对于汉化软件充满热情, 我软已经发布了以下的开源产品在 Transifex 平台,让社区的小伙伴们参与翻译以及审核: 如何参与? – Transifex 的新手 登录 Transifex 如果您第一次使用 Transifex, 您可以新建立一个账号或是通过您的 GitHub, Google 或 LinkedIn 账号…

第六期.Net开源社群联合分享--除了情结和价格,Azure最适合什么场景?等你来讲趟坑的实战经验!

嘿嘿,大家好啊!好荣幸啊这一期,能够咱们.NET开源社区一块来做这次线上分享会。 我就是各位小伙伴可爱而且博学而且低调而且人见人爱花见花开而且谦虚但是经常口不择言的主持人老板娘Grace。 这次有新朋友,有老朋友,有…

支付系统的防重设计

转载自 支付系统的防重设计 导读 “目前在互联网应用的大部分支付场景中,对接支付宝、微信移动支付产品这样需要用户参与支付流程的支付方式已经变得非常普遍,类似的还有PC端银行网银支付;而通过绑定用户银行卡、对接银行卡快捷支付通道直接…

Windows Server Containers 支持 Windows 开发者使用 Docker

在过去几年里,Docker 和容器已成为全球开发界和企业最热门的话题之一。去年秋天发布的 Windows Server 2016 支持 Windows 开发者使用容器,使得这一热门话题再次升温。Windows 和 Docker 是如何走到一起的? 一切始于 2014 年隆重举办的普吉特…

漫画:什么是二叉堆?(修正版)

转载自 漫画:什么是二叉堆?(修正版) 什么是二叉堆? 二叉堆本质上是一种完全二叉树,它分为两个类型: 1.最大堆 2.最小堆 什么是最大堆呢?最大堆任何一个父节点的值,都…

漫画:什么是堆排序

转载自 漫画:什么是堆排序 在上一篇漫画中,小灰介绍了 二叉堆 这样一种强大的数据结构: 漫画:什么是二叉堆?(修正版) 那么,这个二叉堆怎样来使用呢?我们这一期将会详…

监控——《微服务设计》读书笔记

在单块应用的世界里,当我们遇到问题时,我们至少清楚从哪里开始调查。网站访问速度?网站访问异常?CPU占用过高?这些都是单块应用程序的问题,单一的故障点会极大地简化对问题的排查。 而现在我们面对了多个微…

什么是 TCC分布式事务

转载自 什么是 TCC分布式事务 近两年微服务变得越来越火热,各种框架与组件的出现,更是为微服务的开发提供了便利。 我们都知道,每个微服务都是一个对应的小服务,多个服务之间可以方便的进行功能的组合,来形成功能更…

.NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇

Linux守护进程是Linux的后台服务进程,相当于Windows服务,对于为Linux开发服务程序的朋友来说,Linux守护进程相关技术是必不可少的,因为这个技术不仅仅是为了开发守护进程,还可以拓展到多进程,父子进程文件描…

选择大公司还是小公司

转载自 选择大公司还是小公司 本文转载自公众号 stormzhang,文中的“我”是原文作者。 前一段时间,我一知识星球的球友问我这么一个问题,说他是某 985 应届生,拿到了 BAT 一家互联网大公司的 offer,但同时他还拿到了…

未来的C#之只读引用与结构体

C中提供了const特性,使用该特性定义的参数,其所引用的参数或对象将不会被调用函数修改(当然const还提供了更多的特性,参见“Const正确性”)。在新的建议中,C#也将提供类似的特性。 只读ref参数 在C#中&am…

漫画:什么是优先队列

转载自 漫画:什么是优先队列 在之前的漫画中,我们介绍了二叉堆和堆排序。没看过的小伙伴可以看一看前文: 漫画:什么是二叉堆?(修正版) 漫画:什么是堆排序? 这一次&a…