Secret | ten million real-time data processing per second level is how to achieve?

Author: Busy fish technology - Yang Jing

1, design background

        Currently busy fish actual production deployment environment has become increasingly complex, dependent on a variety of services lateral plate were wrong section, longitudinal rely increasingly complex operating environment. When service problems, the timely positioning in the vast amounts of data to the root of the problem due to become a serious challenge test fish free service capabilities.
        When a problem is often necessary to line ten minutes, or even longer to find the cause of the problem, and therefore a fast automatic diagnostic system requirements on the application of Health, and is a basis for rapid diagnosis of high-performance real-time data processing system.
       This real-time data processing system needs to have the following capabilities:
1, real-time data collection, real-time analysis of complex calculation, analysis persistence.
2, can handle a wide variety of data. Contains the application log, host performance monitoring indicators, call link map.
3, high reliability. The system no problem and the data can not be lost.
4, high-performance, the end of the delay. Data processing delay is not more than 3 seconds, ten million second-level support for data processing.
      This article does not involve a detailed analysis model automatic diagnosis of the problem, only discuss the overall design of real-time data link.

2, the definition of input and output

       For ease of understanding the operation of the system, we define the overall input and output of the system is as follows:
 Input:
        service request log (TraceID comprising, a timestamp, client IP, IP server, time-consuming, return code, service name, method name)
        environment monitoring data (index name, ip, timestamp, index value). Such as cpu, jvm gc times, jvm gc time-consuming database index.
Output:
        a service over a period of time the root cause error, error analysis results for each service using a directed acyclic graph expression. (That is, the root node is erroneous analysis of the leaf node that is the root cause mistakes node is a leaf node may be dependent on external service jvm error may also be abnormal, and so on).

3, architecture design

      In the actual system is running, over time, the log data and the monitoring data is generated in a steady stream. Data generated each has its own timestamp. Real-time transmission of these data with the same time stamp as the water flow in different pipes.

     

If a steady stream of real-time data likened to running water, and that data processing and water production process is similar:

                  

Naturally, we are processing the real time data is decomposed into the collection, transmission, pre-calculated, stored in several stages.
The overall system architecture design as follows:

                         

       collection

        Ali from research using the sls log service product (containing logtail + loghub component), is a collection logtail client, logtail was chosen because of its excellent performance, high reliability and its flexible plug-in extension mechanism, you can customize your own leisure fish real-time acquisition acquisition plug-in implementation of a wide variety of data.

       transmission

        loghub can be understood as a publish-subscribe component data, and functions like kafka, as a data transmission channel which is more stable, more secure, detailed comparison article reference: https://yq.aliyun.com/articles/35979?spm=5176.10695662 .1996646101.searchclickresult.6f2c7fbe6g3xgP

       Pretreatment

        Preprocessing real-time data stream using blink calculation processing component (open source version is called flink, Ali inside flink blink on the basis of enhanced versions). The most commonly used real-time streaming of open source computing products Jstorm, SparkStream, Flink. Jstorm Since no intermediate state of the computation, intermediate results during the calculation required necessarily depend on an external storage, which will cause frequent io affect its performance; with the SparkStream essentially small batch to simulate real-time calculation, there are in fact certain delay; Flink because of its excellent state management mechanisms to ensure its performance and real-time calculations, while providing a complete SQL expression, so that the flow calculation easier.

      Computing and persistence

       数据经过预处理后最终生成调用链路聚合日志和主机监控数据,其中主机监控数据会独立存储在tsdb时序数据库中,供后续统计分析。tsdb由于其针对时间指标数据的特别存储结构设计,非常适合做时序数据的存储与查询。调用链路日志聚合数据,提供给cep/graph service做诊断模型分析。cep/graph service是闲鱼自研的一个应用,实现模型分析、复杂的数据处理以及外部服务进行交互,同时借助rdb实现图数据的实时聚合。
       最后cep/graph service分析的结果作为一个图数据,实时转储在lindorm中提供在线查询。lindorm可以看作是增强版的hbase,在系统中充当持久化存储的角色。

4、设计细节与性能优化

采集

      日志和指标数据采集使用logtail,整个数据采集过程如图:

 

其提供了非常灵活的插件机制,共有四种类型的插件:

  • inputs: 输入插件,获取数据。
  • processors: 处理插件,对得到的数据进行处理。
  • aggregators: 聚合插件,对数据进行聚合。
  • flushers: 输出插件,将数据输出到指定 sink。

      由于指标数据(比如cpu、内存、jvm指标)的获取需要调用本地机器上的服务接口获取,因此应尽量减少请求次数,在logtail中,一个input占用一个goroutine。闲鱼通过定制input插件和processors插件,将多个指标数据(比如cpu、内存、jvm指标)在一个input插件中通过一次服务请求获取(指标获取接口由基础监控团队提供),并将其格式化成一个json数组对象,在processors插件中再拆分成多条数据,以减少系统的io次数同时提升性能。

