博睿数据创新大数据处理引擎,企业大数据在线处理工作量可降低80%

2022-07-27

越来越多的企业认识到大数据对于自身未来发展的重要性,纷纷开始使用并逐渐依赖大数据处理的相关技术。但随着需要处理的数据越来越多,业务场景越发复杂,在实际执行过程中遇到很多问题,如大数据人才紧缺,相关技术缺乏沉淀,难以突破瓶颈,同时不同业务部门的业务需求纷繁多样,导致不同项目代码重复开发、重复造轮子、项目技术架构五花八门的情况也很常见,给后期维护和迭代带来很大的挑战。

对于以上的现实问题,博睿数据以10年的大数据项目实践经验,抽象和设计出一套灵活轻便、场景通用、稳定高效的超级大数据处理引擎框架—Bonree Ants,以满足企业复杂多年的数据处理需求。

 

Bonree Ants是什么?


Ants(蚁群)名称源于其寓意:高效协作、小而有力、合纵连横,我们认为其可以诠释这套超级引擎框架的初衷:轻便灵活、场景通用、稳定高效。

Bonree Ants大数据处理引擎框架是一个针对时序指标数据处理的通用流式计算引擎框架。此引擎框架负责范围包括原始数据预处理、准实时计算(支持默认算子和自定义算子)、多种时间粒度批量计算、数据落地及各种容错处理,同时支持自定义高级功能自定义扩展机制,默认支持如时序指标动态基线计算、报警条件判断计算等扩展等。


 

Bonree Ants有怎样的超级马力?

 

Bonree Ants可以帮助企业便捷快速的实现海量时序指标数据的在线流式处理。我们的目标是,对于常见的时序指标流式处理的业务场景可完全不需要研发人员参与,只需非研发业务人员对数据应用进行简单配置和业务脚本描述,即可实现其目标;而对于复杂业务场景我们则希望研发人员通过引擎的插件机制,进行少量编码来实现相关与业务强关联的逻辑,而将大数据处理中底层复杂的资源调度、任务编排、容错处理交给引擎负责,快速实现相关大数据处理业务开发,极大降低企业相关开发和维护成本。

通过在博睿数据众多服务项目的实践,应用Bonree Ants引擎框架之后,大数据处理开发工作量整体降低了80%,整体项目周期缩短40%以上。

 

Bonree Ants的强大源于优秀的设计架构

undefined

(Bonree Ants整体架构图)

 

Bonree Ants引擎框架依赖开源组件运行:ZooKeeper、Kafka、Storm、Redis,依赖少,部署简单,架构轻便,这也是其核心优势之一。

Bonree Ants底层计算框架基于Storm,之所以选择Storm作为底层计算框架,主要考虑到Storm自身的实时性高、资源开销小,外部依赖少、纯内存计算、容错性好等特性。

Bonree Ants将时序指标大数据处理过程抽象为以下几个主要流程,即:预处理、准实时计算、小批量计算、大批量计算、落地入库等。以上流程均由运行于Storm之上的Preprocessing Topology、Calculation Topology、Storage Topology三类拓扑负责完成。

Bonree Ants整个数据处理过程中数据不落地,均在内存中完成。由于需支持大时间粒度批量计算业务场景,Bonree Ants引入Redis作为Storm集群辅助内存存储集群,以降低大批量计算时对Storm集群内存的开销,由于采用内存计算的方式,Bonree Ants实时性高,对磁盘I/O几乎无影响。

Bonree Ants批量计算是基于时间粒度的聚合计算,默认支持1秒、1分钟、10分钟、1小时、1天等五个不同时间粒度的聚合。由于各粒度计算之间存在递进依赖关系,因此为减少计算资源开销,加速计算过程,Bonree Ants在Redis集群缓存了各粒度中间计算结果,以备下一时间粒度计算直接使用,从而减少数据处理量级。

Bonree Ants对于最终计算结果落地只提供了基本框架支持。由于不负责最终数据存储,因此也不会对最终数据落地存储组件有任何限制。Bonree Ants默认内置支持Mysql存储方案,如采用Mysql作为最终落地数据库,则建表和结果数据入库过程均可由Bonree Ants自动完成。如需采用其他落地方案,如HBase等,则由用户开发Storage-Plugin插件进行自定义支持。

