Redis在項目中常見的12種使用場景示例和說明
Redis 是一個開源的高性能鍵值對數(shù)據(jù)庫,它以其內(nèi)存中數(shù)據(jù)存儲、鍵過期策略、持久化、事務(wù)、豐富的數(shù)據(jù)類型支持以及原子操作等特性,在許多項目中扮演著關(guān)鍵角色。以下是整理的12個Redis在項目中常見的使用場景舉例說明和解釋。
1.計數(shù)器
針對Redis作為排行榜和計數(shù)器的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis來實現(xiàn)一個簡單的文章點贊功能,并將點贊數(shù)用作排行榜的依據(jù)。
場景描述
假設(shè)我們正在開發(fā)一個博客平臺,用戶可以對文章進行點贊。
我們希望根據(jù)文章的點贊數(shù)來顯示一個實時更新的熱門文章排行榜。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis 服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 定義文章實體類
public class Article {
private String id;
private String title;
private int likeCount;
// 省略構(gòu)造函數(shù)、getter和setter方法
}2 創(chuàng)建文章服務(wù)接口和實現(xiàn)類
@Service
public class ArticleService {
@Autowired
private StringRedisTemplate redisTemplate;
public void likeArticle(String articleId) {
// 增加文章的點贊數(shù)
redisTemplate.opsForValue().increment(articleId, 1);
}
public List<Article> getTopLikedArticles(int topN) {
// 獲取topN個點贊數(shù)最多的文章
Set<String> articleIds = redisTemplate.keys("article:*:likeCount");
List<Article> topArticles = new ArrayList<>();
for (String id : articleIds) {
int likeCount = (Integer) redisTemplate.opsForValue().get(id);
Article article = new Article();
article.setId(id.replace("article:", "").replace(":likeCount", ""));
article.setTitle("文章標題待查詢");
article.setLikeCount(likeCount);
topArticles.add(article);
}
// 根據(jù)點贊數(shù)排序
topArticles.sort((a1, a2) -> a2.getLikeCount() - a1.getLikeCount());
return topArticles.subList(0, topN);
}
}3 創(chuàng)建控制器
@RestController
@RequestMapping("/articles")
public class ArticleController {
@Autowired
private ArticleService articleService;
@PostMapping("/{id}/like")
public ResponseEntity<String> likeArticle(@PathVariable String id) {
articleService.likeArticle(id);
return ResponseEntity.ok("點贊成功");
}
@GetMapping("/top/{topN}")
public ResponseEntity<List<Article>> getTopLikedArticles(@PathVariable int topN) {
List<Article> topArticles = articleService.getTopLikedArticles(topN);
return ResponseEntity.ok(topArticles);
}
}詳細解釋

通過這種方式,我們可以利用Redis的原子操作和高性能特性來實現(xiàn)一個高效的點贊和排行榜功能。
每次用戶點贊時,Redis都會原子性地更新點贊數(shù),而獲取排行榜時,我們可以快速地從Redis中檢索和排序數(shù)據(jù),從而提供實時的熱門文章排行。
2. 實時分析
針對Redis作為實時分析使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis的Sorted Set來實現(xiàn)一個簡單的用戶在線時長統(tǒng)計和分析功能。
場景描述
假設(shè)我們正在開發(fā)一個在線教育平臺,需要統(tǒng)計每個用戶的在線時長,并根據(jù)這些數(shù)據(jù)生成實時的在線時長排行榜。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 用戶在線時長服務(wù)接口和實現(xiàn)類
@Service
public class OnlineDurationService {
@Autowired
private StringRedisTemplate redisTemplate;
public void updateUserOnlineDuration(String userId, long duration) {
// 使用Sorted Set存儲用戶ID和在線時長
redisTemplate.opsForZSet().incrementScore("user:online:duration", userId, duration);
}
public Set<String> getTopUsersByOnlineDuration(int topN) {
// 獲取在線時長最長的前N個用戶
Set<String> topUsers = redisTemplate.opsForZSet().reverseRange("user:online:duration", 0, topN - 1);
return topUsers;
}
}2 用戶登錄和登出邏輯
@Controller
public class UserController {
@Autowired
private OnlineDurationService onlineDurationService;
@PostMapping("/user/{userId}/login")
public ResponseEntity<String> userLogin(@PathVariable String userId) {
// 用戶登錄邏輯,可以是任何觸發(fā)登錄的事件
return ResponseEntity.ok("User " + userId + " logged in");
}
@PostMapping("/user/{userId}/logout")
public ResponseEntity<String> userLogout(@PathVariable String userId) {
// 用戶登出時記錄在線時長
long duration = // 計算用戶在線時長的邏輯
onlineDurationService.updateUserOnlineDuration(userId, duration);
return ResponseEntity.ok("User " + userId + " logged out");
}
}3 獲取在線時長排行榜
@RestController
@RequestMapping("/users")
public class UserRankController {
@Autowired
private OnlineDurationService onlineDurationService;
@GetMapping("/online-duration/top/{topN}")
public ResponseEntity<Set<String>> getTopUsersByOnlineDuration(@PathVariable int topN) {
Set<String> topUsers = onlineDurationService.getTopUsersByOnlineDuration(topN);
return ResponseEntity.ok(topUsers);
}
}詳細解釋

