# 02-針對商品排行榜,你是怎麼實現的 ## 背景描述 當時產品提出了每日熱銷排行榜在零點進行變更的需求。在我接到這個需求後,我立即想到了使用Redis的有序集合(ZSET)來實現這個功能,並與我們的技術負責人進行了溝通。 經過與技術負責人的討論和確認,我們一致認為使用有序集合是一個可行的解決方案 ...
02-針對商品排行榜,你是怎麼實現的
背景描述
當時產品提出了每日熱銷排行榜在零點進行變更的需求。在我接到這個需求後,我立即想到了使用Redis的有序集合(ZSET)來實現這個功能,並與我們的技術負責人進行了溝通。
經過與技術負責人的討論和確認,我們一致認為使用有序集合是一個可行的解決方案。因此,我進行了技術評審,並得到了批准開始實施該方案。
在實現過程中,我使用了Redis的有序集合數據結構來存儲和排序商品銷量信息。具體而言,我將日期作為有序集合的key,商品ID作為成員(member),銷售數量作為分值(score)。每當有訂單數據更新時,我通過調用ZINCRBY
命令來增加對應商品的銷售數量。這樣,在每天零點之前,所有的訂單數據會被累積到有序集合中。
至於定時更新排行榜數據的功能,我採用了Spring Boot提供的定時任務註解(@Scheduled
)來指定每天零點執行更新操作。在定時任務中,我首先刪除前一天的排行榜數據,然後根據最新的訂單數據重新生成排行榜。
代碼實現
// 記錄訂單數據
public void recordOrderData(String date, String productId, int quantity) {
// 更新有序集合中對應商品的銷售數量
redisTemplate.opsForZSet().incrementScore("daily_ranking_" + date, productId, quantity);
}
// 查詢每日商品銷量排行榜
public List<String> getDailyRanking(String date, int topN) {
// 獲取分值最高的成員,即銷量最高的商品ID
Set<String> members = redisTemplate.opsForZSet().reverseRange("daily_ranking_" + date, 0, topN - 1);
return new ArrayList<>(members);
}
// 定時任務更新排行榜數據(程式員fly)
@Scheduled(cron = "0 0 0 * * ?") // 每天零點執行
public void updateDailyRanking() {
String date = LocalDate.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd")); // 昨天的日期
String today = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); // 今天的日期
// 清除前一天的排行榜數據
redisTemplate.delete("daily_ranking_" + date);
// 根據最新的訂單數據重新生成排行榜(程式員fly)
// 假設從資料庫或緩存中獲取當日的訂單數據,並根據訂單數據更新有序集合的分值
List<Order> orders = orderService.getOrdersByDate(today);
for (Order order : orders) {
String productId = order.getProductId();
int quantity = order.getQuantity();
recordOrderData(today, productId, quantity);
}
}
上述代碼示例中,在實現每日熱銷排行榜的功能時,使用了Redis有序集合來存儲和排序商品銷量信息。對應的方法包括:
recordOrderData
:用於記錄訂單數據,並通過調用incrementScore
命令更新對應日期的有序集合中商品的銷售數量。getDailyRanking
:查詢每日商品銷量排行榜,並通過調用reverseRange
命令獲取分值最高的成員(即銷量最高的商品ID)。updateDailyRanking
:定時任務,在每天零點執行。其中,清除前一天的排行榜數據後,根據最新的訂單數據重新生成排行榜。
擴展點
- 分散式鎖:在多個節點同時執行定時任務時,使用分散式鎖來避免併發訪問的問題。可以使用Redis的分散式鎖機制(如RedLock),通過加鎖和解鎖操作來控制併發訪問,防止重覆記錄或更新排行榜。
- 性能優化:如果每天的訂單數據量較大,可以考慮對數據進行批量處理,減少與Redis的交互次數。例如,可以在一次操作中記錄多個訂單數據,或者使用Redis的pipeline技術進行批量操作。另外,根據實際情況設置合理的分頁查詢或限制每次更新的數量,以平衡性能和及時性
本文由博客一文多發平臺 OpenWrite 發佈!