優化:Toc小程序猜你喜歡功能

引言:來自自創的小程序中熱點接口,本小程序專為在校學生自提點餐使用

一、功能描述

該功能作為一個推薦的職責,根據用戶最近行為給用戶推薦用戶可能喜歡去吃的店鋪,可能比較簡潔,但是需要設計的方面挺多的,需要有三個方面去走:

設計架構如下:

  1. 用戶行為采集
  2. 冷熱數據隔離
  3. 推薦店鋪緩存的預熱
  4. 猜你喜歡接口查詢(核心)

從這些設計上就能保證在使用接口查詢的時候,就不需要花很多時間去分析,保證了熱點接口的響應時間處于較低的一個狀態,不過對于一個熱點接口,不止要保證他的高性能,還需要保證他的高可用,這就需要涉及到降級策略,這些都是一個考量的標準。

二、接口功能實現

用戶行為采集

這里我使用到的技術棧有美團的mzt-Biz-Log框架做類似AOP的切面功能,保證用戶進店行為日志優雅的實現,加上redis進行統計猜你喜歡服務的用戶,使用rocketmq進行日志的統計,實現進店異步化,并且達到削峰限流的效果。

消息隊列的異步化,保證了用戶正常去訪問一個店鋪詳細的體驗,達到日志記錄無感化。

由于消息隊列是異步線程去處理的,傳遞用戶的消息過來很重要,更加方便去獲取到用戶線程id

  • 這里使用到的就是美團的mzt-Biz-Log框架,進行優雅的日志記錄,后續可以新增一個實現類進行高內聚的做具體的日志完善邏輯
  • 注意這里使用了全局唯一自增的id,后續在分表冷熱隔離中會被用到進行刪除數據的操作

使用類似AOP的思想對日志的完善,這里我對用戶數據分了16個表,保證熱點查詢不會聚集在單表中,具體的分表學習可以移步到我這篇文章進行學習:

SpringBoot中使用Sharding-JDBC實戰(實戰+版本兼容+Bug解決)_springboot shardingjdbc-CSDN博客文章瀏覽閱讀3.2k次,點贊23次,收藏37次。這里整理的是使用SpringBoot3.2.4和ShardingSphere-JDBC5.5.0進行分表操作,里面有遇到的bug并且解決的流程,還有結合自己之前做的秒殺博客進行測試分表,很詳細_springboot shardingjdbc https://blog.csdn.net/qq_73440769/article/details/143992138?spm=1001.2014.3001.5502

冷熱數據隔離

這個功能主要由另外的一個博主進行實現,歡迎參考他的文章進行詳細學習:

優化:將針對單一日志表的冷熱數據分離類改造成通用類-CSDN博客文章瀏覽閱讀283次,點贊5次,收藏4次。文章介紹了店鋪推薦系統中日志數據存儲方案的優化過程。原方案將熱數據存入Elasticsearch,現改為存儲冷數據,并針對代碼冗余問題進行重構。通過引入泛型機制實現通用處理類,將固定代碼參數化,同時為不同日志類型提供定制化ES處理邏輯。優化后的方案提升了代碼復用性,支持多日志表并行處理,并通過線程池提高執行效率。文中詳細展示了改進后的代碼實現,包括通用日志處理方法、任務創建機制和重試策略等核心功能模塊。 https://blog.csdn.net/2401_88959292/article/details/148619523?spm=1001.2014.3001.5502其實思想就是:使用定時任務進行隔離一個月之前的數據,將冷數據進行歸檔,保證熱數據才會被用來進行分析,這樣就能極大的削減db的承重,提升查詢效率、釋放 MySQL 壓力,這里隔離的數據庫可以不適用es,可以使用一些實時數倉比較合適。

  • 每天凌晨執行,支持分頁游標 + 泛型處理;
  • 支持所有進店日志的通用遷移;
  • 使用多線程 + 重試機制處理批量插入,保障穩定性。
  • 每類日志各跑一個線程任務,互不干擾