通過這種方式,我們可以利用Redis的Sorted Set來存儲和排序用戶的在線時長,實現(xiàn)一個高效的實時在線時長統(tǒng)計和分析功能。
每當(dāng)用戶登出時,系統(tǒng)都會更新用戶的在線時長,并可以快速地根據(jù)在線時長對用戶進行排名,從而提供一個動態(tài)的在線時長排行榜。這對于在線教育平臺等需要監(jiān)控用戶活躍度的業(yè)務(wù)場景非常有用。
3. 分布式鎖
針對Redis作為分布式鎖的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redisson作為客戶端來實現(xiàn)分布式鎖。
場景描述
假設(shè)我們有一個高流量的電子商務(wù)網(wǎng)站,需要執(zhí)行一些資源密集型的操作,比如生成日報表。為了防止多個實例同時執(zhí)行這些操作,我們需要一個分布式鎖來確保每次只有一個實例可以執(zhí)行這些操作。
創(chuàng)建Spring Boot項目
配置Redisson連接
在src/main/resources/application.properties或application.yml中配置Redisson客戶端連接到Redis服務(wù)器:
# application.properties redisson.address=redis://localhost:6379
或者
# application.yml redisson: address: "redis://localhost:6379"
編寫業(yè)務(wù)代碼
1 配置Redisson
創(chuàng)建一個配置類來配置Redisson客戶端。
@Configuration
public class RedissonConfig {
@Bean(destroyMethod = "shutdown")
public RedissonClient redissonClient() {
RedissonClientConfig config = new RedissonClientConfig();
config.useSingleServer().setAddress(redisson.address);
return Redisson.create(config);
}
@Value("${redisson.address}")
private String redissonAddress;
}2 使用分布式鎖
創(chuàng)建一個服務(wù)類來執(zhí)行需要分布式鎖保護的資源密集型操作。
@Service
public class ReportService {
@Autowired
private RedissonClient redissonClient;
public void generateDailyReport() {
RLock lock = redissonClient.getLock("dailyReportLock");
try {
// 嘗試獲取鎖,最多等待3秒,鎖的自動過期時間設(shè)置為10秒
if (lock.tryLock(3, 10, TimeUnit.SECONDS)) {
// 執(zhí)行生成日報表的操作
System.out.println("Generating daily report...");
// 模擬長時間運行的任務(wù)
TimeUnit.SECONDS.sleep(5);
System.out.println("Daily report generated.");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
// 釋放鎖
lock.unlock();
}
}
}3 創(chuàng)建控制器
創(chuàng)建一個控制器來觸發(fā)生成日報表的操作。
@RestController
@RequestMapping("/reports")
public class ReportController {
@Autowired
private ReportService reportService;
@GetMapping("/daily")
public ResponseEntity<String> generateDailyReport() {
reportService.generateDailyReport();
return ResponseEntity.ok("Daily report generation triggered.");
}
}詳細解釋

通過這種方式,我們可以確保在分布式系統(tǒng)中,即使有多個實例運行,也只有一個實例可以執(zhí)行生成日報表的操作,從而避免資源沖突和重復(fù)勞動。
Redisson客戶端簡化了Redis分布式鎖的使用,使得在Spring Boot應(yīng)用中實現(xiàn)分布式鎖變得簡單而高效。
4. 限流
針對Redis作為限流功能的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis來實現(xiàn)API的限流。
場景描述
假設(shè)我們正在開發(fā)一個公共API服務(wù),該服務(wù)需要對外部請求進行限流,以防止濫用和過載。我們希望對每個IP地址每分鐘的請求次數(shù)進行限制。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 創(chuàng)建限流注解
定義一個自定義注解,用于標識需要限流的API。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
int limit() default 10; // 默認每分鐘請求次數(shù)限制
long timeout() default 60; // 默認時間窗口為60秒
}2 創(chuàng)建限流攔截器
實現(xiàn)一個攔截器來檢查請求頻率。
public class RateLimiterInterceptor implements HandlerInterceptor {
private final RedisTemplate<String, Integer> redisTemplate;
private final String rateLimitKeyPrefix = "rate_limit:";
public RateLimiterInterceptor(RedisTemplate<String, Integer> redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String ip = request.getRemoteAddr();
String methodName = ((MethodSignature) (handler)).getMethod().getName();
String rateLimitKey = rateLimitKeyPrefix + methodName + ":" + ip;
int currentCount = redisTemplate.opsForValue().increment(rateLimitKey);
if (currentCount > 1) {
// 如果當(dāng)前計數(shù)大于1,則說明請求已超過限制
response.sendError(HttpServletResponse.SC_TOO_MANY_REQUESTS, "Too many requests, please try again later.");
return false;
}
// 設(shè)置過期時間
redisTemplate.expire(rateLimitKey, RateLimit.class.cast(((MethodSignature) handler).getMethod().getAnnotation(RateLimit.class)).timeout(), TimeUnit.SECONDS);
return true;
}
}3 配置攔截器
配置攔截器以應(yīng)用于所有控制器。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private RateLimiterInterceptor rateLimiterInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(rateLimiterInterceptor);
}
}4 應(yīng)用限流注解
在需要限流的API上應(yīng)用自定義的RateLimit注解。
@RestController
public class ApiController {
@RateLimit(limit = 5, timeout = 60) // 每分鐘最多5個請求
@GetMapping("/api/resource")
public ResponseEntity<String> getLimitedResource() {
return ResponseEntity.ok("Access to limited resource");
}
}詳細解釋

