日活 2 億 - 的個人錢包系統架構

導讀:百度 APP 內含有現金、活動、虛擬等多類資產信息,分佈於百度 APP 內各個業務線中,用戶回訪信息難度較高,且用戶對百度資產認知度不高。我的錢包建立後,匯聚百度 APP 內所有用戶資產信息,解決了用戶回訪難的問題,建立用戶百度 APP 資產認知。本文主要介紹了錢包從 0 到 1 的搭建過程、遇到的各種問題以及相應的解決方案,旨在拋磚引玉,希望能給讀者帶來思考和幫助。

一、背景

百度 APP 坐擁日活 2 億 +、月活 6 億 + 用戶,在百度 APP 內每時每刻都產生了衆多用戶的資產信息。當前,百度 APP 內含有現金資產、活動資產、虛擬資產等多類資產信息,分佈於百度 APP 內各個業務線中。每個業務線提供用戶獨立的資產信息,業務線間關聯性較低,用戶回訪信息難度較高,不利於形成用戶對百度 APP 資產信息的整體認知。亟需一個系統,能夠匯聚百度 APP 內所有用戶資產信息,支持用戶資產信息統一彙總、展示,收攏用戶回訪入口,建立用戶百度 APP 資產認知,提升百度 APP 用戶體驗,我的錢包應運而生。

二、業務介紹

百度 APP 個人中心裏我的錢包,主要收攏了百度用戶的資產信息,進行統一的管理、展示,同時收攏各個業務線資產查看、使用等能力的入口,便於用戶快速回訪、找到個人的資產信息。錢包在百度 APP 個人中心外露四個金剛位和錢包入口地址,四個金剛位支持配置,運營人員可根據不同時期的活動、營銷等配置不同外露業務方,便於用戶快捷回訪。同時四個金剛位支持業務數據外露展示,使用戶直觀感知個人的資產信息。

在錢包入口點擊後,可進入錢包首頁。首頁中主要外露用戶的現金、提現活動、返現、卡券、虛擬幣、快捷入口等信息,同時支持運營配置營銷、活動。對於現金餘額信息,我們需要用戶授權,用戶授權後查詢用戶在度小滿、百度閃付的餘額,進入明細頁面後,可分別進行授權、查看明細。針對活動提現金額,錢包推動百度 APP 內所有涉及提現金額的業務接入錢包,統一進行管理,支持用戶查看金額明細,其中金額明細中包含兩個部分,一部分是明確返回用戶餘額信息的業務,支持用戶點擊跳轉至具體業務方查看明細,另一部分是彙總百度提現中心全部業務,支持用戶點擊跳轉,建立用戶現金餘額統一管理、訪問的認知。對於虛擬幣數據,可根據用戶各個虛擬幣餘額數量進行動態展示,便於用戶快速知曉自己的虛擬幣信息,點擊具體虛擬幣時,支持跳轉至業務方明細頁面進行查看明細、充值等操作,也支持跳轉至錢包統一虛擬幣明細列表,查看用戶明細、月度彙總等信息。對於業務方接入,錢包提供多種接入方式:API 數據同步、實時查詢、配置跳轉,業務方可根據自己實際情況進行選擇。

△圖 2-1 錢包展示

三、系統業務架構

△圖 3-1 錢包業務架構圖

錢包的整體系統業務架構如上圖 3-1 所示,錢包服務主要面向 C 端用戶、業務接入方、運營人員。針對 C 端用戶,錢包提供百度 APP 個人中心一級入口和錢包首頁兩個核心入口,前端使用 talos 框架實現。用戶通過個人中心入口訪問到達邏輯層後,首先判斷用戶是否命中用戶緩存,該緩存用來標識用戶是否有資產,如果命中緩存且有資產,則讀取數據緩存返回數據。用戶通過錢包首頁進入錢包,根據訪問的模塊,路由適配器根據配置規則,選擇不同數據規則進行數據加載、獲取,數據獲取後按規則進行聚合返回。爲了防止服務異常時影響頁面渲染,提供異常兜底方案,業務方接口異常時使用緩存數據兜底,內部異常時統一返回兜底文案。

