storm应用从数据源读取数据

2018-06-28 21:28:04 admin

storm曾经有将近3年时间,稳定支撑着实时统计、数据同步、对账、监控、风控等业务。订单实时统计是其中一个典型的业务,对数据精确性、性能等方面都有较高请求,也是上线时间最久的一个实时计算应用。经过订单实时统计,描绘运用storm时,遇到的精确性、性能、牢靠性等方面的问题。

订单实时统计的演进

第一版:流程走通

在运用storm之前,显现实时统计数据普通有两种计划:

在数据库里执行count、sum等聚合查询,是简单快速的完成计划,但容易呈现慢查询。

在业务代码里对统计指标做累加,能够满足指标的快速查询,但统计逻辑耦合到业务代码,维护不便当,而且错误数据定位和修正不便当。

既要解耦业务和统计,也要满足指标快速查询,基于storm的实时计算计划能够满足这两点需求。

一个storm应用的根本构造有三局部:数据源、storm应用、结果集。storm应用从数据源读取数据,经过计算后,把结果耐久化或发送音讯给其他应用。

第一版的订单实时统计构造如下图。在数据源方面,最早尝试在业务代码里打日志的方式,但总有业务分支无法掩盖,采集的数据不全。我们的业务数据库是mysql,随后尝试基于mysql binlog的数据源,采用了阿里开源的canal,能够做到完好的搜集业务数据变卦。

在结果数据的处置上,我们把统计结果耐久化到了mysql,并经过另一个后台应用的RESTful API对外提供效劳,一个mysql就能够满足数据的读写需求。

为了提升实时统计应用吞吐量,需求提升音讯的并发度。spout里设置了音讯缓冲区,只需音讯缓冲区不满,就会源源不时从音讯源canal拉取数据,并把分发到多个bolt处置。

第二版:性能提升

第一版的性能瓶颈在统计结果耐久化上。为了确保数据的精确性,把一切的统计指标耐久化放在一个数据库事务里。一笔订单状态更新后,会在一个事务里有两类操作:

订单的历史状态也在数据库里存着,要与历史状态比照决议统计逻辑,并把最新的状态耐久化。storm的应用自身是无状态的,需求运用存储设备记载状态信息

当大家晓得实时计算好用后,各产品都希望有实时数据,统计逻辑越来越复杂。店铺、商品、用户等多个指标的写操作都是在一个事务里commit,这一简单粗暴的方式早期很好满足的统计需求,但是关于update操作持有锁时间过长,严重影响了并发才能。

为此做了数据库事务的瘦身:

去除历史状态的mysql耐久化,而是经过单条binlog音讯的前后状态比照,决议统计逻辑,这样就做到了统计逻辑上的无状态。但又产生了新问题,如何保证音讯有且只要处置一次,为此引入了一个redis用于保管最近24小时内已胜利处置的音讯binlog偏移量,而storm的音讯分发机制又能够保证相同音讯总是能分配到一个bolt,防止线程平安问题。

统计业务拆分,先是线上业务和公司内部业务别离,随后又把线上业务按不同产品拆分。这个不只仅是bolt级别的拆分,而是在spout就完整分开

随着统计应用拆分,在canal和storm应用之间加上音讯队列。canal不支持多消费者,而实时统计业务也不用关系数据库底层迁移、主从切换等维护工作,加上音讯队列能把底层数据的维护和性能优化交给更专业的团队来做。

热点数据在mysql里做了分桶。比方,通常一个店铺天级别的统计指标在mysql里是一行数据。假如这个店铺有突发的大量订单,会呈现多个bolt同时去update这行数据,呈现数据热点,mysql里该行数据的锁竞争异常剧烈。我们把这样的热点数据做了分桶,实考证明在特定场景下能够有一个数量级吞吐量提升。

最终,第二版的订单实时统计构造如下,主要变化在于引入了MQ,并运用redis作为音讯状态的存储。而且由最初的一个应用,被拆成了多个应用。

为您推荐