本文简单介绍 HBase 的数据导入工具 ImportTSV 。通过一次将 hive 大表导入 HBase 的实战案例,梳理期间遇到的问题,调研更优的导入方式。本文着重关注:
ImportTsv 是 HBase 提供的一个命令行工具,将存储在 HDFS 上的数据文件,通过指定的分隔符解析后,导入到 HBase 表中。(TSV :Tab-separated values)
这样的方式导入数据与正常写入流程不同的是,跳过了 WAL、Memcache 与 Flush 的过程,直接将 HFile 文件移动到 HBase 表空间目录下即可,不影响 RegionServer 的性能。
ImportTsv 提供两种导入的方式:
首先创建 hbase 表:user (大表一定要预分区,不然全部会写到一个 region),然后执行命令导入:
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator="," -Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:gender,info:age,info:idNumber,info:address,info:birthday user /tmp/user.txt
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator="," -Dimporttsv.bulk.output=/louisvv/hfile_tmp -Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:gender,info:age,info:idNumber,info:address,info:birthday user /yw/user.txt
Hive 表 42 亿行数据导入 HBase,采用上述提到的方案 2 : hfile + bulkload
Hive 表信息:
表名:hive_pub.dim_ip_cover_all_info_20220801_001
行数:42 亿
rowkey 为表第一个字段 ip_num,是 ip 转出的数值,保证唯一。
数据样例如下:
ip_num ip begin_ip end_ip country province_name city_name
1214810642 72.104.138.18 72.55.192.0 72.135.255.255 美国 美国
1214810654 72.104.138.30 72.55.192.0 72.135.255.255 美国 美国
137497864 8.50.13.8 8.47.158.0 8.127.255.255 美国 美国
137497876 8.50.13.20 8.47.158.0 8.127.255.255 美国 美国
137497888 8.50.13.32 8.47.158.0 8.127.255.255 美国 美国
137497900 8.50.13.44 8.47.158.0 8.127.255.255 美国 美国
137497912 8.50.13.56 8.47.158.0 8.127.255.255 美国 美国
137497924 8.50.13.68 8.47.158.0 8.127.255.255 美国 美国
3699562708 220.130.216.212 220.130.216.0 220.130.217.255 中国 台湾 彰化县
3699562720 220.130.216.224 220.130.216.0 220.130.217.255 中国 台湾 彰化县
这一步非常重要,hbase 建表如果不预分区,所有数据默认会写到一个分区,导入后需要长时间的 split ,compaction。 以下是我们的建表语句,指定压缩,预分区文件为手动生成的: /tmp/split.txt。
create 'ns:xx', {NAME => 'cf',COMPRESSION => 'snappy' },SPLITS_FILE => '/tmp/split.txt'
下面的重点的就是如何创建预分区,预分区的目的是让数据均衡分布在不同了 region - 分区。理解预分区需要理解 HBase rowkey 的字典排序,可以参考:[HBase] - 理解 HBase Rowkey 字典排序 - 简书
需要基于 rowkey 分布特征,划分分区,让数据均衡, hbase 提供三种预分区算法,注意DecimalStringSplit 算法 HBase 低版本1.4 以下不支持:
了解 rowkey 特征,如果适用以上算法,可以直接采用这种方式建表。例如以下是创建一个 50 个 region 的表,采用 UniformSplit 分区算法。
create 'ns:xx', {NAME => 'cf',COMPRESSION => 'snappy' }, { NUMREGIONS => 50, SPLITALGO => 'UniformSplit' }
如果 rowkey 特征不适用于上述三种算法,需要自己生成分区区间,语法为:
# 直接指定
create 'ns:xx', {NAME => 'cf',COMPRESSION => 'snappy' }, SPLITS => ['10','20','30','40']
# 通过文件指定
create 'ns:xx', {NAME => 'cf',COMPRESSION => 'snappy' }, SPLITS_FILE => '/tmp/split.txt'
分析本案例:rowkey 的特点为:数值型,范围为:0-9999999,数据分布较为均衡。
数据行数:42亿,数据量 1.2 T。
根据数据分布,输出 split 分区文件如下,按照这个粒度,一共有 200+ 分区。这个可以通过手工或者脚本生成。
100|
105|
110|
115|
...
995|
具体分多少个分区,这个不一定需要绝对精准,可以大概估算,分区多,粒度细,分区少,粒度粗。 region个数估算,大致可以依据公示 :<region 个数> = <总数据量> / <单个region 的大小>(5-8G)来估算。
上述数据分粗一点,可以以1开头,2开头, 3开头, 4开头...9开头,一共 10 个分区。如果数据量大了 10 个分区可能太少。
1
2
3
4
5
6
7
8
9
一个 todo 疑问,是否有其他生成 splits 的方式,更优的方式?
导出 hive 数据到 hdfs(字段逗号分隔)
利用 importTsv 命令生成 hfile,需要指定列分隔符,HBASE_ROW_KEY 标识第一个字段为 rowkey,最后一个参数是数据文件的位置。
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator="|" \
-Dimporttsv.bulk.output=/data/hfile_tmp/ \
-Dimporttsv.columns=HBASE_ROW_KEY,cf:ip,cf:begin_ip,cf:end_ip,cf:country,cf:province_name,cf:city_name \
-Dmapreduce.map/reduce.memory.mb=5120 \
-Dmapreduce.map/reduce.java.opts=-Xmx4096m \
ns:xx /path/to/hdfs/tsvfile
bulkload 的实现原理可以参考之前的文章:HBase Bulkload 迁移数据及问题思考 - 简书
命令如下:
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /path/to/hfile hbase_table
导入后执行一次 major compact 有助于提高数据本地化率, 合并小文件。操作建议在闲时执行。命令在 hbase shell 执行:
major_compact 'ns:table'
上述流程稍显麻烦,是否还有其他更优的方式?
可以基于 Hive-HBase Integration 来导入 (https://cwiki.apache.org/confluence/display/Hive/HBaseIntegration)。 步骤如下:
创建 HBase 表(同样注意创建预分区)
创建 hive 表 ,目的是为了生成 hfile,
需要注意,hive 下需要添加 HBase 相关的 jar:
add jar /lib/hive-hbase-handler-2.3.3.jar;
add jar /lib/hbase-protocol-1.1.1.jar;
add jar /lib/hbase-common-1.1.1.jar;
add jar /lib/hbase-client-1.1.1.jar;
add jar /lib/hbase-server-1.1.1.jar;
创建表:
create table stu_info{
name string comment '名字',
age int comment'年龄'
}
STORED AS
INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHFileOutputFormat'
TBLPROPERTIES ('hfile.family.path' = '/user/hive-hbase/info');
输出格式一定要为:HiveHFileOutputFormat。/user/hive-hbase/info 是生成的 hfile 在 HDFS 上的路径,其中 info 为 Hbase 的 family。
insert overwrite table stu_info select xxx from xxx
到 hfile.family.path 目录查看生成的 hfile
bin/hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /user/hive-hbase/info/ hbase_table
参考致謝:
使用ImportTSV向HBase中导入数据 | LouisvV's Blog
hive表数据导入到Hbase - CodeAntenna
Creating HBase HFiles From a Hive Table - Cloudera Community - 244627
理解 HBase Rowkey 字典排序 - 简书
HBase Bulkload 迁移数据及问题思考 - 简书
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手