1. Introduction of Redis

Redis (Remote Dictionary Server) is an open source, network-enabled, memory-based and persistent logging, key-value database written in ANSI C language, and provides multiple language APIS. Redis is a high performance key-value database. The appearance of Redis, in some cases, can play a good complement to the relational database. It provides Java, C/C++, C#, PHP, JavaScript, Perl, object-C, Python, Ruby, Erlang and other clients, easy to use.

Redis supports master/slave synchronization. Data can be synchronized from the primary server to any number of secondary servers, which can be the primary server associated with other secondary servers. This allows Redis to perform single-layer tree replication. Data can be written intentionally or unintentionally. The fully implemented publish/subscribe mechanism makes it possible to subscribe to a channel and receive a complete record of message releases from the master server when the tree is synchronized anywhere from the database. Synchronization helps with scalability and data redundancy for read operations.

Redis keys are all strings, and their values are diversified, as shown in the following figure:

Redis data type ENCODING Indicates the returned ENCODING Underlying corresponding data structure
string int An integer of type long
string embstr A simple dynamic string encoded by embstr
string raw Simple dynamic string
list ziplist List of compression
list linkedlist Two-way linked list
hash ziplist List of compression
hash ht The dictionary
set intset The integer set
set ht The dictionary
zset ziplist List of compression
zset skiplist Jump table

2. Five data types of Redis

2.1 String Object (String)

String object model:

Redis provides three different data structures to implement string objects, and automatically selects the appropriate data structure according to different data. String objects are not just strings, numbers are fine.

  • Int: When the data is an integer string of type long, the underlying implementation uses an integer of type long. This value is stored directly in the PTR property of the string OBJECT, and OBJECT ENCODING is int.

  • Raw: When the data is a String with a length greater than 44 bytes, the underlying implementation uses Simple Dynamic strings. Here we have to refer to the Simple Dynamic String (SDS) of Redis. SDS has three attributes, free, len and BUF. Free stores how much space is left and len stores the current length of the string, excluding trailing null characters. Buf is a list that holds real string data, including free and null characters. SDS will not be introduced in detail in this paper. Please click ON SDS to learn more.

  • Embstr: Simple dynamic string implementation using embSTR encoding at the bottom when the data is a string of less than 44 bytes. In contrast to RAW, EMBSTR allocates memory only once, allocating a contiguous chunk of memory.

2.2 List Objects

List object model:

List objects in Redis are often used as message queues, and the underlying implementation is Ziplist and LinkedList. Just use it as a linked list when you’re using it.

  • ziplist

    The ziplist encoding of list objects must meet the following two requirements: First, all strings must be shorter than the set value of 64 bytes (you can modify the list-max-ziplist-value field in the configuration file). Second, the number of stored elements is less than the set value of 512 (you can modify the list-max-ziplist-entries field in the configuration file). Ziplist is similar to python’s List in that it takes up a contiguous list of memory addresses, thereby reducing the memory footprint of Pointers.

Zlbytes: indicates the total memory usage

Zltail: Offset to tail

Zllen: indicates the number of internal nodes

The node, the node

Zlend: Tail identifier

Previous_entry_length: indicates the length of the previous node

Encoding: Indicates the data type

Content: indicates real data

The tail node nodeN is found directly according to zlbytes and zltail, and then traversed backwards according to the previous_entry_length of each node. Adding and removing nodes causes cascading updates to other nodes because each node stores the length of the previous node.

  • linkedlist

    Linkedlist has three attributes, head, tail, and len. Head refers to the head of the list, tail refers to the tail of the list, and len is the length of the list.

2.3 Hash Objects

The model of hashed objects:

The redis value type hash, which is actually the map type, is to put a map data in the position of the value. We want to learn more about, you can refer to this article: www.jianshu.com/p/658365f0a…

2.4 Set Objects (Set)

Model of collection object types:

A value of the Set type ensures that each value is unique.

The collection object in Redis has two basic implementations, namely integer collection and HashTable. The set of integers is used when all elements are integers and the number of elements is less than 512 (configurable in the set-max-intset-entries field in the configuration file), and the rest are implemented using hashTable. Intset (intset, intset, intset) Intset has three attributes: encoding: record type int16, int32, int64, Length: record length, content: store specific data. The specific structure is shown as follows:

