Tag Archives: redis

Error condition on socket for Sync: connection reused

Error condition on socket for Sync: connection reused

First of all, I shut down the firewall of Linux, and then I didn’t solve it

Close firewall
Start: systemctl start firewalld
Close: systemctl stop firewalld
View Status: systemctl status firewalld
boot disable: systemctl disable firewalld
boot enable: systemctl enable firewalld

Finally, the redis.conf Change bind127.0.0.1 in to 0.0.0.0, so that all IP can be connected

 

Restart service

from server

 

master server

You can see that the connection was successful

Notes on @ pathvariable annotation in springcloud openfeign

SpringCloud-Feign-@PathVariable
Feign pathvariable annotation was empty on param 0.
when using feign, if the parameter contains

@If the parameter is in the form of pathvariable, the corresponding parameter should be marked with value =, otherwise the IllegalStateException exception will be thrown

as

@GetMapping(value = "/payment/consumer/hystrix/ok/get/{id}")
    public String payment_ok(@PathVariable Integer id)

The above code will report feign pathvariable annotation was empty on param 0

    @GetMapping(value = "/payment/consumer/hystrix/ok/get/{id}")
    public String payment_ok(@PathVariable(value="id") Integer id)

So you can go through

(2) unrecoverable error: corrupted cluster config file

stay https://blog.csdn.net/zly_ On the basis of this blog post 9117 / article / details / 83349778, we found another error when starting redis. The error content is as follows

➜  7000 ../redis-server redis.conf &
[1] 11045
11045:C 24 Oct 2018 19:26:52.320 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
11045:C 24 Oct 2018 19:26:52.320 # Redis version=999.999.999, bits=64, commit=54e8dd11, modified=0, pid=11045, just started
11045:C 24 Oct 2018 19:26:52.320 # Configuration loaded
11045:M 24 Oct 2018 19:26:52.322 * Increased maximum number of open files to 10032 (it was originally set to 7168).
11045:M 24 Oct 2018 19:26:52.323 # Unrecoverable error: corrupted cluster config file.

The literal meaning is a damaged cluster configuration. Similarly, find the corresponding error throw point in the source code and find the following information

1. The output point of the error log is the code below

fmterr:
    serverLog(LL_WARNING,
        "Unrecoverable error: corrupted cluster config file.");
    zfree(line);
    if (fp) fclose(fp);
    exit(1);
}

According to the source code interpretation found that we did not build nodes.conf By default, this method returns a C_ Err, and then the caller clusterinit function creates a new file and a cluster. The overall code of clusterloadconfig function is as follows. But now I found this document and read it to prove it wrong redis.conf There is an error in the configuration file. After searching the configuration file, it is found that the parameter of cluster config file is configured incorrectly, and it is changed to cluster config file nodes.conf Problem solving.

/* Load the cluster config from 'filename'.
 *
 * If the file does not exist or is zero-length (this may happen because
 * when we lock the nodes.conf file, we create a zero-length one for the
 * sake of locking if it does not already exist), C_ERR is returned.
 * If the configuration was loaded from the file, C_OK is returned. */