通過這種方式,我們可以利用Redis的原子遞增操作和鍵過期特性來實現(xiàn)API的限流。
每次請求都會檢查當(dāng)前IP的請求計數(shù),如果超過限制,則返回429錯誤碼(Too Many Requests)。
這有助于保護API免受濫用,并確保服務(wù)的穩(wěn)定性和可用性。
5. 全頁緩存
針對Redis作為全頁緩存的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis來緩存整個頁面的HTML內(nèi)容。
場景描述
假設(shè)我們正在開發(fā)一個新聞網(wǎng)站,該網(wǎng)站的首頁包含多個新聞文章的摘要信息。由于首頁訪問頻率很高,我們希望將整個首頁的內(nèi)容緩存起來,以減少數(shù)據(jù)庫的查詢次數(shù)和頁面渲染時間。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 創(chuàng)建新聞文章服務(wù)
@Service
public class NewsService {
// 假設(shè)有一個方法來獲取新聞列表
public List<Article> getNewsList() {
// 這里是獲取新聞列表的邏輯
return Collections.emptyList();
}
}2 配置Redis緩存
創(chuàng)建一個配置類來設(shè)置Spring Cache和Redis緩存。
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
RedisCacheManager cacheManager = new RedisCacheManager(connectionFactory);
// 設(shè)置緩存過期時間(例如5分鐘)
cacheManager.setDefaultExpiration(300);
return cacheManager;
}
}3 創(chuàng)建控制器和視圖
創(chuàng)建一個控制器來返回首頁,并使用Redis緩存整個頁面。
@Controller
public class NewsController {
@Autowired
private NewsService newsService;
@Autowired
private CacheManager cacheManager;
@GetMapping("/")
@Cacheable(value = "homePage", condition = "#root.caches[0].name == 'homePage'")
public String homePage(Model model) {
// 嘗試從緩存中獲取頁面
model.addAttribute("newsList", newsService.getNewsList());
return "home";
}
}4 創(chuàng)建Thymeleaf模板
創(chuàng)建一個Thymeleaf模板home.html來渲染首頁。
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>首頁</title>
</head>
<body>
<h1>新聞首頁</h1>
<div th:each="article : ${newsList}">
<h2 th:text="${article.title}"></h2>
<p th:text="${article.summary}"></p>
</div>
</body>
</html>詳細解釋

