Getting started with Redis

learning target


Introduction to Redis

Redis is completely open source, complies with the BSD protocol, and is a high-performance key-value database.


  1. Redis supports data persistence. The data in the memory can be stored on the disk, and it can be loaded again for use when restarting.
  2. Redis not only supports simple key-value type data, but also provides storage for list, set, zset, hash and other data structures.
  3. Redis supports data backup, that is, data backup in master-slave mode.

Advantages of Redis:

  1. Very high performance-Redis can read 110,000 times/s, and write 81,000 times/s.
  2. Rich data types-Redis supports Strings, Lists, Hashes, Set and Zset data type operations in binary cases.
  3. Atomic-All Redis operations are atomic, meaning that they either succeed in execution or fail and are not executed at all. A single operation is atomic. Multiple operations also support transactions, that is, atomicity, packaged by MULTI and EXEC instructions.
  4. Rich features-Redis also supports publish/subscribe, notification, key expiration and other features.

Redis installation and use

Linux installation

Install the gcc compiler first, which can be used to compile c, c++ and other codes

 yum -y install gcc //-y表示自动安装

Install Redis

 wget //下载redis安装包到usr/local
 tar xzf redis-2.8.17.tar.gz
 cd redis-2.8.17

Redis configuration (enter the redis.conf file in the redis directory)

 cd /usr/local/redis-5.0.4
 vi redis.conf(本人的redis放在/usr/local)

Comment out bind

Protected mode no

Insert picture description here

Use Redis

1. Start the server src./redis-server …/redis.conf

Insert picture description here

2. Start the client src./redis-cli

Insert picture description here

Windows installation

  • Download the windows version of redis from the official website
  • Unzip
  • Start the server
  • Start the client
Insert picture description here

Redis data types

The data types are:

string (suitable for saving a single data)

 	set key value
 	get key
 	set key value EX 10  //10秒钟之后失效
Insert picture description here

Hash (suitable for storing complex types of data, such as: generally can be used to store a complete custom object in Java)

 	//name "zhangsan" age 23 sex "nan" 是 key对应的值> hmset user name "zhangsan" age 23 sex "nan"
 	//hmget获取hash中的某一个属性的值> hmget user name
 	1) "zhangsan"> hmget user age
 	1) "23"
 	//hgetall是获取hash中的所有属性对应的值> hgetall user
 	1) "name"
 	2) "zhangsan"
 	3) "age"
 	4) "23"
 	5) "sex"
 	6) "nan"

list list (suitable for storing ordered and repeatable data)

Linked list structure used for data storage

lpush add from right to left

rpush add from left to right

lrange key start stop

 //lpush用来存储一个列表的命令。interesting是列表的名称,"basketball"列表中的值> lpush interesting "basketball"
 (integer) 1> lpush interesting "football" "ball"
 (integer) 3
 //lrange输出列表中的数据的命令, interesting就是列表的名称 。 0 2是列表的开始输出索引和结束索引。> lrange interesting 0 2
 1) "ball"
 2) "football"
 3) "basketball"

set unordered collection (suitable for storing unordered, non-repeatable data)

 sadd key member //存数据
 smembers key //取数据
 案例:> sadd strset "a" "b" "c"
 (integer) 3> smembers strset
 1) "b"
 2) "c"
 3) "a"

zset ordered collection (suitable for storing ordered, non-repeatable data)

 zadd key score member  (score是一个数字,zset就是通过这个数字进行排序,可以重复)
 zrangebyscore key 0 1000 //通过分数排序输出
Insert picture description here

SpringBoot integrates Redis

1) Dependence


2) Configuration file

3) Configure RedisTemplate

public class RedisConfig {

    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        // hash的key也采用String的序列化方式
        // value序列化方式采用jackson
        // hash的value序列化方式采用jackson
        return template;

Common methods of using RestTemplate :

  1. opsForValue obtains an operation object of string type
  2. opsForHash obtains the operation object of hash type

5) The process of using the cache

The process of querying products by id

1) Query the Redis cache with id as the key, return the data if it can be found, and end

2) If you can't find it, query the database, the database finds it, cache it to Redis, and return the data

3) If the database can't find it, return null and end

4) At the same time as adding, deleting and modifying the database, modify the cache

