作者 | 交易中臺團隊
導(dǎo)讀
隨著公司內(nèi)容生態(tài)的蓬勃發(fā)展,內(nèi)容產(chǎn)出方和流量提供方最關(guān)注的“收益結(jié)算”的工作,也就成為重中之重。本文基于內(nèi)容分潤結(jié)算業(yè)務(wù)為入口,介紹了實現(xiàn)過程中的重難點,比如千萬級和百萬級數(shù)據(jù)量下的技術(shù)選型和最終實現(xiàn),滿足了業(yè)務(wù)需求的同時,最終實現(xiàn)了高效,準(zhǔn)確的資金結(jié)算,文章旨在拋磚引玉,希望能給讀者帶來思考和幫助。
全文5185字,預(yù)計閱讀時間13分鐘。
01 業(yè)務(wù)介紹
什么是內(nèi)容分潤平臺呢?簡單來說,百家號等平臺負(fù)責(zé)內(nèi)容的生產(chǎn)和引入,手百等渠道方負(fù)責(zé)內(nèi)容的分發(fā),鳳巢等廣告平臺負(fù)責(zé)在此流量上進行變現(xiàn)。而分潤平臺,則是根據(jù)上述各方提供的數(shù)據(jù),通過核心策略模型,賦予作者、媒體、小程序主和用戶,合理的、差異化的、有競爭力的分潤收益,以吸引更加優(yōu)質(zhì)的內(nèi)容和流量的入駐和合作。通過這種多方相互協(xié)作模式,實現(xiàn)互惠共贏的目的。
1.1 三大功能點
針對上述的業(yè)務(wù)特點,結(jié)算系統(tǒng)需要包含三大功能,用于支撐內(nèi)容分潤業(yè)務(wù)的準(zhǔn)確性、合規(guī)性、及時性。
功能一:結(jié)算模型
這是我們最關(guān)鍵的功能,它負(fù)責(zé)將出色的文章轉(zhuǎn)化為作者的分潤收益。該模型的輸入數(shù)據(jù)包括數(shù)據(jù)中臺生成的用戶維度的日分潤明細(xì)和日補貼明細(xì),而輸出則是每月的結(jié)算賬單,這些賬單會被發(fā)送到統(tǒng)一業(yè)務(wù)平臺用于付款。在這個過程中,我們經(jīng)歷了一系列步驟,包括每日的計算、每月的總結(jié)、預(yù)提、計提和賬單生成等,所有這些步驟都是按照不同的維度逐層計算和聚合的,最終實現(xiàn)了賬單的付款。
功能二:C端內(nèi)容交易平臺
這個功能主要面向用戶,旨在幫助作者及時查看他們的收益,并進一步激勵他們的創(chuàng)作動力。作者只需登錄平臺,即可查看每日的預(yù)估收益、文章的分發(fā)情況、瀏覽量等數(shù)據(jù),還可以查看每月實際的付款賬單,提供發(fā)票等相關(guān)數(shù)據(jù)。
功能三:O端管理端平臺
為了確保資金結(jié)算更加合規(guī)和準(zhǔn)確,整個結(jié)算體系引入了運營管理和反作弊等不同角色。這些角色在管理端負(fù)責(zé)資金管控、發(fā)票審核、黑名單管理等各種操作,以確保整個過程的合規(guī)性。
1.2 名詞解釋
PALO:百度數(shù)據(jù)倉庫,是基于開源ApacheDoris構(gòu)建的企業(yè)級MPP云數(shù)據(jù)倉庫,可有效地支持在線實時數(shù)據(jù)分析。
BNS(Baidu Naming Service):是指百度名字服務(wù)。BNS提供服務(wù)名稱或服務(wù)組名稱到服務(wù)所有運行實例的映射,你可以根據(jù)一個名字(服務(wù)名或服務(wù)組) 獲取服務(wù)的信息,包括實例的主機名和IP、實例的運行狀態(tài)、端口、負(fù)載、實例自定義配置標(biāo)簽以及其他實例自定義信息。用于滿足服務(wù)交互中常見的資源定位、IP白名單維護、查詢服務(wù)下的機器列表、負(fù)載均衡以及其他任何依賴于這些信息的開發(fā)、測試和運維需求。目前BNS已經(jīng)在全百度各業(yè)務(wù)線中廣泛使用,UB、RAL等框架的支持和各語言SDK也已經(jīng)發(fā)布。
02 業(yè)務(wù)架構(gòu)
2.1 架構(gòu)分層介紹
圖1是整個內(nèi)容分潤的業(yè)務(wù)架構(gòu)。內(nèi)容分潤結(jié)算面向數(shù)據(jù)中臺,業(yè)務(wù)方,用戶(作者)和運營管理提供服務(wù)。
△圖1.內(nèi)容分潤結(jié)算平臺系統(tǒng)架構(gòu)
2.2 關(guān)鍵匯總文件
對于數(shù)據(jù)中臺,我們是直接下游,同時在整個內(nèi)容分潤流程的流程中,我們扮演的是最末端的角色。百家號、問一問、百度文庫等業(yè)務(wù)會將作者的內(nèi)容分發(fā)數(shù)據(jù)、廣告貢獻等給到數(shù)據(jù)中臺,數(shù)據(jù)中臺按照各種分潤計算模型歸一化數(shù)據(jù)結(jié)構(gòu),產(chǎn)出三份較為詳細(xì)的明細(xì)文件,包括日分潤明細(xì),日內(nèi)容分發(fā)明細(xì),日補貼明細(xì)。
日分潤明細(xì):作者內(nèi)容分發(fā)或流量貢獻所獲得的分潤詳情,明細(xì)中包括分潤金額,文章分發(fā)渠道,父子賬號等字段。
日補貼明細(xì):基于運管管理的二次資金分配詳情。
日內(nèi)容分發(fā)明細(xì):作者的內(nèi)容分發(fā)貢獻報表。
數(shù)據(jù)中臺會將這些數(shù)據(jù)以離線文件的形式提供給我們,結(jié)算系統(tǒng)每日基于配置規(guī)則,進行離線計算,最終將數(shù)據(jù)進行降維匯總。后續(xù)每月月初,基于這些匯總數(shù)據(jù),做二次匯聚產(chǎn)出用戶收益賬單。
2.3 服務(wù)提供方式
結(jié)算系統(tǒng)根據(jù)外部需求,提供多種接入方式。面對業(yè)務(wù)方,結(jié)算系統(tǒng)提供API、網(wǎng)頁嵌入模式接入方式。若業(yè)務(wù)有其自建平臺,可將結(jié)算系統(tǒng)提供的網(wǎng)頁嵌入其平臺內(nèi)部,用于展示用戶的收入信息或上傳發(fā)票等。若無自建平臺,也可API形式接入。新用戶在業(yè)務(wù)側(cè)申請入駐作者后,業(yè)務(wù)調(diào)用結(jié)算系統(tǒng)API完成用戶注冊,開通計費單元,維護財務(wù)信息等。后續(xù)作者在內(nèi)容分潤平臺查看其收入,文章分發(fā)報表,重新維護財務(wù)信息等。若有重要變更或通知,系統(tǒng)通過站內(nèi)信方式通知作者。
系統(tǒng)整體支持三種賬號體系,面向作者提供兩類百度常用賬號登錄方式,面向管理端提供內(nèi)網(wǎng)賬號登錄方式,基于此賬戶體系做了靈活權(quán)限控制,不同用戶登錄管理端,看到的可操作菜單欄各不相同,避免出現(xiàn)越權(quán)操作。同時基于此賬號體系,能靈活獲取上下級,構(gòu)建了自動化的審批流程。
結(jié)算系統(tǒng)的平穩(wěn)、合規(guī)、高效運行離不開各類協(xié)同生態(tài)的合力支持。反作弊能力貫穿整個內(nèi)容分潤的始終,著力于打擊黑產(chǎn),識別作弊用戶。OCR、發(fā)票平臺為發(fā)票識別,發(fā)票鑒定提供了通用服務(wù)。財務(wù)的各類審核,業(yè)務(wù)的多維度監(jiān)管則進一步為資金結(jié)算的合規(guī)安全保駕護航。各類角色、各個系統(tǒng)協(xié)同合作,促成了目前內(nèi)容分潤結(jié)算系統(tǒng)。
03 技術(shù)難點和細(xì)節(jié)
上文以整體的視角介紹了內(nèi)容分潤結(jié)算系統(tǒng)的架構(gòu)設(shè)計,下面我們將枚舉幾種業(yè)務(wù)場景構(gòu)建過程中的技術(shù)選型,來詳細(xì)介紹該系統(tǒng)的技術(shù)落地。
3.1 千萬級數(shù)據(jù)日度任務(wù)的技術(shù)選型
場景:每日上游會給我們產(chǎn)出明細(xì)數(shù)據(jù),數(shù)據(jù)為細(xì)粒度,量級為大幾千萬級別,格式為AFS文件(離線文件),需要基于某些過濾規(guī)則和計算規(guī)則做二次匯聚,后續(xù)支持多維度查詢,作者端展示報表。
3.1.1 DB批處理方案
最初任務(wù)是在物理機上通過sql批處理,任務(wù)串行執(zhí)行,簡單明了,同時成功同時失敗。但隨著數(shù)據(jù)量持續(xù)遞增,串行執(zhí)行可能面臨著實效性問題?;谠嫉腄B思路,我們構(gòu)建了基于DDBS(關(guān)系型分布式數(shù)據(jù)庫系統(tǒng))的解決方案,全部依賴于DB,因匯聚是基于用戶維度,所以基于子賬號uid計算shardingKey分表,過濾規(guī)則也落入庫中,后續(xù)使用表之間連接過濾,相同分表中的同子用戶數(shù)據(jù)匯聚。使用在線服務(wù),按照分表規(guī)則,啟動多線程執(zhí)行任務(wù),實時寫入日匯總數(shù)據(jù)表。具體方案如圖2。
△圖2.基于DDBS的解決方案
3.1.2 離線計算
利用SPARK天然的分布式計算能力,采用離線計算方案,匯聚時使用SPARK計算?;谏嫌翁峁┑碾x線文件,構(gòu)建RDD1文件,后續(xù)基于一些過濾規(guī)則過濾數(shù)據(jù)和然后基于集合規(guī)則,使用reduceBykey聚合,產(chǎn)出新的RDD2文件。這個RDD2文件就是我們后續(xù)使用的日表數(shù)據(jù)。因有各類在線查詢需求,需持久化到數(shù)據(jù)庫中,又因產(chǎn)出的日表需支持各角色多維度查詢,調(diào)研后采用PALO數(shù)據(jù)倉庫,具體方案如圖3所示。
△圖3.基于SPARK+PALO+DB解決方案
對比兩種方案后,我們最終選擇方案二實施。方案二的優(yōu)點比較突出:1.SPARK集群自帶分布式計算能力,無需我們按照方案一方式自行實現(xiàn)分布式計算;2.數(shù)據(jù)存儲于PALO,相比于傳統(tǒng)的MYSQL,在大批量數(shù)據(jù)和多維度報表場景,PALO性能優(yōu)勢更加明顯。3.方案一有一個最大也是我們最踩坑的性能問題,實時大批量寫入DDBS數(shù)據(jù)庫導(dǎo)致較高的主從延遲,影響了其他業(yè)務(wù)場景。
3.2 百萬級數(shù)據(jù)的月度任務(wù)
場景:基于上述場景會產(chǎn)出月表,數(shù)據(jù)量大約在百萬級別,遵循月度出賬計算模型,產(chǎn)出最終的預(yù)提數(shù)據(jù)。日度任務(wù)和月度任務(wù)的最主要區(qū)別在于日度任務(wù)計算過程密集,月度任務(wù)過濾過程密集。
月度產(chǎn)出計提任務(wù)實際就是計算用戶本月收入以及本月可結(jié)算的收入,可結(jié)算收入=以前累積未結(jié)算金額+本月收入。目前該任務(wù)輸入的數(shù)據(jù)量相對較少,且以過濾為核心,因此此類任務(wù)未采用SPARK計算。而各類過濾規(guī)則與當(dāng)前用戶各種屬性息息相關(guān),因此任務(wù)圍繞用戶uid展開,采用以用戶uid為底表,先通過各類策略過濾uid,后置再計算的方案。數(shù)據(jù)量雖然相對日度任務(wù)較少,但畢竟在百萬級別,如果使用單一線程處理所有用戶,速度會極其緩慢,所以必須拆分任務(wù),使用并行計算的方式提升效率,而如何拆分任務(wù),如何保障任務(wù)全部執(zhí)行是月度任務(wù)模型需要考慮的核心問題。
3.2.1 冪等的分布式數(shù)據(jù)批處理框架master節(jié)點
我們設(shè)計了主從任務(wù)模型,用于支持上述任務(wù)拆分執(zhí)行,主結(jié)點先置啟動,用于數(shù)據(jù)備份、初始化出賬任務(wù),以及調(diào)度從節(jié)點。從結(jié)點則等待主結(jié)點啟動子任務(wù)指令,啟動后獲取子任務(wù)執(zhí)行。具體模型如下圖4,5所示。
△圖4.主節(jié)點生命周期
圖5描述了主節(jié)點的生命周期,主節(jié)點收到出賬指令后,優(yōu)先做的是賬戶余額類表的數(shù)據(jù)備份,這個動作歸因于我們月度任務(wù)的特殊性,月度任務(wù)產(chǎn)出的數(shù)據(jù)表在其他時間不會更新,即上個月出賬結(jié)束后,賬戶余額類的相關(guān)表會在下一次出賬完畢才更新。
備份表的環(huán)節(jié)非常重要:
1.是可以在月度任務(wù)結(jié)束后做數(shù)據(jù)總額驗證工作;
2.是可以用于兜底,一旦月度任務(wù)產(chǎn)出數(shù)據(jù)異常,也可回退到備份數(shù)據(jù),重新啟動任務(wù)。
主節(jié)點任務(wù)的第二步則是確認(rèn)出賬任務(wù)的用戶uid范圍,我們系統(tǒng)為了既支持C端用戶體系,也支持商家賬號體系,重新設(shè)計了一套內(nèi)部用戶id,不論是用戶賬號還是商家賬號的id均會唯一映射成一個內(nèi)部uid,后文提到的該任務(wù)的uid均為內(nèi)部uid。內(nèi)部uid為自增id,因此查詢數(shù)據(jù)庫,即可獲取到最大uid和最小uid,也就確定了我們本次任務(wù)的uid范圍。在redis中設(shè)置兩個key代表uid的最值。至此,出賬任務(wù)的前置準(zhǔn)備工作就完成了。主節(jié)點獲取執(zhí)行子任務(wù)配置的BNS,基于BNS解析出所有實例,發(fā)送子出賬任務(wù)指令,子實例獲取到指令后,啟動N個線程執(zhí)行任務(wù),即假設(shè)有M個子實例,那最終就是M*N個線程同時執(zhí)行任務(wù)。從主節(jié)點的任務(wù)可看出,該任務(wù)無其特殊性,即主節(jié)點實際和從結(jié)點是平等關(guān)系,任何實例都可成為主,也可成為從,這就為調(diào)度任務(wù)進一步提高了靈活性。
3.2.2 woker節(jié)點的任務(wù)流程
△圖5.從節(jié)點生命周期
圖5以上述實例中的一個線程作為示例,詳細(xì)描述了線程啟動后,執(zhí)行的子任務(wù)的過程。首先獲取目前的最大uid和最小uid,最大uid為主節(jié)點固定值,最小uid則是一個游標(biāo)。若最小uid已經(jīng)大于最大uid,則代表所有uid已經(jīng)處理完畢,線程結(jié)束。若不滿足上述條件,則繼續(xù)執(zhí)行任務(wù),利用redis的incryBy指令,將最小uid向前移動N個數(shù)值,這N個uid就是本次子任務(wù)的執(zhí)行范圍。拿到uid后,先將uid變?yōu)镹條任務(wù)批量落入Job表,并設(shè)置初始化狀態(tài)。落庫失敗,引入報警機制。落庫成功后,按照出賬模型,啟動過濾規(guī)則。所有被過濾的用戶uid均批量寫入job表,設(shè)置任務(wù)結(jié)束狀態(tài),并且標(biāo)記過濾原因,便于后續(xù)運營查詢。過濾規(guī)則執(zhí)行完畢,剩余uid十不存一,此時我們利用sql計算本月用戶結(jié)算金額。計算完畢,寫入jobDB的臨時產(chǎn)出表,設(shè)置job任務(wù)完結(jié)態(tài),此時一輪子任務(wù)就執(zhí)行完畢。線程繼續(xù)重復(fù)執(zhí)行上述過程,直至所有線程均結(jié)束,代表出賬任務(wù)執(zhí)行完畢。
3.2.3 出賬確認(rèn)任務(wù)
所有任務(wù)執(zhí)行完畢后,主節(jié)點會收到出賬任務(wù)確認(rèn)指令。
△圖6.出賬確認(rèn)任務(wù)
該任務(wù)的主要目的就是確認(rèn)所有uid均執(zhí)行完畢,無疏漏,具體如圖6所示。上文提到,子任務(wù)執(zhí)行時,都是先置落庫job表的,確認(rèn)任務(wù)的第一步:掃描job表,看是否有非完結(jié)態(tài)的任務(wù),若有,則啟動子任務(wù),重新執(zhí)行這批數(shù)據(jù)。確認(rèn)任務(wù)第二步:獲取job表中所有執(zhí)行的uid數(shù)量和需要執(zhí)行任務(wù)的uid數(shù)量,確認(rèn)數(shù)量是否一致,若不一致,重新執(zhí)行出賬任務(wù),任務(wù)基于uid和業(yè)務(wù)期間重入,已經(jīng)被執(zhí)行的任務(wù)會被跳過。多次兜底策略執(zhí)行完畢后,數(shù)據(jù)總量校驗一致后,會將臨時月度產(chǎn)出數(shù)據(jù)寫入正式DB,清理臨時數(shù)據(jù)。之所以設(shè)置臨時表:1.是為了數(shù)據(jù)校驗工作,若數(shù)據(jù)校驗異常,可快速清理該表,重新啟動任務(wù);2.若直接寫入正式線上庫,大量數(shù)據(jù)的并發(fā)寫入會導(dǎo)致數(shù)據(jù)庫的主從延遲,會影響其他線上實時業(yè)務(wù)場景。后置寫入實現(xiàn)了另類的『讀寫分離』,任務(wù)過程中僅讀正式表,任務(wù)完畢臨時表往正式表寫入數(shù)據(jù)。
04 總結(jié)
本文主要介紹了在構(gòu)建結(jié)算系統(tǒng)過程中的幾個技術(shù)重點和難點,而要維護整套系統(tǒng)的平穩(wěn)運行,不僅有這些技術(shù)重點,也有看似微不足道但卻環(huán)環(huán)相扣的細(xì)枝末節(jié),保障每個環(huán)節(jié)不掉鏈子是運維工作的重要一環(huán),后續(xù)我們將著力于提升運維效率,節(jié)省人力成本,向著運維自動化、智能化改造。另外目前的技術(shù)方案取決于我們的數(shù)據(jù)量級,未來業(yè)務(wù)蓬勃發(fā)展,業(yè)務(wù)架構(gòu)也會持續(xù)迭代,期待我們向著更加完備的架構(gòu)前進。
——END——
推薦閱讀
小程序編譯器性能優(yōu)化之路
百度APP iOS端包體積50M優(yōu)化實踐(六)無用方法清理
基于異常上線場景的實時攔截與問題分發(fā)策略
極致優(yōu)化 SSD 并行讀調(diào)度文章來源:http://www.zghlxwxcb.cn/news/detail-729107.html
AI文本創(chuàng)作在百度App發(fā)文的實踐文章來源地址http://www.zghlxwxcb.cn/news/detail-729107.html
到了這里,關(guān)于百度交易中臺之內(nèi)容分潤結(jié)算系統(tǒng)架構(gòu)淺析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!