最新发布《数智时代的AI人才粮仓模型解读白皮书(2024版)》,立即领取! 了解详情
写点什么

构建可扩展的机器学习系统(一):你所需的架构设计知识

  • 2019-05-20
  • 本文字数:4030 字

    阅读完需:约 13 分钟

构建可扩展的机器学习系统(一):你所需的架构设计知识

本文介绍了机器学习应用中的一些软件工程基础,快速浏览了最流行的一些架构模式、设计模式,以及面向对象设计的 SOLID 原则,目的是让读者尽可能多地了解构建可扩展软件的主要贡献因素。应用程序设计是否能够适应变化,是构建成功解决方案的关键,如果设计过程很仓促,项目结束时,一定会为犯下的错误交学费。

正文

本专题将通过两篇系列文章,介绍与体系结构和设计有关的软件工程基础知识,以及如何在机器学习管道(ML Pipeline)的每个步骤中应用这些基础知识:


第1部分:问题陈述 |架构风格 |设计模式 |SOLID

第2部分:构建机器学习管道

介绍

就像以前在 Steven Geringer 著名的维恩图中看到的,数据科学是 3 个学科的交集:计算机科学、数学/统计学和特定的领域知识。



数据科学维恩图[©Steven Geringer]


拥有基本(甚至是高级)的编程技能,是将端到端的经验结合在一起的关键,但还不足以创建一个可以发布的应用程序。除非从 IT 背景进入数据科学和机器学习(ML),并且在构建企业级的、分布式的、可靠的系统方面拥有实际经验,否则您的 Jupyter 笔记本(译者: 可创建和共享自己的文学化程序文档)没资格成为优秀的软件,遗憾的是,您也不能成为软件工程师!


虽然您打算构建的是一个很好的预测产品的原型,但仍然需要通过工程技术的路线图来推动它。所需要的是一个由专业软件工程师组成的团队,可以将(一次性)概念验证转化为高性能可靠松耦合可扩展的系统!


一切都是设计出来的; 但设计得好的东西很少!


在本系列中,我们将展示如何实现良好设计的一些想法。第一部分从基础知识开始,第二部分逐步设计整体架构。这里建议的架构是技术无关的,机器学习管道将被分解成责任明确的不同层,可以从许多技术堆栈中选择如何来实现每一层。


接下来看看成功的解决方案应该是如何实现的。

问题陈述

我们的主要目标是建立一个系统,具备以下特性:


▸减少延迟;

▸集成系统的其他部分(例如数据存储,报告,图形用户界面),但松耦合

▸可以水平和垂直伸缩

▸消息驱动,即系统通过异步、非阻塞的消息传递进行通信

▸提供工作负载管理相关的高效计算

▸容错和自我修复,即故障管理

▸支持批量和实时处理。

架构风格

我们将首先介绍一个反应式系统,并快速浏览最流行的架构模式。

反应式系统

反应式系统设计范式采用前后一致的方法来建立更好的系统,这些系统是根据“反应式宣言”的原则进行设计的。每个反应式原则对应一个可扩展性的重要系统维度:


• 易响应的 → 时间


• 易扩展的 → 负载


• 可恢复的→ 错误


• 消息驱动的 → 通信。



反应系统的特性

面向服务架构(SOA)

SOA 将业务问题分解为服务,这些服务通过网络来共享信息。它们还共享代码(即公共组件),以保持反应式系统的一致性和特性,从而减少开发工作。


服务提供者发布合约,规定服务的特征以及如何使用服务。服务使用者可以在注册中心中找到服务元数据,开发所需的客户端组件来绑定和使用它。


协调器(Orchestrator)是一个综合服务,负责调用和组合其他服务。此外,编排(Choreography)采用去中心化的方法组合服务,服务通过消息/事件的交换进行交互。



SOA

流式(Streaming)架构

流式架构包括以下组件:


  • 生产者:生成和发送消息的应用程序

  • 消费者:订阅和使用消息的应用程序

  • 主题:类别特定的记录流,存储成有序和不可变的记录序列,通过分布式集群进行分区和复制

  • 流处理器:以特定方式处理消息的应用程序(例如数据转换、ML 模型等)。



流式架构

Lambda 架构

Lambda(λ)架构旨在以集成的方式处理实时和过去聚合的批量数据。它分离了实时和批处理的职责,查询层提供了所有数据的统一视图。


这个概念很简单:生成数据时,会在存储之前对其进行处理,因此分析可以包括最后一秒、最后一分钟或最后一小时生成的数据,只处理传入的数据,而不是所有的数据。



Lambda 架构

微服务架构

微服务是一种架构风格,它将应用程序构造为小型、自主、松耦合和协作的服务集合,围绕业务领域进行建模。这些服务使用同步协议(HTTP/REST)或异步协议(AMQP)进行通信,可以彼此独立地开发和部署。每个服务都有自己的数据库,以便与其他服务分离。



