Advanced use Redis

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, Jedisand Lettuceuse only as a brief description springof redisintegration and use the content as the primary explanation.

Jedis

github.com/xetorthio/j…

The introduction of dependence:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.3</version>
</dependency>
复制代码

JedisIs the command for redis package, using substantially the redis-clisame, 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 share Jedisinstances, but create a large number of Jedis will cause unnecessary overhead even greater impact on performance, so use JedisPoolto 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: Jedisyou need to call after use Jedis.closemethod to release the resources (. JedisTo achieve the AutoCloseablerecommended try-with-resourcewording of)

Lettuce

lettuce.io/

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-redisIs Spring Datapart 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-rediswhen developing, it is probably the most commonly used RedisTemplate, so before we begin to understand the next RedisTemplate:

  • RedisTemplateIt is a simplified tool like Redis access.
  • Security thread (thread-safe), can be used as a single embodiment.
  • Around its implementation executemethods, support callback, it provides RedisConnectiontreatment need not be concerned lifecycle connection (in short, do not turn off without creating a connection)

Very simple to use, first of all in Configurationthe definition of StringRedisTemplatethe 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, GenericJackson2JsonRedisSerializerit is its implementation.

  • (B): KeySerializeris used to serialize redis key, HashKeySerializerused to serialize the data structure field redis hash should not be confused.

Of course, do not forget application.ymlto 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: Get Binary-safe stringsoperation class ValueOperations(That is redis spring for operating a package type in the same manner, a hash, setalso have corresponding packaging HashOperations, SetOperationsetc.).
[Copyright]
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 prefixspliced 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 RedisSerializeris spring-data-redissubject 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.

RedisTemplateRedis operation and RedisSerializerare necessarily linked, and you can specify by implementing this interface RedisTemplateis KeySerializerto 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 StringRedisTemplateminor 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;
}
复制代码
  • StringRedisSerializerReplace Custom GenericRedisKeySerializerand 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

RedisTemplateDefault JDK serialization JdkSerializationRedisSerializer, 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 RedisSerializerand create RedisTemplatethe 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

  1. Redis entry
  2. Advanced use Redis
  3. Redis Distributed Lock

references

[Copyright]
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

Guess you like

Origin blog.csdn.net/weixin_33885253/article/details/93176756