HighLoad ++,Anastasia Tsymbalyuk,Stanislav Tselovalnikov(Sberbank):我们如何成为MDA

接下来的高负荷++会议将在圣彼得堡。举办2020年4月6日和7,
详细信息和门票在这里。 HighLoad ++西伯利亚2019。大厅“克拉斯诺亚尔斯克”。 6月25日,下午2点摘要和介绍

从头开始开发工业数据管理和发布系统绝非易事。尤其是当有完整的积压订单时,上班时间只有四分之一,并且产品需求永远动荡。



我们将以构建元数据管理系统的示例为例,介绍如何在短时间内构建一个工业可扩展系统,其中包括数据的存储和分发。

我们的方法充分利用了元数据,动态SQL代码以及基于Swagger代码源和把手的代码生成功能。该解决方案减少了系统的开发和重新配置时间,并且添加新的管理对象不需要一行新代码。

我们将告诉您团队中的工作原理:我们遵守哪些规则,使用哪些工具,遇到哪些困难以及如何英勇地克服这些困难。

Anastasia Tsymbalyuk(以下简称AC): -我叫Nastya,我叫Stas!

Stas Tselovalnikov(以下简称SC): -大家好!

AC: -今天我们将向您介绍MDA,以及如何使用这种方法减少开发时间,并向世界介绍工业可扩展元数据管理系统。万岁!

SC: -Nastya,什么是MDA?

AC: -Stas,我想我们现在将继续进行此操作。更准确地说,我将在演示文稿的末尾讨论这一点。首先让我们谈谈我们:



我可以形容自己是寻求工业IT解决方案协同作用的人。

SC: -还有我?

SberData团队做什么?


AC: -您只是工业上的乳齿动物,因为您为舞会带来了多个解决方案!

SC: -实际上,我们在Sberbank的同一团队中一起工作,并管理SberData元数据:



AC: -SberData,如果以简单的方式,是一个分析平台,每个客户的所有数字轨道都在此流动。如果您是Sberbank的客户,则有关您的所有信息都将在那里精确地流动。许多数据集存储在此处,但我们了解数据量并不意味着其质量。没有上下文的数据有时是完全无用的,因为我们无法应用,解释,保护和丰富它。

这些任务仅由元数据解决。它们向我们展示了数据的业务背景和技术组成部分,即它们的显示位置,如何转换的,现在,最小的描述就是标记。这足以开始使用数据并信任它。这正是元数据要解决的任务。

SC: -换句话说,我们的团队的任务是提高Sberbank信息分析平台的效率,因为您刚才所说的信息应该在正确的时间,正确的位置传递给正确的人。记住,您还说过,如果数据是现代石油,那么元数据就是该石油储量的地图。

AC:-的确,这是我的出色发言之一,对此我感到非常自豪。从技术上讲,这项任务被简化为我们必须在平台内部创建元数据管理工具并确保其整个生命周期的事实。
但是,为了陷入我们学科领域的问题并了解我们的立场,我建议在9个月前回滚。

想象一下:窗外是十一月,鸟儿都飞向南方,我们很难过...到那时,我们已经与团队一起成功地驾驶了飞行员,那里有顾客-我们都呆在舒适地带,直到没有返回的那一刻。

模型元数据管理系统




SC: -在舒适区域中还有其他事情……实际上,我们的任务是创建Metadata Broker,这应该给与我们的客户,程序和系统进行交流的机会。我们的客户应该有机会在后端级别发送或接收某种元数据包。我们在提供此功能时,必须在四个逻辑级别上累积有关元数据的最一致,最相关的信息:

  • 业务词汇表级别。
  • 逻辑模型的级别。
  • 物理模型的级别。
  • 由于工业环境的逆转,我们收到的环境状态。

所有这些必须保持一致。

AC: -是的,真的。但是在这里,我也将以一种简单的方式进行解释,因为我不排除主题领域不清楚和不可理解...

商业词汇是关于几个西装革履的聪明人几个小时想出的...如何命名一个术语,如何提出一个公式计算。他们思考了很长时间,最后他们只有一个业务术语表。

逻辑模型是关于分析师如何看待自己在世界上的看法,他能够与这些精明的人建立起西装和领带,但同时又了解如何着陆。远离物理实现的细节。

物理模型是关于何时轮到苛刻的程序员,真正了解如何降落这些对象的架构师-将对象放置在哪个表中,创建哪些字段,挂起哪些索引的……

环境状态是一种强制转换。这就像汽车的证词。程序员有时想告诉机器一件事,但她误会了。只是环境的状态向我们展示了实际情况,因此我们不断地比较所有事物。而且我们知道程序员所说的与环境的实际状态之间存在差异。

描述元数据的情况


SC: -让我们用一个具体的例子来解释它,例如,我们有四个指定级别。假设我们有这些认真的人,他们在业务词汇表级别工作,他们根本不了解内部的安排和方式。但是他们知道他们需要制作一份强制性报告表格,他们需要获得个人账户的平均余额:



在这个级别上,一个人应该已经拥有一个业务术语表(强制性报告的术语)或拥有一个业务术语表(个人账户的平均余额)。接下来是完全了解他的分析师,他可以和他说相同的语言,但他也可以和程序员说相同的语言。

