431.行缓存和键缓存请求流程图

MemTable:如果 memtable 有目标分区数据,这个数据会被读出来并且和从 SSTables 中读出来的数据进行合并。SSTable 的数据访问如下面所示的步骤。

Row Cache(SSTables 中频繁被访问的数据)

  1. 在 Cassandra2.2+,它们被存储在堆外内存,使用全新的实现避免造成垃圾回收对 JVM 造成压力。存在在 row cache 的子集数据可以在特定的一段时间内配置一定大小的内存。row cache 使用LRU(least-recently-userd)进行回收在申请内存。存储在 row cache 中的数据是SSTables 中频繁被访问的数据。存储到row cache中后,数据就可以被后续的查询访问。row cache不是写更新。如果写某行了,这行的缓存就会失效,并且不会被继续缓存,直到这行被读到。类似的,如果一个partition更新了,整个partition的cache都会被移除,但目标的数据在row cache中找不到,就会去检查 Bloom filter。

Bloom Filter(查找数据可能对应的 SSTable)

  1. 首先,Cassandra 检查 Bloom filter 去发现哪个 SSTables 中有可能有请求的分区数据。Bloom filter 是存储在堆外内存。每个 SSTable 都有一个关联的 Bloom filter。一个 Bloom filter 可以建立一个 SSTable 没有包含的特定的分区数据。同样也可以找到分区数据存在 SSTable 中的可能性。它可以加速查找 partition key 的查找过程。然而,因为 Bloom filter 是一个概率函数,所以可能会得到错误的结果,并不是所有的 SSTables 都可以被 Bloom filter 识别出是否有数据。如果Bloom filter 不能够查找到 SSTable,Cassandra 会检查 partition key cache。Bloom filter 大小增长很适宜,每 10 亿数据 1~2GB。在极端情况下,可以一个分区一行。都可以很轻松的将数十亿的 entries 存储在单个机器上。Bloom filter 是可以调节的,如果你愿意用内存来换取性能。

Partition Key Cache(查找数据可能对应的 Partition key)

  1. partition key 缓存如果开启了,将 partition index 存储在堆外内存。key cache 使用一小块可配置大小的内存。在读的过程中,每个”hit”保存一个检索。如果在 key cache 中找到了 partition key。就直接到 compression offset map 中招对应的块。partition key cache 热启动后工作的更好,相比较冷启动,有很大的性能提升。如果一个节点上的内存非常受限制,可能的话,需要限制保存在 key cache 中的 partition key 数目。如果一个在 key cache 中没有找到 partition key。就会去partition summary中去找。partition key cache 大小是可以配置的,意义就是存储在key cache 中的 partition keys 数目。

Partition Summary(内存中存储一些 partition index 的样本)

  1. partition summary 是存储在堆外内存的结构,存储一些 partition index 的样本。如果一个partition index 包含所有的 partition keys。鉴于一个 partition summary 从每 X 个 keys 中取样,然后将每 X 个 key map 到 index 文件中。例如,如果一个 partition summary 设置了 20keys进行取样。它就会存储 SSTable file 开始的一个 key,20th 个 key,以此类推。尽管并不知道partition key 的具体位置,partition summary 可以缩短找到 partition 数据位置。当找到了partition key 值可能的范围后,就会去找 partition index。通过配置取样频率,你可以用内存来换取性能,当 partition summary 包含的数据越多,使用的内存越多。可以通过表定义的 index interval 属性来改变样本频率。固定大小的内存可以通过 index_summary_capacity_in_mb 属性来设置,默认是堆大小的 5%。

Partition Index(磁盘中)

  1. partition index 驻扎在磁盘中,索引所有 partition keys 和偏移量的映射。如果 partition summary 已经查到 partition keys 的范围,现在的检索就是根据这个范围值来检索目标 partition key。需要进行单次检索和顺序读。根据找到的信息。然后去 compression offset map 中去找磁盘中有这个数据的块。如果 partition index 必须要被检索,则需要检索两次磁盘去找到目标数据。

Compression offset map(磁盘中)

  1. compression offset map 存储磁盘数据准确位置的指针。存储在堆外内存,可以被 partition key cache 或者 partition index 访问。一旦 compression offset map 识别出来磁盘中的数据位置,就会从正确的 SStable(s)中取出数据。查询就会收到结果集。