微服务架构

REST 架构

REST 是一种用于开发 Web 服务的架构风格,它建立在 Internet HTTP 的现有特性之上,允许以无状态的方式传输、访问和操作文本数据,即应用程序可以在不知道状态的情况下进行通信。


RESTful API 服务通过统一资源定位器(URL)公开,提供了创建、请求、更新或删除(CRUD)数据的功能。它最适合处理解耦(生成/消费的 ) 信息和(生成/使用信息的 ) 技术的系统。



REST 架构

设计模式

我们将浅显地介绍这个主题,并且只讨论我在本系列的第二部分中可能提到的那些模式。(虽然我每天都在使用它们,但很难用简单的语言全部解释清楚)


软件设计模式是针对软件工程中常见问题的优化的、可重复的解决方案。它是一个解决问题的模板,可以在许多不同的情况下使用。

策略

策略模式定义了一系列算法,将每个算法放在一个单独的类中,相互之间可互换。将行为封装在单独的类中,消除了任何条件语句,在运行时可以选择正确的算法(即策略)。


  • 使用说明:业务规则有不同的实现,或者需要算法的不同变体。



策略模式

模板方法

模板方法旨在从不同的过程中抽象出一个通用的过程。它定义了算法的骨架,将某些步骤推迟到子类。子类可以覆盖某些行为,但不能更改骨架。


  • 使用说明:遵循一系列一致的步骤,各个步骤可能有不同的实现。


⭐ 与策略模式的区别


  • 模板:子类编译时选择算法。

  • 策略:控制运行时选择算法。



模板方法模式

责任链

责任链模式通过启用一个或多个处理程序来满足请求,避免将客户端(请求的发送者)与接收者耦合。这些处理程序连接到一个链中,每个处理程序都包含对链中下一个处理程序的引用。



  • 使用说明:多个对象可以处理一个请求,处理程序(或序列)的优先级事先不知道。



责任链模式

观察者

观察者模式(缩写为 Publish/Subscribe 或简称 PubSub)通过定义对象之间的一对多依赖关系,可以轻松地进行通信广播,当一个对象的状态发生变化时,它的所有依赖关系都会自动得到通知和更新。观察者负责注册它们所“观察”的事件。


  • 使用说明:当改变某个对象时同时需要改变其他对象,不知道多少对象需要改变。



观察者模式

建造者

建造者模式旨在逐步构造一个复杂的对象,分离构造与表示。实质上,它允许使用相同的代码,生成对象的不同类型和表示形式。


  • 使用说明:虽然各个构造步骤有所不同,但可以使用相同的整体构建过程来构建多种复杂对象。



建造者模式

工厂方法

工厂方法定义了一个用于创建对象的接口,由子类来完成实例化。


  • 使用说明:对象的具体类型和依赖关系事先不知道。



工厂方法模式

抽象工厂

抽象工厂关注如何创建相关产品的系列,不指定它们具体的类。


  • 使用说明:不同的规则采用不同的实现,这些规则要么是未知的,要么是可扩展的。


⭐️ 与抽象方法的区别


  • 抽象工厂:创建其他工厂,这些工厂反过来创建从基类派生的对象。

  • 抽象方法:创建从特定基类派生的对象。



抽象工厂模式

装饰

装饰模式动态地将新的职责附加到对象上,将对象放置在包含行为的特殊包装类(wrapper)中,因此不会影响原来方法的签名(继承上的组合)。


  • 使用说明:运行时为对象分配额外的行为,不会破坏使用这些对象的代码。



装饰模式

仓库

仓库模式解决了数据检索和持久化的代码集中化问题,并为数据访问操作提供了抽象,类似内存中域对象的集合,允许执行 CRUD 方法,消除了各种数据库问题。


  • 使用说明:分离业务逻辑和访问数据的代码。



资源库模式

小奖励

想进一步了解模式?可以先从“Gang of Four”的书《设计模式:可重用的面向对象软件的基础》开始。下面的图展示了模式之间的关系,非常重要:



设计模式之间的关系

SOLID

我们唯一的设计原则是 SOLID,它们对于每个软件开发人员来说都是必不可少的。


正如Bob大叔所说:它们不是法律,也不是完美的真理。它们类似于一个规则:每天一个苹果,医生远离我 ”。


这意味着,它们不是某种“魔法”,不是带来牛奶、蜂蜜和优质软件的应许之地,它们是健壮、持久软件的关键贡献者。


简而言之,这些原则围绕两个主要的概念展开,是成功企业应用程序的基石:耦合是类了解另一个类并与之交互的程度;而内聚表示类具有单一用途的程度。换一种说法:


- 耦合是关于类如何相互作用的;

- 内聚关注单个类的设计方式。

单一责任原则

一个类应该有一个,而且只有一个变化的理由


