整合redis可查看博文
springboot 整合redis_springboot整合redis csdn-CSDN博客
集群中操作注意事項
1 多鍵操作失敗:
當使用multiGet等需要同時訪問多個鍵的方法時,如果沒有使用Hash Tags,這些鍵可能會被分配到不同的槽中。如果這些槽位于不同的Redis節點上,那么multiGet將無法正確返回所有鍵的值。
2 Pipeline操作受限:
在Redis集群中,pipeline操作不能跨越多個槽進行。如果通過pipeline發送的命令涉及多個不同的槽(即鍵被分配到了不同的節點),則可能會導致部分命令失敗或者整個pipeline操作效率降低。
3 事務支持有限:
Redis集群不支持原生的MULTI/EXEC事務模型,特別是當事務涉及多個不同的槽時。因此,嘗試在集群模式下使用事務來管理多個鍵的操作可能會失敗。
代碼示例
1 application.yml
spring:application:name: zha7zha8data:redis:cluster:nodes:- 192.168.1.100:6381- 192.168.1.100:6382- 192.168.1.100:6383- 192.168.1.100:6384- 192.168.1.100:6385- 192.168.1.100:6386
2 測試類,注意:{user}: 這樣的標識,名稱無所謂,只要都加了相同的標識,寫了些反例和正例
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.Arrays;
import java.util.List;@SpringBootTest(classes = Zha7zha8Application.class)
public class RedisClusterTest {@Autowiredprivate StringRedisTemplate redisTemplate;/*** 反例:未使用 Hash Tags,可能導致 Key 分配到不同的 Slot* 注意:由于 'user:dfss' 和 'user:00' 沒有共同的 Hash Tag,* 這些鍵可能會被分配到不同的槽中,這在某些情況下(如 multiGet)可能會導致問題。* 例如,在Redis集群環境中,如果這些鍵位于不同的節點上,那么 multiGet 可能無法正確返回所有鍵的值。*/@Testvoid testWithoutHashTags() {// 定義兩個沒有使用 Hash Tags 的鍵String key1 = "user:dfss";String key2 = "user:11";// 設置鍵值對redisTemplate.opsForValue().set(key1, "Alice");redisTemplate.opsForValue().set(key2, "Bob");// 嘗試從 Redis 中獲取這兩個值List<String> values = redisTemplate.opsForValue().multiGet(Arrays.asList(key1, key2));System.out.println("從 Redis 中獲取的值 (無 Hash Tags): " + values);}/*** 正例:使用 Hash Tags 確保 'user:1' 和 'user:2' 在同一個 Slot* 使用相同的 Hash Tag '{user}' 確保了 'user:1' 和 'user:2' 被分配到同一個槽中,* 這樣可以保證 multiGet 操作能夠成功返回所有相關的鍵值。*/@Testvoid testWithHashTags() {// 定義兩個使用相同 Hash Tags 的鍵String key1 = "{user}:1";String key2 = "{user}:2";// 設置鍵值對redisTemplate.opsForValue().set(key1, "Alice");redisTemplate.opsForValue().set(key2, "Bob");// 從 Redis 中獲取這兩個值List<String> values = redisTemplate.opsForValue().multiGet(Arrays.asList(key1, key2));System.out.println("從 Redis 中獲取的值 (有 Hash Tags): " + values);}/*** Pipeline 操作反例* 注意:由于 'user:1' 和 'user:2' 沒有共同的 Hash Tag,* 這些鍵可能會被分配到不同的槽中。雖然 pipeline 操作會嘗試執行所有的命令,* 但如果涉及到跨多個節點的操作,可能會導致部分命令失敗或效率降低。*/@Testvoid pipelineOperationWithoutHashTags() {// 定義兩個沒有使用 Hash Tags 的鍵String key1 = "user:1";String key2 = "user:2";// Pipeline 操作List<Object> results = redisTemplate.executePipelined((RedisCallback<String>) connection -> {connection.set(key1.getBytes(), "Alice".getBytes());connection.set(key2.getBytes(), "Bob".getBytes());return null;});System.out.println("Pipeline 操作的結果 (無 Hash Tags): " + results);}/*** Pipeline 操作正例* 使用相同的 Hash Tag '{user}' 確保了 'user:1' 和 'user:2' 被分配到同一個槽中,* 這使得 pipeline 操作能夠在同一節點上順利執行,提高了操作的一致性和效率。*/@Testvoid pipelineOperationWithHashTags() {// 定義兩個使用相同 Hash Tags 的鍵String key1 = "{user}:1";String key2 = "{user}:2";// Pipeline 操作List<Object> results = redisTemplate.executePipelined((RedisCallback<String>) connection -> {connection.set(key1.getBytes(), "Alice".getBytes());connection.set(key2.getBytes(), "Bob".getBytes());return null;});System.out.println("Pipeline 操作的結果 (有 Hash Tags): " + results);}
}