他说:“听着,这里您将整个故事分为多个单独的帐户作为实体,并且它们具有一个属性-平均余额。”

接下来是架构师,他说:“我们将展示向法人提供的贷款。因此,我们将创建一个个人账户的物理表,我们将创建一个个人账户的每日余额的物理表(因为在交易日结束时每天都会收到这些余额)。并且在截止日期每月一次,我们将根据要求计算平均值(每月余额表)。”

说到做到。然后我们的解析器来了,他去了工业电路,对他说:“是的,我知道-有必要的表格……”这个表格还有什么其他的呢?在这里(作为示例)-分区和索引,尽管严格来讲,分区和索引都可以在物理模型的设计级别上,但是可能还有其他内容(例如,数据量)。

在元数据级别注册和存储


AC: -所有物品如何存放在我们的手中?这是Stas先前绘制的示例的超级简化形式!这一切将如何摆在我们身上?



实际上,它将在词汇表对象中占一行,在术语对象中占一行,在实体中占一行,在属性中占一行,依此类推。在上图中,每个矩形都是我们控制系统中的一个对象,表示存储在其中的该信息或那个信息。

为了向您慢慢介绍术语,请您注意以下内容...什么是元数据管理对象?从物理上讲,这是以表格的形式表示的,但是实际上,某些信息存储在其中,包括术语,词汇表,实体,属性等。术语“对象”将在我们的演示文稿中继续使用。

SC: -这里必须说每个多维数据集只是我们系统中存储元数据的一个表,我们将此称为控制对象。

元数据要求


入口处我们有什么?在入口处,我们收到了非常有趣的要求。它们很多,但是在这里我们要展示三个主要的:



第一个要求是相当经典的。我们被告知:“伙计们,曾经带给您的一切都将永远到来。” 历史记录已完成,并且您对元数据系统所做的任何更改(一包100个字段的数据包到达(100个更改)还是一个表中的一个字段更改都没有关系)都需要对元数据进行新的注册。他们还需要返回响应:

  • 默认情况下-当前状态;
  • 按日期
  • 通过修订号。

第二个要求更有趣:我们被告知他们可以与我们一起处理对象,但是他们必须使用Java进行大量编程,但是他们不想这样做。他们建议我们一次混合100个对象(或10个),并且应该处理此事务(因为我们可以)。混合是什么意思?例如,出现了10列。它们有一个指向表标识符的链接,但我们没有表本身-它位于JSON的末尾。 “您要进行思考和处理-必须做到”!

为了引起人们的关注,第三个:“我们不仅希望能够使用您将成为我们的API,而且希望了解自己……”然后以任意顺序说:“通过第三个对象,将我们从这个对象到那个对象的结合给我们。并且让您的系统本身了解如何完成所有操作,询问数据库并以JSON返回结果。”

我们在入口处有这样一个故事。

估计数




AC: -根据我们的近似计算,为了实现整个概念,每个控制对象都需要参与七个接口:简单(简单),用于对象范围的写/读和删除...

三个-用于通用写/读/删除,t也就是说,我们可以以任何顺序将其全部扔掉,以及如何将汤集转移到系统中,她将找出删除,放置和读取的顺序。

还有一件事-建立层次结构以便我们可以向系统指示-“让我们从一个对象回到另一个对象”;它返回一棵嵌套对象的树。

实施复杂度


SC: -除了故事开始时提出的技术要求外,我们还有其他困难。



首先,这是需求的不确定性。并非每个团队都不能总是清楚地阐明他们需要从服务中获得什么,并且通常情况下,真理的时刻是在原型电路上制作一些故事的时刻诞生的。当它到达舞会时,可能会有几个周期。

AC: -这是一开始就宣布的动荡。

SC: -接下来...

截止日期太长了,因为即使在启动时,也有超过五个团队依赖我们。流派经典:昨天需要结果。工作选项处于烫马模式,这就是我们所做的。

第三是大量发展。Nastya在她的幻灯片上显示,当我们研究做什么和如何做的要求时,我们意识到:1个对象需要七个API(为此需要七个API或参与其中)。这意味着如果我们有一个补丁(6个对象,模型,42个API)将在一周内发布...

标准方法


AC: -是的,实际上每周42个API只是冰山一角。我们很清楚,为了确保这42个API正常工作,我们需要:

  • 首先,为对象创建存储结构;
  • 其次,要确保其处理逻辑。
  • 第三,编写对象所参与的(或专门为其配置的)API;
  • 第四,最好用测试的轮廓覆盖所有这些内容,测试并说一切都很好。
  • 第五(蛋糕上的樱桃)记录整个故事。



自然,发生在我们身上的第一件事(开始时,我们向您展示了一个近似图)-我们大约有35个对象。他们必须做些事,必须推论所有这些,而且时间很少。我们想到的第一个主意是坐下,卷起袖子,开始编码。

即使在这种模式下工作了几天(我们有3个团队),我们也达到了如此炽热的温度……每个人都很紧张……而且我们意识到我们需要寻找一种不同的方法。

定制方法


我们开始关注我们在做什么。这种方法的想法一直摆在我们眼前,因为我们从事元数据已有很长时间了。某种程度上,马上就没有发生在我们