對于怎么不給時間加索引也能保證比較快速的查詢需要隔離的店鋪,首先id是自增的,查16個表中最靠近一個月的最小的id,比這個id小的就是一定需要進行刪除的,或者給時間字段加上索引也是可以的,實現也是使用類似的思想。

推薦店鋪緩存的預熱

目的:為了保證用戶的體驗,將復雜的分析過程放在了凌晨,使用定時任務進行分析,將分析好的結果放進redis,這樣子用戶體驗感就極佳,歡迎參考這位博主的思路:

優化日志分析店鋪推薦方案:用戶范圍的精確度以及ES與MySQL的查詢效率差異-CSDN博客文章瀏覽閱讀785次,點贊6次,收藏15次。本文針對原有店鋪推薦方案的兩個核心問題提出優化方案。問題一是用戶范圍不精確,通過Redis記錄用戶每月首次進店行為作為登錄標識,并統計熱點用戶(月登錄≥14天);問題二是數據處理效率低,改用MySQL存儲熱數據(建立用戶-店鋪映射),ES僅作冷備份。方案采用Lua腳本確保原子性操作,并優化了權重計算模型(店鋪50%、分類30%、分區20%)。最終實現通過分批并行處理用戶日志數據,結合個性化推薦與熱門店鋪補充機制,顯著提升了10萬級用戶日志場景下的推薦效率和精準度。 https://blog.csdn.net/2401_88959292/article/details/148618437?spm=1001.2014.3001.5502

為避免推薦實時計算帶來性能瓶頸,我們采用“離線計算 + 緩存預熱”方式,利用定時任務每天構建用戶維度的推薦結果,緩存到 Redis 中。

  • 用戶分批處理(活躍用戶訪問≥7天),每批200人,異步線程池分析;
  • 推薦維度包括:訪問頻率、店鋪分類、分區,采用加權模型打分;
  • 冷熱數據分離后,在構建推薦時能快速分析歷史行為;
  • 最終結果緩存到 Redis 的 STORE_RECOMMEND_ONE:{userId} 列表中;
  • 未登錄用戶使用通用熱門推薦(Top 打分店鋪)。

這里講一下推薦維度的意義:

我們可以參考先成的推薦系統,比如抖音刷碎片,會有幾個考量:

  • 比如你愛刷這個人視頻比較多,就會給你很多推薦;
  • 比如你喜歡刷這類型視頻比較多,也會給你推薦很多類似的;
  • 比如你比較喜歡刷當前地區的視頻,抖音也會給你推薦很多

參考上面的三點,就可以類比到我們的這些維度。我們會拿出日志,取出這些維度的數據,給每個維度進行賦分,各乘于一個百分比,最后相加得到最后得分,取出前四名的放進最后預熱的結果中。

這里大家可能會想,是給所有用戶進行分析嗎。回答是:不是。因為熱點分析的消耗成本是很大的,有些用戶不是小程序常駐,只是偶爾使用,甚至只是為了體驗一次,這些用戶的話推薦優先級就不是最高的,所以我們會在日志記錄的時候就記錄需要被推薦的用戶,這些用戶的考量標準是:一個月內最少使用一周,這里我使用了redis的自增id進行記錄有哪些用戶一個月內使用了多少次,用set集合保證一個用戶一天最多記錄一次就好,這里就可以得到我需要分析的用戶。

猜你喜歡接口查詢(核心)

這里是重中之重,這里需要保證高性能并且高可用,那就需要避免走db的路線,最好是走緩存。高可用就需要準備一些降級策略,避免服務掛掉。

這個是我對這個接口的設計流程圖,使用了多層的降級策略,保證了接口的高可用。

如果登錄的用戶沒有對應的推薦緩存或者沒有登錄的用戶,需要走降級策略:

1、第一層降級

這里會取出默認策略中推薦的緩存店鋪,如果有很特殊的情況導致這些緩存失效了,就需要繼續服務降級去完善默認推薦的緩存店鋪

2、第二層降級

