我在 Cassandra 中有一个表,我在其中填充了一些包含 1000 个条目的行(每行包含 10000 多列)。行中的条目非常频繁地更新,基本上只是用不同的值更新了一个字段(它是一个整数)。列的所有其他值保持不变。我的问题是,更新会就地完成吗?Cassandra 对条目的频繁更新有多好?
3 回答
首先,每次更新也是 cassandra 的顺序写入,因此,就 cassandra 而言,无论您是更新还是写入,它对 cassandra 都没有任何影响。
真正的问题是您需要多快才能读取这些写入内容才能读取?正如@john 建议的那样,首先将所有写入写入驻留在内存中的可变 CQL Memtable。因此,对于特定 CQL 表,每个更新本质上都作为新的顺序条目附加到 memtable 中。为了持久性,它同时定期写入“commitlog”(每 10 秒)。
当 Memtable 已满或达到 comittlog 的总大小时,cassandra 将所有数据刷新到不可变的排序字符串表 (SSTable)。在刷新之后,压缩是保留新列值的所有 PK 条目并删除所有先前值(更新之前)的过程。
频繁刷新会带来频繁顺序写入磁盘和压缩的开销,这可能会占用大量 I/O 并对 cassandra 性能产生严重影响。
就读取而言,首先 cassandra 将尝试从row cache
(如果启用)或从memtable
. 如果它在那里失败,它将按顺序转到bloom filter
、key cache
、partition summary
,partition index
最后转到 SSTable 。当为所有列值收集数据时,其在内存中的聚合和具有最新时间戳的列值在聚合后返回给客户端,并row cache
为该分区键创建一个条目。
因此,是的,当您查询分区键时,它将扫描所有 SSTable 以查找该特定 CQL 表,并扫描 memtable 以查找所有尚未刷新到磁盘的列值。
最初,这些更新存储在称为 Memtable 的内存数据结构中。Memtables 会定期刷新到不可变的 SSTables。
因此,将从各种 SSTable 中读取单个宽行。在称为“压缩”的过程中,不同的 SSTable 将被合并到磁盘上更大的 SSTable。
增加刷新 Memtables 的阈值是一种优化方法。如果在 Memtable 刷新到磁盘之前更新非常快,我认为更新应该在内存中就地,但不确定。
此外,每个读取操作都会首先检查 Memtables,如果数据仍然存在,它将被简单地返回——这是最快的访问。
Cassandra读取路径:
When a read request for a row comes in to a node, the row must be combined from all SSTables on that node that contain columns from the row in question
Cassandra写入路径:
不,无法进行就地更新。
正如@john 建议的那样,如果您经常写入,那么您应该延迟刷新过程。在刷新期间,对存储在 MemTable 中的同一分区的多次写入将作为单个分区写入新创建的 SSTable 中。
C* 适合大量写入。但是,您需要监控每次读取访问的 SSTable 数量。如果 # 太高,那么您需要检查您的压缩策略。