官方地址: Storage Engine
存储引擎
参考: Cassandra 写机制
- cassandra 首先将客户端提交的数据和操作记录写入到 commitLog,其目的是:为了提升可靠性,起到数据恢复的作用
- 接着 cassandra 将数据写入到 内存表 memtable 中, memtable 中 组织的数据 按照 key 排序。当 memtable 中的数据到达一定限制后(周期性 / 批量)flush 到 一个 SSTable 中。 这种机制,相当于 缓存 写回机制(write back cache),目的在于:将随机 IO 写改为 顺序 IO 写,大大降低了 写操作对于存储系统的压力。
- SSTable 写入成功之后,不可变更,只能读取,因此对于 Cassandra 而言,只有 顺序写,没有随机写 操作
- 由于 SSTbale 的只读性,因此 同一个 Column Family 的数据可能存储在 多个 SSTable 中,如果一个 Column Family 中的数据量很大的时候,此时 Cassandra 会合并读取多个 SSTable 和 Memtable ,导致 查询的效率 严重下降。
- 在 4 的基础上:因此,cassandra 引入了 BloomFilter ,每个 SSTable 都会有一个 BloomFilter , 是一个存储在 内存中的数据结构,它可以快速判断某个给定的 key 是否位于 某个 SSTable 中,因此,Cassandra 能够 快速定位 某个 key 对应的 SSTable
- 为了避免大量SSTable带来的性能影响,Cassandra通过一种称为压缩(Compaction)的机制来处理随着时间推移而不断膨胀的SSTables。Cassandra定期将多个SSTable合并成一个SSTable,由于每个SSTable中的数据均是有序的,因此只要做一次合并排序就可以完成该任务,这个代价是可以接受的。
- Cassandra 的数据存储目录下,可以看到三种类型的文件,文件名的格式类似于:(Column Family Name-序号-Data.db / Column Family Name-序号-Filter.db / Column Family Name-序号-index.db). 其中Data.db 文件是 SSTable 数据文件,SSTable 是 Sorted Strings Table 的缩写,按照key 排序后存储 key/value 键值字符串。index.db 是索引文件,保存的是每个 key 在数据文件中的偏移位置,而 Filter.db 则是 Bloom Filter 算法生产的映射文件。
_
CommitLog
提交日志是 Cassandra
节点本地所有突变的仅追加日志。写入 Cassandra
的所有数据都将首先写入提交日志,然后再写入内存表。这在意外关机的情况下提供了耐用性。启动时,提交日志中的任何突变都将应用于内存表。
所有数据写入操作都通过存储在commitlog
段中进行优化,,从而减少了写入磁盘所需的查找次数。提交日志段受commitlog_segment_size_in_mb
选项限制,一旦达到大小,就会创建一个新的提交日志段。一旦将所有Commitlog数据刷新到SSTables后,就可以对其进行归档,删除或回收。当 Cassandra
将数据早于特定点写入 SSTables
时, Commitlog
段将被截断。在停止 Cassandra
之前运行 nodetoolrain
将把 memtables
中的所有内容写入 SSTables
,并且无需在启动时与提交日志同步。
-
commitlog_segment_size_in_mb
: 默认大小为32,几乎总是可以的,但是,如果要归档提交日志段(请参见commitlog_archiving.properties
),则可能需要更精细的归档粒度。8或16 MB是合理的。还可以通过cassandra.yaml中的max_mutation_size_in_kb
设置来配置最大突变大小。默认值为commitlog_segment_size_in_mb * 1024
的一半。
注意:如果明确设置了max_mutation_size_in_kb,则commitlog_segment_size_in_mb必须设置为至少两倍于max_mutation_size_in_kb / 1024
commitlog_sync
可以是: "periodic
" or "batch
" , 默认: batch
-
batch
: 在batch
模式下,Cassandra
不会应答(ack)写操作直到commitlog
写到(fsync)
磁盘上。它会在fsyncs
之间等待commitlog_sync_batch_window_in_ms
毫秒。这个窗口期应保持短,因为writer
线程在等待时将无法完成额外的工作。出于同样的原因,您可能需要增加concurrent_writes
-
commitlog_sync_batch_window_in_ms
: 在batch , fsyncs
之间等待的时间。默认值为 2
-
-
periodic
: 在periodic
模式下,写操作会被立即应答(ack)
,每commitlog_sync_period_in_ms
毫秒都会简单地同步CommitLog
-
commitlog_sync_period_in_ms
:在periodic
,fsyncs
之间等待的时间。默认值为 10000
-
如果发生意外关机, 则如果同步延迟, 则
Cassandra
可能会失去同步期间或更多的数据。如果使用batch
模式, 建议将commitlogs
存储在单独的存储设备中
commitlog_directory
在磁性机械硬盘(magnetic HDD)
上运行时, 默认情况下此选项被注释掉,这个目录应该和data目录分开存放到不同的物理磁盘。如果未设置, 则默认目录为 $CASSANDRA _home/data/commitlog
commitlog_compression
压缩以应用于commitlog。 如果省略,则提交日志将被解压缩。 支持LZ4,Snappy和Deflate压缩器.
# - class_name: LZ4Compressor
# parameters:
# -
commitlog_total_space_in_mb
commitlog
占用的总空间。如果使用的空间超过了这个值,Cassandra
转到下一个最近的段,刷新那些最旧的commitlog
段对应的 memtables
到磁盘中,删除这些log段。这减少了启动时重播的数据量,防止不经常更新的表不定期的保留commitlog
段。一个小的commitlog
总空间会导致不活跃的表产生更频繁的刷新活动
The default value is the smaller of 8192, and 1/4 of the total space of the commitlog volume.
Memtables
Memtables
是内存结构,作为 Cassandra
的写入缓冲。通常,每个表有一个活跃的 memtable
。最终,memtables
被刷新到磁盘上,成为不可变的 SSTables
。这可以通过多种方式触发:
-
memtables
的内存使用量超过配置的阈值( memtable_cleanup_threshold)
-
CommitLog
接近其最大大小,并强制执行memtable
刷新以允许释放commitlog
段
Memtables
可以完全存储在堆上或部分堆外存储,具体取决于memtable_allocation_type
SSTables
SSTables
是 Cassandra
用于在磁盘上保存数据的不可变数据文档。由于SSTables
从Memtables
刷新到磁盘或从其他节点流式传输,Cassandra
会触发将多个SSTable
组合成一个的压缩
由于SSTables
从Memtables
刷新到磁盘或从其他节点流式传输,因此Cassandra
会触发压缩将多个SSTable
组合成一个。 一旦编写了新的SSTable
,就可以删除旧的SSTable
- Data.db: 实际数据, 即行的内容
- Index.db: 从分区键(partition keys)到Data.db文档中的位置的索引。对于宽分区,这可能还包括分区内行的索引
- Summary.db: Index.db文档中每128个条目(默认情况下)的采样
- Filter.db: SSTable中分区键(partition keys)的布隆过滤器(Bloom Filter)
- CompressionInfo.db: Data.db文档中的压缩块的偏移量和长度的元数据
- Statistics.db: 存储SSTable相关的元数据,包括时间戳,逻辑删除(tombstones),集群key,压缩,修复,压缩,TTL等信息
- Digest.crc32: Data.db文档的CRC-32摘要
- TOC.txt: SSTable的组件文档的纯文本列表
Within the Data.db file, rows are organized by partition. These partitions are sorted in token order (i.e. by a hash of the partition key when the default partitioner, Murmur3Partition, is used). Within a partition, rows are stored in the order of their clustering keys.
可以选择使用基于块的压缩来压缩SSTable。