Memtable理解

6

我有关于Cassandra Memtable的问题。感谢您的帮助。

Memtable的相关信息:

1) 存放在RAM中;

2) 每个ColumnFamily结构都有一个memtable;

3) 一个ColumnFamily可以存在多个memtable;

问题:

1) 什么时候会为ColumnFamily创建额外的memtable?需要满足什么条件?我认为在创建额外的commit log文件后会创建额外的memtable。这是正确的吗?

2) 达到commit log大小阈值后会发生什么?我认为会开始将memtable放入队列;在队列填满后,将开始将memtable刷新到sstable,然后删除旧的commit log(在hdd上)和相应的memtables(在ram中)。在这种情况下,部分memtable内存将始终为空,并且commit log始终会被填满90-100%吗?

3) 当达到memtable大小阈值时会发生什么?与前面的情况类似,会开始刷新到sstable吗?某些部分的commit log也将始终为空,并且memtable内存将填满90-100%吗?

4) 关于memtable_allocation_type: 在官方资源中 - "offheap_buffers将单元格名称和值移动到DirectBuffer对象中。这对读取的影响最小-值仍然是“活动”的Java缓冲区-但仅在存储大字符串或blob时才会显着减少堆内存."。DirectBuffer是什么意思?它放置在Java堆中吗?您能提供一些关于此的信息网站链接吗?

非常感谢!

1个回答

15
  1. 对于给定的列族,通常只有一个内存中的Memtable,除了特殊情况如修复过程或待处理的刷新。
  2. 当提交日志已满时,会触发刷新:Memtable被写入磁盘作为SSTable,然后清除Memtable并回收提交日志。新的周期从空提交日志/Memtable开始。
  3. 当Memtable超过给定大小时,会像上面一样触发刷新。
  4. 通常默认情况下,Memtable保存在Java堆内存中。自Cassandra 2.1以来,Memtable可以存储在Java堆之外,以减轻GC压力。但是这个设置是一些特殊情况的优化。Cassandra可以使用JNA将数据存储在Java堆之外,这意味着这些数据不会被JVM知道,因此不适合进行垃圾回收。但是Java对象必须进行转换才能在其中存储/检索。这就是为什么这些Java对象不被视为“活着的”。

我建议你观看https://academy.datastax.com/courses/learning-cassandra-write-path


谢谢!但是在一些文章和书籍中存在不同的信息。哪一个是真实的呢?这是来自 Eben Hewitt 的书《Cassandra:权威指南》中的引用:“此刷新操作是非阻塞的;对于单个列族可能存在多个内存表,其中一个是当前的,其余的则等待被刷新”。 - bissquit
1
请注意,《Cassandra:权威指南》这本书有点老了,一些信息对于最近的Cassandra版本来说已经不是最新的了。 - G Quintana
我可以问最后一个问题吗?关于memtable_flush_queue_size参数:手册中存在建议“至少设置为单个表上创建的索引的最大数量。”为什么是单个表中的索引,如果此参数设置了队列中的memtable的最大值? - bissquit
在 flush Commit log 文件期间,文件并不是完全重新创建的,而是被回收利用。我不太清楚 Memtables。关于索引,每个二级索引都被存储为某种二级 Memtable(相同的数据以不同的方式排序)用于同一列族。你引用的规则是为了确保主数据和索引一起写入。虽然可以使用索引,但不建议这样做,并且应该限制在特殊情况下使用。再次强调,我认为索引不是 flush 的标准场景。在一个表上有 3 个索引似乎是一个糟糕的想法。 - G Quintana
我建议您阅读Robbie Strickland的《Cassandra高可用性进展》一书。 - G Quintana
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接