2.5 Ordered collection objects

An ordered set (zset) is not much different from a set (set), except that a score is added for sorting.

The ordered set in Redis is implemented by Ziplist and Skiplist skip tables. When all strings are shorter than the set value of 64 bytes (list-max-ziplist-value can be modified in the configuration file), And the number of stored elements is less than the set value of 512 (you can modify the list-max-ziplist-entries field in the configuration file) use ziplist implementation, other cases use skiplist implementation, skiplist implementation principle here stolen, here is a good blog to write. Click to see how skip lists work.

3. Installation of Redis

You can download Redis from the official website or Chinese website. The Windows version of Redis is no longer up to date, so we installed Redis version 6.0.3, which supports a lot of things. In this tutorial, we will only explain and study the five data types of Redis.

Liverpoolfc.tv: redis. IO /

Chinese website: www.redis.net.cn/

GCC 4.8.5, redis6.0+ GCC 5.3 and above, so you need to upgrade GCC version.

Download the Linux tar. Gz package and decompress the package.

CD redis - 6.0.3Copy the code

The bin directory is not found. You need to use make to install it.

#Start by checking the GCC environment
gcc -v 
#Viewing the GCC Version
yum -y install centos-release-scl 
#Upgrade to version 9.1
yum -y install devtoolset-9-gcc devtoolset-9-gcc- c++ devtoolset-9-binutils 

scl enable devtoolset-9 bash 
#This is temporary if you want to use GCC 9.1 for a long time:
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile 
#Go to Redis and decompress the file
make 
#6.0 pit, GCC version 9.0 or above
#Waiting for the completion of
Copy the code

After making, you can see the SRC directory in the redis directory. After entering the SRC directory, you can see redis-server and redis-cli.

It is recommended to copy the Redis configuration file and keep a native one.

Redis configuration you can search the common configuration on the Internet, here to recommend a common configuration, more detailed:

Blog.csdn.net/ymrfzr/arti…

At this point Redis is up and running.

Note: redis IP address bindings must be commented out to allow all IP addresses to access, otherwise we will not be able to access from Windows.

Comment out the following line:

At the same time, turn off Redis service protection mode and set protected-mode to no. As follows:

4. Spring Boot integrates Redis

  • 4.1 Building projects and introducing dependencies

    I’m not going to write it down here. Go directly to POM.xml:

    <! -- SpringBoot parent project -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2. RELEASE</version>
        <relativePath/> <! -- lookup parent from repository -->
    </parent>
    
    <dependencies>
        <! - springboot -- web components -- -- >
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.2. RELEASE</version>
        </dependency>
        <! -- Redis integrates springBoot components -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.3.0. RELEASE</version>
        </dependency>
        <! - lombok component - >
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
    </dependencies>
    Copy the code
  • 4.2 Configuration of Redis

    Project configuration file, application.yml:

    butterflytri:
      host: 127.0. 01.
    server:
      port: 8080 # Application port
      servlet:
        context-path: /butterflytri # apply mapping
    spring:
      application:
        name: redis # app name
      redis:
        host: ${butterflytri.host} # redis address
        port: 6379 # redis port, default is 6379
        timeout: 10000 # Connection timeout (ms)
        database: 0 # redis specifies the shard to be used. The default is 0
        jedis: # Use the redis tool - Jedis
          pool:
            max-active: 8 The maximum number of connections in the pool (using negative values to indicate no limit) defaults to 8
            max-wait: - 1 The maximum connection pool blocking wait time (negative value indicates no limit) defaults to -1
            max-idle: 8 The maximum number of free connections in the connection pool defaults to 8
            min-idle: 0 The minimum free connection in the connection pool defaults to 0
    Copy the code

    There is also an additional configuration class called redisconfig.java:

    package com.butterflytri.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    / * * *@author: WJF
     * @date: 2020/5/24
     * @description: RedisConfig
     */
    
    @Configuration
    public class RedisConfig {
    
        /** * Redis serializes the values of key/value pairs: generic *@return RedisSerializer
         */
        private RedisSerializer redisValueSerializer(a) {
            return new GenericJackson2JsonRedisSerializer();
        }
    
        /** * serialization of keys in redis: all keys are strings *@return RedisSerializer
         */
        private RedisSerializer redisKeySerializer(a) {
            return new StringRedisSerializer();
        }
    
        @Bean("redisTemplate")
        public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            redisTemplate.setKeySerializer(redisKeySerializer());
            redisTemplate.setValueSerializer(redisValueSerializer());
            returnredisTemplate; }}Copy the code
  • 4.3 Use of redisTemplate

    CRUD for values of type value:

    ValueServiceImpl. Java:

    package com.butterflytri.service.impl;
    
    import com.butterflytri.service.ValueService;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    
    / * * *@author: WJF
     * @date: 2020/5/27
     * @description: ValueServiceImpl
     */
    @Service
    public class ValueServiceImpl implements ValueService {
    
        @Resource
        private RedisTemplate<String, Object> redisTemplate;
    
        @Override
        public void addValue(String key, Object value) {
            redisTemplate.opsForValue().set(key,value);
        }
    
        @Override
        public Object get(String key) {
            return redisTemplate.opsForValue().get(key);
        }
    
        @Override
        public Object update(String key, Object newValue) {
            return redisTemplate.opsForValue().getAndSet(key,newValue);
        }
    
        @Override
        public void delete(String key) { redisTemplate.delete(key); }}Copy the code

    CRUD for values of type List:

    I’ve added an enumeration type to control where to add, because the List type corresponds to a linked List.

    ListServiceImpl. Java:

    package com.butterflytri.service.impl;
    
    import com.butterflytri.enums.OpsType;
    import com.butterflytri.service.ListService;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import java.util.List;
    
    / * * *@author: WJF
     * @date: 2020/5/28
     * @description: ListServiceImpl
     */
    @Service
    public class ListServiceImpl implements ListService {
    
        @Resource
        private RedisTemplate<String, Object> redisTemplate;
    
        @Override
        public void addList(String key, List<Object> list, OpsType type) {
            switch (type) {
                case RIGHT:
                    redisTemplate.opsForList().rightPushAll(key, list);
                    break;
                case LEFT:
                    redisTemplate.opsForList().leftPushAll(key, list);
                    break;
                default:
                    throw new RuntimeException("Type cannot be null"); }}@Override
        public void add(String redisKey, Object value, OpsType type) {
            switch (type) {
                case RIGHT:
                    redisTemplate.opsForList().rightPush(redisKey, value);
                    break;
                case LEFT:
                    redisTemplate.opsForList().leftPush(redisKey, value);
                    break;
                default:
                    throw new RuntimeException("Type cannot be null"); }}@Override
        public List<Object> get(String key) {
            return redisTemplate.opsForList().range(key, 0, -1);
        }
    
        @Override
        public Object update(String key, Object value, Integer index) {
            Object obj = redisTemplate.opsForList().index(key, index);
            redisTemplate.opsForList().set(key,index,value);
            return obj;
        }
    
        @Override
        public void delete(String key) {
            redisTemplate.delete(key);
        }
    
        @Override
        public void deleteValue(String redisKey, OpsType type) {
            switch (type) {
                case RIGHT:
                    redisTemplate.opsForList().rightPop(redisKey);
                    break;
                case LEFT:
                    redisTemplate.opsForList().leftPop(redisKey);
                    break;
                default:
                    throw new RuntimeException("Type cannot be null"); }}}Copy the code

    CRUD for Hash values:

    The hash type is the most common type we use.

    HashServiceImpl.java:

    package com.butterflytri.service.impl;
    
    import com.butterflytri.service.HashService;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import java.util.Map;
    
    / * * *@author: WJF
     * @date: 2020/5/28
     * @description: HashServiceImpl
     */
    @Service
    public class HashServiceImpl implements HashService {
    
        @Resource
        private RedisTemplate<String, Object> redisTemplate;
    
        @Override
        public void addHashAll(String key, Map<String, Object> value) {
            redisTemplate.opsForHash().putAll(key, value);
        }
    
        @Override
        public void addHash(String redisKey, String key, Object value) {
            redisTemplate.opsForHash().put(redisKey, key, value);
        }
    
        @Override
        public Object get(String redisKey, String key) {
            return redisTemplate.opsForHash().get(redisKey, key);
        }
    
        @Override
        public Object update(String redisKey, String key, Object value) {
            Object obj = this.get(redisKey, key);
            this.delete(redisKey,key);
            redisTemplate.opsForHash().put(redisKey, key, value);
            return obj;
        }
    
        @Override
        public void delete(String redisKey, String key) {
            redisTemplate.opsForHash().delete(redisKey, key);
        }
    
        @Override
        public void deleteAll(String redisKey) { redisTemplate.delete(redisKey); }}Copy the code

    CRUD on the value of Set:

    package com.butterflytri.service.impl;
    
    import com.butterflytri.service.SetService;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import java.util.Set;
    
    / * * *@author: WJF
     * @date: 2020/5/28
     * @description: SetServiceImpl
     */
    @Service
    public class SetServiceImpl implements SetService {
    
        @Resource
        private RedisTemplate<String, Object> redisTemplate;
    
    
        @Override
        public void addAll(String key, Set<Object> set) {
            redisTemplate.opsForSet().add(key,set);
        }
    
        @Override
        public void add(String key, Object value) {
            redisTemplate.opsForSet().add(key,value);
        }
    
        @Override
        public Set<Object> findAll(String key) {
            return redisTemplate.opsForSet().members(key);
        }
    
        @Override
        public void deleteValue(String key, Object value) {
            redisTemplate.opsForSet().remove(key,value);
        }
    
        @Override
        public void delete(String key) { redisTemplate.delete(key); }}Copy the code

    CRUD for values of type ZSet:

    package com.butterflytri.service.impl;
    
    import com.butterflytri.service.SortedSetService;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    
    import javax.annotation.Resource;
    import java.util.LinkedHashSet;
    
    / * * *@author: WJF
     * @date: 2020/5/28
     * @description: SortedSetServiceImpl
     */
    @Service
    public class SortedSetServiceImpl implements SortedSetService {
    
        @Resource
        private RedisTemplate<String, Object> redisTemplate;
    
        @Override
        public void add(String key, String value, Double score) {
            redisTemplate.opsForZSet().add(key, value, score);
        }
    
        @Override
        public LinkedHashSet<Object> findAll(String key) {
            return (LinkedHashSet<Object>) redisTemplate.opsForZSet().range(key,0, -1);
        }
    
        @Override
        public Long count(String key, Double scoreFrom, Double scoreTo) {
            return redisTemplate.opsForZSet().count(key,scoreFrom,scoreTo);
        }
    
        @Override
        public LinkedHashSet<Object> findByScore(String key, Double scoreFrom, Double scoreTo) {
            return (LinkedHashSet<Object>) redisTemplate.opsForZSet().rangeByScore(key,scoreFrom,scoreTo);
        }
    
        @Override
        public Long rank(String key, Object value) {
            return redisTemplate.opsForZSet().rank(key,value);
        }
    
        @Override
        public void remove(String key, String value) {
            redisTemplate.opsForZSet().remove(key,value);
        }
    
        @Override
        public void delete(String key) { redisTemplate.delete(key); }}Copy the code

    There are a lot of Java clients in Redis, in this case we use Jedis, there is also a very good Java language client called lettuce, you can see, Spring never reconstructs wheels, only simplifies the use of wheels, redisTemplate is a super simple implementation. At this point redis is done integrating Spring Boot.

5. Project address

Portal of this project:

  • GitHub —> spring-data-redis
  • Gitee —> spring-data-redis

This tutorial will be updated all the time, if you think bloggers can write, pay attention to it, and it can be more convenient to learn next time.


  • Author: Butterfly – Tri
  • Reference:Butterfly-Tri personal blog
  • All rights reserved. Welcome to keep the original link for reprinting 🙃