Spring boot forum project practice_ 04

Redis, one-stop happy energy storage solution

1. Introduction to redis

  • Redis is a NoSQL database based on key value pairs. Its values support a variety of data structures:

    • Strings, hashes, lists, sets, sorted sets, etc

  • Redis stores all data in memory, so its read-write performance is amazing. At the same time, redis can also save the data in memory to the hard disk in the form of snapshot or log to ensure the security of the data

  • Typical application scenarios of Redis include: cache, leaderboard, counter, social network, message queue, etc.

  • Reference website:

  • Common Redis commands:

    • Clear current data: flushdb

    • Strings:

      • Storage: set key [character splicing ': "] value

      • Get: get key

      • Number plus: incr key, return integer

      • Number minus: decr key, return integer

        • Addition and subtraction can only be of integer type

    • Hashes:

      • Store: hset key [character splicing ': "] field [hash key] value

      • Get: hget key [character splicing ': "] field

    • Lists: [can be understood as a horizontal array]

      • According to its access can be left or right, the characteristics of queue and stack can be realized respectively

      • Enter: left or right

      • Zuo Jin

        • Save multiple values on the left: lpush key value [value...]

        • View current list length: len key

        • View the index value in the specified key list: lindex key index

        • View the value of the specified range: lrange key start stop

      • Out: left or right

      • Specify right out: rpop key

    • Sets:

      • Save to collection element: sadd key member [member...]

      • Statistics collection element: scar key

      • Random pop-up element: spop key [available for lucky draw]

      • View the remaining elements of the collection: smembers key

    • Sorted sets:

      • Add element: zadd key [NX|XX] [CH] [INCR] score member [score member...] [fractional element name]

      • Query the score of a value: zscore key member

      • Return the ranking of a value: zrank key member [from small to large by default, starting from 0]

      • Take the data of a certain range: zrange key start stop [with scores]

    • Global: keys pattern

      • View all current key s: keys*

      • View all keys at the beginning of test: keys test*

      • View the type of a key: type key

      • Check whether a key exists: EXISTS key [key...]

      • Delete a key: del key [key...]

      • Set the expiration time of a key [auto delete upon expiration]: expire key seconds

 

2. Spring integrates Redis

 

  • Introduce dependency

    • spring-boot-starter-data-redis

  • Configure Redis

  • k:Object in k-v in Spring default configuration

    The commonly used k: String types are actually opened

    So you need to configure it manually

    • Configure database parameters

    • Write configuration classes and construct RedisTemplate

      • // be based on Spring Framed
        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.RedisSerializer;
        ​
        @Configuration
        public class RedisConfig {
        ​
            // Access connection factory, To create an object
            @Bean
            public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
                // Instantiation of method
                RedisTemplate<String,Object> template = new RedisTemplate<String,Object>();
                // Set connection factory for object
                template.setConnectionFactory(factory);
        ​
                // set up key Serialization mode of, Parameter is spring Framed redis Lower
                // Returns a serializer that can serialize strings
                template.setKeySerializer(RedisSerializer.string());
        ​
                // set up value Serialization mode of
                template.setValueSerializer(RedisSerializer.json());
        ​
                // set up hash of key Serialization mode of
                template.setHashKeySerializer(RedisSerializer.string());
        ​
                // set up hash of value Serialization mode of
                template.setHashValueSerializer(RedisSerializer.json());
        ​
                // Effective after trigger setting
                template.afterPropertiesSet();
                return template;
            }
        ​
        }
  • Visit Redis

    • redisTemplate.opsForValue()

      • @Test
        public void testStrings(){
            String redisKey = "test:count";
        ​
            // String Value of type
            redisTemplate.opsForValue().set(redisKey,1);
        ​
            System.out.println(redisTemplate.opsForValue().get(redisKey));
            System.out.println(redisTemplate.opsForValue().increment(redisKey));
            System.out.println(redisTemplate.opsForValue().decrement(redisKey));
        }

         

    • redisTemplate.opsForHash()

      • // visit hash
            @Test
            public void  testHashes(){
                String redisKey = "test:user";
                redisTemplate.opsForHash().put(redisKey,"id",1);
                redisTemplate.opsForHash().put(redisKey,"username","Zhang San");
        ​
                System.out.println(redisTemplate.opsForHash().get(redisKey, "id"));
                System.out.println(redisTemplate.opsForHash().get(redisKey, "username"));
        ​
            }

         

    • redisTemplate.opsForList()

      • @Test
            public void testLists(){
                // Left entry list
                String redisKey = "test:ids";
        ​
                // Put data
                redisTemplate.opsForList().leftPush(redisKey,101);
                redisTemplate.opsForList().leftPush(redisKey,102);
                redisTemplate.opsForList().leftPush(redisKey,103);
        ​
                // Fetch data
                // Count the number of current elements
                System.out.println(redisTemplate.opsForList().size(redisKey));
                // Gets the element at the specified location, Gets the element corresponding to an index
                System.out.println(redisTemplate.opsForList().index(redisKey,0));
                // Get elements by index range
                System.out.println(redisTemplate.opsForList().range(redisKey, 0, 2));
                // Pop up element, Left out
                System.out.println(redisTemplate.opsForList().leftPop(redisKey));
                System.out.println(redisTemplate.opsForList().leftPop(redisKey));
                System.out.println(redisTemplate.opsForList().leftPop(redisKey));
            }

         

    • redisTemplate.opsForSet()

      • @Test
            public void  testSets(){
                String redisKey = "test:teachers";
        ​
                redisTemplate.opsForSet().add(redisKey,"Liu Bei","Guan Yu","Fei Zhang","Zhao Yun","kong ming");
        ​
                // Number of statistical elements
                System.out.println(redisTemplate.opsForSet().size(redisKey));
                // Pop up a data, Random pop-up
                System.out.println(redisTemplate.opsForSet().pop(redisKey));
                // What is the data in the current collection, Show all elements in the current collection
                System.out.println(redisTemplate.opsForSet().members(redisKey));
                
            }

         

    • redisTemplate.opsForZSet()

      • @Test
            public void testSortedSets(){
                String redisKey = "test:students";
        ​
                // Add element, And its corresponding score
                redisTemplate.opsForZSet().add(redisKey,"Tang Monk",80);
                redisTemplate.opsForZSet().add(redisKey,"name of a fictitious monkey with supernatural powers",90);
                redisTemplate.opsForZSet().add(redisKey,"Bajie",50);
                redisTemplate.opsForZSet().add(redisKey,"Monk Sha",70);
                redisTemplate.opsForZSet().add(redisKey,"old but strong",60);
        ​
                // Total number of statistical elements
                System.out.println(redisTemplate.opsForZSet().zCard(redisKey));
                // Query the score of an element
                System.out.println(redisTemplate.opsForZSet().score(redisKey,"Bajie"));
                // Query the ranking of an element, Default from small to large
                System.out.println(redisTemplate.opsForZSet().rank(redisKey,"Bajie"));
                // Flashback ranking, According to the score from big to small
                System.out.println(redisTemplate.opsForZSet().reverseRank(redisKey,"Bajie"));
                // Take the top three from small to large
                System.out.println(redisTemplate.opsForZSet().range(redisKey,0,2));
                // Take the top three from big to small
                System.out.println(redisTemplate.opsForZSet().reverseRange(redisKey,0,2));
                
            }
    • Access to key

      • // Access public type key
            @Test
            public void testKeys(){
        ​
                // Generally not used in the program keys * This command, This command is usually a direct query
        ​
                redisTemplate.delete("test:user");
        ​
                // judge key Does it exist
                System.out.println(redisTemplate.hasKey("test:user"));
        ​
                // set up key Expiration time of
                // TimeUnit. Set time unit: day, Time, branch, second, millisecond...
                redisTemplate.expire("test:students",10, TimeUnit.SECONDS);
            }

         

    • If you access the same key multiple times, you can bind the key to avoid copying the redisKey:

      • // Multiple visits to the same key
            @Test
            public void testBoundOperations(){
                String redisKey = "test:count";
        ​
                // Bound XXX Operations: XXX : What type of data do you want to access, Here is String
                // redisTemplate.bound XXX Ops : Bind specific data types, Here is String
                BoundValueOperations operations = redisTemplate.boundValueOps(redisKey);
                // This is binding key Don't write it every time.
                operations.increment();
                operations.increment();
                operations.increment();
                operations.increment();
                operations.increment();
                System.out.println(operations.get());
        ​
            }

 

Redis transactions

Redis is a non relational database, so there is no need to strictly abide by ACID

In the actual production environment, it is recommended to implement it with programmatic transactions. Declarative transactions can only be used for the whole method and cannot control individual code lines

//Programming transaction
 
@Test
    public void testTransactional() {
        Object obj = redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                String redisKey = "test:tx";
                // Enable transactions
                operations.multi();
​
                operations.opsForSet().add(redisKey,"Zhang San");
                operations.opsForSet().add(redisKey,"Li Si");
                operations.opsForSet().add(redisKey,"Wang Wu");
​
                // The transaction process cannot be read
                System.out.println(operations.opsForSet().members(redisKey));
                //operations.exec() : Commit transaction
                return operations.exec();
            }
        });