int clusterLoadConfig(char *filename) {
    FILE *fp = fopen(filename,"r");
    struct stat sb;
    char *line;
    int maxline, j;

    if (fp == NULL) {
        if (errno == ENOENT) {
            return C_ERR;
        } else {
            serverLog(LL_WARNING,
                "Loading the cluster node config from %s: %s",
                filename, strerror(errno));
            exit(1);
        }
    }

    /* Check if the file is zero-length: if so return C_ERR to signal
     * we have to write the config. */
    if (fstat(fileno(fp),&sb) != -1 && sb.st_size == 0) {
        fclose(fp);
        return C_ERR;
    }

    /* Parse the file. Note that single lines of the cluster config file can
     * be really long as they include all the hash slots of the node.
     * This means in the worst possible case, half of the Redis slots will be
     * present in a single line, possibly in importing or migrating state, so
     * together with the node ID of the sender/receiver.
     *
     * To simplify we allocate 1024+CLUSTER_SLOTS*128 bytes per line. */
    maxline = 1024+CLUSTER_SLOTS*128;
    line = zmalloc(maxline);
    while(fgets(line,maxline,fp) != NULL) {
        int argc;
        sds *argv;
        clusterNode *n, *master;
        char *p, *s;

        /* Skip blank lines, they can be created either by users manually
         * editing nodes.conf or by the config writing process if stopped
         * before the truncate() call. */
        if (line[0] == '\n' || line[0] == '\0') continue;

        /* Split the line into arguments for processing. */
        argv = sdssplitargs(line,&argc);
        if (argv == NULL) goto fmterr;

        /* Handle the special "vars" line. Don't pretend it is the last
         * line even if it actually is when generated by Redis. */
        if (strcasecmp(argv[0],"vars") == 0) {
            for (j = 1; j < argc; j += 2) {
                if (strcasecmp(argv[j],"currentEpoch") == 0) {
                    server.cluster->currentEpoch =
                            strtoull(argv[j+1],NULL,10);
                } else if (strcasecmp(argv[j],"lastVoteEpoch") == 0) {
                    server.cluster->lastVoteEpoch =
                            strtoull(argv[j+1],NULL,10);
                } else {
                    serverLog(LL_WARNING,
                        "Skipping unknown cluster config variable '%s'",
                        argv[j]);
                }
            }
            sdsfreesplitres(argv,argc);
            continue;
        }

        /* Regular config lines have at least eight fields */
        if (argc < 8) goto fmterr;

        /* Create this node if it does not exist */
        n = clusterLookupNode(argv[0]);
        if (!n) {
            n = createClusterNode(argv[0],0);
            clusterAddNode(n);
        }
        /* Address and port */
        if ((p = strrchr(argv[1],':')) == NULL) goto fmterr;
        *p = '\0';
        memcpy(n->ip,argv[1],strlen(argv[1])+1);
        char *port = p+1;
        char *busp = strchr(port,'@');
        if (busp) {
            *busp = '\0';
            busp++;
        }
        n->port = atoi(port);
        /* In older versions of nodes.conf the "@busport" part is missing.
         * In this case we set it to the default offset of 10000 from the
         * base port. */
        n->cport = busp ? atoi(busp) : n->port + CLUSTER_PORT_INCR;

        /* Parse flags */
        p = s = argv[2];
        while(p) {
            p = strchr(s,',');
            if (p) *p = '\0';
            if (!strcasecmp(s,"myself")) {
                serverAssert(server.cluster->myself == NULL);
                myself = server.cluster->myself = n;
                n->flags |= CLUSTER_NODE_MYSELF;
            } else if (!strcasecmp(s,"master")) {
                n->flags |= CLUSTER_NODE_MASTER;
            } else if (!strcasecmp(s,"slave")) {
                n->flags |= CLUSTER_NODE_SLAVE;
            } else if (!strcasecmp(s,"fail?")) {
                n->flags |= CLUSTER_NODE_PFAIL;
            } else if (!strcasecmp(s,"fail")) {
                n->flags |= CLUSTER_NODE_FAIL;
                n->fail_time = mstime();
            } else if (!strcasecmp(s,"handshake")) {
                n->flags |= CLUSTER_NODE_HANDSHAKE;
            } else if (!strcasecmp(s,"noaddr")) {
                n->flags |= CLUSTER_NODE_NOADDR;
            } else if (!strcasecmp(s,"nofailover")) {
                n->flags |= CLUSTER_NODE_NOFAILOVER;
            } else if (!strcasecmp(s,"noflags")) {
                /* nothing to do */
            } else {
                serverPanic("Unknown flag in redis cluster config file");
            }
            if (p) s = p+1;
        }

        /* Get master if any. Set the master and populate master's
         * slave list. */
        if (argv[3][0] != '-') {
            master = clusterLookupNode(argv[3]);
            if (!master) {
                master = createClusterNode(argv[3],0);
                clusterAddNode(master);
            }
            n->slaveof = master;
            clusterNodeAddSlave(master,n);
        }

        /* Set ping sent / pong received timestamps */
        if (atoi(argv[4])) n->ping_sent = mstime();
        if (atoi(argv[5])) n->pong_received = mstime();

        /* Set configEpoch for this node. */
        n->configEpoch = strtoull(argv[6],NULL,10);

        /* Populate hash slots served by this instance. */
        for (j = 8; j < argc; j++) {
            int start, stop;

            if (argv[j][0] == '[') {
                /* Here we handle migrating / importing slots */
                int slot;
                char direction;
                clusterNode *cn;

                p = strchr(argv[j],'-');
                serverAssert(p != NULL);
                *p = '\0';
                direction = p[1]; /* Either '>' or '<' */
                slot = atoi(argv[j]+1);
                if (slot < 0 || slot >= CLUSTER_SLOTS) goto fmterr;
                p += 3;
                cn = clusterLookupNode(p);
                if (!cn) {
                    cn = createClusterNode(p,0);
                    clusterAddNode(cn);
                }
                if (direction == '>') {
                    server.cluster->migrating_slots_to[slot] = cn;
                } else {
                    server.cluster->importing_slots_from[slot] = cn;
                }
                continue;
            } else if ((p = strchr(argv[j],'-')) != NULL) {
                *p = '\0';
                start = atoi(argv[j]);
                stop = atoi(p+1);
            } else {
                start = stop = atoi(argv[j]);
            }
            if (start < 0 || start >= CLUSTER_SLOTS) goto fmterr;
            if (stop < 0 || stop >= CLUSTER_SLOTS) goto fmterr;
            while(start <= stop) clusterAddSlot(n, start++);
        }

        sdsfreesplitres(argv,argc);
    }
    /* Config sanity check */
    if (server.cluster->myself == NULL) goto fmterr;

    zfree(line);
    fclose(fp);

    serverLog(LL_NOTICE,"Node configuration loaded, I'm %.40s", myself->name);

    /* Something that should never happen: currentEpoch smaller than
     * the max epoch found in the nodes configuration. However we handle this
     * as some form of protection against manual editing of critical files. */
    if (clusterGetMaxEpoch() > server.cluster->currentEpoch) {
        server.cluster->currentEpoch = clusterGetMaxEpoch();
    }
    return C_OK;

fmterr:
    serverLog(LL_WARNING,
        "Unrecoverable error: corrupted cluster config file.");
    zfree(line);
    if (fp) fclose(fp);
    exit(1);
}

 

