天天看點

TOP100直擊|如何在一周内上線50個使用者增長政策

作者:閑魚技術-蘭昊

在閑魚使用者增長業務上的實驗

我們最先落地的業務是在使用者增長上,閑魚的使用者增長業務有如下描述:

  • 閑魚的賣家都是普通小賣家,而非專業的B類商家。是以無法統一組織起來參加營銷活動帶來買家活躍。
  • 我們目前DAU已經突破到2000W,如何承接好這麼大體量的使用者,對營運同學是個很大的考驗。

在年初時,我們在使用者增長下做了多個實驗,其中兩個實驗如下:

TOP100直擊|如何在一周内上線50個使用者增長政策
TOP100直擊|如何在一周内上線50個使用者增長政策

之是以會做以上實驗,主要還是希望使用者能在APP上多停留一會。當使用者浏覽時間越長,就越有可能發現閑魚上還有很多有趣的内容,無論是商品寶貝還是魚塘内的文章。進而達到吸引使用者下一次還能再回來的目的,最終帶來使用者增長。我們做的實驗上線後大部分都取得了不錯的業務效果,但是在過程中也暴露了兩個問題:

  • 研發周期長。一開始,我們先用最快的實作方案來做,主要是為了快速驗證規則政策的有效性,并沒有做大而全的設計,每個需求都是case by case地寫代碼來實作。那麼從開始開發真正能到上線,很可能就是三周,主要因為用戶端發版是有視窗的。
  • 營運效率慢。因為上線慢,導緻擷取業務資料後再分析效果就很晚了,然後還要根據資料再去做調整那就更晚了。這樣算下來,一年也上不了幾個規則政策。

工程化解法——基于事件流的規則引擎

針對上述問題,我們先做了一層業務抽象。營運先通過對使用者的各種行為進行一個分析和歸類,得出一個共同的具體的規則,再将這個規則實時地作用到使用者身上進行幹預。

TOP100直擊|如何在一周内上線50個使用者增長政策

針對這層業務抽象,我們再做了工程化,目的就是為了提升研發效率和營運效率。這樣就有了第一個方案——基于事件流的規則引擎,我們認為使用者的行為是一串順序的行為事件流,使用一段簡單的事件描述DSL,再結合輸入和輸出的定義,就可以完整地定義一個規則。

TOP100直擊|如何在一周内上線50個使用者增長政策

以上述使用者增長的第二個實驗為例,如下圖所示的DSL即可簡單表達出來:

TOP100直擊|如何在一周内上線50個使用者增長政策
TOP100直擊|如何在一周内上線50個使用者增長政策

規則引擎的局限性

該規則引擎可以很好地解決之前使用者增長業務下的幾個政策,随後我們進行了内部推廣,準備在閑魚C2C安全業務下也落地。在C2C安全業務上有如下描述:

TOP100直擊|如何在一周内上線50個使用者增長政策

在C2C安全業務上,也有一個看似是一個針對一系列行為作出的規則抽象,如下圖所示:

TOP100直擊|如何在一周内上線50個使用者增長政策

但是将上述規則套上規則引擎後,就會發現無法将安全的規則套上規則引擎。假設我們的詳細規則是1分鐘内被拉黑2次,就對該使用者打上高危标記。那麼我們想一想,當來了第一個拉黑事件後,比對上了。然後緊接着來了第二個拉黑事件,也比對上了。此時按照規則引擎的視角,條件已經滿足了,可以進行下一步操作了。但是再仔細看一看規則,我們的規則是要被不同的使用者拉黑,因為有可能是同一個使用者操作了多次拉黑(同時多開裝置)。而規則引擎上隻知道比對到了2次拉黑事件,對規則引擎來說已經滿足了。卻無法知道是否是不同人操作的。起根本原因是因為在規則引擎裡,事件都是無狀态的,無法回溯去做聚合計算。

TOP100直擊|如何在一周内上線50個使用者增長政策

新的解決方案

針對規則引擎的局限性,重新分析和梳理了我們的實際業務場景。并結合了業界知名的通用的解決方案後,設計出了新的方案,定義了新的DSL。可以看到,我們的文法是類SQL的,主要有以下幾個考慮:

  • SQL已經是語義完備的程式設計語言,不用再去做額外的文法設計。
  • SQL是一門很簡單的語言,不需要花太多時間就可以掌握。
  • 我們閑魚的營運同學會寫SQL,這樣會讓上線效率更快。
TOP100直擊|如何在一周内上線50個使用者增長政策
TOP100直擊|如何在一周内上線50個使用者增長政策

新的DSL方案與之前的規則引擎相比主要有以下幾個增強:

  • 增加了條件表達式。可以支援更豐富更複雜的事件描述,也就能支撐更多的業務場景。
  • 增加了時間表達式。通過WITHIN關鍵字,定義了一個時間視窗。通過HAVING之後跟的DISTINCT等關鍵字,就可以針對時間視窗内的事件進行聚合計算。使用新的方案,就可以很好地解決上述C2C業務上的規則描述問題。
  • 擴充性強。遵循了業界标準,與具體業務的輸入和輸出無關,便于推廣。

