热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

分布式数据库和Hadoop都不够好,于是我们设计分布式SQL计算系统

在有了一些分布式数据库和Hadoop实际应用经验的基础上,对比两者的优点和不足,加上自己的一些提炼和思考,设计了一套综合两者的系统。\x0a具体一点,使用数据库水平分割的思想实现数

设计思想
 

为了解决分布式数据库下,复杂的 SQL(如全局性的排序、分组、join、子查询,特别是非均衡字段的这些逻辑操作)难以实现的问题;在有了一些分布式数据库和 Hadoop 实际应用经验的基础上,对比两者的优点和不足,加上自己的一些提炼和思考, 设计了一套综合两者的系统,利用两者的优点, 补充两者的不足。具体的说, 使用数据库水平分割的思想实现数据存储,使用 MapReduce的思想实现 SQL 计算。

这里的数据库水平分割的意思是只分库不分表,对于不同数量级别的表,分库的数量可以不一样,例如 1 亿的数据量分 10 个分库,10 亿的分 50 个分库。对于使用 MapReduce的思想实现计算 ; 对于一个需求,转换成一个或多个有依赖关系的SQL,其中的每个SQL分解成一个或多个 MapReduce任务,每个 MapReduce任务又包含 mapsql、洗牌(shuffle)、reducesql,这个过程可以理解为类似 hive,区别是连 MapReduce任务中的 map 和 reduce 操作也是通过 SQL 实现, 而非 Hadoop 中的 map 和 reduce 操作.

这是基本的 MapReduce的思想,但是在 Hadoop 的生态圈中, 第一代的 MapReduce将结果存储于磁盘,第二代的 MapReduce根据内存使用情况将结果存储于内存或磁盘,类比一下用数据库来存储,那么 MapReduce 的结果就是存储在表中,而数据库的缓存机制天然支持根据内存情况决定存储在内存还是磁盘 ; 另外,Hadoop 生态圈中, 计算模型也并非一种,这里的 MapReduce的计算思想,可以用类似 spark 的 RDD 迭代计算方式来替代 ; 本系统还是基于 MapReduce来说明的。

架构
 

根据以上的思想, 系统的架构如下:

没有代理节点
 

有代理节点
 

模块说明
 

关于系统中的模块,由于和绝大部分的分布式系统类似,这里仅做简要说明:

名称说明
协调节点,也叫代理节点(proxy node)实现常用的数据库客户端和服务端协议,接收客户端请求,并且将请求转换成执行计划,获取执行结果,发送给客户端
客户端(client)发送请求和接收执行结果的;如果是没有协调节点,那么客户端也负责协调节点的工作
数据库节点(db node)用于存储实际的数据,运行接收的mapsql和reducesql
主控机(master)是主进程,管理各个模块和元数据
元数据库(meta database)存储系统的元数据的地方



两种架构的区别
 

无代理节点的时候,客户端担负着比较大的工作,包括:发送请求、解析 SQL、生成执行计划、申请资源、安排执行、获取结果等;有代理节点的时候,代理节点担负着接受请求、解析 SQL、生成执行计划、申请资源、安排执行、返回结果给客户端等大部分责任,另外代理节点提供支持外部协议的接口,如 mysql 的 c/s 协议,使用 mysql 的命令行可以直接连接进来执行 SQL,整个系统就像普通的 mysql server 一样。

应用架构
 

实际应用环境可能是正式环境一套, 正式备份环境一套, 线下环境一套, 可以按照如下的架构进行部署。

基本概念 说明
 

下面针对架构中的一些概念做些说明

概念说明
分布式表类似关系型表的概念,只不过数据是分布在不同的数据库节点上,通过某个字段将数据水平分割到不同的分库的表中
分布式表的分割字段,也叫均衡字段存储数据的时候决定将数据插入分布式表的某个分库的依据字段,如常用的用户id
分布式表的分割方法,也叫均衡策略存储的时候决定如何根据分割字段将数据插入分布式表的方法,如列表,范围,取模hash
计算的洗牌字段类似存储数据时候的分割字段,MapReduce计算的时候,将数据插入reduce端数据库表中所依据的字段;是通过分析SQL得到
计算的洗牌方法类似存储的时候,在MapReduce计算的时候,决定如何根据洗牌字段将数据插入reduce端数据库表中的方法
任务树,也叫阶段树根据客户端输入的SQL,进行分析得到的执行计划
任务节点,也叫阶段(stage)是任务树的某个节点,其实就是MapReduce任务;包含map,洗牌和reduce过程

