我们有一个共同的要求(数据迁移)来批量修改数据,例如用户ID列(将用户ID 001更改为002,将用户ID 003更改为004) . 但是表1中的用户id字段不是主键(除了select * from table之外,我们无法获取所有行的更新),而table2中的用户id字段是主键(这种情况我们可以处理) . 因此,我们没有方法可以使用所有表的原因来选择所有数据 .
那么如何满足这个要求呢?
我只想出两种方法:
(1)从具有提取大小设置的表中选择* . 然后更新它 . //是对的吗? (2)使用copy命令到一个CVS,然后修改它并再次导入 . //性能很慢?
这些方法是否可用于 生产环境 (具有>百万条记录 . )或是否有任何其他标准更好的方法来满足此要求? Sstableloader?猪?
也许通常要求修改一个列所有存在的表,因此可能存在于标准解决方案中 .
无论我们最后选择哪种方法,当迁移数据时, how to solve new data migration issue during the past period of old data migration. 换句话说,如何解决增加数据迁移的问题?
期待你的重播
table1 userid(pk)名称性
table2 phonenumber(pk)userid
3 回答
我并不完全清楚你要做什么,但你可能想看看使用spark-cassandra连接器来使用Spark做这些转换 .
使用连接器,您可以将整个表读入spark RDD,对这些RDD中的字段进行连接和转换,然后将生成的RDD保存回Cassandra . 因此,对于您所描述的内容,您大致会执行以下步骤:
将table1和table2读入RDD1和RDD2
可能在RDD1和RDD2之间的用户标识上进行连接以创建RDD3
转换userid字段以及您想要更改的任何其他内容
在Cassandra中创建表,无论你想成为什么主键
将转换后的RDD保存到Cassandra中的新表中
这种方法可以很好地扩展到数百万条记录,因为如果没有足够的系统内存来同时保存内存中的所有内容,那么Spark就可以处理数据块 . Spark可以同时在所有节点上并行完成大量工作,而不是编写CQL客户端来获取所有记录,并在单个客户端计算机上完成所有这些工作 .
困难的部分是将Spark添加到您的Cassandra集群并学习如何编写Spark作业,但如果这是您经常要做的事情,那么它可能是值得的 .
根据数据量,您可能有3个选项:
1)CQLSH中的
COPY TO
,它将使用分页并创建CSV文件 . 然后,您可以使用您选择的编程语言解析该CSV,使用更新的ID创建新CSV,截断表(或创建新表),然后将其重新导入系统 . 这将适用于几百万条目,我可能不会尝试几十亿 .COPY FROM
不需要提前知道所有密钥 .2)使用火花 . Jim Meyer做了一个合理的工作来解释火花 . Spark将比CQLSH中的
COPY
命令更好地扩展,但需要额外的设置 .3)使用
CQLSSTableWriter
,sstableloader
和流媒体 . 使用带分页的驱动程序(例如datastax java驱动程序)读取行 . 使用CQLSSTableWriter转换该数据并编写新的OFFLINE sstables . 删除或截断旧表,并使用sstableloader
将新sstables提供给集群 . 这适用于数TB的数据,如果您提前计划,可以并行化 . Yuki Morishita does a good job documenting this approach on the Datastax blog . 您不一定需要知道所有键,您可以SELECT DISTINCT
获取每一行,或使用COPY FROM
生成CSV文件 .这闻起来像一个反模式 .
主键应该稳定
主键(尤其是分区键)不应该更改,尤其是整个数据集的全局键 .
当分区键更改时,行将获得新标记,并且必须将行从其当前副本节点移动到新副本节点 .
当主键的任何部分发生更改时,需要使用行 .
更改主键是一项昂贵的操作 . 正如您所发现的那样,更新其他表中的所有引用也很昂贵 .
如果您选择作为主键的字段不稳定,则应考虑使用另一个更稳定的字段作为主键 . 最坏的情况,使用合成密钥(uuid或timeuuid) .
我强烈建议您重新访问您的数据模型并将其调整为以不需要修改主键的方式支持您的“数据迁移”需求 .
如果您提供有关迁移要求的更多详细信息,那么我们可能会建议更好的方法来对其进行建模 .