針對之前的C2C業務上的規則描述問題,使用新方案的例子如下:

TOP100直擊|如何在一周内上線50個使用者增長政策
TOP100直擊|如何在一周内上線50個使用者增長政策

整體分層架構

基于這套用EPL(Event Programming Language)寫出的DSL,為了做好工程化,我們做了如下的整體分層架構。為了快速實作最小閉環驗證效果,我們選擇先基于Blink(Blink是阿裡對Flink的内部優化和更新)做雲上的解析和計算引擎。

在這個分層架構裡,至上而下分别是:

  • 業務應用。在這裡是我們整個系統的業務方,已經在多個業務場景下做了落地。
  • 任務投放。這裡是對業務應用層提供DSL聲明和投放的能力,能可以做簡單的圈人,以及與使用者觸達子產品的關聯。
  • 使用者觸達。這個子產品用于接收來EPL引擎計算的結果,根據關聯的Action來實施動作。同時這個子產品也可以獨立對業務應用提供服務,即各個業務方可以擁有自己的邏輯,通過使用者觸達子產品來觸達使用者。
  • EPL引擎。目前已經實作了雲上的解析和結算。用于接收來自任務投放裡聲明的DSL,再去解析和運作在Blink上。
  • 事件采集。負責通過服務端日志和行為打點裡采集行為事件,并歸一化地輸出給EPL引擎。
TOP100直擊|如何在一周内上線50個使用者增長政策

事件采集

通過切面的方式攔截所有的網絡請求和行為打點,再記錄到服務端日志流裡。同時通過一個事實任務對事件流進行清洗,按前面定義的格式清洗出我們想要的事件。再将清洗後的日志輸出到另一個日志流裡,供EPL引擎來讀取。

TOP100直擊|如何在一周内上線50個使用者增長政策

EPL實作

由于我們采取了類SQL文法,而Calcite是業界通用的解析SQL的工具,是以我們采用Calcite并通過自定義其中的parser來解析。如果是單一事件的DSL,則會解析成Flink SQL。如果是多事件的DSL,則會解析後通過直接調用Blink的API接口的方式來實作。

TOP100直擊|如何在一周内上線50個使用者增長政策

使用者觸達

當EPL引擎計算出結果之後,會輸出給使用者觸達子產品。首先會進行一個Action路由,最終決策出需要由具體哪一個Action來響應,最後通過與用戶端之間的長連接配接将Action下發到端上。端上收到具體的Action後,會先判斷目前使用者的行為是否允許展示該Action。如果可以的話,就直接執行Action的具體内容,曝光給使用者。使用者看到這次響應後會有相應的行為,那麼這部分的行為會影響到Action路由,對這次的路由的做出一個回報。

TOP100直擊|如何在一周内上線50個使用者增長政策

案例

新方案上線後,我們就在越來越多的業務場景裡進行了落地。這裡列舉2個例子:

TOP100直擊|如何在一周内上線50個使用者增長政策
TOP100直擊|如何在一周内上線50個使用者增長政策
TOP100直擊|如何在一周内上線50個使用者增長政策

在上述魚塘的例子裡,可以看出來,我們這套方案已經有了一點算法推薦的影子了。在上述租房的例子裡,由于規則過于複雜,用DSL表達起來很麻煩,是以就做成隻采集4次浏覽不同租房寶貝的規則,即觸發後,就将這裡的資料都給到租房的具體開發的業務方,這也是我們在落地過程中摸到的邊界。

結論

使用這一套完整方案,研發效率上有了很大的提升。原先通過寫代碼case by case的方式一般要4個工作日完成整個研發流程,極端情況下需要跟用戶端版本則需要2-3周的時間。現在通過寫SQL的方式一般要0.5個工作日即可上線。此外,這套方案還有如下幾個優勢:

  • 高性能。整條鍊路計算完畢平均耗時5秒。
  • 高可靠。依托于Blink的高可靠性,承載了雙十一上億的流量。

通過在多個業務的落地實踐,我們也摸索出來這套方案的适用邊界:

  • 對實時性要求高
  • 強營運主導規則
  • 能夠用SQL表達

未來規劃

目前整套方案還有如下幾個問題:

  • 整條鍊路計算完畢平均需要5秒左右。如果放到對實時性要求更高的遊戲任務場景下時,這就無法滿足了。假設,今天有個任務是浏覽10個寶貝詳情。當使用者浏覽到第10個寶貝時,還要再等5秒才給予響應,使用者是無法接受的。是以需要對整體性能有進一步提升,要在毫秒級内給出響應。
  • 閑魚的業務已經連年保持了高增長,未來可能會面對比當下翻三番的使用者流量,如果所有計算依然全部放在雲上,則對雲上的算力消耗是個極大的挑戰。
  • 目前我們的設計上,是沒有算法接入的,隻有簡單的圈人。而為了讓規則的投放更加精準,進而提升規則對使用者的有效性,是需要與算法結合的。

是以綜上,我們未來的規劃将會聚焦于端側實時計算能力的挖掘和算法能力的結合上。

繼續閱讀