身上…… 您可能会猜到,这个想法的本质是使用元数据。它包含以下事实:一旦我们为某些代码(例如,多个API或用于处理逻辑的过程,用于创建结构的脚本)创建了模板,我们便会收集存储库的结构(这是某些元数据)。一旦我们创建了此模板,然后遍历所有元数据。通过标签,将属性替换为代码(对象名称,字段,重要特征),并准备好生成的代码。



就是说,只需一次混淆即可-创建一个模板,然后将所有这些信息用于现有对象和新对象。在这里,我们介绍另一个概念-#META_META。我将解释原因,以免混淆您。

我们的系统从事元数据管理,我们使用的方法描述了一个元数据管理系统,即两个元数据。“ MetaMeta”-我们在团队内部在家中称呼它。为了不进一步混淆其他人,我们将使用这个术语。

确保历史化和修订的机制


SC: -您总结了我们其余的演讲。我们将更详细地说明。

我必须说,在准备演讲时,我们被要求提供同事可能感兴趣的技术信息。我们将做到这一点。此外,幻灯片将更具技术性-也许有人会发现一些有趣的东西。

首先,我们如何解决历史化和修订的问题。也许这与多少人相似。考虑使用元数据作为示例,它描述了发布表中的单个字段(作为示例):



它具有一个ID-“ 7”,一个名称-进位标记,一个链接id_table 73和一个字段255。我们在主键和替代键中输入从该条目生效的时间点开始的一个字段(日期类型)-valid_from。还有一个字段-该记录的有效日期(valid_to)。在这种情况下,默认情况下会填充它们-显然,该条目原则上始终有效。直到我们想要更改字段的长度,这种情况才会发生。
一旦我们想要执行此操作,就关闭valid_to记录(我们修复事件发生的时间戳)。同时,我们创造了一个新记录(“ 300”)。很容易注意到,在这种情况下,如果您从某个时间点通过valid_from和valid_to之间的“争斗”(介于两者之间)查看数据库,那么我们将获得一条记录,但当时是相关的。同时,我们同时保留了一些修订日志:



在其中,我们记录了按顺序(序列)ID递增的修订,以及与该修订ID对应的时间点。因此,我们能够满足第一个需求。

AC:- 我猜是!这里的方法是相同的。我们知道系统中的每个对象都具有这两个必填字段,一旦我们感到困惑-对该模板的处理逻辑进行了编码,然后(当生成动态代码时)我们只需替换相应对象的名称即可。因此,系统中的每个对象都将成为修订版本,并且可以处理所有这些内容-我们通常不编写任何代码。

批量更新


SC: -对我来说第二个要求是更有趣。老实说,谈到入口,刚开始我只是昏昏欲睡。但是决定来了!

我提醒您,这是相同的情况,例如,带有数据包的JSON出现在我们面前,它需要插入系统中的第n个对象。同时,在开始时,我们有10列指向一个不存在的表,该表位于JSON尾部。该怎么办?



我们找到了使用递归层次查询机制的出路-可以肯定的是,通过先验构造可以建立众所周知的连接。我们这样做如下:这是我们的生产代码的一部分:



在这一点上(用红色椭圆形圈起来的一段代码)是给出想法的重点。此时,该对象链接到另一个由外键链接的对象,该外键位于系统中。

要理解:如果有人用Oracle编写代码,则有All_columns,All_all_表,All_constraint表-这是由脚本处理的字典(如上面的幻灯片所示)。

在输出中,我们得到的字段为我们提供了处理对象的优先级,并另外提供了一个描述符-它本质上是任何元数据记录的唯一字符串标识符。上面的幻灯片中也指出了接收描述符的代码。

例如,一个字段-它看起来像什么?这是平台代码:oracle KP。,生产。 KP,my_scheme。KP,my_table。 KP等,其中KP是域代码。因此会有这样的描述符。

AC: -这里有什么问题?我们在系统中有对象,它们的插入顺序对我们非常重要。例如,我们不能在表的前面插入列,因为一列必须引用特定的表。正如我们的标准操作:首先,插入表,作为响应,我们获得一个id数组,通过这些ID,我们将这些列抛出并进行第二次插入操作。

实际上,正如Stas所展示的,这条链的长度达到8-9个对象。用户使用标准方法需要依次执行所有这些操作(所有这9个操作),并清楚地了解其顺序,以免发生错误。

就我正确解释Stas而言,我们可以将所有这些对象以任何顺序传输到系统,而不必担心我们需要如何插入该对象-我们只是将汤集放入系统中,并且所有这些都决定了插入顺序。
我唯一的问题是:如果我们第一次插入对象该怎么办?我们之前插入了表格,我们不知道其ID。我们如何指示(纯粹是假设的示例)我们需要插入两个表,每个表都有一个列?我们如何指示在此JSON列中引用的是table1,而不是table2?

SC: -一个描述符!我们在该幻灯片上指示的手柄(上一个)。
在这张幻灯片上,给出了解决方案:



描述符在系统中用作一种不存在的助记符字段,但会替换id。到那时,系统一开始就知道有必要插入表-insert时,它将收到id;并且已经在为insert和column生成SQL查询的阶段,它将对id进行操作。用户不能洗蒸汽浴:“握住手柄并执行!”。系统将执行。

通用查询一组相关对象


