本文作者:有內鬼
背景介紹
1.2021年開始,社交直播活動中台因為需要支持的產品越來越多,優化過程中發現對於很多讀場景來説中心緩存的讀取已經成為了性能瓶頸,所以大量業務場景
開始採取二級緩存方案,將原來的中心 memcache 作為二級緩存,採用 guava、local memcache 作為一級緩存,來減少網絡 IO、提升鏈路性能。
2.活動中台在發展過程中,因為需要支持多個產品,產品業務方的業務需求差異越來越大,統一運營後台已經無法滿足業務方需求,於是決定將運營後台各業務線獨立
應用開發維護,不再在領域服務中維護運營後台代碼,並且拆離運營後台後也有利於領域服務穩定,但是這樣就帶來了不同應用清理緩存的問題。
3.常見的解決思路都是通過廣播數據變更的思路去解決本地緩存更新的問題,如訂閲數據庫的 binlog ,基於註冊中心響應方式。
首先我們決定採用的是訂閲數據庫表變更 binlog 廣播消息的方案,當相關表發生變更後,通知所有相關領域服務,然後清理本地緩存。該種方案在實際使用一段時間後,
出現了一些問題:
①運行層面上執行鏈路隱蔽,當出現緩存不一致問題時,很難快速定位到哪台實例的緩存是錯誤的。
②代碼層面上入口隱蔽,除了開發者團隊其他成員無法快速得知相關緩存清理鏈路,導致維護成本越來越高。
③運營後台隨着不同業務獨立開發後,各業務開發人員並不想再在運營後台工程中額外花費時間編寫清理中心緩存的代碼。
4.通過訂閲數據庫 binlog 方式的不良體驗後,我們決定尋找更優雅的解決方案。首先調研了市面上的一些開源方案,發現都不盡滿意:
①中心緩存大多隻支持 redis,並且依賴並不可靠的 pub / sub 不夠健壯,並且團隊使用的中心緩存是 memcache
②框架年久失修、實現方式不優雅、不方便使用,模擬spring-cache的註解形式,同樣會造成鏈路隱蔽的問題。
綜上所述,團隊決定自行開發一款能夠應用於多級緩存一致性場景的框架,對這款框架的目標:
①能夠清晰的讓團隊成員瞭解所有緩存清理鏈路和多級緩存的使用情況,並且框架要足夠簡單易用,不會對團隊成員使用造成困擾額外增加開發成本。
②框架要足夠健壯,首先要有異常重試機制,其次清理緩存的執行鏈路都要記錄,便於排查問題。最後要能夠支持更加複雜的業務場景,不限於只能支持二級緩存。
③良好適配團隊的技術棧。
詳細設計
1.模型抽象
以一個最簡單的二級緩存清理為例,當配置發生變更需要清理緩存時,需要先清理二級緩存即中心緩存,然後再清理一級緩存即本地緩存,整體鏈路可以抽象為一個單向鏈表。
一棵樹在極端情況下會退化成一個鏈表,我們反向思考就代表我們可以將上面的單向鏈表複雜為一棵樹,從而可以支持更加複雜的緩存清理場景。一個緩存清理事件不再只
清理一箇中心緩存和一個本地緩存,層級也不再最多隻能支持兩層,理論上可以支持無數層。所以在緩存管道中,我們把緩存清理鏈路抽象為樹結構,緩存清理事件作為樹的
根節點,事件源下面是緩存清理鏈路的葉子節點,每條路徑又可以看做一個單向鏈表。
2.緩存管道應用結構
緩存管道應用分為兩大模塊:節點發現模塊、事件執行模塊
①節點發現模塊:緩存管道通過監聽固定zk路徑下的變化事件,來維護執行緩存清理的節點信息,供執行緩存清理事件時使用。為了保證一致性,還會每隔一段時間全量
比對節點信息,保障節點信息的正確。
②事件執行模塊:當緩存管道接收到緩存清理事件後,會根據接收事件的編碼,獲取到由開發人員編排的緩存清理節點鏈路,根據鏈路結構通過長鏈接同步執行節點清理
緩存操作,失敗後不會 fast-fail,會最多進行3次重試,完全失敗後存入失敗流水,供後續調度任務掃描繼續重試。
3.執行節點
①節點訂閲與發現:引入緩存管道提供的執行器sdk包的領域服務,在啓動過程中會向固定的 zookeeper 地址寫入節點信息(所屬事件源編碼、ip、執行節點編碼)。
緩存管道監聽到該路徑下的變化後,會在緩存管道的發現中心對節點信息進行維護,供後續清理緩存時調用。
②節點調用與執行:緩存管道通過長鏈接與執行節點進行通信同步獲得調用結果。調用節點分為兩種策略,所有選一對應中心緩存的清理,在所有提供清理中心緩存清理功
能的節點中選取一個進行調用即可。第二種策略為選取所有對應本地緩存的清理,本地緩存的清理需要調用所有提供清理本地緩存的節點。
4.接入方式
緩存管道提供了兩個 sdk,對應事件發送方和緩存清理執行方,讓開發人員方便接入。
①事件發送 sdk 一般接入方為緩存清理事件發起者,例如運營後台。當配置發生變更想要清理緩存時,直接調用提供的sdk即可產生緩存清理事件,然後由緩存管道去執行。
②緩存清理執行 sdk 一般接入方為需要執行緩存清理的服務,即領域服務,他們在運行過程中會讀緩存,當發生配置變更時,他們需要清理自己的緩存信息。
5.緩存事件節點結構配置
每個緩存清理事件都有自己唯一的事件編碼,事件編碼下就是不同緩存清理節點的節點編碼結構關係。我們為這種關係維護提供了運營後台,開發人員可以在完成接入後在運營
後台自行編排緩存清理執行鏈路。這樣所有開發人員也可在運營後台完全直觀的看到所有多級緩存的緩存清理鏈路,不再隱藏在代碼中。
緩存管道全景圖
總結
社交直播緩存管道上線快1年時間,從派對房選取一個小業務作為試點開始,如今已經大規模應用在了社交直播活動業務中,很關鍵的支持了活動擴展點組件、活動交易平台的發展。
中間也經歷過出海改造,海外配合降本部署方式從一個產品一個集羣改造為一個機房一個集羣。後續希望能夠將該系統推廣到更多的業務中去實踐,讓它繼續發展。
雲音樂社交直播活動中台技術團隊,主要負責社交直播相關產品的活動、增值、營收類業務研發,為 Look 直播、聲波、心遇、HeartUp 等相關產品提供一站式的活動中台解決方案,重點圍繞着社交、直播場景營收增值活動架構體系中台化建設為方向。歡迎有興趣的同學一起交流。