​
        System.out.println(obj);
    }

 

  • The printing results show that:

    • The first query structure is empty, which ensures the atomicity of transactions

    • The second printing result: the first three "1": the number of elements affected by each operation; This is followed by the specific elements in the collection

 

3. Like

Storing the likes data in Redis improves performance, which is better than storing them in memory

Asynchronous request

  • give the thumbs-up

    • Support likes to posts and comments

    • Like for the first time and cancel like for the second time [double click to cancel]

  • Number of likes on homepage

    • Count the number of likes of Posts

  • Number of likes on detail page

    • Count the number of likes

    • Show like status

 

4. Praise I received

  • Reconstruct the like function

    • Take the user as the key and record the number of likes

    • increment(key), decrement(key)

  • Develop personal homepage

    • Query the number of likes with the user as the key

 

5. Concern and cancellation

  • demand

    • Develop and cancel the following functions

    • Count the number of users' attention and fans

  • crux

    • If A is A fan, B is A fan.

    • The goal of attention can be users, posts, topics, etc. these goals are abstracted as entities when they are realized.

 

6. Follow list and fan list

  • Business layer

    • Query the person concerned by a user and support paging.

    • Query the fans of a user and support paging.

  • Presentation layer

    • Handle "query people of interest" and "query fans" requests.

    • Write the templates of "query followers" and "query fans".

 

7. Optimize login module

  • Use Redis to store verification code

    • The verification code needs frequent access and refresh, which requires high performance

    • The verification code does not need to be saved permanently, and it usually becomes invalid after a short time

      • Set expiration time

    • In distributed deployment, there is a problem of Session sharing

  • Use Redis to store login credentials [do not delete, keep user records]

    • When processing each request, the user's login credentials must be queried, and the access efficiency is very high

  • Use Redis to cache user information [temporarily, delete +]

    • When processing each request, the user information must be queried according to the credentials, and the access frequency is very high

Posted by harmor on Mon, 16 May 2022 14:55:39 +0300