Play Redis - Introduction to Redis

Play Redis - Introduction to Redis

Introduction to Redis

The Redis series will write three articles: the first is an introduction to Redis; the second is an introduction to Redis operations and maintenance, including AOF and RDB persistence, Redis master-slave synchronization, sentry mode and cluster building; and the third is a write cache and distributed lock.

1. Overview of Redis

In traditional java web projects, database is used to store data, but there are some fatal drawbacks, which mainly come from performance.Because database persistent data is mainly disk-oriented and disk read/write is slower, in general management systems, there is no high concurrency, so there is often no requirement to read/write a large amount of data in an instant. It is not a big problem to use database for read/write at this time, but in the Internet, there is often a large amount of data demand, such as some commodities.In a snap-up scenario, or when the home page access is large in an instant, thousands of requests will arrive in an instant, requiring the system to complete thousands of read/write operations in a very short period of time, which is often not acceptable to the database, and can easily cause the paralysis of the database system, eventually leading to serious problems of service downtime.
To overcome these problems, NoSQL technology is often introduced in java web projects, and the NoSQL tool is also a simple database, which is mainly memory-based and provides some persistence capabilities.Redis and MongoDB are currently the most widely used NoSQL.Redis's performance advantages come from three main sources.First, it is written based on ANSIC, close to the machine language of assembly language, and runs very fast.Second, it is memory-based read/write, which is naturally much faster than disk read/write in the database.Finally, there are only six types of data in its database structure. The data structure is relatively simple, so there are fewer rules, while the database is a paradigm. There are more rules to consider for integrity and normality, so it is more complex to handle business.So in general, Redis is several to a dozen times faster than a normal database. If you store high hit data on Redis and read/write and manipulate the data through Redis, the performance of the system will be much better than if you only use the database, so using Redis is critical to the responsiveness and performance of Java Internet projects.

2. Redis usage scenarios

  • 1. Caching

In read/write operations on databases, the reality is that the number of reads measured is much more than the number of writes, typically in the ratio of 1:9 to 3:7, so there is more possibility of reading than writing.Generally speaking, store some common data, such as user login information; some main business information, such as the bank will store some basic customer information, bank card information, recent transaction information and so on.

  • 2. Use of time-limited business
    The expire command can be used in redis to set the lifetime of a key, after which redis will delete it.This feature can be used in business scenarios such as time-limited preferential activity information, mobile phone verification codes, etc.

  • 3. Counter-related problems

Because incrby commands can increase atomicity, redis can be used for high concurrent seconds killing, generation of distributed serial numbers, and specific businesses such as limiting how many text messages a mobile phone number sends, how many requests a interface can limit in a minute, how many calls an interface can limit in a day, and so on.

  • 4. Questions related to leaderboards

Relational databases are generally slow to query on rankings, so hot spot data can be sorted using the SortedSet of redis.

  • 5. Distributed Locks

This is mainly done using the redis setnx command, setnx:'set if not exists'is to successfully set the cache and return 1 if it does not exist, otherwise return 0.

......

3. Basic Types

Currently Redis supports six data types: String, List, set, hash, zset, and HyperLogLog.

To program with Redis, familiarize yourself with the six data types and understand their common commands.These six types of data defined by Redis are useful because they provide simple storage capabilities and allow you to perform some calculations on the stored data.

For example, strings can support floating-point number auto-increment, auto-decrement, character substring, set intersection, union, ordered set sorting, and so on, so using them can help to quickly calculate some small data collections, simplify programming, and it is much faster than the database, so they are very meaningful to improve system performance.

Four SpringBoot Integrated Redis

(1) Introducing dependencies

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

(2) yml configuration

  redis:
    host: localhost # Redis Server Address
    database: 0 # Redis database index (default 0)
    port: 6379 # Redis Server Connection Port
    password:"test" # Redis Server Connection Password (blank by default and quoted here!!!)
    jedis:
      pool:
        max-active: 8 # Maximum number of connections in connection pool (negative means no limit), maximum number of connections that can be made
        max-wait: -1ms # Maximum blocking wait time for connection pool (use a negative value to indicate no limit)
        max-idle: 8 # Maximum idle connection in connection pool, too much idle may be destroyed
        min-idle: 0 # Minimum idle connections in connection pool, make sure to keep several control connections
    timeout: 3000ms # Connection timeout (milliseconds)

(3) Injection Template starts

After the last two steps, you've actually configured it and injected Template into your code to set, get, and enable it.

Teplate currently has two known types, RedisTemplate and
String RedisTemplate (which is actually RedisTemplate <String, String>) encapsulates the upper part of a writing.
So you can only use RedisTemplate for your own use and write generics if you want.

(4) Write Config classes

