Apache Cassandra 和 Apache Ignite: 架构简化思考


声明:本文转载自https://my.oschina.net/liyuj/blog/1607711,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

Apache Cassandra在软件架构师和工程师当中,正在成为日益流行的数据库,很多人愿意将数据交给它。目前,这个著名的NoSQL数据库已经有了大量的部署。毋庸置疑,Cassandra实至名归,他用简单的方法达到了目标:保证快速写入的前提下实现了无限扩展和高可用

这两个基本功能帮助Cassandra快速崛起,它解决了传统关系型数据库无法解决的问题。这些问题需要水平扩展、高可用、容错以及7*24小时无故障运行,传统关系型数据库至少现在还无法全面满足这些条件(除了可能的分布式关系型数据库,比如Google Spanner以及CockroachDB)。

但是,扩展性和高可用不是没有代价的,被简化的设计原则和关系数据库特性宠坏的我们,不得不去学习如何正确地使用Cassandra,如何正确地进行数据建模,以及如何在没有高级SQL特性的情况下解决问题。

在本文中,会展示Cassandra数据建模概念中不为人知的一面,这是Cassandra架构的总览,然后通过学习Cassandra给我们带来的丰富现代数据库特性,给出如何使架构简化的建议。

正确地进行数据建模

当然,掌握Cassandra的数据建模思想需要一定的时间(这不是个大问题),这方面的资源也有很多。这个思想基于一个非常规策略,需要我们事先去猜数据库上执行的所有查询。坦白说,这也是可行的,设想有一组查询,使Cassandra的表针对这些查询进行优化,然后进入生产。

这个方法叫做查询驱动方法,这意味着应用的开发由查询驱动,不能在还不知道查询是什么样的情况下,就 进行一个应用的开发。这个模式有些棘手,但是它在Cassandra环境中带来了更快和更廉价的写入。

比如,假定一个应用要跟踪一个厂商生产的所有车辆,然后评估每个厂商的生产能力,在关系型世界中,数据模型可能如下: 从技术上来说,在Cassandra中使用同样的模式也不是不行,但是从架构的视角来看,该模型不可行,因为Cassandra无法对不同的表进行关联--我们肯定需要将车辆、厂商以及产量的数据聚合成一个结果集。如果要做到这一点,就需要放弃关系模型,发挥非常规策略的优势。

该策略会引导我们形成一个应用需要的查询操作的列表,然后围绕它们设计模型。实际上,这很简单。下面会针对不熟悉Cassandra的举例说明这个策略。

假定应用需要支持如下的查询:

Q1:获得一个厂商在特定时间窗口内生产的车型(最新,第一)

如果要在Cassandra中高效地执行该查询,下面会创建一张表,通过vendor_name进行分区,然后将production_yearcar_model作为聚类列:

CREATE TABLE cars_by_vendor_year_model (  vendor_name text,  production_year int,  car_model text,  total int,  PRIMARY KEY ((vendor_name), production_year, car_model) ) WITH CLUSTERING ORDER BY (production_year DESC, car_model ASC); 

之后,就可以根据之前定义的Q1执行一个Cassandra查询了:

select car_model, production_year, total from cars_by_vendor_year_model where vendor_name = 'Ford Motors' and production_year >= 2017 

在这基础上,该表还可以满足下面的操作:

  • 获取一个厂商生产的车型:
select * from cars_by_vendor_year_model where vendor_name = 'Ford Motors' 
  • 获取某一年一个特定车型的产量:
select * where vendor_name = 'Ford Motors' and production_year = 2016 and car_model = 'Explorer' 

接下来,需要为应用需要支持的每个查询都进行这样的练习,所有的工作完成后,就可以将应用部署到生产环境了。好了,工作完成了!准备拿奖金吧!

缺点

好,还有一个可能拿不到奖金。

在生产环境中的应用,经常会面对基于Cassandra架构的不足,如果有人跳出我们划定的框框,希望快速地增加一个新的操作来增强应用时,这样的事就会经常发生,这就是Cassandra的不足。

