Linux 環境 Redis 服務端部署
# 1. 下載編譯
wget https://download.redis.io/releases/redis-2.8.19.tar.gz
tar -zxvf redis-2.8.19.tar.gz
cd redis-2.8.19 && make
# 2. 安裝到標準目錄
mkdir -p /usr/local/redis
cp src/redis-{server,cli,benchmark} /usr/local/redis/
cp redis.conf /usr/local/redis/
# 3. 啟動 (前台/後台)
cd /usr/local/redis
./redis-server ./redis.conf # 前台
nohup ./redis-server ./redis.conf & # 後台
# 4. 客戶端測試
./redis-cli
127.0.0.1:6379> set key "value"
OK
127.0.0.1:6379> get key
"value"
# 5. 防火牆開放 6379 端口 (跨機訪問必須)
iptables -A INPUT -p tcp --dport 6379 -j ACCEPT
service iptables save && service iptables restart
Maven 依賴配置
<dependencies>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<!-- Jedis 客戶端 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.1.0</version>
</dependency>
<!-- Spring Data Redis 封裝 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.1.1.RELEASE</version>
</dependency>
<!-- JUnit 測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
Spring 配置核心:StringRedisTemplate 選型關鍵
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:redis.properties" />
<!-- 連接工廠 -->
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${hostName}" />
<property name="port" value="${port}" />
<property name="database" value="${index}" />
</bean>
<!-- 關鍵:使用 StringRedisTemplate 而非 RedisTemplate -->
<bean id="redisTemplate"
class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
</beans>
為什麼必須用 StringRedisTemplate?
RedisTemplate 默認使用 JdkSerializationRedisSerializer (Java 序列化)
- 存入字符串 "hello" 實際存儲為字節流 `\xac\xed\x00\x05t\x00\x05hello`
StringRedisTemplate 使用 StringRedisSerializer,直接存 UTF-8 字符串
- 與
redis-cli 直接操作兼容,調試直觀
redis.properties 配置
hostName=192.168.1.225
port=6379
index=0 # 數據庫索引 0-15,默認 16 個庫
完整 CRUD 測試用例
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-redis.xml")
public class RedisTest {
@Autowired
private StringRedisTemplate redisTemplate;
@Test
public void testStringOperations() {
ValueOperations<String, String> ops = redisTemplate.opsForValue();
// Set / Get
ops.set("user:1:name", "ZhangSan");
assertEquals("ZhangSan", ops.get("user:1:name"));
// Set with TTL
ops.set("session:abc", "userData", 30, TimeUnit.MINUTES);
// Increment (原子)
ops.set("counter", "0");
ops.increment("counter"); // 1
ops.increment("counter", 5); // 6
// GetSet (原子獲取並設置)
String old = ops.getAndSet("key", "newValue");
}
@Test
public void testHashOperations() {
HashOperations<String, String, String> ops = redisTemplate.opsForHash();
ops.put("user:1", "name", "LiSi");
ops.put("user:1", "age", "25");
Map<String, String> user = ops.entries("user:1");
}
@Test
public void testListOperations() {
ListOperations<String, String> ops = redisTemplate.opsForList();
ops.rightPush("queue", "task1");
ops.rightPush("queue", "task2");
String task = ops.leftPop("queue"); // 阻塞版: leftPop(key, timeout, unit)
}
@Test
public void testSetOperations() {
SetOperations<String, String> ops = redisTemplate.opsForSet();
ops.add("tags", "java", "spring", "redis");
ops.members("tags"); // [java, spring, redis]
}
@Test
public void testZSetOperations() {
ZSetOperations<String, String> ops = redisTemplate.opsForZSet();
ops.add("ranking", "player1", 100);
ops.add("ranking", "player2", 200);
ops.range("ranking", 0, -1); // 按分數升序
}
}
生產環境優化建議
- 連接池配置:
JedisPoolConfig 設置 maxTotal、maxIdle、minIdle、maxWaitMillis
- 序列化策略:複雜對象用
GenericJackson2JsonRedisSerializer (JSON 可讀、跨語言)
- Key 過期策略:業務層統一管理 TTL,避免內存洩漏
- 管道操作:批量寫入使用
redisTemplate.executePipelined() 減少 RTT
- Lua 腳本:原子複合操作 (如分佈式鎖) 使用
DefaultRedisScript