请有人向我澄清了解提交日志及其使用情况。
在Cassandra中,写入磁盘时,提交日志是第一个入口点或MemTables。
如果Memtables是刷新到磁盘的,那么提交日志的用途是,如果数据节点关闭,提交日志的唯一目的是服务器同步问题吗?
答案 0 :(得分:59)
您可以将提交日志视为优化,但如果没有它,Cassandra将会非常缓慢。当MemTables写入磁盘时,我们称之为SSTables。 SSTables是不可变的,这意味着一旦Cassandra将它们写入磁盘,它就不会更新它们。因此,当列更改时,Cassandra需要将新的SSTable写入磁盘。如果Cassandra在每次更新时都将这些SSTable写入磁盘,那么它将完全受IO限制并且非常慢。
所以Cassandra使用一些技巧来获得更好的表现。它不是在每次列更新时将SSTable写入磁盘,而是将更新保留在内存中并定期将这些更改刷新到磁盘以使IO保持在合理的水平。但这导致了一个明显的问题,即如果机器出现故障或Cassandra崩溃,您将丢失该节点上的数据。为了避免丢失数据,除了保留最近的内存更改外,Cassandra还将更改写入其CommitLog。
你可能会问为什么写一个提交日志比编写SSTable更好。 CommitLog针对写入进行了优化。与以排序顺序存储行的SSTable不同,CommitLog按照Cassandra处理它们的顺序存储更新。 CommitLog还将所有列系列的更改存储在一个文件中,因此当磁盘同时接收多个列系列的更新时,不需要执行大量搜索。
基本上将CommitLog写入磁盘是更好的,因为它必须写入比写入SSTables更少的数据,并将所有数据写入磁盘上的单个位置。
Cassandra会跟踪已刷新到SSTables的数据,并且一旦写入了早于某个点的所有数据,就能截断提交日志。
当Cassandra启动时,它必须从最后一个已知的好时间点(我们知道所有先前写入写入SSTable的时间点)读取提交日志。它将提交日志中的更改重新应用于其MemTables,以便在停止时进入相同的状态。这个过程可能很慢,所以如果你要停止一个Cassandra节点进行维护,最好在关闭它之前使用nodetool drain
,这会将MemTables中的所有内容刷新到SSTables并在启动时大量工作小。
答案 1 :(得分:29)
cassandra中的写入路径如下:
Cassandra Node ---->Commitlog-----------------> Memtable
| |
| |
|---> Periodically |---> Periodically
sync to disk flush to SSTable
Memtable和CommitLog并行 NOT 写入(种类)。必须在开始写入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大小超出 - 或者flushto由nodetool或opscenter执行。因此,memtable中的数据不会直接保留。
话虽如此,重启节点之前的好处是调用“nodetool flush”以确保你的memtable是持久的。这也会在节点再次出现后减少提交日志的播放时间。