這里如果沒有推薦店鋪就會去redis里面去隨機四個店鋪進行填充,這里為啥不用分布式鎖保證只有一個用戶更新默認推薦店鋪,可以這樣子理解,在一開始有預檢,一家很大程度的避免有不同推薦店鋪的行為,即使在短時間內有很多線程過了這個預檢測,我基于redis單線程的特性,指令在機器里面是單線程執行的特性,使用lua腳本保證各個線程執行指令的有序性,就能保證只有第一個線程的策略是實施的,后續線程的策略都不會成功,大家可能又會想,還是存在很多用戶推薦店鋪的數據不一致啊,再換個角度,我們這里的推薦店鋪都是一個隨機策略,哪怕是不同用戶的推薦不同又有什么問題呢嗎,下面給出lua腳本的實現:

其實大家會發現,這里使用了redis進行隨機,就可能極端情況下會出現緩存一致性的問題,出現這個問題,那就繼續服務降級。不過有個情況是不可能出現問題的,出現也會在及其短的時間內進行避免,可以關注下面這段代碼:

如果這個店鋪ids集合的數據量少于4,就會導致這些線程在不斷的更新默認店鋪的緩存,這豈不是災難性的,其實這個redis緩存和店鋪詳細緩存在小程序各個接口中多多少少都用到了,如果沒有了,點開小程序,也會啟動別的接口進行redis緩存的重構,對于我們目前小卡拉米小程序,還是不需要考慮這點帶來的影響,并發并沒美團那么高。

3、第三層降級

根據上一點講過的緩存不一致問題,也就是和db的不一致,redis中ids緩存和店鋪集合緩存不一致的問題,關于和db的不一致問題,很多方案都是加鎖,然后只用一個線程進行查db更新緩存,避免緩存擊穿;關于第二個不一致問題,我在那個流程圖里面有做了解釋,大家可以參考一下。

4、第四層降級

可以參考第三層降級里面,如果遇到了緩存穿透,就需要走空緩存的策略進一步一面,繼續服務降級,通過上面四層的降級,我覺得整個接口處于相對比較好的高可用狀態。

三、優化

可以看到上面第一版的方案中,我是拿到一個店鋪id就去redis查一個店鋪,這種就會帶來一個問題,無法充分利用redis的性能,對于傳輸網絡的開銷還是很大的,就會導致大部分時間浪費在網絡上了,所以我把多次用單個id去查redis改為一次用多個id去查redis。

1、優化方案實現

完善前:

完善后:

優化了多次網絡帶來的開銷:

第一次降級前代碼不變。

具體修改為多次查詢的邏輯:

具體使用:

默認策略修復:

2、性能測試

這里博主已經做了多次測試,下面的數據大致是均值的水平,所以只提供了一份測試數據(測試默認緩存帶來的優化)

(1)響應測試(ABtest):

優化前:

緩存重構的時候(203ms):

緩存不重構的時候(135ms):

優化后:

緩存重構的時候(155ms):

緩存不重構的時候(75ms):

在對推薦緩存邏輯進行優化后,系統整體響應時間得到了明顯改善。

  • 緩存不重構的場景下,響應時間從 135ms 降至 76ms,優化幅度約為 43.7%
  • 緩存重構的場景中,響應時間從 203ms 降至 155ms,優化幅度約為 23.6%

(2)jmeter測吞吐量

這里博主jmeter配置有些問題,雖然是異常,但是是正常走代碼邏輯的。

1000用戶qps1000測試(225.6/sec):

1用戶qps1000測試(654.9/sec):?

四、最后

歡迎大家給更多的建議,toc菜鳥希望可以得到更多好的方案進行學習,期待大家指點。

大家也可以關注一下這個博主,這個功能是由我們兩個共同進行一個實現和完善:

Yilena-CSDN博客Yilena擅長八股輕松學,業務場景方案分析以及優化方案,解決方案,等方面的知識 https://blog.csdn.net/2401_88959292?type=blog

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90819.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90819.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90819.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Datawhale AI 夏令營:讓AI理解列車排期表 Notebook(Baseline拆解)

