写点什么

使用 Akka、Kafka 和 ElasticSearch 等构建分析引擎

  • 2016-08-14
  • 本文字数:2414 字

    阅读完需:约 8 分钟

本文翻译自 Building Analytics Engine Using Akka, Kafka & ElasticSearch ,已获得原作者 Satendra Kumar 和网站授权。

在这篇文章里,我将和大家分享一下我用 Scala、Akka、Play、Kafka 和 ElasticSearch 等构建大型分布式、容错、可扩展的分析引擎的经验。

我的分析引擎主要是用于文本分析的。输入有结构化的、非结构化的和半结构化的数据,我们会用分析引擎对数据进行大量处理。如下图所示为第一代架构,分析引擎可以用 REST 客户端或 Web 客户端(引擎内置)访问。

(点击放大图像)

简单描述一下用到的技术:

  • Play 框架做 REST 服务器和 WEB 应用。Play 是个基于轻量级、无状态和 WEB 友好的 MVC 框架。
  • Akka 集群作处理引擎。Akka 是个工具集,用于在 JVM 上简化编写高并发、分布式、和有弹性的消息驱动应用。
  • ClusterClient 用于与 Akka 集群通信。它运行在 REST 服务器上,将任务发给 Akka 集群。使用 ClusterClient 是一个非常错误的决定,因为它并不会维持与 Akka 集群的长连接,因而会经常报连接错误,而且重新建立连接时还要把那个 Client 所在的 JVM 也一起重启。
  • ElasticSearch 用作查询引擎和数据存储,包括原始数据和分析结果。
  • Kibana 用作可视化平台。Kibana 是有弹性的分析和可视化平台。
  • Akka Actor 用作 ElasticSearch 的数据导入导出服务。它的表现非常好,服务从来没出过故障。
  • S3 用作集中化文件存储。
  • Elastic Load Balance 用作节点之间的负载均衡。
  • MySQL 用于元数据存储。

我们从 Akka 2.2.x 版开始用起,也碰到了一些严重问题,主要表现为:

  • ClusterClient 与 Akka 集群之间连接断开:在负载大 CPU 使用率高时,ClusterClient 常常莫名其妙的与 Akka 集群断开连接。因为它是个第三方库,所以我们只好把 JVM 重启来让它继续工作,有的时候还要半夜爬起来处理问题。
  • 资源利用率:我们发现 REST 服务器上 CPU 使用率只有 2-5%,这样太浪费资源了,Amazon EC2 服务器可不便宜。
  • 延迟问题:REST 服务器运行在不同的服务器上。这样就造成了延迟问题,因为对于每一条 Client 发过来的请求,它都要把请求反序列化,再序列化然后才能发到 Akka 集群。从 Akka 集群发来的响应消息也是一样,要先反序列化再序列化,然后才能发给请求方。这样的序列化和反序列化过程常常导致超时问题。而且,我们只是把 Play 用作 REST 后台而不是完整的 WEB 框架,我承认这是我们的设计问题。

为了解决这些问题我们设计了第二代架构,主要变化有:

  • 去掉 Akka ClusterClient。
  • Spray 替换掉 Play 架构,因为把 Play 用作 REST 服务不是个正确的决定。Spray 是个轻量级 HTTP 服务器。
  • 为了减少端到端的延迟,我们把 REST 服务运行在 Akka 集群节点所在的 JVM 上,而不是单独的节点上。

新架构是这样的:

(点击放大图像)

太棒了,这样的系统工作得非常好。生活又变得非常美好,团队也得到了很多表扬。

三个月后,来了个要增加Datasift 做为数据源的新需求,提供流数据和历史数据。这个需求好满足,只要增加一个新服务,从 Datasift 中拉取数据并发送到分析集群上即可。

(点击放大图像)

增加新服务很简单,但却导致了新问题:

  • 上述架构本质上来说是个推送模型,每当有大量的流或历史数据被推送过来时,集群就会处理不过来。
  • 我们决定把集群由 4 个节点扩展为 8 个节点。这样峰值情况下还可以,但正常情况下大多数节点都处于非常空闲的状态。我们用的是 Amazon EC2 4x.Large 节点,非常贵,所以就引发出了基础设施的费用问题
  • 我们决定使用 Amazon 的自动扩容服务。在集群上负载增加时它的确是自动扩容了,可是负载降下来时它却没有缩容。Amazon 自动扩容服务对我们的业务情况处理得不够好。
  • 另一个问题是 Akka 集群的内部节点通信在 CPU 使用率超过 90% 时常常出问题,原因可能是因为我们经验不够不会配 Akka 集群,也有可能是 Akka 集群那时候不象现在这么成熟。
  • 如果有节点崩溃的话,那整个处理过程就会停止。

当我们在努力为这个问题找解决方案时,又收到需求要再增加一种数据源!

在经过很多次头脑风暴之后,我们明白了现有架构的问题,于是做出了一个简单、可扩展和容错的第三代架构

(点击放大图像)

在这个新架构里,我们去掉了Akka 集群,重写了分析引擎。它完全是基于Akka Actor 的,REST 服务也是运行在相同的JVM 上。REST 服务只是简单的从客户端接收请求,做认证和鉴权,然后创建一条待处理消息发送到Kafka 队列中去。分析引擎的每个节点都会从Kafka 队列中拉取数据,处理完毕再拉取下一批。这样它就永远不会忙不过来。

受益于Kafka 的内部机制,不管哪个节点死掉了,Kafka 都会自动的把要处理的消息发送到另一个正常节点上,所以不会有任何消息丢失。

在这个架构下我们就不必继续租用以前的Amazon EC2 4X large 服务器了,只要用Amazon EC2 2X large 就可以支持任何负载,节省了很多钱。(此处应有掌声。:) )

