The Redis Tutorial (Java version)
Blog address https://blog.piaoruiqing.com/blog/2019/06/11/redis use Advanced
Key words
Jedis
: Redis java client implementation.Lettuce
: Redis java client implementation, based netty.spring-data-redis
: Spring for redis package, simple configuration, provides an abstraction of interaction with the storage package Redis, very elegant, but also extremely scalability integrated Jedis, Lettuce and other official redis client after springboot2.0 integrated client from the default. Jedis changed Lettuce.
Foreword
This article will explain for the use of Java integrated Redis, Jedis
and Lettuce
use only as a brief description spring
of redis
integration and use the content as the primary explanation.
Jedis
The introduction of dependence:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.3</version>
</dependency>
复制代码
Jedis
Is the command for redis package, using substantially the redis-cli
same, an example of operation using the following string:
/** jedis pool */
private static final JedisPool POOL = new JedisPool(new JedisPoolConfig(), "test-redis-server", 6379);
// test Binary-safe strings with Jedis
try (Jedis jedis = POOL.getResource()){
{ // SET mykey myvalue
String result = jedis.set("mykey", "myvalue");
LOGGER.info("cmd: SET mykey myvalue, result: {}", result);
}
{ // GET mykey
String result = jedis.get("mykey");
LOGGER.info("cmd: GET mykey, result: {}", result);
}
{ // KEYS my*
Set<String> keys = jedis.keys("my*");
LOGGER.info("cmd: KEYS my*, result: {}", JsonUtils.writeValueAsString(keys, true));
}
{ // EXISTS mykey
Boolean result = jedis.exists("mykey");
LOGGER.info("cmd: EXISTS mykey, result: {}", result);
}
{ // DEL mykey
Long result = jedis.del("mykey");
LOGGER.info("cmd: DEL mykey, result: {}", result);
}
{ // GET mykey
String result = jedis.get("mykey");
LOGGER.info("cmd: GET mykey, result: {}", result);
}
}
复制代码
JedisPool
: Jedis not thread-safe, so multiple threads not shareJedis
instances, but create a large number of Jedis will cause unnecessary overhead even greater impact on performance, so useJedisPool
to avoid these problems, it is a thread-safe network connection pool can reliably use it to create multiple instances Jedis, after completion Jedis instance recycled to the connection pool.JedisPool.getResource
: Get a Jedis from the connection pool connection Note:Jedis
you need to call after useJedis.close
method to release the resources (.Jedis
To achieve theAutoCloseable
recommendedtry-with-resource
wording of)
Lettuce
The introduction of dependence:
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
复制代码
Lettuce is a scalable Redis client, used to build non-blocking Reactive applications. It is based Netty framework for building high performance, advanced features and support of many redis currently springboot2.0 Lettuce has been redis client as the default corresponding with the previous section, using the example of the operation string is as follows:
/** redis client */
private static final RedisClient CLIENT = RedisClient.create("redis://@test-redis-server:6379/0");
// test Binary-safe strings with Lettuce
try (StatefulRedisConnection<String, String> connection = CLIENT.connect()) {
RedisCommands<String, String> commands = connection.sync();
{ // SET mykey myvalue
String result = commands.set("mykey", "myvalue");
LOGGER.info("cmd: SET mykey myvalue, result: {}", result);
}
{ // GET mykey
String result = commands.get("mykey");
LOGGER.info("cmd: GET mykey, result: {}", result);
}
{ // KEYS my*
List<String> keys = commands.keys("my*");
LOGGER.info("cmd: KEYS my*, result: {}", JsonUtils.writeValueAsString(keys, true));
}
{ // EXISTS mykey
Long result = commands.exists("mykey");
LOGGER.info("cmd: EXISTS mykey, result: {}", result);
}
{ // DEL mykey
Long result = commands.del("mykey");
LOGGER.info("cmd: DEL mykey, result: {}", result);
}
{ // GET mykey
String result = commands.get("mykey");
LOGGER.info("cmd: GET mykey, result: {}", result);
}
}
复制代码
Spring Integration
spring-data-redis
IsSpring Data
part of the family, it provides a simple configuration to easily access redis, provides low-level and high-level abstraction for storage operation, the developer freed from the underlying implementation.
The introduction of dependence:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
复制代码
Use spring-data-redis
when developing, it is probably the most commonly used RedisTemplate
, so before we begin to understand the next RedisTemplate
:
RedisTemplate
It is a simplified tool like Redis access.- Security thread (thread-safe), can be used as a single embodiment.
- Around its implementation
execute
methods, support callback, it providesRedisConnection
treatment need not be concerned lifecycle connection (in short, do not turn off without creating a connection)
Very simple to use, first of all in Configuration
the definition of StringRedisTemplate
the Bean:
/**
* StringRedisTemplate
* @param factory
* @return
*/
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
StringRedisSerializer serializer = new StringRedisSerializer(); // (一)
template.setKeySerializer(serializer); // (二)
template.setHashKeySerializer(serializer);
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
return template;
}
复制代码
-
(A):
RedisSerializer
: object to a binary array serialization and deserialization interfaces, serialization and deserialization and key value,StringRedisSerializer
,GenericJackson2JsonRedisSerializer
it is its implementation. -
(B):
KeySerializer
is used to serialize redis key,HashKeySerializer
used to serialize the data structure field redis hash should not be confused.
Of course, do not forget application.yml
to add redis configuration:
spring:
redis:
host: test-redis-server
port: 6379
复制代码
Preparatory work completed, now come to experience the same corresponds to the foregoing, using the example string operations are as follows::
@Resource
private StringRedisTemplate stringRedisTemplate;
/**
* test Binary-safe strings with RedisTemplate
*/
@Test
public void testStringRedisTemplateSimple() {
{ // SET mykey myvalue
stringRedisTemplate.opsForValue().set("mykey", "myvalue");
}
{ // GET mykey
String result = stringRedisTemplate.opsForValue().get("mykey");
LOGGER.info("cmd: GET mykey, result: {}", result);
}
{ // KEYS my*
Set<String> keys = stringRedisTemplate.keys("my*");
LOGGER.info("cmd: KEYS my*, result: {}", JsonUtils.writeValueAsString(keys, true));
}
{ // EXISTS mykey
Boolean result = stringRedisTemplate.hasKey("mykey");
LOGGER.info("cmd: EXISTS mykey, result: {}", result);
}
{ // DEL mykey
Boolean result = stringRedisTemplate.delete("mykey");
LOGGER.info("cmd: DEL mykey, result: {}", result);
}
{ // GET mykey
String result = stringRedisTemplate.opsForValue().get("mykey");
LOGGER.info("cmd: GET mykey, result: {}", result);
}
}
复制代码
opsForValue
: GetBinary-safe strings
operation classValueOperations
(That is redis spring for operating a package type in the same manner, ahash
,set
also have corresponding packagingHashOperations
,SetOperations
etc.).
This article published in Pu Ruiqing's blog , allows non-commercial use reproduced, reprinted but must retain the original author Pu Ruiqing and links: blog.piaoruiqing.com . If the authorization aspects of consultation or cooperation, please contact E-mail: piaoruiqing @ Gmail. COM .
Advanced
Division of application cache
Cache of different applications simply by key is the prefix to divide
Let us consider the question, if we want to divide for different applications (service) cache, to facilitate management and maintenance, how to achieve?
Perhaps the increase prefix is a good idea, but if every time coding is required prefix prefix
spliced to key in one hand, increased workload, another surface also increases the risk of error, if you forget how to do stitching For Maybe you also think, previously mentioned RedisSerializer
is spring-data-redis
subject to an array of binary serialization and de-serialization interface for serialization and de-serialization key and value, we can make a fuss from here:
public interface RedisSerializer<T> {
/**
* Serialize the given object to binary data.
*
* @param t object to serialize. Can be {@literal null}.
* @return the equivalent binary data. Can be {@literal null}.
*/
@Nullable
byte[] serialize(@Nullable T t) throws SerializationException;
/**
* Deserialize an object from the given binary data.
*
* @param bytes object binary representation. Can be {@literal null}.
* @return the equivalent object instance. Can be {@literal null}.
*/
@Nullable
T deserialize(@Nullable byte[] bytes) throws SerializationException;
}
复制代码
serialize
: Object -> byte array.deserialize
: Byte array -> object.
RedisTemplate
Redis operation and RedisSerializer
are necessarily linked, and you can specify by implementing this interface RedisTemplate
is KeySerializer
to achieve increased prefix function. Thus, the increase in the operating prefix it was spun off from the business, for the caller, it is completely transparent, still elegant, specifically implemented as follows:
/**
* generic redis key serializer
* @author piaoruiqing
* @date: 2019-06-11 22:37
*/
public class GenericRedisKeySerializer implements RedisSerializer<Object> {
private final Charset charset;
private String prefix;
private int index;
public GenericRedisKeySerializer(String prefix) {
this(prefix, StandardCharsets.UTF_8);
}
public GenericRedisKeySerializer(String prefix, Charset charset) {
Assert.notNull(charset);
Assert.notNull(prefix);
this.charset = charset;
this.prefix = prefix + ":";
index = this.prefix.length();
}
@Override
public String deserialize(byte[] bytes) {
if (null == bytes) {
return null;
}
String key = new String(bytes, charset);
if (key.indexOf(prefix) == 0) {
return key.substring(index, key.length());
}
return key;
}
@Override
public byte[] serialize(Object key) {
if (null == key) {
return null;
}
String string = key.toString();
if (!string.startsWith(prefix)) {
string = prefix + string;
}
return string.getBytes(charset);
}
}
复制代码
The foregoing StringRedisTemplate
minor modifications:
@Value("${spring.application.name:undefined}")
private String applicationName;
/**
* StringRedisTemplate
* @param factory
* @return
*/
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
// StringRedisSerializer serializer = new StringRedisSerializer();
GenericRedisKeySerializer serializer = new GenericRedisKeySerializer(applicationName);
template.setKeySerializer(serializer);
template.setHashKeySerializer(serializer);
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
return template;
}
复制代码
StringRedisSerializer
Replace CustomGenericRedisKeySerializer
and specify a prefix for the name of the application
Experience:
stringRedisTemplate.opsForValue().set("mykey", "myvalue");
String result = stringRedisTemplate.opsForValue().get("mykey"); // "myvalue"
复制代码
Connection to redis View key, it has been prefixed with the
root@ubuntu:/home/ubuntu# docker exec -it redis redis-cli
127.0.0.1:6379> keys *
1) "redis-simple:mykey"
复制代码
Custom Serialization
RedisTemplate
Default JDK serializationJdkSerializationRedisSerializer
, we can specify the sequence of other ways, such as JSON, protostuff
The foregoing has described how to customize the serialization key, the sequence of the same value as their configuration, are implemented RedisSerializer
and create RedisTemplate
the specified time, the code will not repeat the paste.
Common serialized in several ways:
JDK
: Default, more convenient, can serialize all classes, but slow and occupy a large space.JSON
: Good performance, output compare the content easy to read.Protostuff
: High performance, high speed and small footprint.
Epilogue
This paper explains the use redis redis java client, as well as advanced integration with spring, will explain the follow-up for other tips Redis, so stay tuned.
Series of articles
references
This article published in Pu Ruiqing's blog , allows non-commercial use reproduced, reprinted but must retain the original author Pu Ruiqing and links: blog.piaoruiqing.com . If the authorization aspects of consultation or cooperation, please contact E-mail: piaoruiqing @ Gmail. COM .
Reproduced in: https: //juejin.im/post/5cffcb2b6fb9a07ef3765f8b