也许是我最喜欢的情况。这是我们最喜欢的技术要求。他们来找我们说:“伙计们,请这样做,以便系统可以执行所有操作!请从一个对象到另一个对象。猜猜它们如何相互融合。请给我们回JSON。我们不想使用您的服务进行大量编程” ...

问题:“如何?!”

我们实际上以相同的方式进行。完全相同的构造:



用于解决此问题。唯一的区别是,存在一个有效的过滤器,该过滤器仅针对那些需要描述符的故事才解开该层次树。相对而言,每个对象都是唯一的。在这里,系统中所有可能的连接均未扭转(我们有大约50个对象)。

对象之间的所有可能连接都已预先准备好。如果我们有一个对象分别涉及三个关系,那么将准备三行,以便算法可以理解。并且,一旦JSON请求到达我们,我们便转到MeteMet预先准备好该故事的地方,我们正在寻找所需的方式。如果找不到,这是一个故事,如果找到,我们将在数据库中形成查询。运行-返回JSON(根据要求)。

AC: -结果,我们可以将要从中接收的对象传送到系统。而且,如果您可以勾勒出两个对象之间的清晰连接,则系统本身将确定该树在对象中返回给您的嵌套层次为:

非常灵活!我们的用户再次处于“动荡”状态:今天他们需要一件事,明天他们需要另一件事。这种解决方案使我们能够非常灵活地调整结构。这是我们核心方面使用的三个关键案例。

SC: -让我们总结一下。显然,由于时间有限,我们现在不会告诉所有筹码。我们认为,我们执行并告知了三个案例。我们成功了,我们能够将所有最复杂的逻辑以及应该对每个元数据管理对象统一工作的逻辑放入内核代码中。

我们无法使此代码100%动态,这意味着对于任何已创建的对象(无关紧要-已创建或将在以后创建;最重要的是,要根据规则创建),系统可以正常工作-无需添加,重写任何内容。只需测试就足够了。我们将整个故事分为三种通用方法。我认为,它们足以解决几乎所有业务问题:

  • 首先,这个通用的“更新器”是一种可以对以随机顺序传输的一个或一组对象进行更新/插入/删除(删除正在关闭记录)的方法。
  • 第二种方法只能返回一个对象的通用信息。
  • 第三种是可以返回由对象组连接的Join信息的相同方法。

事实就是这样,我们成为了核心。然后,我们将继续进行您最喜欢的部分。

应用程序入口点


AC: -是的,这是我最喜欢的部分,因为这是我的职责范围-Application Server。为了了解我的处境,我将尝试再次让您陷入困境。
Stas做得很好,并通过了这三种操作这些对象的标准方法。这纯粹是粗略的描述-实际上还有很多:



让我们回到让您沉浸其中的开始...系统中的元数据将如何显示在这里?



如果我们看到环境中有一个表,它将作为表对象中的一条记录和字段对象中的几条记录落入我们的系统。本质上,我们已经建立了一个结构。

我们可以注意到这些对象的数量是不同的。然后,为了操纵这些对象,使所有内容都具有通用结构,以便所有这三种方法都了解正在讨论的内容,Stas随马而动。它需要并翻转所有对象,也就是说,它将我们的元数据管理系统中的任何对象表示为四行:



由于我们的元数据管理系统中的任何对象实际上是一个表,因此可以根据以下四个符号来分解任何对象:行号,表格,字段和字段值。所有这些都是Stas提出的,我需要以某种方式实施它并将其提供给用户。

SC:-对不起,但是我如何才能给您一些平坦的答案,例如,尚未创建的列,将在某个时候创建​​,而上帝知道它们可以是什么?..因此,在动态代码条件下,唯一的选择是配置之间的交互核心和应用程序,以便仅在我们看到时将这些信息传输给您。我认为,从我的角度来看,这个决定是巧妙的,因为它仅来自您。

AC: -现在我们不会对此争论。在截止日期结束前的两周,我坚持这样的事实:我手上有这三种方法(在上一张幻灯片的左侧)操纵通用结构(在同一张幻灯片的右侧)。

我的第一个想法是简单地将所有内容包装在API级别上,并以此向用户说:“看,多么了不起的事情!你什么都可以做!传输任何对象,甚至不存在的对象。太好了,是吗??!



他们说:“但是您知道您的服务根本不专业吗?作为用户,我不知道我可以将哪些对象转移到系统中,如何操作它们。对于我来说,这是一个黑匣子,我通常担心我会提交数据;我可能会误会-我很害怕。做到这一点,以便我可以清楚地遵循说明,并查看系统中有哪些对象以及可以使用哪些操作方法。”

斑点。一种方法


然后我们发现为我们的服务制定规格很酷。简而言之,要列出我们系统中的对象,要点,操作以及它们之间相互影响的对象的列表。碰巧在我们公司中,出于这些目的,我们将Swagger用作某种体系结构解决方案。



看完Swagger结构后,我意识到我需要将系统中对象的结构放在某处。从内核中,我仅收到三种标准方法和一个表更换器。没有其他的。对于我来说,从这四个标准字段中获取存储库中的整个结构似乎是不可能的任务。我真诚地不明白从哪里可以得到关于对象的所有描述,所有允许的值,所有逻辑...