Step1、讀取數據 import pandas as pd import requests import re import json from tqdm import tqdm# 讀取數據 data pd.read_excel(data/info_table.xlsx) data data.fillna(無數據) dataStep2、注冊硅基流動https://cloud.siliconflow.cnQwen/Qwen3-8B 模型可以免費使用&…

vue寫的app設置角標

原生App角標(UniApp示例)調用plus.runtime.setBadgeNumber方法設置安卓/iOS角標:javascriptCopy Code// 設置角標 plus.runtime.setBadgeNumber(99); // 清除角標(部分平臺需特殊處理) plus.runtime.setBadgeNumber(0)…

GAN/cGAN中到底要不要注入噪聲

MelGAN論文MelGAN針對的是從mel譜生成語音,里面說當條件很強的時候,隨機噪聲就沒啥用了,因此沒將noise注入到生成器中;運用的判別器也僅有1個輸入,不是cGAN的形式image-to-image translation with conditional adversa…

備份一下我的 mac mini 的環境變量配置情況

export PATH“/opt/homebrew/bin:$PATH” #THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!! export SDKMAN_DIR“HOME/.sdkman"[[?s"HOME/.sdkman" [[ -s "HOME/.sdkman"[[?s"HOME/.sdkman/bin/sdkman-init.sh” ]] && so…

JVM學習日記(十)Day10

G1回收器 這一篇是詳細說明G1回收器的,因為他相對來說確實是個縫合怪,上篇的內容又太多了所不清楚,所有這一篇進行詳細的說明, 第一個呢就是其實G1是兼顧并行和并發的,簡單來說就是既可以并行也可以并發,…

使用IP掃描工具排查網絡問題

隨著企業的發展,網絡中會新增各類設備,從臺式機、服務器到物聯網設備和虛擬機(VMs),所有這些設備都通過復雜的子網和虛擬局域網(VLAN)相連。 這種復雜性給 IT 團隊帶來了壓力,他們需…

Wireshark TS | 發送數據超出接收窗口

前言 來自于測試中無意發現到的一個接收窗口滿的案例,特殊,或者可以說我以前都沒在實際場景中見過。一開始都沒整太明白,花了些精力才算是弄清楚了些,記錄分享下。 問題說明 在研究擁塞控制的慢啟動階段時,通過 packet…

C語言自定義數據類型詳解(四)——聯合體

好的,接下來我們來學習最后一個自定義數據類型——聯合體。 一、什么是聯合體: 聯合體又叫共用體,用關鍵字union來進行定義。又因為所有的成員變量共用同一段內存空間(關于這一點,我們不久就會加以驗證)&…

[python][flask]Flask-Login 使用詳解

1. 簡介Flask-Login 是 Flask 的一個擴展,專門用于處理用戶認證相關的功能。它提供了用戶會話管理、登錄/注銷視圖、記住我功能等常見認證需求,讓開發者能夠快速實現安全的用戶認證系統。2. 安裝與基礎配置首先,需要安裝 Flask-Login&#xf…

【WebGPU學習雜記】WebAssembly中的relaxed_madd指令到底做了什么?

relaxed_madd 這條指令到底做了什么核心&#xff1a;relaxed_madd 是一個分量級別 (Component-wise) 的操作 首先&#xff0c;最重要的一點是&#xff1a;v128.relaxed_madd<f32>(a, b, c) 不是矩陣乘法。它是一個在三個向量 a, b, c 之間進行的、逐個分量的、并行的融合…

【全新上線】境內 Docker 鏡像狀態監控

境內 Docker 鏡像狀態監控&#xff1a;您的 Docker 加速伴侶 在當今云計算和容器化技術飛速發展的時代&#xff0c;Docker 已成為開發者不可或缺的工具。然而&#xff0c;對于身處國內的用戶而言&#xff0c;訪問境外 Docker Hub 等鏡像倉庫時常會遭遇網絡延遲和連接不穩定的困…

