作者:閑魚技術-雲聽
背景
在之前的文章中,我們介紹了納米鏡的功能和背後的分析算法,而閑魚目前業務線多且複雜,怎麼建構一個可擴充性強的系統,使每個業務線都能夠便捷地接入,成為首要關注的問題。
思路分析
标準資料集
納米鏡的分析算法,輸入輸出是固定的,要求輸入是一個固定的标準ODPS資料集,字段包含userid/分桶id/人群切面1/人群切面2/名額1/名額2等,但實際業務場景中,每個業務關注的人群切面與資料名額都是大相徑庭的,為了在限制中尋找靈活性,我們必須對納米鏡的标準資料集做些改造。
由于納米鏡存在資料集依賴,比如說預測算法和切面顯著性算法,就需要依賴具體的某張表去做二次計算,比較好的解決方案是讓業務方按照資料集規範往标準資料集的中間表裡面插資料。
資料集自動生成
隻要讓每個業務将自己的資料按照标準資料集的規範插入到納米鏡中間表中,就能開始使用納米鏡的功能。但實際場景中,業務産出資料集的開發成本很大,并且這種方式對使用方的開放權限很大,假如使用方不按照規範插入資料,會對源資料造成污染,使其變得不可控。那是否能做到資料集自動生成,讓使用方不需要關注資料采集流程呢?
可以看看,在平常的業務開發流程中,生成ODPS資料源的工作流程是:

這整個過程下來,一般都會花費至少2天(1天埋點梳理與開發、1天寫SQL生成報表)的時間,并且很多時候會出現埋點遺漏的問題,又需要重新走一遍開發和釋出流程,造成很多人力上的浪費。
方案設計
标準資料源制定
資料集中的資料類型是固定的,資料類型下字段名稱和值可以是靈活的。
在資料集上,我設計這種一種資料格式,參考:
userid: 使用者userid
bucket_id:bucket_A
indexes: index_visit=1,index_ipv=2
tags: tag_sex=F,tag_age=19
業務資料集自動生成
行業成熟方案及缺點
資料自動生成,意味着上面提到的正常資料開發流程直接抹除,不需要關注埋點開發、也不需要跨專業領域去寫SQL,頁面隻要一上線,活動資料就會自動存儲到納米鏡的标準資料源中。要做到無埋點,業界有類似的方案,也叫做“全埋點”,自動采集坑位曝光點選,但這個方案的缺點很明顯:
1、上傳資料是dom節點位置資訊,清洗麻煩,并且擺脫不了寫SQL的工作
2、增加帶寬、伺服器壓力(每個坑位的曝光點選,無論是否需要都會上傳)
3、業務侵入太強(weex下要監聽坑位曝光事件,子產品開發時需引入定制元件)
4、攜帶不了trackparam資訊(實際業務場景還會關注更多業務資訊 eg.商品id/分桶/紅包金額)
提取使用者行為的最大公約數
本質上,業務關注的是使用者行為。我對曆史埋點開發的資料做了統計,梳理出業務關注的使用者行為類型,包含點選跳轉頁面、紅包曝光、紅包領取、紅包金額、分桶id、管道等。并且發現,所有這些使用者行為,底層都經過了
頁面跳轉
/
HTTP接口請求
url傳參
這幾個API調用,如果API調用的輸入輸出是可固化的,那了解使用者行為的業務語義并采集上報,就具備可能性!
最終方案
要做一個适用所有業務(閑魚/手淘/天貓)的使用者行為采集方案,技術實作上不可能,原因是每個業務自己的工程實作方案完全不同,也無法保持一緻。不過對閑魚來說,工程基建基本成熟穩定,具有業務語義的使用者行為的API輸入輸出已固化,使實作一套隻适用于閑魚的使用者行為自動采集技術方案具有了可能性。總體技術方案如下:
圖中下半部分的虛線部分:産品展現側本文不做太多擴充,本文主要講上半部分的,從端側使用者行為采集到生成納米鏡标準資料源。
相比全埋點,它的特點是:
1、靈活配置
2、減少帶寬、伺服器計算壓力
3、業務無侵入
4、可攜帶trackparam資訊
落地
hook API
閑魚前端封裝了一個util,頁面跳轉(navigator)、http請求(mtop)都由它暴露出來給開發使用,具體調用方式是
navigator.push()
、
mtop.request()
。使用Proxy代理對這兩個API進行hook。這裡以navigator為例。
navigator['push'] = new Proxy(navigator['push'], {
get(target, propKey) {
return target[propKey];
},
set(target, propKey, value) {
target[propKey] = value;
return target[propKey];
},
apply(target, thisArg, args) {
// 先執行原邏輯
const result = target.apply(this, args);
// 是否指定忽略納米鏡分析
const ignoreNanoAnaly = args && args[0] && args[0].api && args[0].ignoreNanoAnaly;
if (ignoreNanoAnaly) {
return result;
}
if (result instanceof Promise && result.then) {
result.then(d => {
// 這裡寫入監聽邏輯
// ...
return Promise.resolve(d);
}).catch(e => {
// 這裡寫入監聽邏輯
// ...
return Promise.reject(e);
});
}
return result;
}
});
使用者行為采集通用配置與可定制化配置
閑魚目前已沉澱下成熟的一套使用者行為采集通用配置,滿足業務方資料分析時的各種資料名額訴求,并且,我們還支援定向擴充,可對具體的頁面spmId定制自己個性化的使用者行為名額,具體的配置參數與含義參考以下demo。
{
"spms": [{
"spm": "common", // 使用者行為通用配置 會對所有頁面産生的使用者行為進行比對
"tasks": [{
"indexType": 0, // 0代表名額 1代表bucket_id 2代表infos 3代表擴充資訊 預設0 這裡主要是需要與納米鏡的标準資料源建立映射關系
"index": "index__ipv", // 名額名稱 IPV
"behavior": [
{
"type": 0, // 使用者行為類型 0代表navigator 1代表mtop 2代表location.href
"condition": "fleamarket://item", // 正則比對是否目标行為 type=navigator比對下跳url;type=mtop比對接口傳回值 不校驗填true
"valueType": "1" // 名額數值類型 0代表boolean 1代表count 字元串屬性鍊代表對應取對應值
}
]
}]
}, {
"spm": "spma.spmb",
"match_uv": true, // 是否采集頁面uv 預設名額名稱是 index__visit
"tasks": [{
"indexType": 0,
"index": "index__gold_copper", // 金寶箱是否打開
"behavior": [{
"type": 1, // mtop接口請求的行為類型
"api": "mtop.api.lottery.draw", // 抽獎接口api名稱
"condition": "d.data.status===5", // mtop傳回值符合該正則比對 則認為符合采集記錄條件 status==5代表使用者成功打開了金寶箱
"valueType": "0" // 是否領取成功 0/1
}]
}]
}]
}
行為聚合與上報
為了減少帶寬和伺服器計算壓力,每次采集到的使用者行為不會立即上報,而是把整個頁面執行個體生命周期的使用者行為做聚合,直到頁面被銷毀或者應用從前台切到背景15秒後做統一上報。
上面提到的demo,假設使用者在spmId為
spma.spmb
的頁面點選跳轉了10次商品詳情頁,并打開了金寶箱,最終上報到伺服器日志的資料長這樣:
{
"page": "spma.spmb",
"indexes": "index__visit=1,index__ipv=10,index__gold_copper=1"
}
效果
目前,已經有多個業務通過這種方式靈活輕便地接入納米鏡,eg. 邊逛邊賺錢、侃侃刀、報價單、322閑魚大促等等,從原本要花費至少2人日的開發量,到隻要活動上線,即可上手納米鏡檢視活動智能分析結論,整體納米鏡使用體驗和使用效率都擷取了極大的提升。
未來
目前納米鏡設計的業務Access模式,已能夠滿足業務0成本接入,如果有更多定制化資料名額訴求,也支援低成本地動态配置。
未來,納米鏡會在資料科學的道路上深入鑽研,現階段我們更多在了解人,也在嘗試從浩如煙海的曆史活動中抽象沉澱知識庫,并且開始嘗試了解貨,了解人與貨之間的喜好關系,并建立人與貨之間的比對關系。
想了解更多細節,就請繼續關注閑魚公衆号吧。