传输

     数据传输使用LogHub,logtail写入数据后直接由blink消费其中的数据,只需设置合理的分区数量即可。分区数要大于等于bink读取任务的并发数,避免blink中的任务空转。

预处理

预处理主要采用bink实现,主要的设计和优化点:

1:编写高效的计算流程

blink是一个有状态的流计算框架,非常适合做实时聚合、join等操作。
在我们的应用中只需要关注出现错误的的请求上相关服务链路的调用情况,因此整个日志处理流分成两个流:
a、服务的请求入口日志作为一个单独的流来处理,筛选出请求出错的数据。
b、其他中间链路的调用日志作为另一个独立的流来处理,通过和上面的流join on traceid实现出错服务依赖的请求数据塞选。

       如上图所示通过双流join后,输出的就是所有发生请求错误相关链路的完整数据。

2:设置合理的state生存周期

       blink在做join的时候本质上是通过state缓存中间数据状态,然后做数据的匹配。而如果state的生命周期太长会导致数据膨胀影响性能,如果state的生命周期太短就会无法正常关联出部分延迟到来的数据,所以需要合理的配置state生存周期,对于该应用允许最大数据延迟为1分钟。

使用niagara作为statebackend,以及设定state数据生命周期,单位毫秒
state.backend.type=niagara
state.backend.niagara.ttl.ms=60000

3:开启 MicroBatch/MiniBatch

       MicroBatch 和 MiniBatch 都是微批处理,只是微批的触发机制上略有不同。原理上都是缓存一定的数据后再触发处理,以减少对 state 的访问从而显著提升吞吐,以及减少输出数据量。

开启join
blink.miniBatch.join.enabled=true
使用 microbatch 时需要保留以下两个 minibatch 配置
blink.miniBatch.allowLatencyMs=5000
防止OOM,每个批次最多缓存多少条数据
blink.miniBatch.size=20000

4:动态负载使用 Dynamic-Rebalance 替代 Rebalance

        blink任务在运行是最忌讳的就是存在计算热点,为保证数据均匀使用Dynamic Rebalance,它可以根据当前各subpartition中堆积的buffer的数量,选择负载较轻的subpartition进行写入,从而实现动态的负载均衡。相比于静态的rebalance策略,在下游各任务计算能力不均衡时,可以使各任务相对负载更加均衡,从而提高整个作业的性能。

开启动态负载
task.dynamic.rebalance.enabled=true

5:自定义输出插件

        数据关联后需要将统一请求链路上的数据作为一个数据包通知下游图分析节点,传统的方式的是通过消息服务来投递数据。但是通过消息服务有两个缺点:
1、其吞吐量和rdb这种内存数据库相比比还是较大差距(大概差一个数量级)。
2、在接受端还需要根据traceid做数据关联。
      我们通过自定义插件的方式将数据通过异步的方式写入RDB,同时设定数据过期时间。在RDB中以数据结构存储。写入的同时只将traceid做为消息内容通过metaQ通知下游计算服务,极大的减少了metaQ的数据传输压力。

图聚合计算

      cep/graph计算服务节点在接收到metaQ的通知后,综合根据请求的链路数据以及依赖的环境监控数据,会实时生成诊断结果。诊断结果简化为如下形式:
                         

       说明本次请求是由于下游jvm的线程池满导致的,但是一次调用并不能说明该服务不可用的根本原因,需要分析整体的错误情况,那就需要对图数据做实时聚合。
       聚合设计如下(为了说明基本思路,做了简化处理):
       1、首先利用redis的zrank能力为根据服务名或ip信息为每个节点分配一个全局唯一排序序号。
       2、为图中的每个节点生成对应图节点编码,编码格式:
            对于头节点:头节点序号|归整时间戳|节点编码
            对于普通节点:|归整时间戳|节点编码
       3、由于每个节点在一个时间周期内都有唯一的key,因此可以将节点编码作为key利用redis为每个节点做计数。同时消除了并发读写的问题。
       4、利用redis中的set集合可以很方便的叠加图的边。
       5、记录根节点,即可通过遍历还原聚合后的图结构。
       聚合后的结果大致如下:
                     
       这样最终生成了服务不可用的整体原因,并且通过叶子节点的计数可以实现根因的排序。

5、收益

        系统上线后,整个实时处理数据链路的延迟不超过三秒。闲鱼服务端问题的定位时间从十多分钟甚至更长时间下降到五秒内。大大的提升了问题定位的效率。

6、未来展望

        目前的系统可以支持闲鱼每秒千万的数据处理能力。后续自动定位问题的服务可能会推广到阿里内部更多的业务场景,随之而来的是数据量的成倍增加,因此对于效率和成本提出了更好的要求。
       未来我们可能做的改进:
1、能够自动的减少或者压缩处理的数据。
2、复杂的模型分析计算也可以在blink中完成,减少io,提升性能。
3、支持多租户的数据隔离。

Guess you like

Origin yq.aliyun.com/articles/706002