Redis是一套基於key-value的in-memory database,常見的用途之一,是拿來作為Application Server的快取系統。
而Lettuce則是一個強調thread-safe的Java Redis Client。
Redis參數設定
可以使用XML或Annotation兩種方式,來設定Redis的IP、Port。
方法(一):建立XML設定檔
以下假設專案使用webapp,並將XML檔案放在src/main/resource底下,取名為lettuce.xml
完整XML檔案範例如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- beans settings -->
</beans>
Sentinel設定
若要連線至3個Sentinel:
- 192.168.1.32:27030
- 192.168.1.32:27031
- 192.168.1.32:27032
範例如下:
<bean id="sentinelConfig" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<constructor-arg name="master" value="mymaster" />
<constructor-arg name="sentinelHostAndPorts">
<set>
<value>192.168.1.32:27030</value>
<value>192.168.1.32:27031</value>
<value>192.168.1.32:27032</value>
</set>
</constructor-arg>
</bean>
Connection設定
Java Redis Client使用lettuce,如下:
<bean id="lettuceConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory">
<constructor-arg ref="sentinelConfig" />
</bean>
RedisTemplate設定
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="lettuceConnectionFactory" />
方法(二):Annotation
建立一個類別,並於class前加上 @Configuration
//...
import org.springframework.context.annotation.Configuration;
//...
@Configuration
public class SpringDataRedisLettuceConfig {
//...
}
Connection Pool 設定
@Bean
public GenericObjectPoolConfig genericObjectPoolConfig() {
GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
genericObjectPoolConfig.setMaxIdle(8);
genericObjectPoolConfig.setMinIdle(0);
genericObjectPoolConfig.setMaxTotal(8);
genericObjectPoolConfig.setMaxWaitMillis(100000);
return genericObjectPoolConfig;
}
Sentinel設定
若要連線至3個Sentinel:
- 192.168.1.32:27030
- 192.168.1.32:27031
- 192.168.1.32:27032
範例如下:
@Bean
public RedisSentinelConfiguration sentinelConfig() {
Set<String> sentinels = new HashSet<>();
sentinels.add("192.168.1.32:27030");
sentinels.add("192.168.1.32:27031");
sentinels.add("192.168.1.32:27032");
RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration("mymaster", sentinels);
return redisSentinelConfiguration;
}
Connection設定
Java Redis Client使用lettuce,如下:
@Bean
public LettuceConnectionFactory lettuceConnectionFactory(RedisSentinelConfiguration sentinelConfig, GenericObjectPoolConfig genericObjectPoolConfig) {
LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
.commandTimeout(Duration.ofMillis(10000))
.poolConfig(genericObjectPoolConfig)
.build();
LettuceConnectionFactory factory = new LettuceConnectionFactory(sentinelConfig, clientConfig);
return factory;
}
RedisTemplate設定
設定KeySerializer使用StringRedisSerializer
@Bean
RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
return redisTemplate;
}
在Java中使用RedisTemplate操作Redis
- 若剛才使用方法(一):建立XML設定檔
由於XML檔案位於src/main/resource/lettuce.xml,此處先使用ClassPathXmlApplicationContext取得RedisTemplate物件:
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] { "lettuce.xml" });
RedisTemplate redisTemplate = ctx.getBean(RedisTemplate.class);
- 若剛才使用方法(二):Annotation的話,則只要確定Spring的root-context.xml中,有設定掃描相關的package即可:
...
<context:component-scan base-package="tw.com.maxkit.cdc.configuration" />
...
設定KeySerializer
設定KeySerializer為StringRedisSerializer
RedisSerializer<String> stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
因為無論是Key還是Value,預設都使用JdkSerializationRedisSerializer;如此一來,假設原本程式中寫入的key為mykey,若沒有將KeySerializer為StringRedisSerializer,寫入資料後,進console查看keys資料如下:
192.168.1.32:7030> keys *
1) "\xac\xed\x00\x05t\x00\x05mykey"
若有將KeySerializer為StringRedisSerializer時,寫入資料後,進console查看keys資料如下
192.168.1.32:7030> keys *
1) "mykey"
兩筆資料將會是不同的key,因此KeySerializer應一開始就設定好,並保持一致。
此外,Value也可以設定使用StringRedisSerializer:
redisTemplate.setValueSerializer(stringSerializer);
不過,如果需要將序列化的物件存入,那就不應將ValueSerializer設為StringRedisSerializer。
透過Operations操作Redis
ValueOperations
取得ValueOperations物件
ValueOperations<String, String> vops = redisTemplate.opsForValue();
寫入字串
vops.set("vops_key","vops_value");
讀取字串
String vops_value = vops.get("vops_key");
寫入/讀取物件
如同之前提到,寫入的Value預設是使用JdkSerializationRedisSerializer。因此也可以寫入有implements Serializable的物件
ValueOperations<String, TestUser> vops = redisTemplate.opsForValue();
vops.set("user:001", new TestUser("Allen", 20));
TestUser user001 = vops.get("user:001");
TestUser需implements Serializable,如下:
public class TestUser implements Serializable {
private String name;
private int age;
public TestUser(String name, int age) {
// ...
ListOperations
建立ListOperations物件
ListOperations<String, String> listOp = redisTemplate.opsForList();
寫入list
long result = listOp.leftPush(key, value);
讀取list
List<String> values = lop.range(key, 0, -1);
不難發現,多數函數名稱都與原本的Redis指令很接近;若已熟悉Redis的話,使用Lettuce也能很快就上手。
刪除key
刪除資料時,直接使用redisTemplate的delete即可。
redisTemplate.delete(key)
沒有留言:
張貼留言