針對不同的業務方,我們提供多種接入方式,對一個人中心一級入口外露業務,我們提供推送、拉取機制,即業務方在用戶數據變更時同步錢包,錢包準時拉取用戶最新數據;對於錢包首頁、列表頁業務,我們提供實時查詢方式,對於利用錢包給業務內導流的業務,我們支持 H5、scheme、talos、端內等多種跳轉能力。配置主要包括基礎配置、擴展配置、流控配置, 實現不同的適配器供上游調用。

運營人員可使用 B 端運營工具,配置、修改接入的業務方信息,也可以管理錢包首頁展示、運營活動、營銷等,同時亦可配置相關的流控、監控等信息。底層服務,我們使用了百度內通用的數據庫、Redis、消息隊列、CDN 等基礎服務,該基礎服務由統一的部門運維,穩定性比較可靠。

四、技術細節

1、資產數據同步

錢包搭建,面臨着一個棘手的問題:百度 APP 內資產信息分佈在不同業務線,信息間互相隔離,系統異構。如果推動業務方直接暴露 API 查詢數據,則需要業務方接口達到錢包要求的高 QPS、底平響、高穩定性,同時業務線內可能存在一些特殊情況,再加上節假日、活動等特殊時期流量突增,會嚴重影響錢包數據展示,進而影響用戶體驗。存在部分業務方用戶量級較小,但必須得提供符合錢包需要的性能,這就對業務方帶來額外壓力。如果要求所有業務方將全量數據同步至錢包,又面臨業務線數據推送、錢包海量數據存儲、數據準確性對賬等問題。

針對如上一系列問題,我們確定了接入錢包的原則:①在個人中心破殼展示位外露的業務方,必須將資產數據同步至錢包,錢包服務內部確保接口可用性和降級方案;②錢包首頁展示數據,支持業務方選擇是否將數據同步至錢包,如果不同步數據,需要提供滿足 QPS、平響等要求的 API 供錢包調用;③錢包二級頁面、三級頁面數據,需業務方提供查詢 API 或者落地頁,實時查詢業務方數據進行展示,確保明細數據準確無誤。

1.1 數據同步

對於業務方同步的用戶資產數據,我們只存儲用戶的最新數據,考慮數據量級問題,錢包不存儲歷史快照。錢包定義業務方數據推送的接口規範,業務方在數據更新時,需及時通知錢包拉取最新數據。爲了防止業務方推送數據時流量突增對錢包 sever 的影響以及提高錢包 server 的吞吐,引入消息隊列進行削鋒,即接到業務方資產數據變更請求時,放入消息隊列後返回業務方通知成功,錢包 server 內消費隊列消息,根據配置信息向業務方拉取最新數據進行更新。對於用戶資產明細數據,錢包定義接口規範,業務方實現後將調用地址提供給錢包,錢包進行配置,用戶訪問時實時調用。

於是,我們設計瞭如下的數據同步方案:

△圖 4-1 業務方數據同步

①用戶資產變更時,業務方調用錢包接口通知信息變更;

②錢包接到通知後,放入消息隊列;

③消費任務獲取消息隊列中消息進行消費處理;

④根據配置,拉取業務方最新信息,更新至錢包存儲;

在消費消息時,錢包 server 進行批量處理,針對一定時間內同一業務方同一用戶信息,只拉取一次數據,減少對業務方服務壓力。遇到異常時,會進行 3 次重試拉取。錢包 server 控制是否拉取、流控,在下游業務方服務異常時,可及時停止拉取、降低拉取流量,減少或者去除下游系統對錢包的影響。

1.2 實時查詢

針對部分業務方不推送數據,我們定義接口規範,業務方進行實現,實現後上報錢包配置調用方式。對於此類業務方,不允許配置到個人中心展示,防止業務方接口性能不達標拖累整體用戶體驗。實時查詢接口主要分爲餘額、分頁明細接口,錢包統一 format 後進行展示。餘額接口查詢返回後,異步寫入 Redis 進行緩存,用於下次訪問業務接口異常時進行兜底展示,如果後續訪問業務接口正常,則使用最新數據更新 Redis 數據。

