RTB广告中的Cookie Matching

原文:https://developers.google.com/ad-exchange/rtb/cookie-guide 2014年2月14日最后更新

译文:刘佳明@百川广告

Cookie匹配(Cookie Matching)是什么?

简单说来,就是DSP域的cookie与Ad Exchange域的User ID的关联。Ad Exchange提供Cookie匹配服务(Cookie Matching Service),这使得流量购买方(DSP)能够关联如下两类数据:

  1. DSP域的用户Cookie,以标识DSP域的用户。
  2. Doubleclick.net域的用户Cookie,以标识Google用户。(针对每个用户,Google为各DSP提供经加密过的专属于该DSP的Google User ID, 以便该DSP来匹配这一User ID。)

DSP用来维护这两类数据的关联的数据结构,就是匹配表(Matching Table)。DSP负责构建和维护各自的匹配表,而Google则可以为之提供托管。

对一个RTB应用来说,对于某个由Google User ID标识的具体用户,DSP可以对针对这个用户的印象展示(Impression)进行竞价(使用跟这一Google User ID相关联的信息作为竞价依据)。谷歌宣称如果交给它托管匹配表,会简化这一整合过程,减少延迟,blablabla。

背景知识
浏览器cookie通常是由拥有该cookie所属域的域名的一方设置的。该Cookie就标识了在该域名下的这个用户。浏览器安全模型(Browser Security Model)限制了一方不能读取由另一方设置的cookie,即使他们双方同意这种交换(我读你的,你读我的)。流量购买方通常使用第三方广告网络平台(DSP)域的cookie来识别用户,并为此建立从这一cookie到用户信息的数据库索引。

Google自己使用自己旗下的doubleclick.net域的用户cookie来识别用户。对各DSP来说,Google使用专属于该DSP的Google User ID来识别用户,这一ID是取自doubleclick.net域的用户cookie并经过加密后的派生版本。Google将这一Google User ID传给对应的DSP(原始的DoubleClick cookie是绝不会外传的)。

当第一次接收到某个Google User ID的时候,DSP中没有与该Google User ID相关联的用户信息(竞价请求所揭示的用户信息除外)。DSP这时可以将该Google User ID与自身的域的Cookie建立关联,并在后续针对该Google User ID做决策时利用该用户信息。这无论对再营销(remarketing campaign),还是精准人群定向(targeting),或者是使针对印象展示的竞价更精确,都是有用的。

Cookie匹配服务,以匹配表作为数据结构,提供了广告购买方网络(buyer network, 即DSP)所需的DSP cookie与Google User ID之间的关联信息。并且,DSP还可以提供额外的数据让Google来存储并应用到后来的竞价请求中。

匹配表托管的好处

Google说选择让它托管匹配表的DSP享有如下优势:

  •  DSP自身所需的基础设施支持更少
  • 将Google User ID映射到某一有用格式不再需要查表
  • 在预定向(pre-targeting)阶段,有一个选项是说,是否以该Cookie的对应的匹配的有无来进行过滤。

Cookie匹配是如何工作的?

要在匹配表中建立某一关联,DSP必须提供由Google提供给它的标签,叫做匹配标签(Match Tag)。匹配标签可以和广告一起提供,也可以在广告之外单独置于其页面属性(web properties)上。其结构如下:

此处的 1234 就是由Google提供的DSP标识。

DSP应该只在不具有该用户的匹配信息(或者该匹配信息已失效)时才提供匹配标签。

每当接收到用户浏览器发来的带有DSP标签的请求时,Google会以要用户跳转到DSP的302重定向(302 redirect)作为应答。这一重定向的URL中包含了Google User ID和版本号,请求的头部(request headers)则包含了DSP cookie。DSP提供基础 URL(作为跳转入口,译者注),而Google则在此之上添加URL参数。

比如,DSP提供如下基础URL:

Google就可以重定向用户的浏览器到如下URL:

通过google_gid参数传递的Google User ID是一unpadded, URL-safe的base64编码字符串。Google建议,将由Cookie匹配服务返回的该字符串存到匹配表中。

注意:Protocol buffer中的BidRequest类的google_user_id字段就是对应由Cookie匹配服务对应的Google User ID的。

至于google_cver参数,则表示Google User ID对应的数值版本号。Google可能偶尔会改变其cookie模糊方案(cookie obfuscation scheme),那时就会增加google_cver的值。

DSP接收到这条在请求头部包含了DSP cookie的重定向请求之后,更新匹配表以建立DSP cookie与Google User ID之间的关联,然后必须提供一1×1像素的不可见的图片给用户浏览器, 或者返回一204 无内容(204 No Content)的应答。

往匹配表(Match Table)中添加条目跟将匹配标签(Match Tag)提供给用户是以相同的速率进行的。

这一过程可以用下图来说明,所有请求或响应用箭头来表示,而伴随请求或响应的数据项则在括号中标明。

cookie_matching

