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