用戶明細分頁數據包含分頁明細數據和月度彙總數據(月度總收入與總支出),錢包調用下游拆分成兩個接口:分頁明細接口和月度彙總接口,提供給前端展示頁面封裝成一個接口,降低前端交互複雜度。調用下游分頁接口實時返回用戶明細分頁數據,月度彙總接口返回用戶當前明細所屬月份的彙總數據。錢包服務內部根據業務方明細分頁接口數據進行彙總,爲了減少請求業務方次數,錢包內部判斷分頁數據,如果返回數據都是同一月份,則只請求業務方一次月度彙總接口,後續分頁不再請求,如果返回數據分散在兩個月份,則請求業務方月度接口兩次,如果返回數據分散在三個月份(含)以上,則只請求起止兩個月份的月度數據,中間月份數據由錢包根據明細數據內部計算。

2、多級緩存

百度登錄賬號體系中,用戶 id 已超過數十億,存在資產的用戶接近億級,同時錢包會在百度 APP 個人中心破殼展示部分業務,即一級入口,預計會帶來平均萬級 QPS、峯值超過十萬級 QPS 流量,特殊時間點可能會更高。爲了防止服務宕機對百度 APP 產生非預期影響,故需要對破殼展示的數據提供完整緩存方案和降級預案。爲了提升系統的高吞吐,我們決定將一級入口數據全部緩存至 Redis,訪問流量只讀 Redis,如果遇到 Redis 異常時,則返回兜底數據,不查詢 DB(防止壓垮 DB)。DB 數據用來 Redis 極端情況崩潰時恢復 Redis 數據時使用。

針對存在資產的用戶量分析,進入個人中心的用戶存在一個特點:大部分用戶沒有個人中心外露的資產數據,抽象成一個稀疏矩陣,這就使我們在設計的時候,可以考慮兩層緩存:第一層判斷用戶是否擁有資產信息,第二層緩存存儲用戶資產數據。故我們設計瞭如下的兩層緩存方案。

△圖 4-2 錢包兩層緩存方案時序圖

大部分用戶流量會被第一層緩存攔截,設計合理的第一層緩存數據結構,成爲了系統的一個關鍵。我們調研了 hyperLogLog、布隆過濾器、roaringBitmap 等方案,分析和實驗後發現,hyperLogLog 中 pfadd 操作本身可以滿足性能要求,key 的大小在 12k 也滿足,但是由於 pfadd 本身針對於一個 uid,只能操作一次,所以不適合這個場景 hyperLogLog;布隆過濾器在試驗 20 億的數據量下,內存佔用來量大約佔比 3G,內存佔用比較大,基於 redis 的布隆過濾器沒有分佈式的數據能力,本質上還是對 redis 的強依賴,存在風險。

roaringBitmap 在存儲空間上滿足要求,我們根據錢包的實際場景,改進了分桶與計算規則,根據用戶 id 進行 sharding 分桶,桶內使用 uid 的 hash 值對應的 bitmap 位點標記狀態。實驗數據驗證,3000 分片,8 個計算單元,1000W 實驗數據,存儲空間佔用 500M+,誤判率 2.14%,即存在 2.14% 的用戶沒有資產信息會打到第二層緩存,整體對第二層緩存增加壓力可控。

3、讀寫分離

錢包服務承接較大的讀流量和寫流量,爲了防止互相影響,我們將讀寫流量分別拆到不同的服務。用戶訪問讀服務異常時,不影響業務方推送寫入,業務方推送寫入服務異常時,不影響 C 端用戶訪問。讀服務主要承接 C 端用戶通過個人中心和錢包首頁、二級頁面訪問的流量,將用戶訪問的相關數據進行緩存,提升系統平響。寫服務主要承接業拉取業務方數據和 C 端用戶授權信息,同時承接消息隊列消費處理和與下游業務方交互。讀寫服務之間,通過 RPC 接口調用進行交互。

△圖 4-3 讀寫分離

4、數據一致

