【问题标题】:How to migrate a cassandra counter table to another cluster?如何将 cassandra 计数器表迁移到另一个集群?
【发布时间】:2022-08-09 16:48:08
【问题描述】:

我们有一个 21 节点的 cassandra 集群,其中有一个包含近 20 亿行的 cassandra 计数器表。 我曾尝试迁移此表。首先,我使用这样的代码(在 golang 中)在两个集群中进行了双重写入:

counterDiff := incrementValue
_, err := newRepo.FindById(ctx, id)
if err != nil {
    if err == ErrRecordNotFound {
        record, err := oldRepo.FindById(ctx, id)
        if err != nil {
            // log
            return
        }
        counterDiff = record.Count
    } else {
        // log
        return
    }
}
newRepo.Update(ctx, id, counterDiff, false)

事实上,我用旧集群的值初始化了新的计数器。

然后我使用 CQL 查询迁移数据,并在新集群中一一写入所有行,如果行/键不存在。

但不幸的是,在验证步骤中,我看到了两个集群之间的一些差异,并且很多差异(不是全部)的形式为:newClusterValue == n * oldClusterValue

现在我有4个问题:

  1. 我的迁移策略有什么问题?我认为我应该在我的双重写入功能中使用互斥锁来防止竞争条件。有什么建议吗?还有什么问题吗?
  2. scylla 或 cassandra sstableloader 工具如何处理计数器列?我可以使用它们进行迁移吗?
  3. 迁移计数器表的最佳方法是什么?
  4. 由于更新不是幂等的,cassandra 计数器表是否适合准确计数?在大数据的情况下有更好的解决方案吗?

    标签: cassandra migration database-migration scylla


    【解决方案1】:

    您问了几个问题,我将尝试回答其中一些问题,希望其他人能回答其他问题:

    1:确实,您的“双重写入”的复制步骤存在并发更新问题:如果您有 n 个并发更新,它们都会将新计数器增加旧计数器的数量,因此您最终会增加新计数器如您所见,按 n * oldcounter 进行计数器。

    4:除了计数器之外的另一个选项是具有“乐观锁定”的 LWT(获取当前计数,如果当前计数仍然等于 count,则将其设置为 count+1,否则重复)。但这也不是幂等的,因为如果事务以不干净的方式失败(例如,网络问题、重新启动等),您不知道是否也应该重复它。您也许可以做的事情(我自己从未尝试过,也许其他人做过?)是在您的 LWT 批处理中为同一个分区设置两个语句 - 一个更新静态列中的实际计数器,另一个设置“唯一 id " 如果尚未设置,则在客户端生成的唯一 ID 上聚类行。如果 LWT 更新因为第二部分失败而失败,则表示过去更新已经成功,不应再重试。如果幂等性仅跨越 1 小时就足够了(即,您不希望 2 小时后重试同一查询),则可以使用较短的 TTL(例如 1 小时)创建唯一 id 行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-27
      • 1970-01-01
      • 2014-06-26
      • 1970-01-01
      • 2017-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多