SC:-这是什么意思?您和我都有MetaMeta,它以实时模式提供内核。实时执行的内核会生成一个与数据库通信的SQL查询。一切都在那里,而不仅仅是您需要的。对象之间也有链接。

AC: -在Stas的建议下,我去了MetaMetu并感到惊讶,因为那里存在所有用于生成标准规格的绅士工具包。然后想到的是,您需要创建一个模板并根据七个可能的场景来绘制所有内容-每个对象7个标准API。

斑点。OAS +把手


因此,很容易注意到规范的组成:



您可以访问OAS网站和把手(在幻灯片的底部),并查看其组成-一组端点,一组方法,最后有模型。该代码会不时重复。对于每个对象,我们必须编写get,put。删除;对于一组对象,我们必须编写此类代码。

诀窍是只写一次整个故事,而不再洗澡。幻灯片显示了真实代码的示例。蓝色对象是车把中的标签,这是模板引擎;非常灵活,我建议大家-您可以为自己进行自定义,编写自定义标签处理程序...

代替这些蓝色标记的是,当此模板在所有元数据上运行时,所有重要属性都将被替换-对象名称,其描述,某种逻辑(例如,我们需要根据属性添加一个附加参数)等等。最后是他正在解释的模型的链接。

应用程序代码。Swagger Codegen +把手


我们编码,记录的所有内容均构成了规范。一切都很酷,很好。我们为每个对象获得了所有7种可能的方案。

给用户。他说:“哇!凉!现在我们要使用它!”又是什么问题?

我们有一个规范,详细描述了每种方法,如何处理以及要操作的对象。并且有三种标准的内核方法将上述倒排表作为输入。

然后,您只需要彼此交叉(现在对我来说似乎很容易)。也就是说,当用户在界面中调用方法时,我们必须正确正确地将其转发到内核,将模型(我们拥有漂亮的规格)转换为这四个标准字段。那就是所有要做的事情。



为了将所有这些付诸实践,我们需要“名义”转换...

转换次数


Swagger最初具有这样的工具-Swagger Codegen。如果您曾经编造过规格,则有一个按钮“ Generate server part”。单击,选择一种语言-为您生成一个完成的项目。

它的产生非常明显:有所有的类描述,所有的端点描述...-它起作用。您可以在本地运行-它可以工作。问题是一个:它返回存根-每个方法都不递增。

想法是在代码生成器中基于这七个场景添加逻辑-“破坏”标准模板之一,为您自己配置。这只是我们在模板引擎中使用的真实代码的示例,以及为自己配置此代码生成器所需执行的操作的列表:



他们所做的最重要的事情是连接必要的库,编写用于与内核通信的类,并在内核方面解释(取决于方案)对一个或多个方法的调用。该模型也被转换了:从规格中指示的漂亮模型扩展到四个领域,然后转换回原来的模型。

可能最困难的情况是给用户一棵树,因为内核还向我们返回了四行-看看层次结构处于什么级别。我们使用了IDE中的外部关系机制,也就是说,我们转到MetaMetu,查看了从一条到另一条的所有路径,并通过它们动态生成一棵树。用户可以从任何物体问我们他想要的东西-一棵美丽的树将在出口处返回给他,其中所有东西都已经按照结构进行了布置。

SC: -我会停一秒钟,因为我已经开始迷路了。我将以“我是否正确理解”的方式询问您...

您想说的是,我们已经计算出了必须为某些新对象编写的所有最复杂,最复杂的代码。为了节省时间而不是去做,我们设法将所有内容都推送到内核中并使该故事具有动态性……但是这个API(正如他们所戏称的那样,“固执”)是如此“可以做任何事情”,以至于很难将其提供给外部:使用它,您可以破坏元数据。这是一方面。

另一方面,我们意识到除非向客户客户提供API,否则我们无法与客户客户进行通信,这将是嵌入在系统中的那些元数据管理对象的唯一投影(实际上,为我们的服务执行了一定的合同)。似乎一切都被我们击中了:如果没有对象-它就不存在,并且当它出现时-合同扩展出现了,一个新代码。

我们似乎已经开始避免手工编码,但是在这里您建议按按钮进行编码。同样,当我们需要用手书写时,我们设法摆脱了历史。这是真的?

AC: -是的,确实如此。总的来说,我的想法是至少在模板引擎的帮助下一劳永逸地开始编程。编写一次代码,然后放松。并且即使系统中出现了新对象-通过按钮启动更新,所有内容都已收紧,我们有了新结构,生成了新方法,一切都很好。

调整MetaMeta


为了使我们的服务更好,我们丰富了标准的MetaMeta。在入口处,我们剩下了核心部分。我们还为对象添加了附加说明,这些对象按区域分组。我们在规范中显示所有这些内容,以便用户了解他正在操纵什么以及他当前正在通信的对象。



只有我们在那里添加了一些小东西-类型,格式,可接受值的列表,模式,示例。这也使用户感到满意-他们已经清楚地知道可以插入什么,不能插入什么。我们还向用户提供了一个客户端工件,这使我们能够在与我们的服务进行通信时捕获错误(精确地按照格式,已经在编译阶段)。