DSP可以在请求上设置额外的URL参数,它们最终会在重定向时传给DSP的Cookie Mapping服务器。

所有不以google_前缀开头的参量都会直接被拷给重定向URL。传给Cookie匹配服务的参数的次序无关紧要,而额外阐述传给重定向URL的顺序也不能保证。

DSP可以使用这些参数来传递额外的关于这次展示的信息,只是这些参量不能长于1KB.

使用https而非http来请求Cookie匹配服务当然也是可以的,这种情况下,重定向URL的协议也相应变为https而非http.

场景举例:

对Web用户来说,cookie匹配是什么样子? 其幕后又发生了些什么?我们通过两个场景来介绍一下:

场景1:Cookies已清空

Jane清空了所有cookie的缓存。然后她访问ExampleNews.com的主页。

看看发生了些什么:

  1. ExampleNews.com渲染页面,并向Google(针对广告位发布商的DoubleClick,即DoubleClick for Publishers)请求广告。
  2. 由于该广告单元是符合动态分配条件的,Ad Exchange向FinestDSP及其他DSP发送竞价请求。
  3. FinestDSP的bid engine(竞价引擎)程序负责处理该竞价请求,并将其竞价响应发送给Ad Exchange。
  4. FinestDSP赢得了这次竞价,将广告和匹配标签(像素)发给Ad Exchange。
  5. Ad Exchange将FinestDSP的广告和匹配标签提供给Jane,同时设置Jane的DoubleClick Cookie。
  6. 匹配标签调用Google的Cookie匹配服务。
  7. Cookie匹配服务读取Jane的DoubleClick Cookie,向FinestDSP发起302重定向(设置了google_user_id)。
  8. 浏览器加载FinestDSP的URL。
  9. FinestDSP生成cookie,存到匹配表中与Jane的google_user_id对应的项中。
  10. FinestDSP将其cookie种植到Jane的浏览器,并用1×1像素的不可见图像来响应这次重定向。

cookie-matching-schematic

场景2:DSP Cookie和DoubleClick Cookie

场景1发生一周之后,Jane又访问了ExampleNews.com。此时Jane的机器中既有DSP又有DoubleClick的cookie,我们看看匹配如何完成:

  1. 网页渲染,执行HTML代码,向Google请求广告。
  2. 在广告位竞价中,DoubleClick作为广告交易平台,向RTB市场的购买方FinestDSP发送了竞价请求,这样就给了FinestDSP是否要就这次展示竞价的选择权。
  3. FinestDSP接收到包含展示信息和google_user_id的竞价请求。
  4. FinestDSP到期匹配表中查询该google_user_id, 找到了一周之前在场景1里种植的cookie。
  5. 根据与这一cookie相关联的信息,Finest决定参与这次展示的竞价,并赢得了这次竞价。
  6. Jane看到了根据她的兴趣(根据FinestDSP拥有的关于她的信息)量身定制的广告。

 

Never use syslog from within signal handler

今天调试程序的时候发现worker进程收到信号后就似乎“不工作”了。gdb attach上去一看:

原来是锁住了。Google “syslog  signal handler” ,看到:

Non-reentrant functions are functions that cannot safely be called, interrupted, and then recalled before the first call has finished without resulting in memory corruption. This can lead to an unexpected system state,an unpredictable result with a variety of potential consequences depending on context, including denial of service and code execution.

Many functions are not reentrant, but some of them can result in the corruption of memory if they are used in a signal handler. The function call syslog() is an example of this. In order to perform its functionality, it allocates a small amount of memory as “scratch space.” If syslog() is suspended by a signal call and the signal handler calls syslog(), the memory used by both of these functions enters an undefined, and possibly, exploitable state. Implementations of malloc() and free() manage metadata in global structures in order to track which memory is allocated versus which memory is available, but they are non-reentrant. Simultaneous calls to these functions can cause corruption of the metadata.

再翻开TLPI或者APUE.3e中关于signal handler,reentrant and async-signal-safe functions的解释,于这一点上便更明白了。

  • APUE.3e       10.6           Reentrant Functions
  • TLPI               21.1.2        Reentrant and Async-Signal-Safe Functions

 

 

创站记

5月1日,到Godaddy买了storypku.com的域名,到阿里云买了台Ubuntu 12.04 LTS云主机。

5月2日,Nginx + WordPress成功搭建此博客并到DNSPOD上设置了DNS记录,成功使用storypku.com域名访问。

5月3日,万事俱备,只差备案。

5月6/7日,邮寄备案材料。拍照。

5月18号,发现可以使用域名访问啦!后被阿里云发现了,又不能访问了。

5月28日,通过工信部备案,狂拽酷炫屌!

Copyright © 2014 · All Rights Reserved · 来吧, 英雄! · 京ICP备14022779号

真是没想到,我竟然会劳神伤财地搭个独立博客!套用周星驰的话说:

人生大起大落得太快,实在是太刺激了。