Visual Studio中部署PaddleOCRv5 (借助ncnn框架)

PaddleOCRv5_ncnn PaddleOCRv5 在Visual Studio中進行圖片OCR檢測&#xff08;ncnn框架open-mobile實現)&#xff0c;嘗試對nihui的ncnn-android-ppocrv5檢測算法的剝離與移植。 本項目Github鏈接如下&#xff1a;PaddleOCRv5_ncnn 寫在前面 本倉庫代碼是基于nihui的ncnn-a…

中級全棧工程師筆試題

解釋ACID特性&#xff0c;如何在node.js中實現事務操作針對React單頁應用&#xff0c;請提供至少5種性能優化方案&#xff0c;并解釋其原理&#xff1a; 減少首屏加載時間優化渲染性能資源加載策略狀態管理優化代碼分割方案 如何防止以下攻擊&#xff1a; JWT令牌挾持Graph QL查…

Windows---動態鏈接庫Dynamic Link Library(.dll)

DLL的“幕后英雄”角色 在Windows操作系統的生態中&#xff0c;有一類文件始終扮演著“幕后英雄”的角色——它們不像.exe文件那樣直接呈現為用戶可見的程序窗口&#xff0c;卻支撐著幾乎所有應用程序的運行&#xff1b;它們不單獨執行&#xff0c;卻承載著系統與軟件的核心功…

深入分析計算機網絡傳輸層和應用層面試題

三、傳輸層面試題&#xff08;Transmission Layer&#xff09;傳輸層位于 OSI 七層模型的第四層&#xff0c;它的核心任務是為兩個主機之間的應用層提供可靠的數據傳輸服務。它不僅承擔了數據的端到端傳輸&#xff0c;而且還實現了諸如差錯檢測、數據流控制、擁塞控制等機制&am…

【RH134 問答題】第 2 章 調度未來任務

目錄crontab 文件中的用戶作業時間格式怎么解釋&#xff1f;如果需要以當前用戶身份計劃周期性作業&#xff0c;在上午 8 點到晚上 9 點之間每兩分鐘一次輸出當前日期和時間&#xff0c;該作業只能在周一到周五運行&#xff0c;周六或周日不能運行。要怎么做&#xff1f;要計劃…

【ee類保研面試】通信類---信息論

25保研er&#xff0c;希望將自己的面試復習分享出來&#xff0c;供大家參考 part0—英語類 part1—通信類 part2—信號類 part3—高數類 part100—self項目準備 文章目錄**面試復習總綱****Chap2: 熵、相對熵和互信息 (Entropy, Relative Entropy, and Mutual Information)****…

vue2+node+express+MongoDB項目安裝啟動啟動

文章目錄 準備環境 安裝MongoDB 安裝 MongoDB Compass(圖形化數據庫管理工具) 安裝 Postman(接口測試工具) 項目結構 配置項目代理 項目啟動 提交項目 生成Access Token 準備環境 默認含有node.js、npm 安裝MongoDB 下載地址:https://www.mongodb.com/try/download/com…

JavaEE初階第十二期:解鎖多線程,從 “單車道” 到 “高速公路” 的編程升級(十)

專欄&#xff1a;JavaEE初階起飛計劃 個人主頁&#xff1a;手握風云 目錄 一、多線程案例 1.1. 定時器 一、多線程案例 1.1. 定時器 定時器是軟件開發的一個重要組件&#xff0c;是一種能夠按照預設的時間間隔或在特定時間點執行某個任務或代碼片段的機制。你可以把它想象成…

EDoF-ToF: extended depth of field time-of-flight imaging解讀, OE 2021

1. 核心問題&#xff1a;iToF相機的“景深”死穴我們之前已經詳細討論過&#xff0c;iToF相機的“景深”&#xff08;有效測量范圍&#xff09;受到光學散焦的嚴重制約。問題根源&#xff1a; 當iToF相機的鏡頭散焦時&#xff0c;來自場景不同深度的光信號會在傳感器像素上發生…