前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我们的产品架构

我们的产品架构

作者头像
张逸
发布2018-03-07 16:46:15
9320
发布2018-03-07 16:46:15
举报
文章被收录于专栏:斑斓

本文是我在中生代技术群分享的话题《创业一年经历的技术风雨》中的第一部分《产品架构与技术选型》的第一部分。

整体架构

我们的产品代号为Mort(这个代号来自电影《马达加斯加》那只萌萌的大眼猴),是基于大数据平台的商业智能(BI)产品。产品架构如下所示:

我们选择了Spark作为我们的大数据分析平台。基于目前的应用场景,主要使用了Spark SQL,目前使用的版本为Spark 1.5.0。我们有计划去同步升级Spark最新版本。

在研发期间,我们从Spark 1.4升级到1.5,经过性能测评的Benchmark,性能确有显著提高。Spark 1.6版本在内存管理方面有明显的改善,Execution Memory与Store Memory的比例可以动态分配,但经过测试,产品的主要性能瓶颈其实是CPU,因为产品的数据分析功能属于计算密集型。这是我们暂时没有考虑升级1.6的主因。

从第一次升级Spark的性能测评,以及我们对这一年来Spark版本演进的观察,我们对Spark的未来充满信心,尤其是Tungsten项目计划,会在内存管理、代码生成以及缓存管理等多方面都会有所提高,对于我们产品而言,算是“坐享其成”了。

由于我们要分析的维度和指标是由客户指定的,这就需要数据分析的聚合操作是灵活可定制的。因此,我们的产品写了一个简单的语法Parser,用以组装Spark SQL的SQL语句,用以执行分析,最后将DataFrame转换为我们期待的数据结构返回给前端。

但是,这种设计方案其实牵涉到两层解析的性能损耗,一个是我们自己的语法Parser,另一个是Spark SQL提供的Parser(通过它将其解析为DataFrame的API调用)。我们考虑在将来会调整方案,直接将客户定制的聚合操作解析为对DataFrame的API调用(可能会使用新版本Spark的DataSet)。

微服务架构

我们的产品需要支持多种数据源,对数据源的访问是由另外一个standalone的服务CData完成的,通过它可以隔离这种数据源的多样性。这相当于一个简单的微服务架构,目前仅提供两个服务,一个服务用于数据分析,一个服务用于对客户数据源的处理:

未来,我们的产品不止限于现有的两个服务,例如我正在考虑将定期的邮件导出服务独立出来,保证该服务的独立性,避免受到其他功能执行的影响。因为这个功能一旦失败,可能会对客户的业务产生重要影响。

然而,我们还是在理智地控制服务的粒度。我们不希望因为盲目地追求微服务架构,而带来运维上的成本。

元数据架构

我们的产品需要存储元数据(Metadata),用以支持Report、Dashboard以及数据分析,主要的数据模型结果如图所示:

针对元数据的处理逻辑,我们将之分为职责清晰的三层架构。自上而下分别为REST路由层、应用服务层和元数据资源库层。

  • REST路由层:将元数据视为资源,响应客户端的HTTP请求,并利用Spray Route将请求路由到对应的动词上。路由层为核心资源提供Router的trait。这些Router只负责处理客户端请求,以及服务端的响应,不应包含具体的业务逻辑。传递的消息格式为Json格式,由Spray实现消息到Json数据的序列化与反序列化。
  • 应用服务层:每个应用服务对应元数据资源的操作用例。由于Mort对元数据的操作并没有非常复杂的业务逻辑,因此这些服务实际上成为了Router到Repository的中转站,目的是为了隔离REST路由层对元数据资源库的依赖。每个服务都被细分为Creator、Editor、Fetcher与Destroyer这样四个细粒度的trait,并放在对应服务的同一个scala文件中。同时,应用服务要负责保障元数据操作的数据完整性和一致性,因而引入了横切关注点(Cross Concern Points)中的事务管理。同时,对操作的验证以及权限和授权操作也会放到应用服务中。
  • 元数据资源库层:每个资源库对象都是一个Scala Object,并对应着数据库中的元数据表。这些对象中的CRUD操作都是原子操作。事实上我们可以认为每个资源库对象就是元数据的访问入口。在其实现中,实际上封装了scalikejdbc的访问逻辑。

REST路由层和应用服务层需要接收和返回的消息非常相似,甚至在某些场景中,消息结构完全相同,但我们仍然定义了两套消息体系(皆被定义为Case Class)。逻辑层与消息之间的关系如下图所示:

在REST路由层,所有的消息皆以Request或Response作为类的后缀名,并被定义为Scala的Case Class。在应用服务层以及元数据资源库层使用的消息对象则被单独定义在Messages模块中。此外,元数据资源库层还会访问由ScalikeJDBC生成的Model对象。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 逸言 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档