シークレット|セカンドレベルあたり千万リアルタイムデータ処理が実現する方法ですか?

著者:ビジー魚の技術 - ヤンジン

1、デザインの背景

        現在、忙しい魚実際の本番デプロイメント環境は、側板が間違っている部分は、縦がますます複雑な動作環境を頼っていた様々なサービスに依存して、ますます複雑になってきています。ときにサービスの問題、無料のサービス機能の重大な挑戦テストの魚になることにより、問題の根本に膨大な量のデータでタイムリーなポジショニング。
        ときに問題が10分を整列する必要があることが多い、またはさらに長く、問題の原因を見つけるために、そして健康の適用に関するので、高速自動診断システムの要件、および高性能なリアルタイムデータ処理システムの迅速な診断のための基礎です。
       :このリアルタイムデータ処理システムは、次の機能持っている必要があります
1、リアルタイムのデータ収集、複雑な計算のリアルタイム分析、解析の永続性を。
図2は、さまざまなデータを扱うことができます。アプリケーションログ、ホストのパフォーマンスモニタリング指標、コール・リンク・マップが含まれています。
3、高い信頼性。システムは問題なく、データが失われることはできません。
4、高性能、遅延の終わり。データ処理遅延が3秒以上、データ処理のため千万第二レベルのサポートではありません。
      この記事では、リアルタイムのデータリンクの全体的な設計を議論し、問題の詳細な解析モデル自動診断を必要としません。

図2に示すように、入力及び出力の定義

       次のようにシステムの動作を理解しやすくするために、我々はシステムの全体的な入力と出力を定義している:
 入力:
        サービス要求のログ(備えるTraceIDを用意、タイムスタンプ、クライアントIP、IPサーバ、時間がかかり、リターンコード、サービス名、メソッド名)
        環境監視データ(インデックス名、IP、タイムスタンプ、インデックス値)。このようなCPU、JVMのGC回、JVMのGC時間のかかるデータベースのインデックスとして。
出力:
        非循環有向グラフ表現を使用して、各サービスのための時間の期間にわたってサービス根本原因のエラー、エラーの分析結果。(すなわち、ルートノードは、ルート原因ミスノードがリーフノードでも異常であってもよい外部サービスJVMエラーに依存してもよいである、というようにリーフノードの誤った分析があります)。

3、アーキテクチャ設計

      実際のシステムで実行され、時間の経過とともに、ログデータと監視データは、定常流で生成されます。データは、それぞれが独自のタイムスタンプを持って生成されました。別の配管内の水の流れと同じタイムスタンプを持つこれらのデータをリアルタイムに伝送。

     

リアルタイムデータの安定した流れは、流水になぞらえ、そのデータ処理や水製造プロセスは類似している場合:

                  

当然のことながら、我々はデータを収集、伝達に分解され、リアルタイムに処理している、いくつかの段階に保存されている、事前に計算。
全体的なシステムアーキテクチャ設計、次のように:

                         

       コレクション

        SLSを用いた研究から、アリは(logtail + loghub成分を含む)、サービス製品のログを、クライアントlogtailコレクションで、logtailは、その優れた性能、高い信頼性と柔軟なプラグイン拡張メカニズムの選ばれた、あなたはあなた自身の余暇の魚をカスタマイズすることができますリアルタイム取得買収は、プラグインデータの多種多様の実装。

       トランスミッション

        loghubは、として理解することができるパブリッシュ・サブスクライブより安全、より安定したデータ伝送路、詳細な比較記事基準として、カフカのような成分データ、および機能を:https://yq.aliyun.com/articles/35979?spm=5176.10695662 .1996646101.searchclickresult.6f2c7fbe6g3xgP

       前処理

        (拡張バージョンに基づいてFLINK点滅インサイドオープンソースバージョンがFLINK呼ばれ、ALI)点滅演算処理コンポーネントを使用してリアルタイム・データ・ストリームを前処理します。オープンソースコンピューティング製品Jstorm、SparkStream、FLINKの最も一般的に使用されるリアルタイムのストリーミング。Jstormは、計算のない中間状態ので、計算中の中間結果Ioは、その性能に影響を与える頻繁原因となる外部記憶装置に依存必ずしも必要では、SparkStreamと本質的に小バッチリアルタイム計算をシミュレートするために、実際に存在します一定の遅延、完全なSQL式を提供しながら、フロー算出が容易となるよう、その優れた状態管理メカニズムのFLINKは、その性能とリアルタイムの計算を確実にします。

      コンピューティングと持続性

       数据经过预处理后最终生成调用链路聚合日志和主机监控数据,其中主机监控数据会独立存储在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、支持多租户的数据隔离。

おすすめ

転載: yq.aliyun.com/articles/706002