通過這種方式,我們可以利用Redis來緩存整個頁面的內(nèi)容。
首頁的訪問非常頻繁,通過緩存可以顯著減少數(shù)據(jù)庫的查詢次數(shù)和頁面渲染時間,提高網(wǎng)站的響應(yīng)速度和性能。
此外,Spring的緩存抽象和Thymeleaf模板使得實現(xiàn)全頁緩存變得簡單而高效。
6. 社交功能
針對Redis作為社交功能存儲的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis來存儲用戶的社交關(guān)系信息,如好友列表和用戶狀態(tài)更新。
場景描述
假設(shè)我們正在開發(fā)一個社交網(wǎng)絡(luò)平臺,用戶可以添加好友,并且可以發(fā)布狀態(tài)更新。我們需要存儲每個用戶的好友列表以及狀態(tài)更新的時間線。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 定義用戶和狀態(tài)更新實體類
public class User {
private String id;
private String name;
// 省略構(gòu)造函數(shù)、getter和setter方法
}
public class StatusUpdate {
private String userId;
private String content;
private Instant timestamp;
// 省略構(gòu)造函數(shù)、getter和setter方法
}2 創(chuàng)建社交服務(wù)
@Service
public class SocialService {
@Autowired
private StringRedisTemplate redisTemplate;
public void addFriend(String userOneId, String userTwoId) {
// 使用集合存儲用戶的好友列表
redisTemplate.opsForSet().add("friends:" + userOneId, userTwoId);
redisTemplate.opsForSet().add("friends:" + userTwoId, userOneId);
}
public Set<String> getFriends(String userId) {
// 獲取用戶的好友列表
return redisTemplate.opsForSet().members("friends:" + userId);
}
public void postStatusUpdate(String userId, String content) {
// 使用列表存儲用戶的狀態(tài)更新時間線
StatusUpdate statusUpdate = new StatusUpdate(userId, content, Instant.now());
redisTemplate.opsForList().rightPush("timeline:" + userId, statusUpdate);
}
public List<StatusUpdate> getStatusUpdates(String userId) {
// 獲取用戶的狀態(tài)更新時間線
return redisTemplate.opsForList().range("timeline:" + userId, 0, -1);
}
}3 創(chuàng)建控制器
@RestController
@RequestMapping("/social")
public class SocialController {
@Autowired
private SocialService socialService;
@PostMapping("/addFriend")
public ResponseEntity<String> addFriend(@RequestParam String userOneId, @RequestParam String userTwoId) {
socialService.addFriend(userOneId, userTwoId);
return ResponseEntity.ok("Friends added successfully");
}
@GetMapping("/friends/{userId}")
public ResponseEntity<Set<String>> getFriends(@PathVariable String userId) {
Set<String> friends = socialService.getFriends(userId);
return ResponseEntity.ok(friends);
}
@PostMapping("/status")
public ResponseEntity<String> postStatusUpdate(@RequestParam String userId, @RequestParam String content) {
socialService.postStatusUpdate(userId, content);
return ResponseEntity.ok("Status updated successfully");
}
@GetMapping("/timeline/{userId}")
public ResponseEntity<List<StatusUpdate>> getStatusUpdates(@PathVariable String userId) {
List<StatusUpdate> updates = socialService.getStatusUpdates(userId);
return ResponseEntity.ok(updates);
}
}詳細解釋