Fatal error in PHP project: class’ redis’ not found

 
Reason 1: The PHP extension php_redis is not installed.
Reason 2: For Windows, pay attention to the PHP version (5.4, 5.6, 7.0) and compilation type (x86, x64)
 
Php_redis download address: http://pecl.php.net/package/redis
 
You can view the PHP version and compilation type using the phpinfo function

 

An error was reported when springboot connected to redis Servlet.service () for servlet [dispatcherServlet] in context with path [] threw e

Made a day, finally 11 o ‘clock more than solved, record once. SerializationException: Cannot SerializationException: Cannot SerializationException: Cannot SerializationException: Cannot SerializationException: Cannot SerializationException: Cannot SerializationException: Cannot SerializationException: Cannot SerializationException:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.redis.serializer.SerializationException: Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: com.wanghaixin.springboot.model.Student] with root cause
Solution:
NotSerializable is not serialized objects, object Article cannot be serialized therefore appeared this problem.
JavaBeans to cache must implement the Serializable interface, because Spring serializes objects before storing them in Redis
For this exception, just modify the corresponding JavaBean object, mine is Student

public class Student implements Serializable 

No such file or directory error when redis is started under Windows

This problem occurs because the Redis server is already started and you can test it by entering the command shown in the figure

Redis-CLI is the client that starts Redis. If you do not configure the environment variables, you will need to go to the installation directory of Redis
To run this command, otherwise an error will occur. If you type ping into the Redis client and it returns Pong, you can prove it
The Redis server has started. But if the reader needs to be reassured by an interface like the one shown below, follow the image
The following operations are performed:

This can be done with the following command:
(1) Redis-cli. Exe enters the client of Redis. If no environment variables are configured, it needs to enter the installation directory of Redis to execute
(2) The original server of Redis was shutdown with shutdown
(3) Exit the client
(4) Redis -server.exe Redis.Windows.conf Restarts the Redis server
If you do not configure a Redis environment variable, you will need to go to the installation directory of Redis to execute the above command. After executing the above commands,
You can see the above interface after the subsequent redis-server execution

When Linux installs redis, it executes make install and reports an error: Make: * * [server. O] error 1 (solved)

Reason:
the Redis’s official website to download version of the 6.0 version of make the installation
This is because the GCC version is too low. The GCC installed in YUM is 4.8.5. Therefore, GCC needs to be upgraded. The upgrade process is as follows:

yum -y install centos-release-scl

yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils

scl enable devtoolset-9 bash

echo "source /opt/rh/devtoolset-9/enable" >> /etc/profile

gcc -v

Can.

Design and implementation of music website based on Java

The graduation design adopts the current popular framework Spring Boot, thus simplifying the operation of environment construction. For students who just finished learning Spring Boot framework, the current system has a certain reference value. Cool page, suitable for young friends.
The main functions include list ranking, online playing, etc., but some of the functions have not been implemented. Students who are interested in this can write relevant codes by themselves, which will help improve their technical level.
The source code

http://www.byamd.xyz/dljd.html

Solve the unexpected end of stream exception thrown by jedis

