【问题标题】:How to fill a Cassandra Column Family from another one's columns?如何从另一个人的列中填充 Cassandra 列族?
【发布时间】:2012-11-25 18:54:01
【问题描述】:

我一直读到,如果您的应用程序经常更改并且经常添加功能,Cassandra 是很好的。

这是有道理的,因为您没有任何固定架构,您可以向行添加列以满足您的需要,而不是运行 ALTER TABLE 查询,这可能会为非常大的表冻结您的数据库数小时。

但是,我有一个无法解决的假设性问题。 假设我有:

CREATE COLUMN FAMILY Students
    with comparator='CompositeType(UTF8Type,UTF8Type),
    and key_validation_class=UUIDType;

每个学生都有一些通用列(你知道,meta:username、meta:password、meta:surname 等),而且每个学生都可以学习 N 门课程。这种 N-N 关系是使用非规范化解决的,将 N 列添加到每个学生(课程:ID1,课程:ID2)。

另一方面,我可能有一个 Courses CF,其中每一行都包含以下所有学生 UUID。

所以我可以问“XXX学习了哪些课程”和“哪些学生学习了YYY课程”。

问题是:如果我没有创建第二个列族怎么办?也许在构建应用程序时,让学生学习特定课程并不是必需的。

这是一个简单的例子,但我相信它很常见。 “使用 Cassandra,您可以根据查询而不是关系来计划 CF”。我现在需要那个查询,而一开始它并不需要。

给定一个包含数千个条目的学生表,您将如何填写 Courses CF?这是 Hadoop、Pig 还是 Hive 的工作(我从未接触过这些,只是猜测)。

【问题讨论】:

  • @ChrisGerken:我不这么认为。他不想复制数据;他想根据现有数据生成新数据。这需要不同的工具。
  • 嗯,重要的事实是,有一种方法可以非常快地完成这项工作,通过 Pig 并行执行,并且该操作不会 DOS 后面的应用程序...

标签: hadoop cassandra


【解决方案1】:

Pig(使用 Hadoop 集成)实际上非常适合此类工作,因为您不仅可以使用 CassandraStorage 读取数据,还可以将数据写回 Cassandra。它为您提供并行处理能力,以最少的时间和开销完成工作。否则,另一种方法是自己编写一些东西来进行提取,然后编写新的 CF。

这是一个 Pig 示例,它从一个 CF 中的一组数据计算平均值并将它们输出到另一个:

rows = LOAD 'cassandra://HadoopTest/TestInput' USING CassandraStorage() AS (key:bytearray,cols:bag{col:tuple(name:chararray,value)});
columns = FOREACH rows GENERATE flatten(cols) AS (name,value);
grouped = GROUP columns BY name;
vals = FOREACH grouped GENERATE group, columns.value AS values;
avgs = FOREACH vals GENERATE group, 'Pig_Average' AS name, (long)SUM(values.value)/COUNT(values.value) AS average;    
cass_group = GROUP avgs BY group;   
cass_out = FOREACH cass_group GENERATE group, avgs.(name, average);
STORE cass_out INTO 'cassandra://HadoopTest/TestOutput' USING CassandraStorage();

【讨论】:

  • @Sarge:好吧,如果您称 Pig 为“应用程序代码”,那么我猜是这样。我认为它更像是一个快速脚本工具。
  • 嗯,显而易见的答案是“读取所有行,写回新表”。然而,我很想看到 Hadoop 在这种工作中发挥作用。此外,在 Cassandra 中读取所有行并不是那么高效...
  • @rs_atl 是的 - 这就是我的意思。我与类似 SQL 的 UPDATE...SELECT 区分开来。
【解决方案2】:

如果您使用现有的 cassandra 文件,则必须展开数据。由于 NOSQL 文件是单向的,这在 Cassandra 本身中可能是一个非常耗时的操作。数据必须以与第一个文件相反的顺序排序。坦率地说,我相信您将不得不返回用于填充第一个文件的原始数据并从中填充这个新文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-27
    • 2015-12-02
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    相关资源
    最近更新 更多