Bonree Ants整体架构设计大量采用插件(plugins)和扩展(extensions)机制,其将与业务强关联的个性化处理,如数据预处理策略抽象为Etl-plugin,将数据和维度指标处理的算子(内置支持sum、max、min等基本算子)开放为Operator-plugin,而将处理结果落盘策略抽象为Storage-plugin。

同时,在支持插件技术外,为了丰富Bonree Ants引擎框架功能,还支持extensions扩展机制。用户可以在现有引擎框架基础上开发自己需要的extension,并以独立计算拓扑的方式提交给Ants,由于Ants加载运行,从而实现Ants功能的延伸。目前,Bonree Ants默认内置动态基线扩展(base-line extension)和报警条件判断扩展(alter-judge extension)。

此外,Bonree Ants还支持插件动态更新和Schema.xml动态更新功能,这样能够帮助用户实现不重启即可更新业务处理逻辑的支持,对用户复杂多变的业务场景带来极大的灵活性。

 

Bonree Ants运行机制解析

undefined

(Bonree Ants运行机制图)

 

1、数据预处理拓扑(PreProcessing Topology)

此拓扑负责从kafka订阅原始数据源并调用etl-plugin插件对数据进行预处理(etl-plugin插件由客户自己来实现),并对将etl后的结果进行准实时聚合处理(计算规则由用户在schema.xml中描述)。

如果用户想要备份etl后的原始明细数据,则只需在Schema.xml中开启相关配置,则由此拓扑在etl后把数据镜像一份发往kafka集群指定topic,由用户自行消费进行后续备份处理。

2、数据计算拓扑(Calculation Topology)

此拓扑负责对etl之后的数据进行按不同时间粒度的批量聚合(规则由Schema.xml描述)。此过程内部有两个子计算拓扑:小批量计算(分钟级),大批量计算(小时级和天级)。计算过程中小粒度的中间计算结果都会缓存到redis集群中,供下一大粒度计算使用。同时,各粒度计算结果会落地到kafka相应的topic,由“数据存储拓扑”订阅进行后续存储操作,从而实现数据计算和落地之间的解耦。

3、数据存储拓扑(Storage Topology)

此拓扑负责数据落地入库,落地数据包括两种,即时序指标数据(结构化)和快照文件数据(非结构化,如业务中存在此类数据的话)两种,用户需根据自身业务需要开发Storage-plugin来实现具体的落盘策略。

除此之外,Bonree Ants默认实现了两个重要的extension扩展,即基线计算extension和报警条件判断extension。

 

Bonree Ants创新企业大数据处理方式

 

Bonree Ants引擎框架自身与业务无耦合,数据处理流程高度抽象,通用性强,简洁开放的架构,较少的组件依赖,开发部署及维护成本低;秒级时延,实时性好,内置批量计算支持;支持extension机制,用户可自行丰富业务场景功能支持;内置多种容错策略,保证稳定与数据安全;同时,Bonree Ants提供强大的在线Web Console支持,可支持可视化管理和监控,具体功能包括如下:



1、APP管理

APP在线创建、Schema在线配置、APP发布上线、下线。

 

2、基础环境监控

zookeeper、storm、kafka、redis等基础集群运行状态监控。


 

3、日志监控

APP运行关键流程节点状态日志收集和监控。

 

Bonree Ants以小而美的理念,以灵活高效的计算方式快速处理企业数字化业务带来的庞大数据量,是企业提高大数据在线处理能力的智能大脑。

文章标签

智能运维

相关文章