package com.wk.redis.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

	@Bean
	@SuppressWarnings("all")
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {

		RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();

		template.setConnectionFactory(factory);

		Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

		ObjectMapper om = new ObjectMapper();

		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

		jackson2JsonRedisSerializer.setObjectMapper(om);

		StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

		// key uses String serialization

		template.setKeySerializer(stringRedisSerializer);

		// hash's key also uses String's serialization

		template.setHashKeySerializer(stringRedisSerializer);

		// value serialization using jackson

		template.setValueSerializer(jackson2JsonRedisSerializer);

		// hash's value serialization uses jackson

		template.setHashValueSerializer(jackson2JsonRedisSerializer);

		template.afterPropertiesSet();

		return template;

	}
}

(5) Writing service classes

package com.wk.redis.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class RedisService {

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	// =============================common============================
	/**
	 * Specify cache expiration time
	 * @param key key
	 * @param time Time (seconds)
	 * @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;
		}
	}

	/**
	 * Get expiration time based on key
	 * @param key Key cannot be null
	 * @return Time (seconds) returning 0 means permanent validity
	 */
	public long getExpire(String key) {
		return redisTemplate.getExpire(key, TimeUnit.SECONDS);
	}

	/**
	 * Determine if key exists
	 * @param key key
	 * @return true Existence false does not exist
	 */
	public boolean hasKey(String key) {
		try {
			return redisTemplate.hasKey(key);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * Delete Cache
	 * @param key One or more values can be passed
	 */
	@SuppressWarnings("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));
			}
		}
	}

	/**
	 * Delete Cache
	 * @param keys One or more values can be passed
	 */
	@SuppressWarnings("unchecked")
	public void del(Collection keys) {
		if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(keys)) {
			redisTemplate.delete(keys);
		}
	}

	// ============================String=============================
	/**
	 * Common Cache Acquisition
	 * @param key key
	 * @return value
	 */
	public Object get(String key) {
		return key == null ? null : redisTemplate.opsForValue().get(key);
	}

	/**
	 * Plain Cache
	 * @param key key
	 * @param value value
	 * @return true Successful false failed
	 */
	public boolean set(String key, Object value) {
		try {
			redisTemplate.opsForValue().set(key, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * Place a regular cache and set the time
	 * @param key key
	 * @param value value
	 * @param time Time (seconds) Time is greater than 0 If time is less than or equal to 0 an indefinite period will be set
	 * @return true Successful false failed
	 */
	public boolean set(String key, Object 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;
		}
	}

	/**
	 * Incremental
	 * @param key key
	 * @param delta To add a few (greater than 0)
	 * @return
	 */
	public long incr(String key, long delta) {
		if (delta < 0) {
			throw new RuntimeException("Increment factor must be greater than 0");
		}
		return redisTemplate.opsForValue().increment(key, delta);
	}

	/**
	 * Decreasing
	 * @param key key
	 * @param delta To reduce by a few (less than 0)
	 * @return
	 */
	public long decr(String key, long delta) {
		if (delta < 0) {
			throw new RuntimeException("Decreasing factor must be greater than 0");
		}
		return redisTemplate.opsForValue().increment(key, -delta);
	}

	// ================================Map=================================
	/**
	 * HashGet
	 * @param key Key cannot be null
	 * @param item Item cannot be null
	 * @return value
	 */
	public Object hget(String key, String item) {
		return redisTemplate.opsForHash().get(key, item);
	}

	/**
	 * Get all keys corresponding to hashKey
	 * @param key key
	 * @return Corresponding multiple key values
	 */
	public Map<Object, Object> hmget(String key) {
		return redisTemplate.opsForHash().entries(key);
	}

	/**
	 * HashSet
	 * @param key key
	 * @param map Corresponds to multiple key values
	 * @return true Successful false failed
	 */
	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 And set the time
	 * @param key key
	 * @param map Corresponds to multiple key values
	 * @param time Time (seconds)
	 * @return true Successful false failed
	 */
	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;
		}
	}

	/**
	 * Put data into a hash table and create it if it doesn't exist
	 * @param key key
	 * @param item term
	 * @param value value
	 * @return true Successful false failed
	 */
	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;
		}
	}

	/**
	 * Put data into a hash table and create it if it doesn't exist
	 * @param key key
	 * @param item term
	 * @param value value
	 * @param time Time (seconds) Note: If the existing hash table has time, this will replace the original time
	 * @return true Successful false failed
	 */
	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;
		}
	}

	/**
	 * Delete values from hash table
	 * @param key Key cannot be null
	 * @param item Item can make multiple cannot be null
	 */
	public void hdel(String key, Object... item) {
		redisTemplate.opsForHash().delete(key, item);
	}

	/**
	 * Delete values from hash table
	 * @param key Key cannot be null
	 * @param items Item can make multiple cannot be null
	 */
	public void hdel(String key, Collection items) {
		redisTemplate.opsForHash().delete(key, items.toArray());
	}

	/**
	 * Determine if there is a value for this item in the hash table
	 * @param key Key cannot be null
	 * @param item Item cannot be null
	 * @return true Existence false does not exist
	 */
	public boolean hHasKey(String key, String item) {
		return redisTemplate.opsForHash().hasKey(key, item);
	}

	/**
	 * hash Increment, if it does not exist, creates one and returns the added value
	 * @param key key
	 * @param item term
	 * @param delta To add a few (greater than 0)
	 * @return
	 */
	public double hincr(String key, String item, double delta) {
		if (delta < 0) {
			throw new RuntimeException("Increment factor must be greater than 0");
		}
		return redisTemplate.opsForHash().increment(key, item, delta);
	}

	/**
	 * hash Decreasing
	 * @param key key
	 * @param item term
	 * @param delta To reduce memory (less than 0)
	 * @return
	 */
	public double hdecr(String key, String item, double delta) {
		if (delta < 0) {
			throw new RuntimeException("Decreasing factor must be greater than 0");
		}
		return redisTemplate.opsForHash().increment(key, item, -delta);
	}

	// ============================set=============================
	/**
	 * Get all the values in the Set based on the key
	 * @param key key
	 * @return
	 */
	public Set<Object> sGet(String key) {
		try {
			return redisTemplate.opsForSet().members(key);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * Query from a set for existence based on value
	 * @param key key
	 * @param value value
	 * @return true Existence false does not exist
	 */
	public boolean sHasKey(String key, Object value) {
		try {
			return redisTemplate.opsForSet().isMember(key, value);
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * Put data into set cache
	 * @param key key
	 * @param values Values can be multiple
	 * @return Number of successes
	 */
	public long sSet(String key, Object... values) {
		try {
			return redisTemplate.opsForSet().add(key, values);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	/**
	 * Put data into set cache
	 * @param key key
	 * @param values Values can be multiple
	 * @return Number of successes
	 */
	public long sSet(String key, Collection values) {
		try {
			return redisTemplate.opsForSet().add(key, values.toArray());
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	/**
	 * Cache set data
	 * @param key key
	 * @param time Time (seconds)
	 * @param values Values can be multiple
	 * @return Number of successes
	 */
	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;
		}
	}

	/**
	 * Get the length of set cache
	 * @param key key
	 * @return
	 */
	public long sGetSetSize(String key) {
		try {
			return redisTemplate.opsForSet().size(key);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	/**
	 * Remove value
	 * @param key key
	 * @param values Values can be multiple
	 * @return Number Removed
	 */
	public long setRemove(String key, Object... values) {
		try {
			Long count = redisTemplate.opsForSet().remove(key, values);
			return count;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	// ===============================list=================================
	/**
	 * Get the contents of the list cache
	 * @param key key
	 * @param start start
	 * @param end End 0 to -1 for all values
	 * @return
	 */
	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;
		}
	}

	/**
	 * Get the length of the list cache
	 * @param key key
	 * @return
	 */
	public long lGetListSize(String key) {
		try {
			return redisTemplate.opsForList().size(key);
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	/**
	 * Get the value in the list by index
	 * @param key key
	 * @param index Index >=0, 0 header, 1 second element, and so on; index < 0, -1, tail, -2 penultimate element, and so on
	 * @return
	 */
	public Object lGetIndex(String key, long index) {
		try {
			return redisTemplate.opsForList().index(key, index);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * Put list in cache
	 * @param key key
	 * @param value value
	 * @return
	 */
	public boolean lSet(String key, Object value) {
		try {
			redisTemplate.opsForList().rightPush(key, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * Put list in cache
	 * @param key key
	 * @param value value
	 * @param time Time (seconds)
	 * @return
	 */
	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;
		}
	}

	/**
	 * Put list in cache
	 * @param key key
	 * @param value 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;
		}
	}

	/**
	 * Put list in cache
	 *
	 * @param key key
	 * @param value value
	 * @param time Time (seconds)
	 * @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;
		}
	}

		/**
		 * Modify a piece of data in a list based on an index
		 * @param key key
		 * @param index Indexes
		 * @param value value
		 * @return
		 */
	public boolean lUpdateIndex(String key, long index, Object value) {
		try {
			redisTemplate.opsForList().set(key, index, value);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

		/**
		 * Remove N values of value
		 * @param key key
		 * @param count How many to remove
		 * @param value value
		 * @return Number Removed
		 */
	public long lRemove(String key, long count, Object value) {
		try {
			Long remove = redisTemplate.opsForList().remove(key, count, value);
			return remove;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
}

Tags: Redis Database Java less

Posted on Thu, 04 Jun 2020 11:54:06 -0700 by ~J~R~R