Cassandra 文档

版本

您正在查看预发布版本的文档。

存储引擎

Cassandra 在写入路径上的多个阶段处理数据,从立即记录写入开始,到将数据写入磁盘结束。

  • 在提交日志中记录数据

  • 将数据写入内存表

  • 从内存表中刷新数据

  • 在 SSTable 中将数据存储在磁盘上

将写入记录到提交日志

当发生写入时,Cassandra 会将数据写入本地追加式 (cassandra.apache.org//glossary.html#commit-log)[提交日志] 到磁盘。此操作通过记录对 Cassandra 节点的每次写入来提供 可配置的持久性。如果发生意外关闭,提交日志将提供数据的永久持久写入。启动时,提交日志中的任何变动将应用于 (cassandra.apache.org//glossary.html#memtable)[内存表]。提交日志在表之间共享。

所有变动在提交日志段中都经过写入优化,从而减少了写入磁盘所需的查找次数。提交日志段受 commitlog_segment_size 选项限制。一旦达到定义的大小,就会创建一个新的提交日志段。提交日志段可以在将所有数据刷新到 (SSTable 后存档、删除或回收。当 Cassandra 将比某个特定时间点更早的数据写入 SSTable 时,提交日志段会被截断。在停止 Cassandra 之前运行 nodetool drain 会将内存表中的所有内容写入 SSTable,并消除启动时与提交日志同步的需要。

  • commitlog_segment_size:默认大小为 32MiB,这几乎总是可以的,但是如果您正在存档提交日志段(请参阅 commitlog_archiving.properties),那么您可能希望更细粒度的存档;8 或 16 MiB 是合理的。commitlog_segment_size 也决定了 cassandra.yamlmax_mutation_size 的默认值。默认情况下,max_mutation_sizecommitlog_segment_size 的一半。

如果显式设置 max_mutation_size,则 commitlog_segment_size 必须至少设置为 max_mutation_size 的两倍。

  • commitlog_sync:可以是 periodicbatch

    • batch:在批处理模式下,Cassandra 不会在提交日志被 fsync 到磁盘之前确认写入。

    • periodic:在周期性模式下,写入会立即确认,提交日志只是每“commitlog_sync_period”毫秒同步一次。

      • commitlog_sync_period:两次“周期性”fsync 之间的等待时间 默认值: 10000ms

默认值: batch

在发生意外关闭的情况下,Cassandra 最多可能会丢失同步周期或更多时间(如果同步延迟)。如果使用 batch 模式,建议将提交日志存储在单独的专用设备中。

  • commitlog_directory:此选项默认情况下被注释掉。在磁性硬盘上运行时,这应该与数据目录位于不同的磁盘上。如果未设置,默认目录为 $CASSANDRA_HOME/data/commitlog

默认值: /var/lib/cassandra/commitlog

  • commitlog_compression:要应用于提交日志的压缩。如果省略,提交日志将以未压缩的方式写入。支持 LZ4、Snappy、Deflate 和 Zstd 压缩器。

默认值:(复杂选项)

#   - class_name: LZ4Compressor
#     parameters:
  • commitlog_total_space:磁盘上用于提交日志的总空间。此选项默认情况下被注释掉。如果空间超过此值,Cassandra 将刷新最旧段中的所有脏表并将其删除。因此,较小的提交日志总空间往往会导致对活动较少的表进行更多刷新操作。默认值为 8192 和提交日志卷总空间的 1/4 之间的较小值。

默认值: 8192MiB

内存表

当发生写入时,Cassandra 还会将数据写入内存表。内存表是 Cassandra 在内存中缓冲写入的结构。通常,每个表都有一个活动的内存表。内存表是 Cassandra 按键查找的数据分区的写回缓存。内存表可以完全存储在堆中,也可以部分存储在堆外,具体取决于 memtable_allocation_type

内存表按排序顺序存储写入,直到达到可配置的限制。当达到限制时,内存表会被刷新到磁盘并成为不可变的 SSTable。刷新可以通过多种方式触发

  • 内存表的内存使用量超过配置的阈值(请参阅 memtable_cleanup_threshold

  • 提交日志 接近其最大大小,并强制刷新内存表以释放提交日志段。

当发生触发事件时,内存表会被放入一个队列中,该队列会被刷新到磁盘。刷新会将数据写入磁盘,按内存表排序顺序进行。还会在磁盘上创建一个分区索引,将令牌映射到磁盘上的位置。

可以使用 cassandra.yaml 文件中的 memtable_heap_spacememtable_offheap_space 设置来配置队列。如果要刷新的数据超过 memtable_cleanup_threshold,Cassandra 会阻塞写入,直到下一次刷新成功。您可以使用 nodetool flushnodetool drain(在不监听其他节点的连接的情况下刷新内存表)手动刷新表。为了减少提交日志重放时间,建议的做法是在重新启动节点之前刷新内存表。如果节点停止工作,重放提交日志会将停止之前存在的内存表中的写入恢复到内存表。

提交日志中的数据在内存表中的对应数据被刷新到磁盘上的 SSTable 后会被清除。

SSTable

SSTable 是 Cassandra 用于将数据持久化到磁盘上的不可变数据文件。SSTable 按表维护。SSTable 是不可变的,在内存表被刷新后不再写入。因此,分区通常存储在多个 SSTable 文件中,因为数据被添加或修改。

每个 SSTable 由存储在单独文件中的多个组件组成

Data.db

实际数据,即行的内容。

Partitions.db

分区索引文件将装饰分区键的唯一前缀映射到数据文件位置,或者,在行索引文件中索引的宽分区的情况下,映射到行索引文件中的位置。

Rows.db

行索引文件只包含包含多行且大于一个索引块的分区的条目。对于所有此类分区,它存储分区键的副本、分区头和行块分隔符的索引,这些索引将每个行键映射到可以找到具有相同或更高行键的任何内容的第一个块。

Index.db

从分区键到 Data.db 文件中位置的索引。对于宽分区,这可能还包括分区内行的索引。

Summary.db

Index.db 文件中(默认情况下)每 128 个条目的采样。

Filter.db

SSTable 中分区键的布隆过滤器。

CompressionInfo.db

有关 Data.db 文件中压缩块的偏移量和长度的元数据。

Statistics.db

存储有关 SSTable 的元数据,包括有关时间戳、墓碑、聚类键、压缩、修复、压缩、TTL 等的信息。

Digest.crc32

Data.db 文件的 CRC-32 摘要。

TOC.txt

SSTable 的组件文件的纯文本列表。

SAI*.db

存储附加索引的索引信息。只有在为表启用 SAI 时才会出现。

请注意,Index.db 文件类型已被 Partitions.dbRows.db 替换。此更改是由于 Cassandra 中包含大 Trie 索引(CEP-25)的结果。

Data.db 文件中,行按分区组织。这些分区按令牌顺序排序(即,当使用默认分区器 Murmur3Partition 时,按分区键的哈希值排序)。在分区内,行按其聚类键的顺序存储。

SSTable 可以选择使用基于块的压缩进行压缩。

当 SSTable 从 memtables 刷新到磁盘或从其他节点流式传输时,Cassandra 会触发压缩操作,将多个 SSTable 合并为一个。写入新的 SSTable 后,可以删除旧的 SSTable。

SSTable 版本

迄今为止的版本号为

版本 0

  • b (0.7.0):在 sstable 文件名中添加版本

  • c (0.7.0):布隆过滤器组件计算原始键字节的哈希值,而不是字符串

  • d (0.7.0):数据组件中的行大小变为长整型,而不是整型

  • e (0.7.0):在数据和索引组件中存储未修饰的键

  • f (0.7.0):切换数据组件中的布隆过滤器实现

  • g (0.8):在元数据组件中跟踪已刷新上下文

版本 1

  • h (1.0):在元数据组件中跟踪最大客户端时间戳

  • hb (1.0.3):在元数据组件中记录压缩比率

  • hc (1.0.4):在元数据组件中记录分区器

  • hd (1.0.10):将行墓碑包含在 maxtimestamp 中

  • he (1.1.3):在元数据组件中包含祖先代

  • hf (1.1.6):标记重放位置对应于 1.1.5+ 基于毫秒的 ID(参见 CASSANDRA-4782)

  • ia (1.2.0)

    • 列索引被提升到索引文件

    • 记录墓碑中删除时间的估计直方图

    • 布隆过滤器(键和列)升级到 Murmur3

  • ib (1.2.1):在元数据组件中跟踪最小客户端时间戳

  • ic (1.2.5):省略每行列名的布隆过滤器

版本 2

  • ja (2.0.0)

    • 超级列被序列化为复合类型(请注意,没有真正的格式更改,这主要是一个标记,用于知道是否应该期望超级列。但是,我们需要一个主要版本升级,因为我们不应该允许将超级列流式传输到这种新格式中)

    • 跟踪 sstable 元数据中的最大本地删除时间

    • 在元数据组件中记录 bloom_filter_fp_chance

    • 从数据文件(CASSANDRA-4180)中删除数据大小和列计数

    • 跟踪最大/最小列值(根据比较器)

  • jb (2.0.1)

    • 从 crc32 切换到 adler32 用于压缩校验和

    • 校验压缩数据

  • ka (2.1.0)

    • 新的 Statistics.db 文件格式

    • 索引摘要可以被下采样,并且采样级别被持久化

    • 将未压缩校验和切换到 adler32

    • 跟踪传统(本地和远程)计数器分片的是否存在

  • la (2.2.0):新的文件名格式

  • lb (2.2.7):包含提交日志下限

版本 3

  • ma (3.0.0)

    • 交换 bf 哈希顺序

    • 以原生方式存储行

  • mb (3.0.7, 3.7):包含提交日志下限

  • mc (3.0.8, 3.9):包含提交日志间隔

  • md (3.0.18, 3.11.4):修正了 sstable 最小/最大聚类

  • me (3.0.25, 3.11.11):添加了 sstable 来源节点的 hostId

版本 4

  • na (4.0-rc1):未压缩块、待处理的修复会话、isTransient、校验和 sstable 元数据文件、新的 Bloomfilter 格式

  • nb (4.0.0):来源主机 ID

版本 5

  • oa (5.0):改进的最小/最大值、分区级删除存在标记、键范围(CASSANDRA-18134)

    • 长整型删除时间,以防止 TTL 溢出

    • 令牌空间覆盖率

基于 Trie 索引的 SSTable 版本 (BTI)

Cassandra 5.0 引入了新的 SSTable 格式 BTI,用于基于 Trie 索引的 SSTable。要使用 BTI 格式,请在 cassandra.yaml 中进行配置,例如

sstable:
  selected_format: bti

版本来自 (BtiFormat#BtiVersion.

有关实现文档,请参见 (BtiFormat.md.

版本 5

  • da (5.0):BIT 格式的初始版本

示例代码

以下示例对于查找所有与“ib”SSTable 版本不匹配的 sstable 很有用

find /var/lib/cassandra/data/ -type f | grep -v -- -ib- | grep -v "/snapshots"