这是不言自明的,但说起来容易做起来难。我们总是想在现有类中添加新的行为,但这是一个引发灾难的处方:每个行为都可能成为未来变化的理由,因此行为越少,在变化时产生错误的机会就越少。

开闭原则

能够扩展类的行为,而无需对其进行修改


类应该对扩展“开放”,但是对修改“关闭”。要实现这一点可以通过继承,即创建一个子类,关闭对原始类进行修改,将自定义的代码添加到子类来引入新的行为。

里氏替换原则

派生类必须可替代基类


当类 A 的行为扩展到子类 B 时,可以确保在不造成任何破坏的情况下用 B 替换 A。这点可能比较吸引人,特别是当把这一原则与开闭原则结合起来时。

接口隔离原则

创建特定于客户端的细粒度接口


接口和类必须尽可能特定,客户端的调用不依赖未使用的方法。这与单一责任原则是一致的。

依赖倒置原则

依赖抽象,而不是具体实现


高层的类不应该依赖于低层的类。它们都应该依赖于抽象。同样,抽象不依赖于细节,细节依赖于抽象。

小奖励

我创建了下面这个快速参考图。如果想知道左边小符号的灵感来自哪里,请参看:“SOLID原则,用励志海报解释” —— 我喜欢作者在这些原则上增加的有趣改变???。



SOLID

脚注

这里无法涵盖所有软件工程概念的详尽列表,它只是阅读下一篇文章的基础,我希望它能让读者了解构建可扩展软件的主要贡献因素。应用程序设计是否能够适应变化,是构建成功解决方案的关键,如果设计过程很仓促,项目结束时,一定会为犯下的错误交付学费。


好的设计是易懂的。伟大的设计是透明的。


原文链接https://towardsdatascience.com/being-a-data-scientist-does-not-make-you-a-software-engineer-c64081526372


公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2019-05-20 17:226624
用户头像

发布了 43 篇内容, 共 33.3 次阅读, 收获喜欢 136 次。

关注

评论

发布
暂无评论
发现更多内容

腾讯35岁架构师提前退休,比别人早2年确定职业目标有多重要?还不学起来等着被裁吗?

android 程序员 移动开发

腾讯一面被拒含泪离开,面试官:Android开发连这些都不懂,哭也没用

android 程序员 移动开发

聊一聊 Android 中巧妙的位操作

android 程序员 移动开发

解决Fragment多层嵌套时onActivityResult无法正确回调的问题

android 程序员 移动开发

编写-Android-Library-的最佳实践-1

android 程序员 移动开发

自学Android,面试被怼,看我如何拿下阿里offer

android 程序员 移动开发

美团外卖Flutter动态化实践

android 程序员 移动开发

耗时118天爆肝【1296页】的“Android高级开发面试题(1)

android 程序员 移动开发

腾讯校招被问Android网络相关面试题,精编参考解析全整理,你不看看吗?

android 程序员 移动开发

自定义ViewGroup实现微信朋友圈九宫格图片控件

android 程序员 移动开发

自定义View(一) Android 可计数EditText实现

android 程序员 移动开发

耗时118天爆肝【1296页】的“Android高级开发面试题

android 程序员 移动开发

腾讯Android中高级面试题大全(含解析)

android 程序员 移动开发

C++学习路线图

泰伦卢

c++

致刚入行的小白,或者工作一到三年的Android程序员,如何规避“内卷

android 程序员 移动开发

蒂花之秀---大神用漫画讲解字符串匹配算法,让你噩梦变美梦

android 程序员 移动开发

脑瓜子嗡嗡的。。Android-UI-线程更新UI也会崩溃?

android 程序员 移动开发

你真的会打印日志?

中间件兴趣圈

Java 11月日更

自定义View

android 程序员 移动开发

网易被裁后,68天吃透这份阿里学长甩我的Android面试笔记,竟让我收到字节跳动和小米offer

android 程序员 移动开发

【架构实战营作业】模块七——王者荣耀商城异地多活架构

聆息

腾讯大牛,一篇文章教你什么是Android-Fragment-,Android高级架构师筑基必备!

android 程序员 移动开发

云计算市场,是时候来一场鱿鱼游戏了

白洞计划

模块三作业

bob

「架构实战营」

计算机编码简析(1)

android 程序员 移动开发

计算机编码简析

android 程序员 移动开发

老板答应给我升职得前夕,34岁的我被优化了?3个月沉淀后迎来转折入职字节跳动!

android 程序员 移动开发

腾讯T3-Android高级架构师学习笔记

android 程序员 移动开发

自定义Gradle插件的开发

android 程序员 移动开发

裸辞两个月从Android转战web前端的求职之路

android 程序员 移动开发

要想工资涨得快,还是得跳槽?一个三本Android程序猿外包到阿里的逆袭之路

android 程序员 移动开发

构建可扩展的机器学习系统(一):你所需的架构设计知识_AI&大模型_Semi Koen_InfoQ精选文章