如果数据模型是关系型的,那么可以准备一个SQL查询,创建一个索引(如果必要),然后给生产环境打个补丁就可以了,但是Cassandra不是这么简单。如果由于架构所限查询无法执行或者无法高效地执行,那么就需要创建一个全新的Cassandra表,配置主键和聚类键来满足特定查询的需求,还需要从已有的表中拷贝必要的数据。

下面回到之前的车辆和厂商的应用,它已被大量用户使用,然后要满足新的需求:

Q2:获取一个厂商某特定车型的产量。

考虑一会之后,可能会得出结论,基于之前创建的cars_by_vendor_year_model表,构造一个新的查询,好吧,查询已经准备好然后执行:

select production_year, total from cars_by_vendor_year_model where vendor_name = 'Ford Motors' and car_model = 'Edge' 

但是,查询出错了,异常如下:

InvalidRequest: code=2200 [Invalid query] message="PRIMARY KEY column "car_model" cannot be restricted (preceding column "production_year" is not restricted)" 

异常大概是说,在通过car_model过滤数据之前,需要指定生产年份!但是年份未知啊,之后就需要创建一个不同的新表来满足Q2

CREATE TABLE cars_by_vendor_model (  vendor_name text,  car_model text,  production_year int,  total int,  PRIMARY KEY ((vendor_name), car_model, production_year) ); 

最后,满足Q2的查询执行成功了:

select production_year, total from cars_by_vendor_model where vendor_name = 'Ford Motors' and car_model = 'Edge' 

现在退一步,看看cars_by_vendor_year_modelcars_by_vendor_model的结构,看看能发现多少不同。好吧,只有一点,主要是调整了聚类键!这样,只是为了满足Q2,做了如下的工作:

  • 创建了一个新表,将之前的数据复制过来;
  • 在应用中嵌入了批处理后,注意两者的原子更新;
  • 应用架构变得复杂;

这个故事会一次又一次地发生,除非应用停止演进。实际上至少是头几年,这是不可能的。这意味着要准备好投入无限复杂的架构中。有办法避免么?绝对的,在现有的Cassandra功能中,能发生奇迹么?不能。

Apache Ignite能解决么?

带关联的SQL查询代价并不低,即使运行在单机上的关系型数据库,随着工作负载的增加也可能发生“阻塞”,这也是为什么很多人即便要忍受Cassandra数据模型技术的缺点也要转向它的原因,但是这导致了架构的复杂化。

分布式的存储、数据库以及平台的市场正在经历大幅度的增长,既有可扩展性,同时又有Cassandra的高可用性,但是同时应用还可以构建在关系模型上,目前来说找到一个这样的数据库是可行的。

在Apache软件基金会(ASF)的项目中找一下,我们发现了Apache Ignite,这是一个以内存为中心的数据存储,它是一个分布式的缓存或者数据库,内建了SQL、键-值还有计算API。 Ignite仍然处于Cassandra这个ASF老朋友的阴影下,虽然仍然有人因为可扩展、高可用以及持久化的原因选择它,但是已经有人确认Ignite在SQL、分布式事务以及内存存储上是无敌的。此外,那些在生产环境非常信任Cassandra的,也可以将Ignite作为缓存层对其进行加速--这可以作为将Cassandra替换为Ignite自身存储的一个中间步骤。

你是否和我一样已经加入了Ignite社区?那么可以期待下一篇文章,届时会使用Ignite构建一个基于简单关系模型的架构,它会使用关系并置、分区概念、高效的并置SQL关联以及其它的技术,为厂商和车辆的应用创建一个示例。如果你等不及或者想自己搞定这个问题,可以看下第一部分第二部分,了解一下Ignite的主要功能和概念。

本文译自Denis Magda的博客

本文发表于2018年01月16日 12:32
(c)注:本文转载自https://my.oschina.net/liyuj/blog/1607711,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2005 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1