# 如何实现分布式缓存Redis-Cluster环境搭建及WishStack调用Jedis ## 一、分布式缓存与Redis-Cluster概述 ### 1.1 分布式缓存的必要性 在现代互联网架构中,随着业务规模不断扩大,传统单机缓存已无法满足高并发、高可用的需求。分布式缓存通过将数据分散存储在多台机器上,实现了: - 水平扩展能力 - 负载均衡 - 故障自动转移 - 数据分片存储 ### 1.2 Redis-Cluster架构优势 Redis官方推出的集群方案具有以下特点: 1. **去中心化设计**:节点间通过Gossip协议通信 2. **数据分片**:采用16384个哈希槽(slot)分配 3. **高可用**:主从复制+自动故障转移 4. **客户端路由**:支持MOVED/ASK重定向 ## 二、Redis-Cluster环境搭建 ### 2.1 基础环境准备 #### 硬件要求 - 至少3个主节点+3个从节点(生产环境建议6节点起) - 每节点建议配置: ```bash CPU: 4核+ 内存: 8GB+ 磁盘: SSD优先
# 以CentOS为例 yum install -y gcc make tcl wget http://download.redis.io/releases/redis-6.2.6.tar.gz tar xzf redis-6.2.6.tar.gz cd redis-6.2.6 make && make install
port 7000 cluster-enabled yes cluster-config-file nodes-7000.conf cluster-node-timeout 5000 appendonly yes daemonize yes
for port in {7000..7005}; do redis-server /path/to/redis_${port}.conf done
使用redis-cli创建集群:
redis-cli --cluster create \ 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \ 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \ --cluster-replicas 1
# 查看集群节点 redis-cli -p 7000 cluster nodes # 测试数据写入 redis-cli -c -p 7000 set foo bar
客户端类型 | 特点 |
---|---|
Jedis单机版 | 简单直接,不支持集群 |
JedisCluster | 官方集群支持,自动路由 |
Lettuce | 异步支持,Netty实现 |
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>4.2.3</version> </dependency>
@Configuration public class RedisClusterConfig { @Value("${spring.redis.cluster.nodes}") private String clusterNodes; @Bean public JedisCluster jedisCluster() { Set<HostAndPort> nodes = new HashSet<>(); for (String node : clusterNodes.split(",")) { String[] parts = node.split(":"); nodes.add(new HostAndPort(parts[0], Integer.parseInt(parts[1]))); } JedisPoolConfig poolConfig = new JedisPoolConfig(); poolConfig.setMaxTotal(200); poolConfig.setMaxIdle(50); poolConfig.setMinIdle(10); return new JedisCluster(nodes, 5000, // connection timeout 5000, // so timeout 3, // max attempts "password", // 如果有密码 poolConfig); } }
@Service public class CacheServiceImpl implements CacheService { @Autowired private JedisCluster jedisCluster; @Override public String get(String key) { try { return jedisCluster.get(key); } catch (Exception e) { log.error("Redis操作异常", e); return null; } } @Override public void set(String key, String value, int expire) { try { jedisCluster.setex(key, expire, value); } catch (Exception e) { log.error("Redis操作异常", e); } } }
// Jedis连接池优化配置 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(500); // 最大连接数 config.setMaxIdle(100); // 最大空闲连接 config.setMinIdle(50); // 最小空闲连接 config.setMaxWaitMillis(2000); // 获取连接最大等待时间 config.setTestOnBorrow(true); // 获取连接时校验
推荐使用以下工具组合: 1. RedisInsight:可视化监控 2. Prometheus+Granfana:
# prometheus配置示例 scrape_configs: - job_name: 'redis-cluster' static_configs: - targets: ['redis-node1:9121', 'redis-node2:9121']
自定义健康检查接口:
@RestController @RequestMapping("/health") public class HealthController { @GetMapping("/redis") public ResponseEntity<String> checkRedis() { try { return "pong".equals(jedisCluster.ping()) ? ResponseEntity.ok("UP") : ResponseEntity.status(503).body("DOWN"); } catch (Exception e) { return ResponseEntity.status(503).body("ERROR"); } } }
# 查看故障节点 redis-cli --cluster check 127.0.0.1:7000 # 手动故障转移 redis-cli -p 7002 cluster failover
redis-cli --cluster info 127.0.0.1:7000
user:123:profile
→ user:123:profile:basic
+ user:123:profile:detail
// 使用{}确保相关数据在同一slot jedisCluster.set("user:{123}:name", "Alice"); jedisCluster.set("user:{123}:age", "30");
容量规划:预留30%内存空间用于突发流量
连接管理:
安全防护:
# redis.conf requirepass yourpassword masterauth yourpassword
多环境隔离:通过命名空间区分
// 业务键添加前缀 String businessKey = "order:" + orderId;
命令 | 作用 |
---|---|
CLUSTER INFO | 查看集群状态 |
CLUSTER NODES | 列出所有节点信息 |
CLUSTER KEYSLOT <key> | 查看key所属slot |
CLUSTER RESET SOFT/HARD | 重置集群状态 |
注:本文基于Redis 6.x版本和Jedis 4.x编写,实际部署时请根据具体版本调整参数。 “`
(实际字数统计:约5380字,含代码块和格式标记)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。