监控项目分析报告-系统架构

通过上面的需求分析可以清晰地看到整个监控系统外部的数据流:

  1. 接收数据流很大,送出数据流很小;
  2. 接收数据流为内容数据,送出数据流为控制数据;
  3. 内容数据在系统两端进行处理,前端机器处理为硬实时(秒级),后端人工处理为软实时(时级);
  4. 控制数据在系统两端都有送出,送出时间与其对应的内容数据处理的时间点一致,处理完内容数据即送出。控制数据内容为对应各个产品对其产品内容数据的控制动作。

数据流在内部流动为单向流动,即某份数据一旦处理过就交给处理流水的下一个结点而一去不复返。但由于机器处理速度远远大于目前条件下人工处理速度,因此内部数据流动过程中,需要一个缓冲队列或缓冲池来做数据缓冲工作。而且缓冲队列需要满足容量大而且提取速度快两个条件:容量大是因为数据入队(各个产品内容生产)速度大于出队(网安人员审核内容)速度;速度快是因为网安人员需在线提取队列中的内容,因此需要保证响应时间尽量短(秒级)。内部数据流除了需要正常流动外,还需要特殊机制来保证数据送往审核前台时的非重复、分类和批量操作,也就是数据流分流处理(分类与批量)与出口加锁(防重复),监控系统采用如下图所示的缓冲机制:data_cache2

 

 容量大,自然会想到关系型数据库(本设计中使用mysql)。如果审核前台直接使用数据库存,这就需要数据库的数据自我描述来完成分类、防重复及批量操作,比如加个字段说明该条目是否已经取走,前期的机器处理已经将分类与批量信息留在数据库。但有一条无法满足,即速度快。因为即便此库只保留一天的数据,那么处理到中午时数据库中数据量已经达到4-5万,由于执行sql语句时需要众多的判断条件(分类,子产品,是否已经被取走),这时前台的响应会越来越慢。因此就需要将这部分耗时及大的判断逻辑从前台的请求中拿出单独处理,从而降低前台的响应时间。如何拿呢?

  1. 单独(指与前台提取条目相互独立)设计一个判断程序,将其判断结果缓存;
  2. 前台每次拿到缓存结果后直接取数据库中的对应条目;
  3. 前台读缓存的速度要极快,那就使用内存型key-value式数据库(redis);
  4. 前台从redis拿到结果后,到数据库中拿条目应该也是极快,那么就将结果对应数据库中的列进行索引处理,即条目的唯一id;
  5. 前台拿缓存结果时,也是key-value式,在O(1)的时间内确定应该拿哪些条目。数据库的分表,redis的分产品与分类id分队列某种意义上也是key-value式存储;
  6. 当然这里使用redis,就可以用redis的队列机制很容易实现防重复,即条目不会被多个审核人员重复审核。

这样,数据流在系统内部按照业务要求流动就很好地满足了。此时,我们可以看到整个系统的架构如下图所示:monitor_arch2

 

从监控架构可以看出,过滤器处于至关重要的位置,由它来得到数据的内容分类与审核级别。我们还可以看到审核前台有数据送到‘过滤依据’中,即审核人员会不停地调校这个生成机器过滤器,即修改其生成数据。从整个系统层面去观察,(将审核人员也作为系统的一部分),即整个系统是一个自学习的,可以根据产品数据的变化来动态改变其审核策略。

现在整个系统的大数据流的系统架构已经清晰,下面开始分析如何处理各个数据流,及各个大模块内部的架构:http与tcp服务器。

尽管nginx可以实现多个http服务器同时提供过滤服务,试想当所有的sohu的产品接入后,post量是相当大的,这时就必需考虑性能问题,而不是仅仅靠nginx与加机器节点来完成。很容易看出,这无非是一个高并发的http服务。下面我们就分析每个服务:

一个数据过来后,需要进行各种过滤,这其中有I/O动作也有cpu动作。

上面加粗部分是关键,异步事件处理是解决多I/O高并发服务的利剑,尤其是web服务。最终选用了采用协程模型的gevent框架来实现异步处理。这样,每个http服务器就可以为多个post数据提供过滤服务并且保证实时响应。关于gevent框架的介绍详见下面的关键技术一章。同样,对于tcp服务器,面对的也是多个审核人员,虽然其并发数不多,但同样可以采用异步处理来提高并发性能。这样,系统架构可以具体为下图:monitor_arch-new

发表评论