eBay Architecture(8)–Async Everywhere

  • Prefer Asynchronous Processing
  1.  
    1. Move as much processing as possible to asynchronous flows.
    2. Where possible,integrate disparate components asychronously.

为什么要这么做呢,同样的,我们从Architect考虑的5个方面来考察:

  • Motivations

使用异步方式以后,就把参与异步处理的几个模块解耦了,假设模块A和模块B是通过Queue或者Messaging Bus交互的,那A交给B一个请求,不需要等待B马上响应。这样也就意味着就算A和B的Capacity不同也可以协同工作。这就意味着在Scalability的角度我们可以独立的扩展(scale)A和B。而且从Availability来说,如果A调用B,B的Capacity不够甚至B down掉了,那也没有关系,因为A知道任务已经在B的Queue里面了,B待会(或者Up以后)去处理这些任务的。

什么事情都是有两面性的,你这里占了便宜,那里就要吃亏一点点。异步方式能提高用户体验,因为用户不用等所有的事物做完以后才得到相应,eBay可以先给用户事件响应,把耗时的工作异步完成。代价是增加了数据执行的时间(data/execution latency)。

异步操作一个更显著的好处是成本。如果我们所有的操作都是同步的,这就意味着我们需要按照Peak Load来build infrastructure。而异步操作的设计是按照Average Load来做的。因为异步能够把Peak Load的任务"延迟"(queueing)到系统稍微空闲一点的时间来做[damping]。

Scalability : can scale components independently
Availability
    • Can decouple availability state
    • Can retry operations
Latency
    • Can significantly improve user experience latency at cost of data/execution latency
    • Can allocate more time to processing than user would tolerate
Cost: can spread peak load over time

我们常用的Async的方法有:

  • Asynchrony Patterns
  1.  
    1. Message Dispatch
    2. Periodic Batch

 

Async Everywhere[Message Dispatch]:Event Streams

Randy用了两个例子来解释Message Dispatch。分别是Event Streams和Search Feeder Infrastructure。

Event Streams

  1. Primary use case produces event
    • E.g.,ITEM.NEW, BID.NEW, ITEM.SOLD, etc.
    • Event typically created transactionally with insert/update of primary table.
  2. Consumers subscribe to event
    • Multiple logical consumers can process each event.
    • Each logical consumer has its own event queue.
    • Within each logical consumer, single consumer instance processes event.
    • Guaranteed at least once delivery; no guaranteed order.
  3. Managing timing conditions
    • Idempotency: processing event N times should give same results as processing once.
    • Readback: consumer typically reads back to primary database for latest data.

     

用一个常见的例子来说明上面的文字。让用户list an new item或者bid an item的时候,会在数据库表中插入或者更新一些记录,于此同时,一个相应的事件Event创建了。

我们有很多的Logical Event Consumers在侦听他们所感兴趣的事件,比如刚才的Item.New事件,我们有Image Processing的Consumer来处理用户上传的图片;我们有用于Summary Update的Consumer…很多很多。这些逻辑Event Consume都有自己的Event Queue。这就是说Consumer之间是独立的。这样的设计也非常容易Scale,只需要增加更多的Consumer就可以了。

接下来就是时序的问题,因为异步往往不能保证时序。事件的处理有可能是out of order的。这里有两个概念:

Idempotency:http://en.wikipedia.org/wiki/Idempotent ,而在这里,我们更关心的是 the ability of a system to produce the same outcome, even if an event or message is received more than once.

ReadBack这个概念也很精巧,类似于By Reference,其实所有的Event本身都不carry database data。他们总是去数据库拿最新的数据。

<注:关于时序问题,我觉得Randy这里的解释还是比较抽象的,最好有一个实际的例子能够帮助我们理解,我再去问问,不知道CDC有没有做Messaging的group。>

 

 

Async Everywhere[Search Feeder Infrastructure]

这篇Blog给出了eBay Search Engine的整个架构。而这个架构正是Message Dispatch的另一个非常好的实例。要不是Randy来给我们做演讲而促使我去网上搜索eBay Architecture的文章,我还真没有想到这样的架构也是公开的。

先看一下架构图:

简单来说,Search Feeder的工作就是从存放Item信息的Primary DB中提取数据,处理后填入Search Infrastructure中。Feeder会不停的(定时的)查看Primary DB中是不是有数据更新,将更新数据提取(constantly polling)出来,做一些内部的处理以后,把“更新”publish给所有的search nodes。而每个search nodes会侦听自己感兴趣的更新信息来更新自己,如果search nodes发现自己有“更新”"漏听"了的话,他们会要求feeder重发更新。

从使用的技术的概念上讲,其实就是Message Dispatching。

  • Feeder reads item updates from primary database
  • Feeder publishes updates via reliable multicast
    1. Persist messages in intermediate data store for recovery
    2. Publish updates to search nodes
    3. Resend recovery messages when messages are missed
  • Search nodes listen to updates
    1. Listen to assigned subset of messages
    2. Update in-memory index in real time
    3. Request recovery

这里有一些我想补充一下,怎么理解Listen to assigned subset of messages?看看上面的图,search nodes是划分(Partition)成一个个Column的,Column的切分方式是预定义好的,一个Column中的Search Nodes是完全一样的,所以Search Nodes只关心划分在自己所在的Column中的更新。还有就是eBay的搜索引擎一个重要的特征就是real time。item的更新应该迅速反反映到搜索引擎中去,不能出现搜索结果上说当前的竞价已经到了200元,而用户点进去一看已经到250元了。更不能说搜索结果上显示物品还没有卖掉,用户点进去看发现已经卖掉了…

图中还有一个细节,就是Search DB。一般不是做Backend的人还不会注意到这点。这个Search DB很重要,目的是为了保留Persistency的信息。整个系统是很精巧的,聚集了当年eBay第一代自主开发自己的搜索引擎的那些元老们的智慧。从个人来说,我很佩服那帮人,他们真的是因为有激情,才做成了这件事情的!我听过这个故事,当年eBay使用的是一个第三方的搜索引擎,一直出问题,情况已经到了很难应付  eBay日益加大的Traffic的地步了,这时候有几个"年轻人"站出来对公司的领导说:"给我们一年时间,我们可以做一个全新的,能够应付将来好多年的搜索引擎!", 领导也很有魄力,于是这些"年轻人"加班加点,最后真的把这件事情做成了!很敬佩他们。

 

 

Async Everywhere[Batch]

Batch是Randy在他的演讲中提到的异步处理的技术中的最后一个例子。Randy是这么引入Batch这个话题的:
"如果你去互联网上看热门的技术文章,人们似乎并不再热衷于Batchle ,大家更多谈论的是Message Driven或者Event Driven的系统,但是实际使用中,有太多的情况Batch是最好的选择。"

比如说 Scheduled Process,那些每个小时运行一次,或者每天运行一次的任务,每周运行一次的任务…还有一种情况Batch也很适用,就是那些要处理所有的或者一大批数据的,而不是只处理特定的一个两个或者一小部分的时候。Randy叫做"Full Table Scan"的任务。

Pattern: Periodic Batch

  • Scheduled offline batch process
  • Most appropriate for
    1. Infrequent, periodic, or scheduled processing (once per day, week, month)
    2. Non-incremental computation (a.k.a. “Full Table Scan”)

Batch在eBay中应用的典型例子有:从第三方导入数据,比如Catalog信息,汇率信息…产生推荐信息,推荐物品(item)啦,产品(products)啦,等等等等….

  • Examples
    1. Import third-party data (catalogs, currency, etc.)
    2. Generate recommendations (items, products, searches, etc.)
    3. Process items at end of auction

这里提到一个例子:Process items at end of auction! Auction是eBay的核心业务之一,Seller登录一个物品,设定一个时间,比如说7天,在这7天里面大家去竞价,7天时间到,价高者得之。在7天结束的那个时间点,没有Event被产生,eBay处理这种情况的方法是 定时跑Batch来发现所有的已经end of action的物品,然后统一产生一个Event来处理。

  • Often drivers further downstream processing through Message Dispatch

<注:
说实话,对最后一点Often drivers further downstream processing我并没有完全理解,说没有完全理解是因为来一个项目,我目前无法判断在downstream processing的时候是不是要使用Batch,比如上面的end of action的情况,怎么来处理time of end action和batch runnung的时间差呢?怎么就不能再end of action的时候发一个Event呢?
>

 

你可能感兴趣的:(搜索引擎,search,processing,asynchronous,Components,Scalability)