下面说明常用的增删改查如何执行, 特别是查询操作

增删改操作
 

当插入数据的时候,根据均衡字段和均衡策略将记录插入到对应的数据库节点中。

当更新数据的时候,需要根据均衡策略判断数据更新前的和更新后的数据库节点是否变化:如果没有变化,直接更新;如果有变化,在更新前的数据库节点中删除老数据,在更新后的数据库节点中插入新数据。

当删除数据的时候,根据均衡策略在相应的数据库节点中删除。

这三种变更数据的操作,只要涉及到多个节点的数据变更,都需要使用分布式事务保证一致性、原子性等事务特性。

查询操作
 

查询操作的原理类似 hive,大家可以对比来理解 ; 为了方便解释查询操作, 首先来说明阶段树和阶段的结构,如下图所示:

阶段树
 

阶段
 


   查询步骤

结合上面的图, 查询操作的具体过程如下:

  1. 将输入 SQL 经过词法、语法、语义分析,集合表结构信息和数据分布信息,生成包含多个阶段(简称 stage)的执行计划,这些阶段具有一定的依赖关系,形成多输入单输出的任务树。

  2. 每个阶段包括两种 SQL,称为 mapsql 和 reducesql,另外每个阶段包括三个操作,map、数据洗牌和 reduce;map 和 reduce 分别执行 mapsql 和 reducesql。

  3. 先在不同的数据库节点中执行 map 操作,map 操作执行 mapsql,它的输入是每个数据库节点上的表内部的数据,输出根据某个字段按照一定的规则进行分割,放到不同的结果集中,结果集作为数据洗牌的输入。

  4. 然后执行数据洗牌的过程,将不同结果集拷贝到不同的将要执行 reduce 的数据库节点上。

  5. 在不同的数据库节点中执行 reduce 操作,reduce 操作执行 reducesql;

  6. 最后返回结果。


   例子

由于系统核心在于存储和计算, 下面对存储和计算相关的概念举例说明

均衡策略

举例说明均衡策略,基本信息如下:表名字:tab_user_login表描述:用于存储用户登录信息节点数:4,分为 0、1、2、3

字段字段类型描述
u_idint用户id
login_ipvarchar用户登录ip
login_provincevarchar登录省份
login_dttimestamp用户登录时间

举例说下如下的几种策略:

列表:以登录省份作为均衡字段为例

登录省份节点id
北京0
广东1
黑龙江2
湖南3
…….…….
河南0
浙江1
辽宁2
四川3

取模 hash:按 4 取模, 以用户 id 作为均衡字段

用户id%4节点id
00
11
22
33

范围: 从 0 到一亿,以用户 id 作为均衡字段

用户id范围节点id
0<=value<2500w0
2500w <=value<5000w1
5000w<=value<7500w2
7500w<=value<1亿3

取模 hash 和范围结合:先范围,再取模, 以用户 id 作为均衡字段

(u_id/10000) % 4节点id
00
11
22
33
查询
 

举例说明查询操作,基本信息如下:

用户表 tab_user_info 如下:

字段字段类型字段描述
u_idInt用户id
u_nameVarchar用户姓名
u_reg_dtTimestamp用户注册时间
u_addrVarchar用户地址
u_ageInt用户年龄

用户登录表 tab_login_info 的结构如下:

字段字段类型字段描述
u_idInt用户id
login_ipInt登录ip
login_dtTimestamp登录时间
login_productVarchar登录到哪个产品中
排序
 

排序的关键点是节点之间存在大小关系,大的 key 或者 key 范围放到节点 id 大的节点上,然后在节点上排序,获取数据的时候根据节点 id 大小依次获取。

以如下 sql 为例,某一注册时间范围内的用户信息,按照年龄和 id 排序:

select * from tab_user_info t where u_reg_dt>=? and u_reg_dt<=? order by u_id

执行计划可能为:

Map:

select * from tab_user_info t where u_reg_dt>=? and u_reg_dt<=? order by u_id

