使用Akka、Kafka和ElasticSearch等构建分析引擎 -- good
本文翻译自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非常适合于流处理和日志汇聚。它的架构设计就已经支持可扩展、分布式、容错等功能。
请耐心等待我改进第四版架构之后再更新这篇文章吧……快乐编程,不断创新!
http://www.infoq.com/cn/articles/use-akka-kafka--build-analysis-engine?utm_campaign=rightbar_v2&utm_source=infoq&utm_medium=articles_link&utm_content=link_text
使用Akka、Kafka和ElasticSearch等构建分析引擎 -- good的更多相关文章
- Elasticsearch源码分析 - 源码构建
原文地址:https://mp.weixin.qq.com/s?__biz=MzU2Njg5Nzk0NQ==&mid=2247483694&idx=1&sn=bd03afe5a ...
- Spark集群 + Akka + Kafka + Scala 开发(3) : 开发一个Akka + Spark的应用
前言 在Spark集群 + Akka + Kafka + Scala 开发(1) : 配置开发环境中,我们已经部署好了一个Spark的开发环境. 在Spark集群 + Akka + Kafka + S ...
- Spark集群 + Akka + Kafka + Scala 开发(2) : 开发一个Spark应用
前言 在Spark集群 + Akka + Kafka + Scala 开发(1) : 配置开发环境,我们已经部署好了一个Spark的开发环境. 本文的目标是写一个Spark应用,并可以在集群中测试. ...
- Spark集群 + Akka + Kafka + Scala 开发(4) : 开发一个Kafka + Spark的应用
前言 在Spark集群 + Akka + Kafka + Scala 开发(1) : 配置开发环境中,我们已经部署好了一个Spark的开发环境. 在Spark集群 + Akka + Kafka + S ...
- Elasticsearch是一个分布式可扩展的实时搜索和分析引擎,elasticsearch安装配置及中文分词
http://fuxiaopang.gitbooks.io/learnelasticsearch/content/ (中文) 在Elasticsearch中,文档术语一种类型(type),各种各样的 ...
- fluentd结合kibana、elasticsearch实时搜索分析hadoop集群日志<转>
转自 http://blog.csdn.net/jiedushi/article/details/12003171 Fluentd是一个开源收集事件和日志系统,它目前提供150+扩展插件让你存储大数据 ...
- 使用 Kafka 和 Spark Streaming 构建实时数据处理系统
使用 Kafka 和 Spark Streaming 构建实时数据处理系统 来源:https://www.ibm.com/developerworks,这篇文章转载自微信里文章,正好解决了我项目中的技 ...
- Filebeat+Kafka+Logstash+ElasticSearch+Kibana 日志采集方案
前言 Elastic Stack 提供 Beats 和 Logstash 套件来采集任何来源.任何格式的数据.其实Beats 和 Logstash的功能差不多,都能够与 Elasticsearch 产 ...
- elasticsearch源码分析之search模块(client端)
elasticsearch源码分析之search模块(client端) 注意,我这里所说的都是通过rest api来做的搜索,所以对于接收到请求的节点,我姑且将之称之为client端,其主要的功能我们 ...
随机推荐
- amazeui学习笔记--css(基本样式)--样式统一Normalize
amazeui学习笔记--css(基本样式)--样式统一Normalize 一.总结 1.统一浏览器默认样式: Amaze UI 也使用了 normalize.css,就是让不同浏览器显示相同的样式 ...
- vue指令应用--实现输入框常见过滤功能
前端开发最常碰到的就是输入框,经常要做各种验证,本公司惯用的需求是直接屏蔽特定字符的输入,如禁止非数字输入,特殊符号输入,空格输入等,这些功能反复使用,做成指令的形式,直接调用,非常方便,上代码: 目 ...
- [React] Create a Virtualized List with Auto Sizing Cells using react-virtualized and CellMeasurer
In this lesson we'll use CellMeasurer and CellMeasurerCache to automatically calculate and cache the ...
- hdu 1506 Largest Rectangle in a Histogram ((dp求最大子矩阵))
# include <stdio.h> # include <algorithm> # include <iostream> # include <math. ...
- android闹钟实现原理
闹钟的原理可用下面我自己画的一幅图来概括:(不对的地方,尽管吐槽) 我们来看看新建闹钟到闹钟响铃的步骤: 1.新建一个闹钟: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
- js和jquery实现页面滚动监听
js和jquery实现页面滚动监听 一.总结 一句话总结:onscroll方法和监听页面元素的高度都可以实现滚动监听. 1.onscroll方法实现滚动监听的核心代码是什么? <body ons ...
- 【48.47%】【POJ 2524】Ubiquitous Religions
Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 32364 Accepted: 15685 Description There a ...
- 超级牛X的免费开源小工具之tldr
github介绍:http://tldr-pages.github.io/ github源码:https://github.com/tldr-pages/tldr 什么是tldr? 新命令行世界?还是 ...
- 利用C#与AE调用GP工具
转自原文 利用C#与AE调用GP工具 第一,首先要明确自己需要调用arctoolbox里面的什么工具,实现什么样的功能. 第三,编写command或tool工具,编写自己要的功能工具. 1)首先创建一 ...
- css 水平垂直居中的方法总结
在项目中经常会遇到设置元素水平垂直居中的需求.而且具体的场景也不同,所以将个人总结的方法做个汇总,希望对浏览者有用. 以下所举的例子都以一个html为准,这里规定好一些公用样式. body { bac ...