通過這種方式,我們可以利用Redis的高性能和數(shù)據(jù)結(jié)構(gòu)特性來實現(xiàn)社交網(wǎng)絡(luò)平臺中的社交功能。
Redis的Set和List數(shù)據(jù)結(jié)構(gòu)非常適合存儲和管理好友關(guān)系和狀態(tài)更新時間線,能夠提供快速的讀寫性能,滿足社交網(wǎng)絡(luò)平臺的需求。
7. 實時推薦系統(tǒng)
針對Redis作為實時推薦系統(tǒng)存儲的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis來存儲用戶行為數(shù)據(jù)和偏好,以及提供一個簡單的推薦功能。
場景描述
假設(shè)我們正在開發(fā)一個電子商務(wù)平臺,我們希望根據(jù)用戶的瀏覽和購買歷史來推薦商品。我們將使用Redis來存儲用戶的這些行為數(shù)據(jù),并根據(jù)這些數(shù)據(jù)生成推薦。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 創(chuàng)建商品和用戶實體類
public class Product {
private String id;
private String name;
// 省略構(gòu)造函數(shù)、getter和setter方法
}
public class User {
private String id;
private String username;
// 省略構(gòu)造函數(shù)、getter和setter方法
}2 創(chuàng)建推薦服務(wù)
@Service
public class RecommendationService {
@Autowired
private StringRedisTemplate redisTemplate;
public void recordView(String userId, String productId) {
// 記錄用戶查看的商品
redisTemplate.opsForList().leftPush("user:" + userId + ":views", productId);
}
public List<String> recommendProducts(String userId) {
// 簡單推薦算法:返回用戶查看次數(shù)最多的商品
Set<String> viewedProducts = redisTemplate.opsForSet().members("user:" + userId + ":views");
Map<String, Long> productViewCounts = new HashMap<>();
viewedProducts.forEach(productId -> {
long count = redisTemplate.opsForValue().decrement("user:" + userId + ":views:" + productId);
productViewCounts.put(productId, count);
});
return productViewCounts.entrySet().stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
}3 創(chuàng)建控制器
@RestController
@RequestMapping("/recommendations")
public class RecommendationController {
@Autowired
private RecommendationService recommendationService;
@PostMapping("/view")
public ResponseEntity<String> recordProductView(@RequestParam String userId, @RequestParam String productId) {
recommendationService.recordView(userId, productId);
return ResponseEntity.ok("View recorded");
}
@GetMapping("/products")
public ResponseEntity<List<String>> getRecommendations(@RequestParam String userId) {
List<String> recommendedProducts = recommendationService.recommendProducts(userId);
return ResponseEntity.ok(recommendedProducts);
}
}詳細解釋

通過這種方式,我們可以利用Redis的高性能和簡單的數(shù)據(jù)結(jié)構(gòu)來快速記錄用戶行為并生成推薦。
雖然這里的推薦算法非常簡單,但它展示了如何使用Redis來實現(xiàn)實時推薦系統(tǒng)的基礎(chǔ)功能。
在實際應(yīng)用中,推薦算法可能會更復(fù)雜,涉及機器學(xué)習(xí)模型和更豐富的用戶行為數(shù)據(jù)。
8. 地理位置信息
針對Redis作為地理位置信息存儲的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis的Geospatial索引來實現(xiàn)基于地理位置的推薦功能。
場景描述
假設(shè)我們正在開發(fā)一款基于位置的社交應(yīng)用,用戶可以查看附近的其他用戶或地點。我們需要存儲用戶的地理位置,并能夠查詢給定位置附近的用戶。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 創(chuàng)建用戶實體類
public class User {
private String id;
private String name;
private double longitude;
private double latitude;
// 省略構(gòu)造函數(shù)、getter和setter方法
}2 創(chuàng)建地理位置服務(wù)
@Service
public class GeoLocationService {
@Autowired
private RedisTemplate<String, User> redisTemplate;
public void addLocation(String userId, double longitude, double latitude) {
User user = new User(userId, "username", longitude, latitude);
// 使用Geospatial索引存儲用戶位置
redisTemplate.opsForGeo().add("userLocations", new GeoLocation(user.getLongitude(), user.getLatitude()), userId);
}
public List<User> getUsersNearby(double longitude, double latitude, double radius) {
// 查詢給定位置附近的用戶
List<GeoWithin> nearbyUsersGeo = redisTemplate.opsForGeo().radius("userLocations",
new Circle(new GeoCoordinate(latitude, longitude), radius),
RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs());
List<User> nearbyUsers = new ArrayList<>();
for (GeoWithin geoWithin : nearbyUsersGeo) {
nearbyUsers.add(redisTemplate.opsForValue().get(geoWithin.getMember()));
}
return nearbyUsers;
}
}3 創(chuàng)建控制器
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private GeoLocationService geoLocationService;
@PostMapping("/addLocation")
public ResponseEntity<String> addLocation(@RequestParam String userId,
@RequestParam double longitude,
@RequestParam double latitude) {
geoLocationService.addLocation(userId, longitude, latitude);
return ResponseEntity.ok("User location added");
}
@GetMapping("/nearby")
public ResponseEntity<List<User>> getUsersNearby(@RequestParam double longitude,
@RequestParam double latitude,
@RequestParam double radius) {
List<User> nearbyUsers = geoLocationService.getUsersNearby(longitude, latitude, radius);
return ResponseEntity.ok(nearbyUsers);
}
}詳細解釋