tonight the Internet is off. I haven’t fixed it for a long time. Write a super short post, and then take a rest as soon as possible.

has a Flink program that reads data from Kafka, summarizes the calculation indicator by the 1-minute scrolling window, and writes the result to Redis, that is, writes once every 1 minute. Although the Kafka Source inputs a huge amount of data, the result is only a few hundred kilobytes per minute. After a few hours of running, the following exception is thrown:

redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
        at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:199)
        at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40)
        at redis.clients.jedis.Protocol.process(Protocol.java:151)
        at redis.clients.jedis.Protocol.read(Protocol.java:215)
// 以下略...

is then restarted frequently, and after up to five minutes the same exception is thrown repeatedly, rendering the data completely unwritable. Redis is standalone version 3.2.10, and Jedis is a version 2.9.0 built into the Flink-Redis connector provided by Bahir.

tracing the Jedis source code according to the exception stack in the figure does not yield any useful information. After various googles, find three search directions:

  1. client output buffer is full;
  2. Jedis instance is operated concurrently by multiple threads;
  3. connection idle for a long time disconnected by the server.

take a look at the buffer Settings:

> config get client-output-buffer-limit
1) "client-output-buffer-limit"
2) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60"

has no limit at all. And even if you do, output of a few hundred K per minute is not a bottleneck at all. The multithreading problem also doesn’t exist, because RedisSink’s parallelism was set to 1 in the code in the first place. So there’s only a third possibility left, take a look at the timeout setting in Redis.conf.

> config get timeout
1) "timeout"
2) "120"

120 seconds is pretty short. Look at the structure when we use connector FlinkJedisPoolConfig instances where I used to, the answer is RedisCommandsContainerBuilder:

    public static RedisCommandsContainer build(FlinkJedisPoolConfig jedisPoolConfig) {
        Objects.requireNonNull(jedisPoolConfig, "Redis pool config should not be Null");

        GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
        genericObjectPoolConfig.setMaxIdle(jedisPoolConfig.getMaxIdle());
        genericObjectPoolConfig.setMaxTotal(jedisPoolConfig.getMaxTotal());
        genericObjectPoolConfig.setMinIdle(jedisPoolConfig.getMinIdle());

        JedisPool jedisPool = new JedisPool(genericObjectPoolConfig, jedisPoolConfig.getHost(),
            jedisPoolConfig.getPort(), jedisPoolConfig.getConnectionTimeout(), jedisPoolConfig.getPassword(),
            jedisPoolConfig.getDatabase());
        return new RedisContainer(jedisPool);
    }

shows that the JedisPool does not monitor idle connection at all. Because concurrency is so low, as the program runs, all connections in JedisPool gradually become idle and do not get cleaned up, and an exception occurs. So be sure to poke fun at the Redis connector first.

has to be changed. There are three ways to modify the idea:

  1. set maxIdle to 0. It is too simple and crude. It treats the symptoms rather than the root causes.

  2. directly adds the configuration items of testOnBorrow and testOnReturn to the FlinkJedisPoolConfig class code, that is, when getting and returning connections from JedisPool, the validity of the connections is tested, and the failed connections are cleaned up. There are two more pings, but there is no bottleneck if you only write one batch of data per minute.

  3. replaces GenericObjectPoolConfig with JedisPoolConfig in the above code. The code for JedisPoolConfig is simple:

public class JedisPoolConfig extends GenericObjectPoolConfig {
  public JedisPoolConfig() {
    // defaults to make your life with connection pool easier :)
    setTestWhileIdle(true);
    setMinEvictableIdleTimeMillis(60000);
    setTimeBetweenEvictionRunsMillis(30000);
    setNumTestsPerEvictionRun(-1);
  }
}

is simple, but the four parameters it defaults to are really ‘make our life easier’ :

  • testWhileIdle: turn on idle connection detection;
  • minEvictableIdleTimeMillis: JedisPool connection in the free time threshold, when this threshold is reached, idle connections will be removed. Redis defaults to 30 minutes, which is too long, so JedisPoolConfig defaults to 1 minute;
  • timeBetweenEvictionRunsMillis: testing free connection cycle, it is 30 seconds;
  • numTestsPerEvictionRun: how many connections are taken for each test. If set to -1, all links are detected.

Of course we could also add an idle connection detection parameter to the GenericObjectPoolConfig used by flinkjejedispoolconfig, but that wouldn’t be as convenient as using JedisPoolConfig directly. This approach is more universal because the overhead associated with testOnBorrow and testOnReturn can be significant at times of high concurrency.

people then good night good night.

Springboot integration redis reports non null key required (solved)