FreeMarker template error (DEBUG mode; use RETHROW in production!): The string doesn't match the expected date/time/date-time format. The string to parse was: "2024年3月5日". The expected format was: "MMM d, y". The nested reason given follows: Unparseable date: "2024年3月5日" ---- FTL stack trace ("~" means nesting-related): - Failed at: #if "2024年3月5日"?date lt item.createTi... [in template "themes/halo_quickstarter/post_newsDetail.ftl" at line 106, column 25] ---- Java stack trace (for programmers): ---- freemarker.core._TemplateModelException: [... Exception message was already printed; see it above ...] at freemarker.core.BuiltInsForMultipleTypes$dateBI$DateParser.parse(BuiltInsForMultipleTypes.java:220) at freemarker.core.BuiltInsForMultipleTypes$dateBI$DateParser.getAsDateModel(BuiltInsForMultipleTypes.java:190) at freemarker.core.BuiltInsForMultipleTypes$dateBI$DateParser.getAsDate(BuiltInsForMultipleTypes.java:197) at freemarker.core.EvalUtil.modelToDate(EvalUtil.java:86) at freemarker.core.EvalUtil.compare(EvalUtil.java:270) at freemarker.core.EvalUtil.compare(EvalUtil.java:115) at freemarker.core.ComparisonExpression.evalToBoolean(ComparisonExpression.java:78) at freemarker.core.IfBlock.accept(IfBlock.java:49) at freemarker.core.Environment.visit(Environment.java:370) at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:321) at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271) at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:244) at freemarker.core.Environment.visitIteratorBlock(Environment.java:644) at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:108) at freemarker.core.IteratorBlock.accept(IteratorBlock.java:94) at freemarker.core.Environment.visit(Environment.java:334) at freemarker.core.Environment.visit(Environment.java:340) at freemarker.core.Environment.visit(Environment.java:340) at freemarker.core.Environment.process(Environment.java:313) at freemarker.template.Template.process(Template.java:383) at org.springframework.web.servlet.view.freemarker.FreeMarkerView.processTemplate(FreeMarkerView.java:391) at org.springframework.web.servlet.view.freemarker.FreeMarkerView.doRender(FreeMarkerView.java:304) at org.springframework.web.servlet.view.freemarker.FreeMarkerView.renderMergedTemplateModel(FreeMarkerView.java:255) at org.springframework.web.servlet.view.AbstractTemplateView.renderMergedOutputModel(AbstractTemplateView.java:179) at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:316) at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1401) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1145) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1084) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:497) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:584) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1631) at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:230) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at run.halo.app.cas.UserInfoFilter.doFilter(UserInfoFilter.java:37) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at org.jasig.cas.client.util.AssertionThreadLocalFilter.doFilter(AssertionThreadLocalFilter.java:54) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at org.jasig.cas.client.util.HttpServletRequestWrapperFilter.doFilter(HttpServletRequestWrapperFilter.java:75) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at run.halo.app.cas.MyAbstractTicketValidationFilter.doFilter(MyAbstractTicketValidationFilter.java:215) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at run.halo.app.cas.MyAuthenticationNoLoginFilter.doFilter(MyAuthenticationNoLoginFilter.java:57) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:102) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at run.halo.app.security.filter.ContentFilter.doAuthenticate(ContentFilter.java:69) at run.halo.app.security.filter.AbstractAuthenticationFilter.doFilterInternal(AbstractAuthenticationFilter.java:229) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at run.halo.app.filter.CorsFilter.doFilter(CorsFilter.java:53) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:96) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at run.halo.app.filter.LogFilter.doFilterInternal(LogFilter.java:40) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1601) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:548) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) at org.eclipse.jetty.server.Server.handle(Server.java:516) at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: freemarker.core.UnparsableValueException: Unparseable date: "2024年3月5日" at freemarker.core.JavaTemplateDateFormat.parse(JavaTemplateDateFormat.java:51) at freemarker.core.JavaTemplateDateFormat.parse(JavaTemplateDateFormat.java:33) at freemarker.core.BuiltInsForMultipleTypes$dateBI$DateParser.parse(BuiltInsForMultipleTypes.java:213) ... 118 more Caused by: java.text.ParseException: Unparseable date: "2024年3月5日" at java.base/java.text.DateFormat.parse(DateFormat.java:395) at freemarker.core.JavaTemplateDateFormat.parse(JavaTemplateDateFormat.java:49) ... 120 more