通過這種方式,我們可以利用Redis的Geospatial索引來存儲和查詢地理位置信息。這對于需要基于地理位置提供服務(wù)的應(yīng)用非常有用,如社交網(wǎng)絡(luò)、共享出行、本地服務(wù)推薦等。
Redis的Geospatial索引提供了高效的鄰近查詢功能,可以快速找到指定范圍內(nèi)的用戶或其他地理位置相關(guān)的實體。
9. 時間序列數(shù)據(jù)
針對Redis作為時間序列數(shù)據(jù)存儲的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis來存儲和查詢時間序列數(shù)據(jù)。
場景描述
假設(shè)我們正在開發(fā)一個監(jiān)控系統(tǒng),需要記錄服務(wù)器的CPU使用率隨時間變化的數(shù)據(jù)。我們將使用Redis的時間序列數(shù)據(jù)結(jié)構(gòu)來存儲這些監(jiān)控數(shù)據(jù),并能夠查詢?nèi)我鈺r間范圍內(nèi)的CPU使用率。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 創(chuàng)建監(jiān)控數(shù)據(jù)實體類
public class CpuUsageData {
private Instant timestamp;
private double cpuUsage;
// 省略構(gòu)造函數(shù)、getter和 setter 方法
}2 創(chuàng)建監(jiān)控服務(wù)
@Service
public class MonitoringService {
@Autowired
private LettuceConnectionFactory connectionFactory;
public void logCpuUsage(String serverId, double cpuUsage) {
// 記錄CPU使用率數(shù)據(jù)
CpuUsageData data = new CpuUsageData(Instant.now(), cpuUsage);
// 使用Lettuce客戶端的命令執(zhí)行器來與RedisTimeSeries模塊交互
StatefulRedisConnection<String, CpuUsageData> connection = connectionFactory.connect();
try {
RedisTimeSeriesCommands<String, CpuUsageData> ts = connection.sync();
ts.add(serverId, data.getTimestamp().toEpochMilli() / 1000, data);
} finally {
connection.close();
}
}
public List<CpuUsageData> getCpuUsageHistory(String serverId, Instant start, Instant end) {
// 查詢指定時間范圍內(nèi)的CPU使用率歷史數(shù)據(jù)
List<CpuUsageData> history = new ArrayList<>();
StatefulRedisConnection<String, CpuUsageData> connection = connectionFactory.connect();
try {
RedisTimeSeriesCommands<String, CpuUsageData> ts = connection.sync();
Range range = Range.create(start.toEpochMilli() / 1000, end.toEpochMilli() / 1000);
Cursor<CpuUsageData> cursor = ts.rangeRead(serverId, range);
while (cursor.hasNext()) {
history.add(cursor.next().getValue());
}
} finally {
connection.close();
}
return history;
}
}3 創(chuàng)建控制器
@RestController
@RequestMapping("/monitoring")
public class MonitoringController {
@Autowired
private MonitoringService monitoringService;
@PostMapping("/logCpuUsage")
public ResponseEntity<String> logCpuUsage(@RequestParam String serverId, @RequestParam double cpuUsage) {
monitoringService.logCpuUsage(serverId, cpuUsage);
return ResponseEntity.ok("CPU usage logged");
}
@GetMapping("/cpuUsageHistory")
public ResponseEntity<List<CpuUsageData>> getCpuUsageHistory(@RequestParam String serverId,
@RequestParam Instant start,
@RequestParam Instant end) {
List<CpuUsageData> history = monitoringService.getCpuUsageHistory(serverId, start, end);
return ResponseEntity.ok(history);
}
}詳細解釋