Shuffle:

执行完成之后,这种情况下由于需要按照 u_id 进行数据洗牌,所以各个存储节点上需要按照 u_id 进行划分。例如有 N 个计算节点,那么按照(最大 u_id- 最小 u_id)/N 平均划分,将不同存储节点上的同一范围的 u_id,划分到同一个计算节点上即可(这里的计算节点存在大小关系)。

Reduce:

select * from tab_user_info t order by u_id

分组聚合
 

关键点和排序类似,节点之间存在大小关系,大的 key 或者 key 范围放到节点 id 大的节点上,然后在节点上分组聚合,获取数据的时候根据节点 id 大小依次获取。

以如下 sql 为例,某一注册时间范围内的用户,按照年龄分组,计算每个分组内的用户数:

select age,count(u_id) v from tab_user_info t where u_reg_dt>=? and u_reg_dt<=? group by age

执行计划可能为:

Map:

select age,count(u_id) v from tab_user_info t where u_reg_dt>=? and u_reg_dt<=? group by age

Shuffle:

执行完成之后,这种情况下由于需要按照 age 进行数据洗牌,考虑到 age 的唯一值比较少,所以数据洗牌可以将所有的记录拷贝到同一个计算节点上。

Reduce:

select age,sum(v) from t where group by age

连接
 

首先明确 join 的字段类型为数字类型和字符串类型,其他类型如日期可以转换为这两种。数字类型的排序很简单,字符串类型的数据排序需要确定规则,类似 mysql 中的 collation,比较常用的是按照 unicode 编码顺序,按照实际存储节点的大小等;其次 join 的方式有等值 join 和非等值 join;以如下常用且比较简单的情况为例。

以如下 sql 为例,某一注册时间范围内的用户的所有登录信息:

select t1.u_id,t1.u_name,t2.login_product

from tab_user_info t1 join tab_login_info t2

on (t1.u_id=t2.u_id and t1.u_reg_dt>=? and t1.u_reg_dt<=?)

执行计划可能为:

Map:

由于是 join,所有的表都要进行查询操作,并且为每张表打上自己的标签,具体实施的时候可以加个表名字字段,在所有存储节点上执行

select u_id,u_name from tab_user_info t where u_reg_dt>=? and t1.u_reg_dt<=?

select u_id, login_product from tab_login_info t

Shuffle:这种情况下由于需要按照 u_id 进行数据洗牌,考虑到 u_id 的唯一值比较多,所以各个存储节点上需要按照 u_id 进行划分,例如有 N 个计算节点,那么按照(最大 u_id- 最小 u_id)/N 平均划分,将不同存储节点上的同一范围的 u_id,划分到同一个计算节点上。

Reduce:

select t1.u_id,t1.u_name,t2.login_product

from tab_user_info t1 join tab_login_info t2

on (t1.u_id=t2.u_id)

子查询
 

由于子查询可以分解成具有依赖关系的不包含子查询的 SQL,所以生成的执行计划,就是多个 SQL 的执行计划按照一定的依赖关系进行依次执行。

与已有系统的区别和优点
 
  • 相比 hdfs 来说,数据的分布是有规则的,hdfs 需要启动之后执行命令去查询文件具体在什么节点上;元数据的较小,记录规则即可,管理成本较低,在启动速度方面很快。

  • 数据是放在数据库中的,可以很好的使用索引和数据库本身的缓存机制,大大提高数据查询的效率,特别是在大量数据的情况下,利用索引查询返回少量的数据。

  • 数据可以进行删除和修改,这在基于 hdfs 的系统中一般比较麻烦和低效。

  • 在计算方面,和 MapReduce  或者其他的分布式计算框架(如 spark)并没有本质的区别(需要进行 shuffle)。但是由于数据的分布是有规则的,在有些地方可以做的更好,在分布式全文索引体现。

  • 由于线上系统一般使用数据库作为最终的存储位置,而把数据库同步到 hdfs 中是比较麻烦的,并且对于有删除和更新的情况,同步数据麻烦低效,速度较慢;相比之下,这个方案可以使用数据库本身提供的镜像复制功能来同步,基本没有额外的麻烦和低效的工作。

  • 基于以上,可以把线上系统(主系统)和线下的数据分析挖掘(从系统)做成统一的方案, 参见应用架构图。

