使用 pig 将小数导入 cassandra

Posted

技术标签:

【中文标题】使用 pig 将小数导入 cassandra【英文标题】:Import decimal to cassandra using pig 【发布时间】:2015-02-26 22:07:42 【问题描述】:

我一直在用头撞墙一段时间,这看起来很简单。我知道我在这里遗漏了一些关键。

使用 Pig 0.12.1.2.1.2.0-402、Cassandra 2.0.9,我正在尝试将精度数(需要保持相同的精度)导入 Cassandra。

数据本身是使用 Sqoop 从 Oracle 导出的,数字看起来不错。

例如:有问题的数据是 38.62782。如果我使用 pig double 或 float 导入,则会丢失精度,这在这种情况下是不可接受的。我尝试了多种组合,pig 的 bigdecimal 似乎非常合适,但我无法让它发挥作用,因为我不断得到以下信息:

ERROR org.apache.pig.tools.pigstats.SimplePigStats  - ERROR: java.math.BigDecimal cannot be cast to org.apache.pig.data.DataByteArray

所以我不明白我需要做什么才能完成这项工作。我只希望 Oracle(和 Sqoop 文件)中的 38.62782 显示为 38.62782 而无需将 Cassandra 列设为文本字段。

样本猪:

DEFINE UnixToISO org.apache.pig.piggybank.evaluation.datetime.convert.UnixToISO();
DEFINE ISOToUnix org.apache.pig.piggybank.evaluation.datetime.convert.ISOToUnix();
DEFINE CustomToDate2Args com.mine.pig.udf.CustomToDate2Args();
DEFINE ToBoolean com.mine.pig.udf.ToBoolean();
DEFINE CustomCqlStorage com.mine.pig.CustomCqlStorage();
DEFINE s2d InvokeForDouble( 'java.lang.Double.parseDouble', 'String' );

oracle_load = LOAD '$input_file' USING PigStorage('     ') AS (
  NAME:chararray,
  MYDOUBLE:chararray,
  MYFLOAT:float,
  MYDECIMAL:bytearray,
  MYTEXT:chararray);

oracle_data = FOREACH oracle_load generate
  (NAME=='null'?null:NAME) as NAME,
  MYDOUBLE,
  MYFLOAT,
  MYDECIMAL,
  MYTEXT;


R = FOREACH oracle_data GENERATE TOTUPLE(TOTUPLE('name',NAME)), TOTUPLE(
  s2d(MYDOUBLE),
  MYFLOAT,
  MYDECIMAL,
  MYTEXT);


STORE R into 'cql://$cass_user:$cass_pass@$cass_keyspace/mydoubletest?output_query=update+$cass_keyspace.mydoubletest+set+mydouble+%3D+%3F,myfloat+%3D+%3F,mydecimal+%3D+%3F,mytext+%3D+%3F' USING CustomCqlStorage();

我正在尝试的表定义仅供参考:

CREATE TABLE mydoubletest (
  name text,
  mydecimal decimal,
  mydouble double,
  myfloat float,
  mytext text,
  PRIMARY KEY ((name))
) WITH
  bloom_filter_fp_chance=0.010000 AND
  caching='KEYS_ONLY' AND
  dclocal_read_repair_chance=0.000000 AND
  gc_grace_seconds=864000 AND
  index_interval=128 AND
  read_repair_chance=0.100000 AND
  replicate_on_write='true' AND
  populate_io_cache_on_flush='false' AND
  default_time_to_live=0 AND
  speculative_retry='99.0PERCENTILE' AND
  memtable_flush_period_in_ms=0 AND
  compaction='class': 'SizeTieredCompactionStrategy' AND
  compression='sstable_compression': 'LZ4Compressor';

【问题讨论】:

这是关于 Cassandra CQL 数据类型及其映射的文档。看看你能不能在这里找到匹配的:datastax.com/documentation/cql/3.1/cql/cql_reference/… 是的,它说 Cassandra 中的小数映射到 java.math.BigDecimal,这让我不能只使用上面的“MYDECIMAL:bigdecimal”(当我这样做时,我得到注明的例外)。也没有 InvokeToBigDecimal 选项,所以我不确定我是否需要对 UDF 做一些事情,但是做一些看似简单的事情似乎是一种迂回的方式。 【参考方案1】:

事实证明,我的问题与我正在寻找的答案大不相同。

首先,创建 UDF 确实可以解决这个问题。不过有两件事,就是我们使用了一个没有考虑 BigDecimal 的自定义 Cql 存储例程。其次,经过进一步探索,由于另一个原因,事实证明问题出在 cqlsh 上。字段实际上并没有丢失精度

但是,我的 整体问题的答案正是此处列出的内容: Astyanax Cassandra Double type precision

【讨论】:

以上是关于使用 pig 将小数导入 cassandra的主要内容,如果未能解决你的问题,请参考以下文章

通过python UDF将文本文件导入pig

使用 Pig 脚本将 Json 导入 Hbase

hadoop/pig导入日志的多级目录

导入猪脚本时出错

无法使用导入解析 org.apache.hcatalog.pig.hcatloader

在 Pig 中使用 Python UDF 时,如何让 Hadoop 查找导入的 Python 模块?