但最重要的是,要使所有这些魔术发挥作用,我们需要在内部达成共识:创建一组特定规则。它们并不多-我数了3个(幻灯片上有2个,因此必须记住其中一个):

  • 命名约定。我们专门在系统中命名对象,以使其更易于识别场景以供进一步使用。
  • 键入协议。这是为了正确确定类型,格式以及它们在内核和应用程序服务器之间进行的斗争,我们使用检查系统,通过该系统,我们可以了解特定属性属于哪种格式。
  • 有效的外键。如果为该对象提供了到另一个对象的无效链接,则所有这些魔术将无法正常工作。

结果


SC: -很酷,但是有很多理论。你能举一些实际的例子吗?

AC: -是的,我特别准备了它。在去参加会议之前,周五晚上,正好是工作日结束前5分钟,Stas告诉我:“哦,看!我发布了模型补丁-太酷了!最好更新我们的服务。”该补丁仅包含两个对象,但我知道使用旧方法时,我将不得不感到困惑并编写或添加7个API。

立即我只需单击一个按钮,即可完成所有这些魔术操作。我特别



用红色圆圈圈出了即将发生魔术地方:我单击按钮...这些当然是屏幕截图,但实际上,所有操作都像这样:



我们有一个新方法(介于两者之间),它已经提供了数据,通过该方法,我们在层次结构中可以查询整个结构,所有嵌套对象:







并且所有方法都有效!我根本没有写过一行代码。

摘要


SC: -首先,事实是什么?我们管理最复杂的逻辑,这将花费我们的程序员最多的时间来打包100%可以与对象一起使用的动态内核代码-那些和将来将要使用的对象:



其次,我们在应用服务器级别成功(在不可能的地方)也避免由于代码生成而进行编程-您演示了相同的按钮:



AC: -我们试图将基于元数据的相同方法扩展到其他区域以及测试区域。我们还会为某个对象编写一次模板,然后在其中插入标签。当此模板沿元数据运行时,它会生成一个包含所有测试场景的完成的工作表,也就是说,实际上,我们涵盖了测试的所有对象。



接下来是蛋糕上的樱桃。我知道很少有人喜欢记录他们的工作。我们也基于元数据解决了这一难题。一旦我们准备了带有html标记的模板,请对其进行标记。当我们遍历元数据时,所有这些标签都将替换为其与对象相对应的属性。



输出是漂亮的html页面。然后,我们在Confluence中进行发布,我们可以为用户提供易于理解的格式,以便他们可以看到系统中的内容,如何使用它,一些最小的描述,可接受的值,必需的属性,键...他们都可以做到这一点看到并且可以很容易地弄清楚。

结果,我们有四个要点,这种方法称为MDA(模型驱动架构)。出于某种原因,尽管我将其称为“软件开发方法”,但这被翻译为“模型驱动的体系结构”。



有什么意义?您创建一个模型,并同意某些规则。然后,您可以使用某种编程语言创建一次该模型的转换模式。所有这些都可以更改旧对象,添加新对象。您只需编写一次代码,就不再麻烦了。

SC: -老实说,当您回答这个问题时,我等了整个报告。让我们继续看我最喜欢的幻灯片。

决定 处理。之前


AC: -“过程。之前-这是我们的骄傲,因为我们经常编程,几乎不吃东西-我们非常邪恶。我必须对每个对象执行所有这5个步骤:



这是非常可悲的,并且花费了我们很多时间。现在,我们将该食物链简化为三个链接,其中最重要的是简单地正确创建对象,仅此而已:



通过按钮(更新)启动MetaMeta,然后进行测试。自从我们最近开始采用这种方法以来,我们目前正在努力确保一切都顺利。我们正在尝试控制整个过程。

据估计,我们开发所有软件的所有人工成本降低了6倍。

SC:-我要真诚地说,数字6没有吹过,甚至很保守。实际上,效率更高。

未来的计划


您在报告末尾要求详述我们的计划。首先,似乎我们不仅必须实现一个完整的解决方案,而且还必须实现一个疏远而封闭的解决方案。这些技术可以在附近适当的地方应用。我希望获得一种将要开发的成品,并且我们能够代表Sberbank提供。

当然,如果我们谈论即时任务,则它们都以项目符号的形式显示在幻灯片上。尽管我们获得了优化,但团队的负担仍然非常严重。我不能肯定地说我们可以从哪个季度开始执行这些步骤。

6号和Nastya带来的案件-他们很诚实。确实是在星期五,当我们需要获取文件(飞机,旅行等)时。相邻的团队原定于周一进行测试,我们需要发布此补丁程序,而不是设置专家。有效!这是真实情况。



如果可以为您中的任何一个派上用场,我将感到高兴。如果您有任何疑问,我们可以提供。报告之后,这里还有一些时间。问。我们将竭诚为您服务!

AC:-的确,我认为这种方法可以开始被每个人使用。不一定是我们的形式(我们从事元数据管理)。它可以是任何事物的控制系统。您所需要拥有的只是事物的关系视图,从那里获取元数据,了解一些模板引擎并了解某种编程语言(它是如何工作的)。

所有这些工具都属于公共领域-您已经可以开始使用Google进行搜索并了解如何使用它们。我相信使用它们将使您的生活更轻松,更好,并通常腾出时间来完成新的,雄心勃勃的,酷炫的任务。谢谢!

