随着世界数据量的迅速增长,给数据的存储和分析带来巨大的挑战。所谓人多力量大,我国能取得当前成就,也不得不说是社会主义的优越性所带来必然成果。分布式的框架能够充分调用集群内部多个节点的存储空间,计算能力等,将大的计算任务分解成子任务,给各个节点一个个小目标,从而实现TB级、PB级的数据分析工作。因此,越来越多的企业和组织开始调整本身的数据库生态,基于分布式框架构建起服务器集群,来应对不断增长的数据压力。这里就会出现一个问题,如何将传统的关系型数据库的数据迁移到分布式数据库里面呢?本文针对该问题进行讨论,主要考虑的是Hbase的框架下的数据导入。
关系形数据库是一种建立在关系模型基础上的数据库。用一张二维表代表现实世界中的实体,用表中的字段代表实体的属性,用外键等联合操作代表实体之间的关系。关系型数据库MySQL中默认安装INFORMATION_SCHEMA数据库,这些存储在INFORMATION_SCHEMA中的数据就叫做数据库系统的元数据。因此,在数据迁移的过程中,可以利用对关系型数据库中元数据表的查询快速获取关系型数据库中各个表的模式和各表之间的关系,然后进行迁移。
HBase是一种Key/Value系统,它运行在HDFS之上(HDFS是分布式文件系统)。怎么理解?也就是说,HBase存数据不是像关系型数据库那样,是一个二维表的形式存数据,反而像哈希表那样,用键值对的形式去存。HBase维护一个主键,和一个字段值,如果多个字段,就维护多个键值对。举个例子,关系型数据库下面这样的一张表,在Hbase会被存储四个key-value:
ID(主键) | NAME | AGE |
---|---|---|
1 | 张三 | 28 |
2 | 李四 | 30 |
ROW | COLUMN+CELL |
---|---|
1 | column=info:NAME,timestamp=1444701130584 ,value=\xE5…… |
1 | column=info:AGE,timestamp=1444701130584 ,value=\xE5…… |
2 | column=info:NAME,timestamp=1444701130584 ,value=\xE5…… |
2 | column=info:AGE,timestamp=1444701130584 ,value=\xE5…… |
HBase的数据存储在HDFS中,能够很好地利用HDFS的分布式处理模式,并从Hadoop的MapReduce程序模型中获益。 HBase逻辑上的表在行的方向上分割成多个HRegion,HRegion按大小分割,每张表开始只有一个Region,随着记录数的不断增加,Region不断增大,当增大到一定程度时,HRegion会被等分成两个新的HRegion。HRegion是HBase中分布式存储和负载均衡的最小单元,但却不是存储的最小单元。HRegion由一个或者多个Store组成,每个Store保存了表中的一个列族(上表中的info就是列族名)。每个Store又由一个 Memstore和0至多个StoreFile(HFile)组成,StoreFile用来存储数据并以HFile的形式保存在HDFS上。HBase这种特性导致了两个结果:1.HBase对于存储必须将其转换成文本,用16进制对其进行描述;2.HBase支持结构化和半结构化,非结构化的数据存储。
将各种类型的数据库或者文件导入到HBase,常见有三种方法:
(1)使用HBase的API中的Put方法
(2)使用HBase 的bulk load工具
(3)使用定制的MapReduce Job方式
这里不打算太过展开,笔者本身对一些细节也不会很清楚,所以这里给大家引导下方向:
Put是HBase的API中携带的方法,主要用于数据量不大的情况下的数据导入工作。
Put导入数据的效率并不高,它是逐个逐个地添加键值对。大概操作流程如下:
<1>在HBase中创建表
<2>写一个java程序,mySQL中的数据导入Hbase,并将其打包为JAR.
1.使用Java创建一个connectHBase() 方法来连接到指定的HBase表。
2.使用Java创建一个 connectDB() 方法来 MySQL。
3.通过脚本执行JAR文件
4.验证导入的数据
Bulk load是通过一个MapReduce Job来实现的,通过Job直接生成一个HBase的内部HFile格式文件来形成一个特殊的HBase数据表,然后直接将数据文件加载到运行的集群中。使用bulk load功能最简单的方式就是使用importtsv 工具。importtsv 是从TSV文件直接加载内容至HBase的一个内置工具。它通过运行一个MapReduce Job,将数据从TSV文件中直接写入HBase的表或者写入一个HBase的自有格式数据文件。
HBase提供importtsv工具支持从TSV文件中将数据导入HBase。使用该工具将文本数据加载至HBase十分高效,因为它是通过MapReduce Job来实施导入的。哪怕是要从现有的关系型数据库中加载数据,也可以先将数据导入文本文件中,然后使用importtsv 工具导入HBase。在导入海量数据时,这个方式运行的很好,因为导出数据比在关系型数据库中执行SQL快很多。
importtsv 工具不仅支持将数据直接加载进HBase的表中,还支持直接生成HBase自有格式文件(HFile),所以你可以用HBase的bulk load工具将生成好的文件直接加载进运行中的HBase集群。这样就减少了在数据迁移过程中,数据传输与HBase加载时产生的网络流量。
具体操作不展开,可参考:http://www.importnew.com/3645.html
不过使用importtsv工具有个缺点,就是它只能够导入tsv格式的文件。
尽管在将文本文件加载入HBase时importtsv工具十分高效,但在许多情况下为了完全控制整个加载过程,你可能更想自己编写MapReduce Job向HBase导入数据。例如在你希望加载其他格式文件时不能使用importtsv工具。
HBase提供TableOutputFormat 用于在MapReduce Job中向HBase的表中写入数据。你也可以使用HFileOutputFormat 类在MapReduce Job中直接生成HBase自有格式文件HFile,之后使用completebulkload 工具加载至运行的HBase集群中。
有特定需求的可以自己定制下数据迁入工具,不过一般推荐使用sqoop,它的底层实现是mapreduce,数据并行导入的,支持mysql,oracle,postgresql等数据库,无须自己开发代码,过滤条件通过query参数可以实现。
sqoop基本上通过 import 和 export 两个方法实现数据的迁移工作。
[root@master bin]# sqoop import --connect jdbc:mysql://192.168.220.20:3306/test --username root --password 123456 --table smq_to_hbase --hbase-table smq_hbase --column-family info --hbase-row-key id
[root@master bin]# sqoop export -connect jdbc:mysql://192.168.220.20:3306/test -username root -password 123456 -tablemployee -export-dir /user/hive/warehouse/test.db/employee --input-fields-terminated-by '\001' --input-null-string '\\N' --input-null-non-string '\\N';
sqoop部分重要参数介绍
--hbase-table:通过指定--hbase-table参数值,指明将数据导入到HBase表中,而不是HDFS上的一个目录。输入表中的每一行将会被转换成一个HBase Put操作的输出表的一行。
--hbase-row-key:你可以使用--hbase-row-key参数,手动的指定row key。默认的情况下,Sqoop会将split-by 列作为HBase rowkey列。如果没有指定split-by值,它将会试图识别关系表的关键字。
如果源表是组合关键字,--hbase-row-key 参数后面值是用逗号分隔的组合关键字属性的列表,在这样种情况下,通过合并组合关键字属性的值来产生HBase的Row key,每个值之间使用下划线分隔开来。
--column-family:必须指定--column-family参数,每一个输出列都会被放到同一个family列族中。
--hbase-create-table:如果HBase中的目标表和列族不存在,如果你使用该参数,Sqoop在运行任务的时候会根据HBase的默认配置,首先创建目标表和列族。
注意一:当源表中是组合关键字的时候,必须手动指定--hbase-row-key参数,Sqoop才能将数据导入到HBase中,否则不行。
注意二:如果HBase中的目标表和列族不存在,如果没加--hbase-create-table参数,Sqoop job将会报错误退出运行。所以你在将数据从源表导入到HBase之前,需要首先在HBase中创建目标表和其对应的列族。
参考文献:
https://www.csdn.net/article/2014-01-07/2818046
http://www.importnew.com/3645.html
http://www.importnew.com/3912.html
https://www.jianshu.com/p/2f760d072497