public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goods> implements IGoodsService {

    public static final String TYPE = "GOODS-";

    private RedisTemplate<String,Object> redisTemplate;

    public Goods getGoodsById(Long id){
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        //1) 以id为键查询Redis缓存,如果能查到就返回数据,结束
        Object value = ops.get(TYPE + id);
        if(value == null){
           // 数据库查到,缓存到Redis,返回
           Goods goods = this.getById(id);
           if(goods != null){
               ops.set(TYPE + id,goods);
           return goods;
            return (Goods) value;

Declarative caching

The dependencies required by the SpringBoot project, the configuration file is the same as above

1. Add the annotation @EnableCaching on the startup class 2.
Redis configuration class

public class RedisConfig {

    public RedisCacheConfiguration provideRedisCacheConfiguration(){
        RedisCacheConfiguration conf = RedisCacheConfiguration.defaultCacheConfig();
        return conf.serializeValuesWith(
                .fromSerializer(new GenericJackson2JsonRedisSerializer()));

3) Cache annotations

@CacheConfig is used on the Service class, such as: @CacheConfig(cacheNames = "books")

@Cacheable is used in the query method, let the method first query the cache

@CachePut is used in the update and add methods. After the database is updated and the data is inserted, it is saved in the cache at the same time

@CacheEvict is used in the delete method, the cache is deleted at the same time after the database is deleted

@Caching can install multiple @CacheEvict in the delete method, and delete the cache at the same time after the database is deleted

Note: The entity class must implement the serialization interface

@CacheConfig(cacheNames = "GOOD")
public class GoodsServiceImpl extends ServiceImpl<GoodsMapper, Goodss> implements IGoodService {
    private GoodsMapper goodsMapper;

    @Cacheable(key = "T(String).valueOf(#id)")
    public Goodss selectOneGoods(Long id) {
        return goodsMapper.selectOneGoods(id);

    @Cacheable(cacheNames = "goods-page",key = "T(String).valueOf(#page.current)")
    public IPage<Goodss> getSelectGoodss(IPage<Goodss> page) {
        return goodsMapper.getSelectGoodss(page);

    @CacheEvict(cacheNames = "goods-page",allEntries = true)
    public Goodss saveGoods(Goodss goodss) {;
         return goodss;

    @CacheEvict(cacheNames = "goods-page",allEntries = true)
    public Goodss updateGoods(Goodss goodss) {
        return goodss;

    @Caching(evict = {@CacheEvict (key = "T(String).valueOf(#id)"),@CacheEvict(cacheNames = "goods-page",allEntries = true)})
    public void deleteGoods(Long id) {


Frequently Asked Questions of Redis

1) Cache breakdown

In the case of high concurrency, the cache will be traversed in a short period of time, and the request will directly hit the database, which may cause excessive database pressure.

Solution: lock the code (double check lock)

2) Cache penetration

In the case of high concurrency, if you query data that does not exist, because the cache and the database do not exist, the request will hit the database, which may cause the system to crash.


​ 1) Save the non-existent data in the cache and set a certain expiration time

​ 2) Bloom filter (directly filter out the request that does not exist) Can not accurately determine whether there is data, and can accurately determine whether the data does not exist

3) Cache avalanche

In the case of high concurrency, the cache server restarts or the hot data expires at the same time, all access to the database, resulting in database downtime


​ 1) Configure the cache cluster

​ 2) Try to set different expiration times for hotspot data, relatively uniform

Solve the code

 public Goods getGoodsById(Long id){
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        Object value = ops.get(TYPE + id);
        if(value == null) {
            synchronized (this) {
                //1) 以id为键查询Redis缓存,如果能查到就返回数据,结束
                value = ops.get(TYPE + id);
                if (value == null) {
                    // 数据库查到,缓存到Redis,返回
                    Goods goods = this.getById(id);
                    if (goods != null) {
                        ops.set(TYPE + id, goods);
                    } else {
                        ops.set(TYPE + id,new Goods(),30, TimeUnit.SECONDS);
                    return goods;
                } else {
                    System.out.println("缓存存在,返回" + value);
                    return (Goods) value;
        System.out.println("缓存存在,返回" + value);
        return (Goods) value;


Redis's transaction is to package a series of operations and submit them together. There is no atomicity, isolation, and no rollback of transactions.

multi start transaction

Insert picture description here

exec commits the transaction

Insert picture description here

discard the transaction

watch monitors a certain data, if the data is modified in another transaction, the current modification is abandoned

Insert picture description here

to sum up:

If there is a syntax error in the transaction, the entire transaction cannot be executed; if there is a data error, the transaction can succeed partly and partly fail.

PS: incr increases the value, decr decreases the value

Distributed lock

Redis can be used as a distributed lock for common access by all services, and internal data can be monitored using the watch (optimistic lock) mechanism.

Pessimistic lock can guarantee thread safety, but the performance is low

Redis provides optimistic locking with high performance

Redis is single-threaded internally, and there is no thread safety issue

Case: The simulated spike function, the inventory of goods is 10, 1000 users come to grab, and there can be no overbought situation

public class GoodsCache {

	Logger logger = Logger.getLogger(GoodsCache.class);
    private RedisTemplate<String,String> redisTemplate;

public String buy(){
    Boolean execute = redisTemplate.execute(new SessionCallback<Boolean>() {
        public Boolean execute(RedisOperations redisOperations) throws DataAccessException {
            int num = Integer.parseInt(redisOperations.opsForValue().get("goods_num").toString());
            if (num <= 0) {
                return false;
            redisOperations.opsForValue().increment("goods_num", -1);
            List list = redisOperations.exec();
            if (list == null || list.isEmpty()) {
                return false;
            logger.error("购买成功" + list.get(0));
            return true;
    return String.valueOf(execute);

public class ProductController {
    public JSONResult buy(){
        return new JSONResult(1,;

Persistence strategy

Why persist? Redis is an in-memory database. After the program is closed, the data will be cleared. Sometimes it is necessary to save the data in the memory in a file for a long time.

Persistence strategy

AOF: Persistence of data per second by default

RDB: Trigger the persistence operation according to the condition (any one)

900 1 modified 1 time in 900 seconds

300 10 Modify 10 times in 300 seconds

60 10000 Modify 10000 times in 60 seconds

Configuration method


Insert picture description here


appendonly yes / no yes enable AOF

appendfsync everysec saves every second

how to choose?

Allow a small amount of data loss, high performance-RDB

Only allow very little data loss-AOF

No data loss is allowed-RDB + AOF

Elimination strategy

Why should it be eliminated? Redis data is stored in memory. Too much data will cause overflow problems. Redis will eliminate some data according to certain strategies.

64-bit system, the upper limit is the upper limit of memory; 32-bit maximum 4G

Configure the maximum memory:

max-memory configuration 0 is unlimited (default)

LRU algorithm: Least Recently Used algorithm, eliminate long-term use of cache

Elimination strategy:



noevication (default) not eliminated

allkeys-lru (recommended) Use LRU to eliminate less used keys

Volatile-lru eliminates less used keys from expired keys

allkeys-random eliminates all keys randomly

Volatile-random is randomly eliminated from expired keys

Volatile-ttl eliminates short-lived keys from expired keys