问题


观众提出的问题(以下简称-A):-我是否正确理解由于使用关系数据库而导致一切堆积如山?在我看来,如果您着眼于面向文档的数据库,那么对于您来说,所有这些解决方案都将比现在看到的容易得多。

SC:不是。当我们谈论术语表级别的工作人员和去舞会的蜘蛛,阅读这些故事并进行检查时,我们从一开始便开始了-确实,负责该术语表领域的表格是在舞会上进行的。他们在我们的服务中说:“伙计们,您应该拥有REST API。你怎么做是你的问题。这是允许的技术列表-使用此列表中的某些内容(这是我们可以在Sberbank中使用的内容)。”

这是我们解决方案,应用架构的级别。相反,对我们而言,不依赖关系则更容易做到这一点。为什么?我将举一个例子,它是众多例子之一。例如,当我写一个字段时,我需要确保它不会在任何地方引用不存在的表。我只是在数据库中做一个外键,并不担心。我没有写线-她不会让我做这张唱片。有很多这样的例子!

在这里,我们宁愿谈论其他事情。一个更复杂的故事:我们将发布一个包含调整/认证数据集的模型补丁,其中有6个对象。而且,不可避免地,要提供这种绅士的API集,您需要三个月的时间(副手)。我们需要一个半星期。如果不应用这些技术,就不可能在这些条件下生存。我们根本不会提供这样的服务水平!

如果您以这样的方式来构建产品,那就是您具有模型补丁(新对象),“做得很好”按钮以及一些将在客户端仿真模式下进行测试的软件,则这是可能的。赢得了新的,旧的并没有失败-这是必须实现的,但是如何-这是团队的选择。



答: -我还有第二个问题。从生活中使用的例子是什么?我了解理论上看起来您至少可以使用META_META对象描述整个世界……但是在生活中,您如何使用它?从实现方式(一切都应该放在一起)来看,它应该放慢速度!

SC:-顺便说一句,没有(令人惊讶)!这个故事的另一个应用是代码生成器。在这里建立一些店面,存储,而您是ETL,您试图将所有可能的选项停放在9个模板中,这9个模板引擎已在前面进行了描述。使用元数据,您可以将这些模板用作存根来描述此转换。此外,该机器无需编程即可提供ETL代码,并基于元数据生成代码。我相信也有这样的技术,方法将是适当和正确的。

答: -我指望一个更具体的例子。

答: -请告诉我,这是在您的要求中写的,您需要进行复杂的结构化查询(Join等)。它以什么语言实现,或者您以某种方式对其进行了逻辑描述?

SC:-通过REST API进行访问,大多数情况下是Java,尽管它可以是任何语言。我们的服务已发布(dhttps,询问https-您将获得JSON)。我们显示的那些代码是SQL。为了理解应该以什么顺序处理,我们对DBMS字典进行了一些SQL调优,并将其以具体化表示形式停放在单独的方案中。因此,当发布模型补丁时,单击“刷新实例化视图”按钮(出现+字段)。但是实际上我们的代码是Java和Oracle。

AC:-在这里值得注意的是,我们决定划分责任范围。我们有意将所有魔力转移到了内核,Application正确地解释了这些答案。也就是说,Join机制本身就出现在内核中,而Java简单地将其全部散布在树中并为用户提供最终结果。

答: -代码生成器会做什么-您是否已经在此处写下了复杂查询的逻辑?还是在客户端完成?我们需要了解正在描述的是哪一侧。事实证明,他们提出了Code Gen,必须在其上以某种结构进行准确描述:例如,我希望我的API学习此类Join,请仔细阅读列表;然后说是否有内部...-复杂的查询就足够了。这是什么时候写的?

SC:-如果我正确理解了您的问题,那么这正是我们的客户,我们的客户(这是一个位于内核,平台内的团队)说:“听着,我们不想编程-给我们这个”的故事。 “就是这样”,一切都在核心完成。核心-本质上是什么? 80%,也许是90%-这是动态代码的生成,该文本将在PL / SQL下调用,但会转到数据库中。在那里,即使时间很长,该行的生成时间也会更长,然后访问数据库(例如,Join请求),返回数据库,将其包装为JSON,然后将其倒置显示。此外,Java将所有这些转换成合同,这取决于结构。

和:-公开了批量更新解决方案。以及如何保证交付-整个包裹或包裹的一部分到达了?他们有一定的缓存数吗?以及如何确保服务不会下降,数据结构也没有任何一致性,以确保没有错误?

SC: -我们有一个协议-有两种更新模式。在其中之一中,您可以设置标志“应用所有可能的方法”。有一些Excel可以将其转换为JSON的软件-可能有1万行。严格来说,您可能会发现两行无效(错误)。然后您要么说:“请尽一切可能”;或“仅在整个故事不会有一个错误的情况下才适用。”例如,在那里,积分状态将为回滚。实际上,对数据库进行了插入,但是未调用commit。

如果发生错误-它调用回滚,它在协议中;无论如何,您都会获得协议。您在每一行上都有一个状态,并且在单独的字段中有一个标识符-一个数字(对象ID)或某个替代键,或两者兼而有之。该协议可以了解我的请求发生了什么。

