Cassandra 卡桑德拉的目的是什么;s提交日志?

Cassandra 卡桑德拉的目的是什么;s提交日志?,cassandra,Cassandra,请有人澄清,让我了解提交日志及其使用 在Cassandra中,写入磁盘时,提交日志是第一个入口点或MemTables 如果将Memtables刷新到磁盘,那么Commit log的用途是什么?Commit log的唯一用途是在数据节点关闭时处理服务器同步问题吗?cassandra中的写入路径如下所示: Cassandra Node ---->Commitlog-----------------> Memtable |

请有人澄清,让我了解提交日志及其使用

在Cassandra中,写入磁盘时,提交日志是第一个入口点或MemTables


如果将Memtables刷新到磁盘,那么Commit log的用途是什么?Commit log的唯一用途是在数据节点关闭时处理服务器同步问题吗?

cassandra中的写入路径如下所示:

Cassandra Node ---->Commitlog-----------------> Memtable
                         |                       |
                         |                       |
                         |---> Periodically      |---> Periodically
                              sync to  disk          flush to SSTable
Memtable和CommitLog不是并行编写的。在开始写入Memtable之前,必须完成对CommitLog的写入。相关源代码堆栈为:

org.apache.cassandra.service.StorageProxy.mutateMV:mutation.apply->
org.apache.cassandra.db.Mutation.apply:Keyspace.open(keyspaceName).apply->
org.apache.cassandra.db.Keyspace.apply->
org.apache.cassandra.db.Keyspace.applyInternal{
    Tracing.trace("Appending to commitlog");
    commitLogPosition = CommitLog.instance.add(mutation)
    ...
    Tracing.trace("Adding to {} memtable",...
    ...
    upd.metadata().name(...);
    ...
    cfs.apply(...);
    ...
}
commitlog的目的是能够在节点崩溃或重新启动后重新创建memtable。这一点很重要,因为memtable只有在“满”时才会刷新到磁盘上,这意味着配置的memtable大小已超过,或者刷新是由nodetool或opscenter执行的。因此,memtable中的数据不会直接持久化


话虽如此,在重新启动节点之前,一件好事是调用“nodetool flush”,以确保memtable被持久化。这也将在节点再次出现后减少commitlog的播放时间。

您可以将commit log视为一种优化,但是如果没有它,Cassandra的速度将非常慢。当MemTables写入磁盘时,我们称之为SSTables。SSTables是不可变的,这意味着一旦Cassandra将它们写入磁盘,它就不会更新它们。因此,当列发生更改时,Cassandra需要将新的SSTable写入磁盘。如果Cassandra在每次更新时都将这些SSTables写入磁盘,那么它将完全受限于IO,而且速度非常慢

因此,卡桑德拉使用了一些技巧来获得更好的性能。它不会在每次列更新时将SSTables写入磁盘,而是将更新保存在内存中,并定期刷新磁盘上的更改,以将IO保持在合理的级别。但这导致了一个明显的问题,即如果机器停机或Cassandra崩溃,您将丢失该节点上的数据。为了避免丢失数据,除了将最近的更改保存在内存中,Cassandra还将更改写入其CommitLog

您可能会问,为什么写CommitLog比只写SSTables要好。CommitLog针对编写进行了优化。与按排序顺序存储行的SSTables不同,CommitLog按Cassandra处理更新的顺序存储更新。CommitLog还将所有列族的更改存储在一个文件中,这样磁盘在同时接收多个列族的更新时就不需要进行大量查找

基本上,将CommitLog写入磁盘会更好,因为它必须比写入SSTables写入更少的数据,并且它将所有数据写入磁盘上的单个位置

Cassandra跟踪哪些数据被刷新到SSTables,并且能够在写入所有早于某个点的数据后截断提交日志


当Cassandra启动时,它必须从最后一个已知的良好时间点(我们知道之前所有写入都写入SSTable的时间点)读回提交日志。它将提交日志中的更改重新应用于其MemTables,以便在停止时可以进入相同的状态。此过程可能会很慢,因此,如果要停止Cassandra节点进行维护,最好在关闭它之前使用
nodetool drain
,这会将MemTables中的所有内容刷新到SSTables,并使启动时的工作量大大减少

停止节点时,如果使用nodetool flush而不是nodetool drain,有什么区别?
nodetool flush
只将memtables刷新到磁盘
nodetool drain
刷新memtables并停止接受来自客户端和其他节点的连接。提交日志是否已复制?否则,提交日志是单点故障,对吗?一旦该部分添加到SSTable中,提交日志也会被删除。否则,提交日志将不断增加,最终磁盘将耗尽空间。提交日志是否已复制?否则,提交日志是单点故障,对吗?每个节点都有自己的提交日志。这不是单点故障。是否在commitlog和memtable都更新后向客户端发出确认?如果是这样,那么为什么不同时执行这两项操作呢?@psanford在将数据写入提交日志时会发送一个ack,而不管数据是否实际在这样复制的数据库中。如果对数据库具有未受限制的提交日志的服务器崩溃,并且ack已经发送,会发生什么情况?