最近有很多与 Cassandra 相关的讨论。
Twitter、Digg、Facebook 等大型网站都在使用它。
什么时候需要使用Cassandra:
- 需要使用Cassandra时
- 不需要使用Cassandra时
- 使用关系型数据库替代Cassandra时
最近有很多与 Cassandra 相关的讨论。
Twitter、Digg、Facebook 等大型网站都在使用它。
什么时候需要使用Cassandra:
没有什么是万能的解决方案,每个技术都是为了解决特定的问题而存在并都有其优缺点。关键在于您要知道自己面临的问题,并确定最适合解决该问题的方案。
我将按照您提出问题的顺序依次回答它们。由于Cassandra基于NoSQL数据库系列,因此在回答您的问题之前,重要的是您了解为什么使用NoSQL数据库。
为什么使用NoSQL
对于RDBMS来说,选择相对容易,因为这一类所有数据库(如MySQL、Oracle、MS SQL、PostgreSQL)几乎都提供了针对ACID属性的相似解决方案。当涉及到NoSQL时,决策变得困难,因为每个NoSQL数据库都提供不同的解决方案,您必须了解哪一个最适合您的应用/系统要求。例如,MongoDB适用于系统要求无模式文档存储的用例。HBase可能适合搜索引擎、分析日志数据或任何需要扫描巨大的二维无连接表格的地方。Redis是为提供各种数据结构(如树、队列、链表等)的内存搜索而构建的,可以很好地用于制作实时排行榜、发布-订阅等系统。同样,还有其他适合不同问题声明(包括Cassandra)的数据库。现在让我们转到原始问题,并逐个回答它们。
何时使用Cassandra
作为NoSQL家族的一部分,Cassandra提供了一个解决方案,用于解决需要具有非常重的写入系统并且希望在存储的数据之上构建一个灵敏的报告系统的问题。考虑Web分析的使用情况,其中为每个请求存储日志数据,并且您想要建立围绕此数据的分析平台,以实时计算每小时、每个浏览器、每个IP等的点击次数。您可以参考此篇博客文章,了解Cassandra适用的更多用例。
何时使用关系型数据库而不是Cassandra
Cassandra基于NoSQL数据库,不提供ACID和关系数据属性。如果你需要强制要求ACID属性(例如金融数据),那么在这种情况下,Cassandra将不适合。显然,你可以通过一些变通方式来实现,但是你最终会编写大量应用程序代码来模拟ACID属性,这将严重影响产品的上市时间。同时,使用Cassandra管理此类系统将变得复杂和繁琐。
何时不使用Cassandra
如果上述解释让人感到有道理,我认为就不需要回答这个问题了。
在评估分布式数据系统时,您必须考虑CAP定理 - 您可以选择以下两个: 一致性、可用性和分区容错性。
Cassandra是一种可用的、分区容错的系统,支持最终一致性。更多信息请参见我撰写的这篇博客文章:NoSQL系统的可视化指南。
Cassandra是解决一个特定问题的答案:当您拥有的数据量太大,无法放在一台服务器上时,该怎么办?如何在多台服务器上存储所有数据而不破坏银行账户并让开发人员保持理智?Facebook每天会获得4TB的新压缩数据,而这个数字很可能会在一年内增长超过两倍。
如果您没有这么多数据,或者您可以支付数百万美元用于企业级Oracle/DB2集群安装和所需的专家设置和维护,则使用SQL数据库就足够了。
然而,Facebook现在几乎完全使用MySQL,放弃了Cassandra,并将分区提升到应用程序堆栈中以获得更快的性能和更好的控制。
NoSQL的一般理念是,你应该使用最适合你的应用程序的数据存储方式。如果你有一张包含金融数据的表格,使用SQL。如果你有需要复杂/缓慢查询才能映射到关系型模式的对象,请使用对象或键值存储。
当然,你遇到的任何现实问题都处于这两个极端之间,而且两种解决方案都不会完美。你需要考虑每种存储的功能和使用其中一个而非另一个的后果,这将非常特定于你试图解决的问题。
我将重点关注一些重要的方面,这些方面可以帮助你决定是否真正需要Cassandra。列表并不详尽,只是我脑海中的一些重点-
在数据集关系(跨数据集)有严格要求时,不要把Cassandra视为首选。
Cassandra默认是AP系统(CAP)。但是它支持可调一致性,这意味着它可以配置为支持CP。 因此,不要只是因为在某个地方读到它是AP系统而忽略它,如果你正在寻找CP系统。 Cassandra更准确地被称为“可调一致性”,这意味着它允许您轻松地决定所需的一致性级别,并平衡可用性级别。
如果你的规模不大,或者可以处理非分布式数据库,请不要使用Cassandra。
如果你的团队认为,只要使用像Cassandra这样的分布式数据库,就可以解决所有问题,那么请认真考虑。起步使用这些数据库非常简单,因为它们带有许多默认值,但为了解决特定问题进行优化和掌握它,需要大量的工程工作。
Cassandra是列导向的,但同时每行也有一个唯一的键。因此,将其视为索引的行定向存储可能会有所帮助。 你甚至可以将它用作文档存储。
Cassandra不强制你预先定义字段。因此,如果你处于创业模式或者你的特性正在发展(如敏捷开发)-Cassandra支持它。所以最好首先考虑查询,然后再考虑回答这些查询所需的数据。
Cassandra针对写入具有真正高吞吐量的优化。如果你的用例以读取为主(例如缓存),那么Cassandra可能不是理想的选择。
没错。当你有大量数据,大量查询但查询种类非常少时,使用Cassandra是很有意义的。Cassandra基本上通过分区和复制来工作。如果所有的查询都基于相同的分区键,那么Cassandra是你最好的选择。如果你得到一个基于非分区键的属性的查询,Cassandra允许你使用新的分区键复制整个数据。因此现在你有了两个不同分区键的相同数据的2个副本。
这就引出了下一个问题。什么时候不使用Cassandra?正如我提到的,Cassandra通过为每个新的分区键复制完整的数据库来扩展。但你不能一遍又一遍地制作新的副本。因此,当你的查询多样化,即每个查询在where子句中有不同的列时,Cassandra不是一个好的选择。
现在到了第三个问题。使用RDBMS的整个要点是当你想要ACID属性时。如果你正在构建像支付服务之类的东西,并希望每个事务都被隔离、每个事务要么完成要么不完成、更改在系统失败后持久,以及交易完成前后银行账户中的金额保持一致,则只有RDBMS可以帮助你实现这一点。
这篇文章详细阐述了整个问题,特别是何时使用Cassandra或其他NoSQL选项来回答“在系统设计面试中选择最佳数据库”的问题 -> 选择最佳数据库。一定要看看。
编辑: 回答proximab在评论中提出的问题,当我们考虑银行系统时,我们立刻想到“ACID是最好的解决方案”。但即使是银行系统也由多个子系统组成,这些子系统可能甚至不涉及任何与交易相关的数据,例如账户持有人的个人信息、账单、信用卡详情、信用历史等。
所有这些信息都需要存储在某个数据库中。现在,如果您存储与帐户相关的信息(如帐户余额),则应始终保持一致。例如,如果您尝试从帐户A向帐户B发送资金,则从帐户A消失的资金应立即显示在帐户B中,并且不能同时存在于两个帐户中。此系统在任何时候都不能不一致。这就是ACID至关重要的地方。
另一方面,如果您要保存信用卡详细信息或信用记录,并且这些信息不应该落入错误的手中,则需要一些只允许授权用户访问的内容。我认为Cassandra支持这种需求。也就是说,像信用历史和信用卡交易等数据是不断增加的。此外,您可以查询的有限数量非常有限。这两个条件使Cassandra成为完美的解决方案。
与正在部署Cassandra的人交谈时,我们发现它不能很好地处理多对多关系。他们正在进行一项非常规的工作来进行初步测试。我向一位Cassandra顾问请教此事,他表示如果你面临这个问题集,他不会推荐使用它。
如果你对以上任何一个问题的回答是“可能”或“不”,那么你应该使用其他技术。如果你对所有问题的回答都是“当然”,那么你应该使用Cassandra。
当你可以在一台设备上完成所有操作时,请使用关系型数据库管理系统。它可能比大多数技术更容易使用,任何人都可以使用它。
重单查询 vs. 亿万轻查询负载是需要考虑的另一个因素,除了其他答案。在 NoSql 风格的数据库中自动优化单个查询本质上更加困难。我使用过 MongoDB,在尝试计算复杂查询时遇到了性能问题。我没有使用过 Cassandra 但我认为它也会有同样的问题。
另一方面,如果您的负载预计是非常多的小查询,并且您想要轻松扩展,则可以利用大多数 NoSql 数据库提供的最终一致性。请注意,最终一致性实际上不是非关系型数据模型的特性,但在基于 NoSql 的系统中更容易实现和设置。
对于单个非常重的查询,任何现代 RDBMS 引擎都可以很好地并行化查询的部分,并利用您投入的所有 CPU 和内存(在单台机器上)。NoSql 数据库没有足够的关于数据结构的信息来使其能够做出假设,从而允许对大查询进行真正智能的并行化。它们确实允许您轻松扩展更多的服务器(或核心),但一旦查询达到一定的复杂度水平,您基本上被迫将其手动拆分为 NoSql 引擎知道如何智能处理的部分。
在我的MongoDB使用经验中,由于查询的复杂性,MongoDB无法对其进行优化并在多个数据上运行部分查询。MongoDB可以并行处理多个查询,但不太擅长优化单个查询。