通過這種方式,我們可以利用Redis的RedisTimeSeries模塊來存儲和查詢時間序列數(shù)據(jù)。這對于需要監(jiān)控和分析隨時間變化的數(shù)據(jù)的應(yīng)用非常有用,如服務(wù)器監(jiān)控、網(wǎng)站訪問量分析等。
RedisTimeSeries提供了高效的時間序列數(shù)據(jù)存儲和查詢功能,可以快速插入和檢索大量時間戳數(shù)據(jù)。
10. 任務(wù)調(diào)度
針對Redis作為任務(wù)調(diào)度的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis的延遲隊列特性來實現(xiàn)任務(wù)調(diào)度。
場景描述
假設(shè)我們正在開發(fā)一個定時任務(wù)管理系統(tǒng),需要安排一些任務(wù)在將來的某個時間點執(zhí)行。我們將使用Redis的schedule命令來安排任務(wù)的執(zhí)行。
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 創(chuàng)建任務(wù)調(diào)度服務(wù)
@Service
public class TaskSchedulingService {
@Autowired
private RedisTemplate<String, Runnable> redisTemplate;
public void scheduleTask(Runnable task, long delay, TimeUnit timeUnit) {
// 將任務(wù)和延遲時間存儲到Redis中
redisTemplate.opsForValue().set(
"task:" + task.hashCode(),
task,
timeUnit.toSeconds(delay),
timeUnit
);
// 使用schedule命令安排任務(wù)在未來執(zhí)行
String scheduleCommand = String.format(
"SCHEDULE %d %s",
System.currentTimeMillis() + timeUnit.toMillis(delay),
"task:" + task.hashCode()
);
redisTemplate.execute((RedisConnection connection) -> {
connection.schedule(scheduleCommand);
return null;
});
}
}2 創(chuàng)建具體的任務(wù)
public class SampleTask implements Runnable {
@Override
public void run() {
System.out.println("Task is running: " + LocalDateTime.now());
// 執(zhí)行任務(wù)邏輯
}
}3 創(chuàng)建控制器
@RestController
@RequestMapping("/tasks")
public class TaskController {
@Autowired
private TaskSchedulingService taskSchedulingService;
@PostMapping("/schedule")
public ResponseEntity<String> scheduleTask(@RequestParam long delay, @RequestParam TimeUnit timeUnit) {
taskSchedulingService.scheduleTask(new SampleTask(), delay, timeUnit);
return ResponseEntity.ok("Task scheduled for execution at " + LocalDateTime.now().plusNanos(timeUnit.toNanos(delay)));
}
}詳細解釋

通過這種方式,我們可以利用Redis的schedule命令來安排任務(wù)的執(zhí)行。這對于需要執(zhí)行定時任務(wù)的應(yīng)用非常有用,如定時數(shù)據(jù)備份、定時發(fā)送通知等。
通過Redis的延遲隊列特性,我們可以簡化任務(wù)調(diào)度的復(fù)雜性,并且能夠靈活地安排任務(wù)在未來的任意時間點執(zhí)行。
11. 數(shù)據(jù)共享
針對Redis作為數(shù)據(jù)共享的使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Redis來實現(xiàn)微服務(wù)架構(gòu)中的服務(wù)間數(shù)據(jù)共享。
場景描述
假設(shè)我們有一個電商平臺,它由多個微服務(wù)組成,比如用戶服務(wù)、產(chǎn)品服務(wù)和訂單服務(wù)。這些服務(wù)需要共享購物車數(shù)據(jù),以確保用戶在平臺上的購物體驗是連貫的。我們將使用Redis來存儲和共享購物車數(shù)據(jù)。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 創(chuàng)建購物車項實體類
public class CartItem {
private String productId;
private int quantity;
// 省略構(gòu)造函數(shù)、getter和setter方法
}2 創(chuàng)建購物車服務(wù)
@Service
public class CartService {
@Autowired
private StringRedisTemplate redisTemplate;
public void addToCart(String cartId, String productId, int quantity) {
// 將購物車項存儲到Redis的Hash結(jié)構(gòu)中
redisTemplate.opsForHash().put("cart:" + cartId, productId, quantity);
}
public Map<String, Integer> getCart(String cartId) {
// 從Redis獲取購物車內(nèi)容
return redisTemplate.opsForHash().entries("cart:" + cartId);
}
}3 創(chuàng)建控制器
@RestController
@RequestMapping("/cart")
public class CartController {
@Autowired
private CartService cartService;
@PostMapping("/{cartId}/items")
public ResponseEntity<String> addToCart(@PathVariable String cartId,
@RequestParam String productId,
@RequestParam int quantity) {
cartService.addToCart(cartId, productId, quantity);
return ResponseEntity.ok("Item added to cart");
}
@GetMapping("/{cartId}")
public ResponseEntity<Map<String, Integer>> getCart(@PathVariable String cartId) {
Map<String, Integer> cart = cartService.getCart(cartId);
return ResponseEntity.ok(cart);
}
}詳細解釋

