从 HBase 中提取数据的最快方法是啥
Posted
技术标签:
【中文标题】从 HBase 中提取数据的最快方法是啥【英文标题】:what is the Fastest way to extract data from HBase从 HBase 中提取数据的最快方法是什么 【发布时间】:2016-12-03 10:03:31 【问题描述】:我有大约 5TB 的数据分布在 HBase 的 30 个不同的表中。 我的用例是基于每个表中的两个特定列,即 YEAR 和 Country,我必须创建 5K 不同的文本文件。 为此,我已经集成了 HIVE 和 HBase,但从 HIVE 中提取需要很长时间。 我必须在 10 小时内完成。 寻求您的想法如何实现。 我对此有一些疑问。
-
HIVE HBase 集成是好方法吗?
使用 mapreduce 从 HBase 提取数据是个好主意吗?
我不能使用 Apache Phoenix,因为它没有与 HBase 一起发布。
IMPALA 也使用高内存,因此我的集群没有为此配置。
public int run(String[] args) throws Exception
int result = 0;
if (hbaseConf == null)
hbaseConf = getHbaseConfiguration();
Job job = new Job(hbaseConf);
job.setJarByClass(HBaseToFileDriver.class);
job.setJobName("Importing Data from HBase to File:::" + args[0]);
Scan scan = new Scan();
scan.setCaching(5000); // 1 is the default in Scan, which will be bad
// for
// MapReduce jobs
scan.setCacheBlocks(false); // don't set to true for MR jobs
scan.addFamily(Bytes.toBytes("cf"));
TableMapReduceUtil.initTableMapperJob(args[0], scan, MyMapper.class, null, null, job);
// No reducers. Just write straight to output files.
job.setNumReduceTasks(0);
job.setOutputFormatClass(SequenceFileOutputFormat.class);
job.setOutputKeyClass(ImmutableBytesWritable.class);
job.setOutputValueClass(Result.class);
FileOutputFormat.setOutputPath(job, new Path(args[1]));
boolean b = job.waitForCompletion(true);
if (!b)
throw new IOException("error with job!");
return result;
我在 HBase 中的数据是这样的
���U"9����|Japan|2012 48433172245 1001371402 FundamentalSeries NULL NULL 139 238474518 1.65494205533344 Price2SFCFLPsr NULL False 3011645 1000190205 False True I Japan 2012
C��t�I�\���7|ThirdPartyPrivate|2009 48934711562 1001371402 FundamentalSeries NULL NULL 9 5631268 21.2315827835749 STCA_PoP NULL False 3011645 1000193170 False True I ThirdPartyPrivate 2009
�����^Z4Ga�|Japan|2013 48433158708 1001371402 FundamentalSeries NULL NULL 507 160531379 1.1248E10 STAX_TTM 500186 False 3011646 1000193168 False False I Japan 2013
G\�=�HO�S�|Japan|2008 48433173983 1001371402 FundamentalSeries NULL NULL 153 1961706488 0.500256556630127 RIBEIT_TTM NULL False 3011646 1000193016 False False I Japan 2008
�G��G�i0�]|Japan|2012 48433336633 1001371402 FundamentalSeries NULL NULL 894 3112047463 14.3904580667924 Ev2SEBIT_Avg5 NULL False 3011645 1000190030 False True I Japan 2012
���r����/8|Japan|2015 48433251137 1001371402 FundamentalSeries NULL NULL 200 2907364871 -46.9431625157866 SNOPA_YoY NULL False 3011646 1000423629 False False I Japan 2015
�)H�<�����t|Japan|2008 48433139729 1001371402 FundamentalSeries NULL NULL 1170 2604636883 0.267980759053007 PPE2ANOA NULL False 3011646 1001262486 False False I Japan 2008
'H�&�g���|Japan|2005 48433195827 1001371402 FundamentalSeries NULL NULL 147 450289107 0.540110660915134 Ev2SEBIT NULL False 3011645 1000190028 False True I Japan 2005
c�\��17ɟ�|Japan|2013 48433160145 1001371402 FundamentalSeries NULL NULL 885 2010667500 -19.6553084635268 SAMI_TTM_YoY NULL False 3011646 1000190297 False False I Japan 2013
j�����||Japan|2010 48433159175 1001371402 FundamentalSeries NULL NULL 214 420693538 -17.3468681844827 SCOR_YoY NULL False 3011646 1000192789 False False I Japan 2010
【问题讨论】:
【参考方案1】:选项 1:请注意 hive hbase 集成和查询 hive 也将在后台使用 mapreduce...
但是你对 hive 执行的 mapreduce 没有细粒度的控制。
选项 3:您还排除了选项 3,即您提到的 Phoenix。
选项 4:Impala 速度更快,但您有一定的限制。所以排除了
选项 2:根据我对 hbase 的经验,我建议使用 mapreduce 从 HBase 提取数据。即您的选项 2,它将对作业的执行进行更精细的控制。
但在这种方法中,您还必须微调您的工作。
scan.setCaching(500);
scan.setCacheBlocks(false);
最重要的是,您必须设计您的 rowkey 以避免 hot spotting 并使用有效的过滤器(例如 FuzzyRowFilter
,例如参见 here),以确保快速访问。
尽量避免使用列值过滤器,以确保不会发生全表扫描。
请注意,表的区域数等于为该特定作业启动的映射器数。所以预先将表格拆分到某个范围(例如 0-9)之间,这样您的所有行都将落入这些确定的区域(当然它可以进一步拆分为多个区域,但这是一种方法,如果确保更少的数量区域,因此所有映射器都会获得足够数量的记录来处理...)
如果我理解正确的话。你想生成多个序列文件;
请查看使用 MultipleOutputs 的使用模式。
see Usage pattern for job submission:
Job job = new Job();
FileInputFormat.setInputPath(job, inDir);
FileOutputFormat.setOutputPath(job, outDir);
job.setMapperClass(MOMap.class);
job.setReducerClass(MOReduce.class);
...
// Defines additional single text based output 'text' for the job
MultipleOutputs.addNamedOutput(job, "text", TextOutputFormat.class,
LongWritable.class, Text.class);
// Defines additional sequence-file based output 'sequence' for the job
MultipleOutputs.addNamedOutput(job, "seq",
SequenceFileOutputFormat.class,
LongWritable.class, Text.class);
...
job.waitForCompletion(true);
...
When used in conjuction with org.apache.hadoop.mapreduce.lib.output.LazyOutputFormat, MultipleOutputs can mimic the behaviour of MultipleTextOutputFormat and MultipleSequenceFileOutputFormat from the old Hadoop API - ie, output can be written from the Reducer to more than one location.
【讨论】:
是的,实际上它很有帮助。我正在实现它。我有一个疑问,我必须根据密钥中的扫描过滤器创建不同的文本文件。我该怎么做? 我也用实施更新了我的问题。 了解到您正在尝试根据扫描结果制作序列文件。您想做什么?你能举一些例子数据吗? 我已经更新了我的行。第一列是我的行键。我有 130 个区域,还没有聚光灯。基于行键中的最后两个元素,即 Year 和 File,即 Japan/ThirdParty我必须创建文本文件。 我的回答中提到的FuzzyRowFilter
在行键中有固定部分和可变部分时可能很有用。在这种情况下,Fixedpart 是 Japan 后跟 year 或 ThirdParty 后跟 year。剩余的可变部分。我了解到您正在基于 rowfilter 进行扫描。关于上面给出的这个检查链接。以上是关于从 HBase 中提取数据的最快方法是啥的主要内容,如果未能解决你的问题,请参考以下文章
在 Python 中提取和清理 HTML 正文文本的最快、最无错误的方法是啥?