SpringBoot integrated Redis reports non null key required(resolved)

notice if the key value given or passed is empty, if it is empty it will report this error

1. Create the SpringBoot project, create the necessary package
; 2. Create application.yml for relevant configuration

server:
  port: 8080
  servlet:
    context-path: /redis
    #mybatis配置
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
  type-aliases-package: com.today.springboot.dao
  mapper-locations: classpath*:mapper/*.xml
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mysql_begin?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false
    type: com.alibaba.druid.pool.DruidDataSource
  redis:
    host: 127.0.0.1
    port: 6379

3. Write redisconfig. Java configuration class

@Configuration
@EnableCaching
public class RedisConfig {

    //编写我们自己的redisTemplate
    //这是写好的一个固定模板,在企业中可以直接使用
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
        //我们为了自己开发方便,一般直接使用<String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        //json序列化配置
        Jackson2JsonRedisSerializer<Object> j2rs = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om=new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        j2rs.setObjectMapper(om);
        //String的序列化
        StringRedisSerializer srs = new StringRedisSerializer();

        //key采用String序列化方式
        template.setKeySerializer(srs);
        //hash的key采用String的序列化方式
        template.setHashKeySerializer(srs);
        //value序列化方式采用jackson
        template.setValueSerializer(j2rs);
        //hash的value序列化方式采用jackson
        template.setHashValueSerializer(j2rs);
        template.afterPropertiesSet();

        return template;
    }

    /**
     * 对hash类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }

    /**
     * 对redis字符串类型数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForValue();
    }

    /**
     * 对链表类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForList();
    }

    /**
     * 对无序集合类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForSet();
    }

    /**
     * 对有序集合类型的数据操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForZSet();
    }
}

4, write redisutil.java helper class. To encapsulate Redis operations, of course, write the appropriate helper class

for your own coding

@Component
public class RedisUtil {


    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    //=================common==================

    /**
     * 指定缓存失败时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }


    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true存在  false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 删除缓存
     *
     * @param key 可以传一个或多个值
     */
    @SuppressWarnings(value = "unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete(CollectionUtils.arrayToList(key));
            }
        }
    }

    // ================String==================

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限制
     * @return true成功 false失败
     */
    public boolean set(String key, String value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key   键
     * @param delta 要减少几个
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     *
     * @param key   键
     * @param delta 要减少几个
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    // =================Map===================

    /**
     * HashGet
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return map 对应多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 键
     * @return map 对应多个键值
     */
    public boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet并设置时间
     *
     * @param key  键
     * @param map  对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除hash表中的值
     *
     * @param key  键 不能为null
     * @param item 项 可以有多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return true存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   要减少几(小于0)
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }

    //====================set===================

    /**
     * 根据key获取set中的所有值
     *
     * @param key 键
     * @return
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 将set数据放入缓存
     *
     * @param key    键
     * @param time   时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取set缓存的长度
     *
     * @param key 键
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().remove(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    //=================List===================

    /**
     * 获取list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束 0 到 -1代表所有值
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取list缓存的长度
     *
     * @param key 键
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引index>=0时, 0 表头,1 第二个元素,以此类推:index<0时,-1表尾,-2倒数第二个元素,以此类推
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引修改list中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        redisTemplate.opsForList().set(key, index, value);
        try {
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除N个为value值
     *
     * @param key   值
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            return redisTemplate.opsForList().remove(key, count, value);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}

5, willful your creative mind to write the best website and system
here to write some test classes to help understand

@SpringBootTest
class RedisSpringbootApplicationTests {

    @Autowired
    @Qualifier("redisTemplate")
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisUtil redisUtil;

    @Test
    public void test1(){
        redisUtil.set("name","today");
        System.out.println(redisUtil.get("name"));
    }

    @Test
    void contextLoads() {
        //redisTemplate
        //opsForValue操作字符串 类似String
        //opsForList操作List 类似List


        //获取redis的连接对象
		//RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
		//connection.flushDb();
		//connection.flushAll();

        redisTemplate.opsForValue().set("mykey","今天");
        System.out.println(redisTemplate.opsForValue().get("mykey"));
    }

    @Test
    public void test() throws JsonProcessingException {
        //真实的开发一般都使用json来传递对象
        User user = new User("today", 3);
		// String jsonUser = new ObjectMapper().writeValueAsString(user);
        redisTemplate.opsForValue().set("user",user);
        System.out.println(redisTemplate.opsForValue().get("user"));
    }

}

published in CSDN for the first time, please forgive me if there is any mistake