個人中心外露的業務數據,針對接入用戶中心外露展示的業務方,我們需要業務方在用戶資產發生變更時及時推送給錢包,以確保用戶在錢包看到的數據與在業務方提供的入口查看的數據是相同的。但實際情況不一定如此,比如業務方推送服務異常、網絡抖動,都有可能導致兩方數據不一致。於是,我們提出了推拉結合的數據一致性解決方案。即業務方資產信息變更時,準時推送錢包,在用戶進入個人中心時,觸發拉取用戶最新資產信息。當前,我們只對用戶的資產信息已被推送至錢包的業務方,拉取用戶最新資產信息,防止拉取全量業務方數據給用戶量級小的業務方帶來過多無效拉取流量導致服務壓垮。針對系統內部,由於展示時只使用 Redis 中緩存數據,如果同步用戶信息時因某些異常導致 Redis 與 DB 中數據不一致,我們採用定時任務,每天凌晨拉取 DB 中前一天(DB 變更時間)有變更的用戶信息,與 Redis 信息進行比對,數據不一致時,拉取業務方最新數據,更新 Redis 數據,做到 T+1 對賬,解決系統內數據不一致問題。

對於錢包內展示的業務方,也會存在服務異常、網絡抖動導致的無法獲取用戶最新信息的問題。我們採用的方案,對於正常請求業務方結果數據,將結果信息寫入 Redis,如果下次訪問業務方接口異常時,使用 Redis 中數據作爲兜底,優先確保數據正常展示。如果後續請求下游接口正常,則使用成功的數據更新 Redis 數據,確保 Redis 數據的準實時性。

△圖 4-4 錢包數據一致方案時序圖

5、配置化

錢包設計之初,就面臨着如何支持業務方快速接入和支持運營人員快速配置用戶展示界面、活動、營銷等信息的問題。通用配置化能力,是解決此類問題的首選方案。

配置化主要分爲兩部分:接入配置化和展示配置化。通過分析發現,不同業務方的接入、展示需求不同,於是我們抽象共同的信息,生成通用基礎信息,對於業務個性化信息,採用擴展模型記錄業務特殊配置。彙總業務方基礎配置 + 擴展配置後,放入 Redis 緩存中。對於錢包展示配置,底層設計展示通用配置,比如展示名稱、文案、跳轉鏈接、圖片 Url、背景圖 Url,對於特殊展示需求,可配置到擴展信息,比如外露 Icon、展示金額,配置信息同樣放入 Redis 緩存中。

項目上線初期,配置信息新增與更改的頻次都很高,容易發生修改錯誤的風險,導致 C 端用戶體驗受損。於是我們設計版本號 + 白名單方案進行放量控制,新版本發佈需與白名單用戶相關聯,配置生效後先使用白名單用戶線上進行驗證,驗證通過後逐步全流量。修改配置時,保存歷史更改全量數據,用於配置信息異常時回滾。

由於錢包對業務方配置信息依賴較強,如果 Redis 異常時會影響錢包的穩定性,所以我們將配置信息同步配置到百度雲控平臺 GCP 中,作爲 Redis 異常時的兜底。緩存有效期可以設置永久有效,在變更配置時同步更新 Redis,同時需要同步更新 GCP 配置,及時下發。

6、數據庫設計

由於用戶量較大,涉及用戶資產信息到了數據庫層面會同步放大,受限於 MySQL 數據庫單機處理能力,故將數據進行拆分,不同的數據放置在不同的機器,便於機器擴容。在數據模型的設計上,數據庫分表字段採用用戶 id 作爲分表字段(shardingKey),這樣通過用戶 id 定位到具體的庫和表,因將整個資產信息庫所有表按照統一規則進行切分,分表規則一致,保證按照同一用戶都能在一個庫,從而可以使用數據庫事務。採用分庫分表模式,後續遇到數據庫存儲瓶頸時,可以很方便的進行橫向擴容。

五、總結

本文重點在介紹了百度 APP 個人錢包搭建的整個技術細節,在項目推動和落地的過程中,也遇到了諸多困難,主要的難點在系統高可用、高穩定、快速支持業務接入。梳理清楚難點與技術關鍵點,抓住關鍵問題,對系統合理做減法,降低系統複雜度,快速推進系統上線,後續不斷迭代,打造極致用戶體驗。後續,在業務上會持續推進業務線快速接入,讓用戶在錢包內可以查看、管理百度系全量資產信息,在技術上繼續推進穩定性、可靠性建設,爲業務方帶來更多用戶流量,爲用戶提供更好的用戶體驗。

作者:小黑哥

來源:百度 Geek 說

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/z6G_fVS12lgzT9DynNeH5w