这完全是个基于拉取模式的架构。所有的请求和浪涌 都通过Kafka 集群处理。它永远不会忙不过来,因为所有操作都是基于拉取模式的。整个系统部署在 26 台 EC2 节点上,已经快两年了,生产系统一次故障都没出过。

我们也用 Kafka 保存了各种服务日志来分析性能、安全和用户行为。Kafka 生产者会把日志发送到 Kafka 服务器中。因为我们已经有了 ElasticSearch 的导入导出服务,我们可以仍然用它们来推送 ElasticSearch 的日志。我们也可以轻松地用 Kibana 将用户行为可视化。

结论

  • Akka Actors 非常适合于打造高并发、分布式、有弹性的应用程序。
  • Spray 非常适合作轻量级 HTTP 服务器。现在它已改名为 Akka-HTTP
  • Play 框架非常适合于构建高并发、可扩展的 WEB 应用,它底层是 Akka。
  • ElasticSearch 是个非常好的搜索引擎,它底层是 Lucene,可以提供全文检索功能。尽管我们也把它当成数据存储来用,但数据持久化并不是它的强项(比如与 Cassandra 相比)。
  • Kafka 非常适合于流处理和日志汇聚。它的架构设计就已经支持可扩展、分布式、容错等功能。

请耐心等待我改进第四版架构之后再更新这篇文章吧……快乐编程,不断创新!

2016-08-14 17:4811684
用户头像

发布了 152 篇内容, 共 73.7 次阅读, 收获喜欢 64 次。

关注

评论 1 条评论

发布
用户头像
很棒!请问您有微信公众号or blog之类的吗,希望和您多交流(akka萌新)
2018-11-08 15:24
回复
没有更多了
发现更多内容

领航全球云经济行业创新,XTransfer入选Bessemer年度报告

XTransfer技术

得物Tech Leader对管理授权的思考是什么?/得物技术管理集锦

得物技术

管理 思考 技术管理 事前授权 任务分配

Vue团队核心成员开发的39行小工具 install-pkg 安装包,值得一学

若川

JavaScript 源码 前端 前端开发 Node

中国20强游戏公司2021年财报分析:业绩大分化时代,开始优胜劣汰

易观分析

游戏公司

模块七:作业

本人法海

「架构实战营」

最佳实践|从Producer 到 Consumer,如何有效监控 Kafka

阿里巴巴云原生

kafka 阿里云 云原生 Promethues

LabVIEW控制Arduino流水灯(基础篇—3)

不脱发的程序猿

单片机 LabVIEW Arduino LIAT 流水灯

LabVIEW控制Arduino采集电位器电压(基础篇—4)

不脱发的程序猿

单片机 LabVIEW LIAT Arduino Uno 采集电位器电压

200多家ISV入驻!阿里云计算巢发布一周年

阿里云弹性计算

计算巢

开讲!XTransfer技术专家亮相Flink CDC Meetup

XTransfer技术

flink XTransfer

ZEGO 开发者文档速查|常用视频配置

ZEGO即构

音视频开发 视频配置

数据中心进化论:华为带来的三个路标与新可能

脑极体

使用 FutureProvider 搞定个人主页异步请求的状态管理

岛上码农

flutter ios 前端 安卓开发 5月月更

网易数帆 Envoy Gateway 实践之旅:坚守 6 年,峥嵘渐显

网易数帆

云原生 Service Mesh istio api 网关 envoy

报名进入尾声,赶快申请加入 sealer 开源之夏吧!

阿里巴巴云原生

阿里云 开源 Kubernetes 云原生 sealer

MDM结合ESB数据集成说明

agileai

数据治理 数据集成 企业服务总线 主数据平台 基础数据方案

华为云&易观分析《互联网出海白皮书2022》:新兴市场成掘金热土

易观分析

华为云 出海

面试官:项目中常用的 .env 文件原理是什么?如何实现?

若川

JavaScript 前端 Node

面试官:请手写一个带取消功能的延迟函数,axios 取消功能的原理是什么

若川

JavaScript 源码 前端 前端开发 axios

什么是区块哈希?哈希游戏开发技术原理方案(源码搭建)

开发微hkkf5566

什么是智能合约?3M互助dapp系统开发逻辑拆解

开发微hkkf5566

动态规划:打家劫舍 ⛄

空城机

算法 5月月更

Maven 跳过测试的几种方式

HoneyMoose

MOVE PROTOCOL全球健康宣言,将健康运动进行到底

西柚子

MOVE PROTOCOL全球健康宣言,将健康运动进行到底

小哈区块

从 vue3 和 vite 源码中,我学到了一行代码统一规范团队包管理器的神器

若川

JavaScript 前端 前端开发 Node web前端开发

直播预告|来啦!「DevOps+MLOps Meetup」火热报名中!

第四范式开发者社区

人工智能 DevOps 极狐GitLab 特征平台 MLOps

Vue3 TypeScript 使用教程 - 实战 Vue3 element-plus 开发「待办清单」

蒋川

typescript 低代码 开发工具 Vue 3 Element Plus

leetcode 81. Search in Rotated Sorted Array II 搜索旋转排序数组 II(中等)

okokabcd

LeetCode 查找

从 vue-cli 源码中,我发现了27行读取 json 文件有趣的 npm 包

若川

JavaScript 前端 前端开发 Node web前端开发

LabVIEW控制Arduino实现PWM呼吸灯(基础篇—5)

不脱发的程序猿

单片机 LabVIEW LIAT Arduino Uno PWM呼吸灯

使用Akka、Kafka和ElasticSearch等构建分析引擎_语言 & 开发_Satendra Kumar_InfoQ精选文章