AC: -用户本人指示他应该移动哪个选项。我们将此参数传递到核心一侧,核心已经产生了所有魔力,给出了答案,然后我们对其进行了解释。

和:“为什么不使用任何有助于定义规则的内置表达式编译器?”假设我们有一个模板,我正在以某种语言(键入/未键入脚本语言)进行博客;写道:“我想要一个清单。”按照第一个问题的建议,传递了此片段,以便某些代码处理器将其全部消耗掉,并将其放入NoSQL数据库中。...仍然不清楚为什么是关系数据库,为什么以及如何以及如何处理数据冗余?一个人向您发送了一个带有十亿垃圾的模板。当一个人需要模板时,这些协议是如何达成的?



SC:“我会尽我所能回答这个问题。”现在,大多数程序都与我们通信。建立集成交互机制后,没有多少人像程序那样与我们交流。当然,在某些情况下,人们会为主要的溢出事件发送一份证据:我们用它们制作JSON,然后上载,但这更多是主要的设置。

当您发送5,000行时,我们有一个模式,其中4,900返回状态为“我已处理,我没有发现任何变化,我什么也没做。”但这反映在协议中,没有错误。一方面,这是冗余。

与某些用于商店橱窗的非规范化结构相比,我们将整个故事存储为近似于第三种正常形式,这并不意味着冗余。

为什么要关系?代码生成器为我们工作,并且对系统中元数据质量的敏感性非常高。并且当我们有机会使用关系配置外键并确保...时,记录根本就不会躺下-如果系统中出现问题,如果发生故障,就会出错。我们想要,但是我们没有在寻找额外的工作……

由于我们写了多少行代码,我们无法衡量:“您是否解决了服务及其稳定性问题?”您可能根本不会写-主要是它有效。从这个意义上讲,这样做只是更快,更方便。

我没有特定的供应商,但是关系数据库已经开发了20年!不只是那样以Windows上的Word或Excel为例-您无需在此处编写代码,而在“汇编程序”的帮助下,这些代码可访问并移动硬盘驱动器的头部以写入文件...这里也一样!我们只是使用了RDBMS中的那些开发,这很方便。

AC:-为了确保满足我们的所有要求,元数据的完整性对我们很重要。在这里,我们可能还想传达一点,我们根本不必固守-我们使用关系,而不是关系...报告的本质是您也可以开始使用它。不一定基于关系,因为可以肯定的是其他人也可以收集某种元数据:至少,哪些表,字段是已编程的。

答: -系统涉及一些用途。您如何计划(或已经完成)将数据传输到系统?很明显,杂货店正在进行某种形式的数据结构更新。这一切怎么来的?自动,您的代理人站着还是在弯曲所有开发团队,以便您接收更新?

AC:-我们有两种操作模式。一种是迫使开发人员自己或团队本身通过REST服务将元数据添加到系统中。第二种操作模式是相同的“真空吸尘器”:我们自己进入环境并从那里获取所有可能的元数据。我们每天执行一次,仅检查开发人员发送给我们的内容。



SC: -在我们检查的四个级别中,前三个级别(词汇表,逻辑模型,物理模型)是默认情况下在Metadata Broker模式下出现的故事,并且我们是被动参与者。他们打电话给我们,给我们传递一些东西,问;我们的任务是以一致的方式停车。尽管有时候我们会利用团队的资源来建立一些故事,但是如果我们对拥有此元数据非常感兴趣。

正如Nastya所说,关于相反的故事(在技术术语中,我们称之为“真空吸尘器”),我们进入了工业环境并读取了一些数据。有不同的情况-我们准备稍后讨论,我们准备讲许多有趣的故事。

答: -我来自金融技术中心。我在那里看到一个熟悉的词-主DACUM。我们的平台具有自己的元数据。您好吗-在这种情况下直接与Oracle表或我们的元数据在一起?因为在我们的例子中,与Oracle表成为朋友并不完全是指示性的。

SC:-有一个这样的表格主DACUM,其中包含接线。这不是秘密:存在和存在适用于该故事的产品。这些是资源库中信息的来源之一。有某种系统是数据提供者。自然地,它是元数据方面引起我们关注的焦点,因为数据沿袭是我们应该在这里展示并且完全没有涉及到的故事之一(由于报告的主题)。您必须显示此字段的数据历史记录来自何处。从这个意义上讲,如果有一个主要的DACUM表,我们就知道了。


一点广告:)


感谢您与我们在一起。你喜欢我们的文章吗?想看更多有趣的资料吗?通过下订单或向您的朋友推荐给开发人员的基于云的VPS,最低价格为4.99美元这是我们为您发明的入门级服务器 独特类似物:关于VPS(KVM)E5-2697 v3(6核)的全部真相10GB DDR4 480GB SSD 1Gbps从$ 19还是如何划分服务器?(RAID1和RAID10提供选件,最多24个内核和最大40GB DDR4)。

阿姆斯特丹的Equinix Tier IV数据中心的戴尔R730xd便宜2倍吗?在荷兰,我们有2台Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100电视戴尔R420-2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB-$ 99起!阅读有关如何构建基础设施大厦的信息。使用Dell R730xd E5-2650 v4服务器花费一欧元9000欧元的c类?

Source: https://habr.com/ru/post/undefined/


All Articles