Apache Cassandra,像许多其他数据库一样,以文件形式存储数据。这些文件位于数据目录中,并组织在SSTables中。这篇文章将讨论这些文件的目录布局和命名模式,并解释Apache Cassandra 4.1中引入的新命名模式。
SSTables
SSTables 是 Cassandra 存储表数据的文件。在一个典型的操作中,一个SSTable的创建是将memtable刷到磁盘或compaction后的结果。每个SSTable数据来自同一张表,但对于一个表来说,通常有许多SSTable。单个的SSTable是由多个文件组成的,称为组件。这些组件通常属于特定的SSTable格式的。BigTable是目前唯一支持的格式,也是Apache Cassandra唯一支持的类型组件(至少在写这篇文章的时候)。例如,单个SSTable是这样一组文件:
nb-1-big-CompressionInfo.db
nb-1-big-Data.db
nb-1-big-Digest.crc32
nb-1-big-Filter.db
nb-1-big-Index.db
nb-1-big-Statistics.db
nb-1-big-Summary.db
nb-1-big-TOC.txt
你可以在文档中找到更多关于BigTable格式的SSTable组件。
目录布局和文件名
SSTable文件存储在数据目录中。目录布局包括每个keyspace一个目录和keyspace目录下每个表一个目录。
data0/
/ks_foo
/tab_bar-<id>
/<version>-<generation id>-<format>-<component>.<ext>
data1/
/ks_foo
/tab_bar-<id>
/<version>-<generation id>-<format>-<component>.<ext>
表的目录名有一个标识符
< version > - 版本标识符是由两个小写字母组成的。这些字母表示主要和次要版本(在古老的 Cassandra 发行版中,版本由一个字母表示)。
< generation id > - 这是区分SSTables的标识符,以及不同SSTables的顺序。
< format > - 这是SSTable格式的标识符。如上所述,目前唯一存在的格式是BigTable,其标识符是’big’。
< component >.< ext > - 组件的名称和该组件特有的扩展。
SSTable标识符
SSTable标识符(也被称为生成标识符)用于区分和排序不同的SSTable。由于每次刷新表时都会创建一个SSTable,所以在同一目录下可以同时存在许多SSTable。新存储的SSTable的生成标识符会保证大于节点上表之前存储的SSTable 标识符。生成标识符通常使用自然数。Cassandra在启动时,在任何新的SSTable写入之前会扫描目录,在本地数据目录中指定表找到递增的最大生成标识符,从而获得新的开始标识符。
注意:Cassandra包括实时数据目录和备份目录,但在执行其启动扫描时忽略了快照目录。因此,在所有的数据目录中,可能会有具有相同标识符的SSTables,而它们是不同的SSTables。基于自然数的一般标识符旨在使每个Cassandra节点和表都是唯一的。这意味着,不仅同一节点上创建的两个不同的表的两个SSTables可能具有相同的标识符,从而具有相同的文件名,而且在不同节点上创建的同一表的两个不同的SSTables也是如此。
正如所料,由于上面讨论的标识符属性,可能会有一些维护问题。例如下面所说,一张表的truncation 会触发快照的创建,并从数据目录中删除所有的SSTable。如果节点重新启动,并且在这之前没有创建SSTable,那么序列就会从头开始重新启动,因为没有现有的SSTable用于识别最后生成的标识符:
/ks_foo
/tab_bar-<id>
/nb-1-big-Data.db
在truncation前有一个快照——也就是说,Cassandra在快照目录中为所有SSTables文件创建了硬链接,然后从实时数据目录中删除文件。
/ks_foo
/tab_bar-<id>
/snapshots
/truncated-<timestamp>-tab_bar
/nb-1-big-Data.db
当节点重新启动时,Cassandra会忽略当前的序列并重新开始;当存储一个新的SSTable时,它将获得"1"作为标识符:
/ks_foo
/tab_bar-<id>
/nb-1-big-Data.db
/snapshots
/truncated-<timestamp>-tab_bar
/nb-1-big-Data.db
正如你所看到的,有可能出现两个名称相同但内容可能不同的SSTable。这种情况只有在用户将SSTable存储在不同的位置进行备份时才会成为问题。由于文件名相同,SSTables的备份很可能与现有的SSTables发生冲突。
引入全局唯一标识符
为了解决基于自然数的SSTable标识符的一些问题,Cassandra 4.1引入了可切换至全局唯一标识符的能力。这些新的标识符是基于时间UUID(UUID类型1),尽管它们的字符串表示方式不同,但在词法上有序,为管理员提供方便。全局唯一标识符的结构如下:
<date part>_<time part>_<nano part><random part>
标识符分为以下几个部分:
< date part > - 编码为4个Base36字符的日期。
< time part > - 以秒为单位的一天时间,编码为4个Base36字符。
< nano part > - 秒的纳秒部分编码为 5 个 Base36 字符。
< random part > - 13个Base36随机字符,固定用于某个节点上的Cassandra系统进程。
这种结构比原始UUID表示法更紧凑,并提供以下属性:
- 标识符按词典序排列。
- 容易区分在同一天创建的SSTable。
- 容易区分由同一过程创建的SSTable。
- 这些标识符在整个Cassandra集群中是唯一的。
- 不需要扫描数据目录来知道从哪个标识符开始。
例如,在同一时间产生的连续标识符看起来是这样:


从这些名称中,我们可以看到,所有标识符的第一部分是3fw2,这意味着所有的SSTables都是在同一天创建的。第二部分是不同的,它的字典序反映了SSTables的创建顺序。接下来的五个字符是创建时间纳秒的部分。最后13个字符在前4个标识符中是相同的,这意味着它们是在同一个节点上创建的,甚至是由Cassandra服务器的同一个实例创建的,也就是同一个进程。第五个标识符的最后13个字符不同,要么是在不同的节点上创建的,要么是在创建该SSTable之前节点已经重新启动了(简单地说,是不同的进程)。
迁移
通过将cassandra.yaml中的enable_uuid_sstable_identifiers标志切换为true,可以启用全局唯一标识符功能。默认情况下是关闭的,因为一旦一个节点开始启用该功能,每个新存储的SSTable都会使用新的机制创建的标识符。因此,这使得降级过程更加困难,因为全局唯一标识符在4.1之前不能被Apache Cassandra读取。因此,所有的SSTable文件都必须使用自然数的旧标识符方法进行手动重命名。
注意该标志设置为 "true"并不会使Cassandra立即根据新方案重命名现有的SSTables。它只影响到新存储的SSTables。存在的SSTable最终会在正常的compaction过程中被删除。
对全局唯一的SSTable标识符的支持在CASSANDRA-17048中实现,是Apache Cassandra 4.1版本的一部分。我们希望它能减少手动备份时的一些问题,因为在任何节点上为任何表创建的每个SSTable都将有一个全局唯一的标识符。
原文标题:Apache Cassandra 4.1: New SSTable Identifiers
原文作者:Jacek Lewandowski
原文地址:https://cassandra.apache.org/_/blog/Apache-Cassandra-4.1-New-SSTable-Identifiers.html




