文章目錄
  1. 1. Google’s Photon: Fault-tolerant and Scalable Joining of Continuous Data Streams 翻译
    1. 1.1. 引言
    2. 1.2. 用例分析
      1. 1.2.1. 问题重描述
      2. 1.2.2. 挑战
      3. 1.2.3. Contribution
    3. 1.3. PAXOS-BASED ID REGISTRY
      1. 1.3.1. IdRegistry Server Architecture
      2. 1.3.2. Scalable IdRegistry
        1. 1.3.2.1. Server-side Batching
        2. 1.3.2.2. Sharding
      3. 1.3.3. Deleting Old Keys
    4. 1.4. SINGLE DATACENTER PIPELINE

Google’s Photon: Fault-tolerant and Scalable Joining of Continuous Data Streams 翻译

引言

做的事情还是stream processing里的join。如果说主要的特色,那就是应用场景以及可靠性了。Photon是一个地理上分布的,低延时,高可靠,支持 at-least once以及nearly exactly once语义的 stream join系统。

Photon用于Google的广告系统中,主要用来将query与user action进行join操作以期望获得多的广告相关信息(billing/business metrics)。性能达到100w/s且端到端的延时小于10s。

弱弱的吹一句水,如果不是地域分离,我们蓝汛的日志都到了200w/s了。

用例分析

首先,join用户操作很重要,比如用户如下操作

  1. 搜索关键词,即query,系统分配query_id,产生搜索结果
  2. 用户看了一会,click了几个结果
  3. 用户又看了一会,又click了几个结果

Server显然知道每次操作,可以对这些操作生成日志,写入GFS,这没有问题。但问题在于我们如何将这三个信息有效的结合在一起?

显然结合这两部操作可以获得更多信息(比如哪个搜索结果更符合等等)。但这两部分操作在时间上是分开进行的。将1-2,1-3结合很容易,可以直接在每次http请求的时候带上query内容,但如何将2-3迅速结合呢?都入库再查询?想想都慢。

等灯等灯,Photon出场。就是用于解决这个问题的。

问题重描述

我们将query log以及click log抽象成两条数据流,因此问题变成系统持续输入两条事件流,输出应该是将其join之后的结果。

那么从数据库的角度从新理一遍吧:query以及click分为两张表,通过一个外键(foreign key)关联。logstream就类似主表,而clickstream就类似外表,最后,join操作就是就是inner join。而结果就是join之后组合在一起的结果。

挑战

  • Exactly Once语义

谁用谁头疼,说起来简单地事情做起来其实很难的,尤其在高吞吐的环境下eactly once 是个异常坑爹的要求。

Wall Street 要求real-time达到exactly Once,一两个小时之内达到完美exactly once。

  • Data Center Level Fault Tolerance

既然跨了data center,可能datacenter 由于各种原因挂掉1min~几天。很多系统GFS、Bigtable是支持部分节点终端的,但是还是无法抵御大规模datacenter级别的挂掉的。与此同时,如果集群挂掉还依靠人工手动在另一个机房搭建环境显然困难重重而且降低可用性。

所以我们支持了机房级容灾。

  • 高扩扩展低延时

系统标配,少废话。

  • 乱序 以及 主表数据延时

多点发送必然存在乱序

Contribution

exactly once + 机房级容灾

PAXOS-BASED ID REGISTRY

容错最简单的办法之一就是replication,因此可以相同的系统部署在不同的机房。对G的很多搜索以及广告服务这都是非常可行的,通过load balance自动将user request分发到最近可用的机器上。

但如果对Photon执行replicatation,多套系统针对同一个数据源,同时执行。需要保证最终的记过只有一套,不然你多计费了,广告主是不会高兴的。因此需要replication之间进行去重,因此需要使一些关键数据能够在worker之间进行share,例如前N天的clickid,即IdRegistry。其中N可以根据存储数量以及 the cost of dropping events that are delayed by more than N days进行选择。注意N天之前的数据时必须被扔掉的,因为已经无法被判重复了。

这样worker的逻辑就相对简单了,worker输出之前,判一下IdRegistry有没有eventid已经存在。如果不存在,需要在先写入eventid,然后输出,同时,IdRegistry需要保证写入同一个eventid的request 会失败。所以,这个问题被转化为另一个问题:

  • IdRegistry需要在多个机房部署,并且可以同步写入(强一致写入类似的)。并且其容忍的可down机房数量需要可配置。

  • Worker需要实现conditional commits, 没有才能写入操作。

所以我们在Paxos的基础上实现了个IDRegistry。The algorithm guarantees synchronous replication of submitted values across the majority of replicas.
图1

在这里有一个photon Pipline的概念,在每个datacenter都有photon pipline。每个pipline处理(这里我理解的处理应该就是做join操作)所在的data center中的全部数据(因为在G,userlog 会被分发到地理隔离的不同的datacenter中)。

Each pipeline keeps retrying until the event is joined (i.e., written to the IdRegistry), which guarantees that each event is processed at least once by the system with minimal loss.

上面这句话写的很烂,尽力尝试,尽力尝试什么啊,你说清楚会死么。

IdRegistry Server Architecture

Scalable IdRegistry

Server-side Batching

Sharding

Deleting Old Keys

SINGLE DATACENTER PIPELINE

文章目錄
  1. 1. Google’s Photon: Fault-tolerant and Scalable Joining of Continuous Data Streams 翻译
    1. 1.1. 引言
    2. 1.2. 用例分析
      1. 1.2.1. 问题重描述
      2. 1.2.2. 挑战
      3. 1.2.3. Contribution
    3. 1.3. PAXOS-BASED ID REGISTRY
      1. 1.3.1. IdRegistry Server Architecture
      2. 1.3.2. Scalable IdRegistry
        1. 1.3.2.1. Server-side Batching
        2. 1.3.2.2. Sharding
      3. 1.3.3. Deleting Old Keys
    4. 1.4. SINGLE DATACENTER PIPELINE