1

我正在浏览 DataStax 文档,发现了一个有趣的声明。

它声称“插入繁重的工作负载在 Cassandra 中受 CPU 限制,然后才成为内存限制”。

有人可以解释一下这种说法是如何提出的吗?什么可能导致卡桑德拉的这种行为?

谢谢。

4

1 回答 1

5

对于不同的工作负载,Cassandra 集群可以是 CPU、内存、I/O 或(偶尔)网络绑定。文档中的声明是,如果您启动一个新集群并进行大量插入,该集群最初将受 CPU 限制,但过了一段时间它会成为内存瓶颈。

为了处理插入,Cassandra 需要反序列化来自客户端的消息,找到应该存储数据的节点并将消息发送到这些节点。然后,这些节点将数据存储在称为 Memtable 的内存数据结构中。

最初这几乎总是受 CPU 限制。但是,随着更多数据的插入,memtable 会变大并刷新到磁盘并创建新的(空)memtable。刷新的 memtables 存储在称为 SSTables 的文件中。有一个持续的后台过程称为压缩,它将 SSTable 合并成越来越大的文件。

在此阶段更多内存会有所帮助的原因有几个:

  • 如果 Cassandra 堆空间不足,它会在内存表较小时刷新内存表。这会创建更小的 SSTable,因此需要更多的工作来压缩它们。
  • 如果工作负载涉及在不同时间覆盖或插入同一行,那么如果该行仍在当前内存表中,这样做会便宜得多。如果不是,则覆盖和新列存储在新的内存表中,然后在压缩期间刷新和合并。同样,更少的内存意味着更多的压缩工作。
  • 您的操作系统在压缩期间使用内存来缓冲读取和写入。如果操作系统不能,那么将会有额外的 I/O,减慢 memtable 刷新和压缩。
  • 插入 Cassandra 会消耗大量 Java 对象,因此需要为垃圾收集器创建工作。如果堆太小,插入可能会在 GC 运行时暂停以产生一些空闲堆。(另一方面,如果堆太大,插入可能会在 stop-the-world GC 期间暂停几秒钟。)

所以插入可能成为内存绑定,但它们也可能成为 I/O 绑定。如果没有足够的 I/O 来刷新内存表,那么一旦内存表刷新队列已满,插入操作就会被阻塞。所以我认为这个说法可能更准确一点:

在成为内存或 I/O 限制之前,Cassandra 中的大量插入工作负载受 CPU 限制。

于 2013-06-10T12:43:09.717 回答