Cassandra 的问题:为什么它是对象存储的元数据数据库的糟糕选择

Cassandra 的问题:为什么它是对象存储的元数据数据库的糟糕选择


Cassandra是一个流行的,经过验证的NoSQL数据库,它支持键值宽列表。像任何强大的工具一样,Cassandra具有理想的用例-特别是,Cassandra擅长支持繁重的写工作负载,同时在支持繁重的读工作负载方面有局限性。Cassandra最终的一致性模型和缺少事务,连接,子查询等多表支持也会限制其用途。

但是,将Cassandra用作对象存储系统的元数据数据库会带来极大的复杂性,从而导致大规模的数据完整性和性能问题-尤其是当人们希望将其对象存储用作主要存储系统时。对象存储的需求要简单得多,并且与Cassandra的构建需求有所不同。

由于无法正确理解将Cassandra用作对象存储元数据数据库的含义,因此许多对象存储供应商将其作为其体系结构的基础部分-不幸的是,它使他们无法从简单的归档工作负载转移到定义了未来存储的现代工作负载中。对象存储(AI / ML,分析,Web /移动应用程序)。

让我们更详细地探讨为什么。

  1. Cassandra从未设计用于管理文件或对象存储元数据,并且在这方面可预见的是薄弱的。不兼容ACID它不具有防止部分成功的写入,伪造,矛盾之类的刚性。Cassandra不支持联接或外键,因此不提供ACID的一致性。此外,如果发生故障,则没有能力回滚事务。

    尽管Cassandra在行级别支持原子性和隔离性,但它以事务性隔离性和原子性为代价来实现高可用性和快速写入性能。

  2. Cassandra在CAP中被归类为AP系统。这意味着它会在可用性和分区容限之间交换一致性。将Cassandra用作对象存储的元数据数据库时,您可以快速或一致-但不能同时使用。

    Cassandra的可调一致性是一种折衷,而不是功能。除了QUORUM或ALL以外的任何设置都意味着您有读取过时数据的风险。除了在其外部执行的对象数据操作外,还应将此一致性设置应用于读取和写入操作。

    在对象存储世界中,这意味着您可以适合存档用例(一次编写,很少阅读),或者选择其他体系结构。

  3. 与一致性问题类似,耐久性保证也是性能和正确性之间的折衷。存储引擎的默认提交日志设置为每10秒定期同步。这意味着在电源故障的情况下,您将损失多达10秒钟的最新更新。使Cassandra持久的唯一合理方法是使用同步批处理模式提交程序,这会降低性能。

  4. Cassandra的高可用性保证不适用于擦除编码的对象存储。使用3的复制因子和2的一致性仲裁,Cassandra只能容忍复制组内的单个节点/驱动器故障。将复制因子和仲裁一致性增加到5或更高,只会使元性能变差。与复制不同,擦除编码可以容忍多个服务器并导致分布式系统中的故障。即使在16个节点的设置中将擦除代码设置配置为6个奇偶校验(任何6个节点都可能失败),您仍然受到弱链接(即Cassandra的复制因子)的限制。操作团队通常不会意识到这些高可用性的意外,直到为时已晚。

  5. 对象存储系统将数据组织在树形结构的分层名称空间中。由于Cassandra不支持分层键名称空间,因此您将必须在每个目录前缀的顶部构建一个树形数据模型,并且还需要为无需目录遍历的直接查找维护一个平面列表。使用批处理提交日志和完整的读/写仲裁以原子方式更新多个表的速度很慢,并且容易损坏。

  6. 尽管对象本身是不可变的,但对象存储系统却是可变的。当您添加,删除,覆盖对象及其元数据,应用策略,收集指标,授予会话令牌和轮换凭证时,元数据总是在变化。Cassandra并非旨在处理此级别的元数据突变,并且绝对不能用于主存储工作负载。对象较大(GB大小)且不经常访问的长期归档用例将起作用,而其他用例则不会。

    原因是Cassandra的日志结构化存储系统会快速将新的写入操作追加到日志文件的末尾,但是会延迟删除操作并使用逻辑删除标记覆盖。清理这些逻辑删除是一项昂贵的操作,因为实际的删除操作是通过将SSTables复制到一个新表中来筛选过时的条目而应用的。必须在所有节点上同时执行此操作。如果延迟清理,那么过多的逻辑删除将导致读取延迟增加,内存GC暂停和查询失败。一些对象存储供应商使用附加的Redis数据库来减轻Cassandra的压力。使用两个数据库管理对象存储元数据很难,并且会带来更多的故障点。  

    最大的陷阱?直到您深入生产并且为时已晚,您才会看到这些问题。

  7. 小对象(大小为KB到MB)将比数据驱动器更快地填充专用于Cassandra的元数据驱动器。同样,小型对象工作负载加剧了Cassandra的局限性,因为它们对延迟和一致性问题很敏感。一些供应商完全将小对象存储在Cassandra中以解决此问题。此时,您只需要在Cassandra数据库之上查看一个S3代理。

    这也是一个坏习惯。

    如果您将对象存储库用于大型对象,并采用擦除编码,并且将Cassandra用作小型对象的数据存储,并使用复制-您会引入非平凡的SLA问题。在这种方法中,数据受到不同保证的保护。考虑到驱动器一直死掉,服务旧对象或损坏的对象的可能性将大大提高。

    如上所述,您的元数据数据库现在是弱链接。可用性,一致性和持久性保证仅与最薄弱的环节一样好。如果最弱的链接使用复制(三个副本),则在丢失数据之前只能承受一个节点或一个驱动器故障。

    一个相反的论点可能是复制五个副本。结果会严重影响性能,您实际上仍然只能承受两个节点或两个驱动器的故障。

    在对小对象使用复制并对大对象使用擦除编码时,还会损害与EC相关的效率提高。如果仅将擦除代码用于大型对象(可能占整个对象池的一小部分),则不会获得很多收益,但会大大增加曝光率。

  8. 将Cassandra用作对象存储的元数据数据库还会引入麻烦的Java依赖关系。反过来,这可能会导致过时的软件和内存管理问题。Cassandra通过不断进行大规模的元数据分配和突变来加重JVM内存管理的负担,从而导致内存耗尽和垃圾回收暂停。

显而易见的是,操作Cassandra集群要比设计合理的对象存储系统复杂得多。Cassandra是为不同目的而构建的,对象存储元数据不是其中之一。Cassandra挣扎的领域是高性能,可伸缩和弹性对象存储的核心领域。

最后一点要注意-对象存储自然适合Blob数据,这就是为什么擦除编码如此有效和高效的原因。Cassandra专为复制而设计。当您将该模型用于元数据时,它破坏了对象存储的擦除编码优势(或者至少使其易碎且容易损坏)。

底线。用对象原子地编写元数据。切勿分开。

我们欢迎您的评论。随时通过Twitter,Slack频道或通过sales@minio.org.cn我们发送注释来与我们联系


上一篇 下一篇