应用场景
 

最后列举一些应用场景


应用场景说明
线上数据库适用于数据量大、并发大、需要分库分表的情况,并且能兼容各种 SQL,这是最直接且比较合适的场景
数据分析由于系统解决了分布式数据库情况下的复杂 SQL 的执行问题,这也非常容易理解的
机器学习机器学习的逻辑也可以通过 SQL 来实现
搜索引擎通过设计三张分布式表,文档表,单词表,语料库表 ; 文档表使用文档 id 作为均衡字段,单词表使用单词 id 作为均衡字段,语料库表使用单词 id 作为均衡字段,结合搜索引擎的思想,抓取,分析,存储 (索引),搜索等步骤,将其中的存储 (索引),搜索移植到分布式数据库上即可 ; 其实就是换了存储,传统的搜索引擎使用倒排表存储,如 Lucene,现在使用分布式数据库
流计算类似 storm,spark streaming,要实现流计算,需要添加其他的组件,如开放服务端口,定时进行 SQL 计算,为了在速度要求比较高,非精确计算的场景查,可以实现类似布隆过滤器来实现唯一值的逻辑计算,而不需要每次使用 SQL 扫描大量数据,只需要每次到布隆过滤查询一次即可


作者介绍

江和慧,目前就职税友软件,曾经任职网易,专注数据处理领域MySQL、Hadoop,分布式数据库




推荐阅读
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • REVERT权限切换的操作步骤和注意事项
    本文介绍了在SQL Server中进行REVERT权限切换的操作步骤和注意事项。首先登录到SQL Server,其中包括一个具有很小权限的普通用户和一个系统管理员角色中的成员。然后通过添加Windows登录到SQL Server,并将其添加到AdventureWorks数据库中的用户列表中。最后通过REVERT命令切换权限。在操作过程中需要注意的是,确保登录名和数据库名的正确性,并遵循安全措施,以防止权限泄露和数据损坏。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文讨论了在使用sp_msforeachdb执行动态SQL命令时,当发生错误时如何捕获数据库名称。提供了两种解决方案,并介绍了如何正确使用'?'来显示数据库名称。 ... [详细]
  • WhenIusepythontoapplythepymysqlmoduletoaddafieldtoatableinthemysqldatabase,itdo ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了在使用Laravel和sqlsrv连接到SQL Server 2016时,如何在插入查询中使用输出子句,并返回所需的值。同时讨论了使用CreatedOn字段返回最近创建的行的解决方法以及使用Eloquent模型创建后,值正确插入数据库但没有返回uniqueidentifier字段的问题。最后给出了一个示例代码。 ... [详细]
  • Python操作MySQL(pymysql模块)详解及示例代码
    本文介绍了使用Python操作MySQL数据库的方法,详细讲解了pymysql模块的安装和连接MySQL数据库的步骤,并提供了示例代码。内容涵盖了创建表、插入数据、查询数据等操作,帮助读者快速掌握Python操作MySQL的技巧。 ... [详细]
  • 微软评估和规划(MAP)的工具包介绍及应用实验手册
    本文介绍了微软评估和规划(MAP)的工具包,该工具包是一个无代理工具,旨在简化和精简通过网络范围内的自动发现和评估IT基础设施在多个方案规划进程。工具包支持库存和使用用于SQL Server和Windows Server迁移评估,以及评估服务器的信息最广泛使用微软的技术。此外,工具包还提供了服务器虚拟化方案,以帮助识别未被充分利用的资源和硬件需要成功巩固服务器使用微软的Hyper - V技术规格。 ... [详细]
  • 什么是大数据lambda架构
    一、什么是Lambda架构Lambda架构由Storm的作者[NathanMarz]提出,根据维基百科的定义,Lambda架构的设计是为了在处理大规模数 ... [详细]
  • php设置数组大小_【大厂必备】2020超经典PHP面试题
    结合我自己这段时间的面试情况,面对的一些php面试题列举出来,基本上结合自己的看法回答的,不妥的地方请大家指出去,与大家一起 ... [详细]
  • 你知道Kafka和Redis的各自优缺点吗?一文带你优化选择,不走弯路 ... [详细]
author-avatar
鱼儿玩玩
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有