【问题标题】:Cassandra commit log clarificationCassandra 提交日志说明
【发布时间】:2016-11-25 04:39:11
【问题描述】:

我已阅读有关 Cassandra 提交日志的几份文档,对我来说,关于此“结构”的信息存在冲突。该图显示,当发生写入时,Cassandra 将写入内存表和提交日志。令人困惑的部分是此提交日志所在的位置。

我反复看到的图表显示了磁盘上的提交日志。但是,如果您阅读更多内容,他们还会谈到内存中的提交日志缓冲区 - 并且该内存块每 10 秒刷新一次到磁盘。

DataStax 文档指出: “当发生写入时,Cassandra 将数据存储在称为 memtable 的内存结构中,为了提供可配置的持久性,它还会将写入附加到内存中的提交日志缓冲区。该缓冲区每 10 秒刷新一次到磁盘”。

他们的图表中没有任何地方显示称为提交日志缓冲区的内存结构。它们只显示驻留在磁盘上的提交日志。

它还指出: “当发生写入时,Cassandra 将数据存储在内存中的结构中,即 memtable,并且还将写入附加到磁盘上的提交日志中。”

所以我对上述内容感到困惑。它是写入提交日志内存缓冲区,最终刷新到磁盘(我假设也称为“提交日志”),还是写入内存表和磁盘上的提交日志?

Apache 的文档指出: “相反,与其他现代系统一样,Cassandra 通过首先将写入附加到提交日志来提供持久性。这意味着只需要对提交日志进行 fsync'd,如果提交日志在其自己的卷上,则无需搜索,因为commitlog 是 append-only。实现细节在 ArchitectureCommitLog 中。

Cassandra 的默认配置将 commitlog_sync 模式设置为周期性,从而导致每 commitlog_sync_period_in_ms 毫秒同步一次 commitlog,因此如果所有副本在该时间窗口内崩溃,您可能会丢失这么多数据。"

我从 Apache 语句中推断出,只有由于写入的异步性质(缓存写入的确认),您才会丢失数据(它甚至指出,如果所有副本在刷新/同步之前崩溃,您可能会丢失数据'd)。

我不确定我可以从 DataStax 文档和图表中推断出什么,因为他们提到了关于提交日志的两种不同的陈述——一种在内存中,一种在磁盘中。

任何人都可以澄清,我认为,一组措辞不佳且相互冲突的文档吗?

我假设有一个提交日志缓冲区,因为它们都引用了它(但 DataStax 没有在图中显示它)。我认为,如何以及何时进行管理是理解的关键。

【问题讨论】:

    标签: cassandra datastax


    【解决方案1】:

    通常在解释写入路径时,提交日志被描述为一个文件 - 确实,提交日志是提供持久性的磁盘存储机制。更深入时会引入混淆,并引入有关缓冲区缓存和必须发出 fsyncs 的部分。对“内存中的提交日志缓冲区”的引用是在谈论操作系统缓冲区缓存,而不是 Cassandra 中的内存结构。您可以在code 中看到提交日志没有单独的内存结构,而是将突变序列化并写入file-backed buffer

    Cassandra 提供了两种管理提交日志中 fsync 的策略。

    commitlog_sync 
        (Default: periodic) The method that Cassandra uses to acknowledge writes in milliseconds:
        periodic: (Default: 10000 milliseconds [10 seconds])
        Used with commitlog_sync_period_in_ms to control how often the commit log is synchronized to disk. Periodic syncs are acknowledged immediately.
    
        batch: (Default: disabled)note
        Used with commitlog_sync_batch_window_in_ms (Default: 2 ms) to control how long Cassandra waits for other writes before performing a sync. When using this method, writes are not acknowledged until fsynced to disk.
    

    periodic 提供更好的性能,但会稍微增加丢失数据的可能性。 batch 设置以延迟为代价保证持久性。

    【讨论】:

    • 所以请帮助我了解写入发生时会发生什么。 Cassandra 在满足一致性时确认写入,假设为 2。这是否意味着它已将其写入磁盘或内存中的提交日志。换句话说,对于要“保证”的事情,您是否必须等到它被刷新(例如,默认为 10000 毫秒或 10 秒)?从我正在阅读的内容,直到内存同步,您有可能丢失数据,在我们的示例中,最多 10 秒 - 但由于内存接收数据(在所有副本上),确认很快符合一致性水平)。
    • 要确认写入,它必须已进入提交日志和内存表。为了达到一致性级别 2,这必须在 2 个节点上发生。我认为您的问题围绕着这个问题 - “进入提交日志”是什么意思?默认情况下,这意味着写入已发送到文件系统,但可能未同步到实际磁盘。如果您需要绝对持久性,那么您可以将 commitlog_sync 更改为批处理,但代价是更高的延迟。
    • @AndrewWeaver 我有一点疑问。您在上面的回答中提到数据有可能丢失。我不明白。如果我们在提交日志中有关于写入的信息,并且我们假设节点在从提交日志被 fsnyced 到实际磁盘之前发生故障,那么节点在重新启动时不会重播提交日志并恢复数据吗?
    • @Vinay,您刚刚回答了自己的问题。如果一个节点在 fsync 之前发生故障,那么它实际上并不在磁盘上。如果它不在磁盘上,则节点无法从提交日志中读取它。
    • 对于未来的读者,here 是一些(旧)参考。
    猜你喜欢
    • 1970-01-01
    • 2015-10-28
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 2014-12-28
    • 1970-01-01
    • 2020-09-03
    相关资源
    最近更新 更多