通過這種方式,我們可以利用Redis的高性能和數(shù)據(jù)共享能力來實現(xiàn)微服務(wù)架構(gòu)中的服務(wù)間數(shù)據(jù)共享。
購物車數(shù)據(jù)被存儲在Redis中,可以被不同的微服務(wù)實例訪問和修改,確保了數(shù)據(jù)的一致性和實時性。
這對于需要高度協(xié)同工作的分布式系統(tǒng)非常有用,如電商平臺、在線協(xié)作工具等。
12. 持久化
針對Redis作為任務(wù)調(diào)度使用場景,下面是一個Java Spring Boot應(yīng)用的案例,其中使用Spring的@Scheduled注解與Redisson結(jié)合來實現(xiàn)任務(wù)調(diào)度。
場景描述
假設(shè)我們有一個自動化的營銷平臺,需要定期(例如每天凌晨1點)執(zhí)行一些任務(wù),比如發(fā)送時事通訊郵件給訂閱用戶。我們將使用Spring的定時任務(wù)功能結(jié)合Redisson來確保分布式環(huán)境下任務(wù)的準時和準確執(zhí)行。
創(chuàng)建Spring Boot項目
配置Redis連接
在src/main/resources/application.properties中配置Redis服務(wù)器的連接信息:
spring.redis.host=localhost spring.redis.port=6379
編寫業(yè)務(wù)代碼
1 創(chuàng)建任務(wù)執(zhí)行服務(wù)
@Service
public class ScheduledTaskService {
public void executeTask() {
// 執(zhí)行任務(wù)的邏輯,例如發(fā)送郵件
System.out.println("Executing scheduled task: " + LocalDateTime.now());
}
}2 配置Redisson
創(chuàng)建一個配置類來配置Redisson客戶端。
@Configuration
public class RedissonConfig {
@Bean(destroyMethod = "shutdown")
public RedissonClient redissonClient() {
RedissonClientConfig config = new RedissonClientConfig();
config.useSingleServer().setAddress("redis://" + spring.redis.host + ":" + spring.redis.port);
return Redisson.create(config);
}
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
}3 創(chuàng)建定時任務(wù)配置
使用Redisson的RedissonScheduledExecutorService來創(chuàng)建一個分布式的調(diào)度器。
@Configuration
public class ScheduledConfig {
@Bean
public RedissonScheduledExecutorService redissonScheduledExecutorService(RedissonClient redissonClient) {
return redissonClient.getExecutorService("myScheduler");
}
}4 創(chuàng)建定時任務(wù)
使用Spring的@Scheduled注解和Redisson的調(diào)度器來執(zhí)行定時任務(wù)。
@Component
public class ScheduledTasks {
@Autowired
private ScheduledTaskService taskService;
@Autowired
private RedissonScheduledExecutorService scheduler;
@Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1點執(zhí)行
public void scheduledTask() {
scheduler.schedule(() -> taskService.executeTask(), 0, TimeUnit.SECONDS);
}
}詳細解釋

通過這種方式,我們可以利用Spring的定時任務(wù)功能和Redisson的分布式調(diào)度器來實現(xiàn)任務(wù)調(diào)度。
這確保了即使在分布式系統(tǒng)中,任務(wù)也能準時和準確地執(zhí)行,避免了任務(wù)執(zhí)行的沖突和重復(fù)。
這對于需要定時執(zhí)行的任務(wù),如發(fā)送時事通訊、數(shù)據(jù)備份、報告生成等場景非常有用。
總結(jié)
到此這篇關(guān)于Redis在項目中常見的12終使用場景示例和說明的文章就介紹到這了,更多相關(guān)Redis常見的12終使用場景內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis超詳細講解高可用主從復(fù)制基礎(chǔ)與哨兵模式方案
Redis因為其高性能和易用性在我們后端的服務(wù)中發(fā)揮了巨大的作用,并且很多重要功能的實現(xiàn)都會依賴redis,本篇我們來了解Redis高可用主從復(fù)制與哨兵模式2022-04-04
SpringBoot整合Redis實現(xiàn)序列化存儲Java對象的操作方法
這篇文章主要介紹了SpringBoot整合Redis實現(xiàn)序列化存儲Java對象,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03
Redis使用RedisTemplate導(dǎo)致key亂碼問題解決
本文主要介紹了Redis使用RedisTemplate導(dǎo)致key亂碼問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06
手把手教你用Redis 實現(xiàn)點贊功能并且與數(shù)據(jù)庫同步
本文主要介紹了Redis 實現(xiàn)點贊功能并且與數(shù)據(jù)庫同步,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

