JAVA:SSM\Distributed CacheRedis\/spring data redis

Keywords: Redis Jedis Database Java

Redis Distributed Cache

Redis is an open source Key-Value database that stores data in memory and is written in C. Enterprise development typically uses redis for caching.

operation flow

Get data from redis first, return directly if you get data, you don't need to access the database. If you can't get data, you can query from the database, then put it in one of the redis, the next time you can query directly from redis, which greatly reduces the high concurrent access pressure of the database.

Persistence scheme

RDB (default support, no configuration required) time-sharing persistence

  • You can set in the configuration file how often to persist, the fewer times to persist, i.e. the fewer operations on the hard disk, the faster, but if the server is powered off before the persistence is completed, the data that is not persisted in memory will be lost

aof real-time persistence

  • Every time you add or delete to redis, the data will be persisted to the hard disk. The data is reliable, not lost, but slow

redis can use both RDB and AOF

Five data types in redis

  • String:string
  • hash: equivalent to map, is a form of key-value pair. The data stored is out of order, keys cannot be duplicated
  • list: The data stored in it is ordered and the data can be duplicated
  • set: The data stored in it is out of order and cannot be duplicated
  • zset: The data stored in it is ordered and cannot be duplicated

redis technology of the same type

  • memcache is the same type of technology as redis. The underlying layer is also written in C. memcache is as fast as redis, but there is no way to persist memcache

The difference between mongodb and redis

  • mongodb is also a nosql database, and the data stored is unstructured
  • redis: Mainly uses memory. There are two persistence schemes, which are very fast and typically used as distributed caches
  • Mongodb: Mainly uses hard disk storage, so you won't worry about data loss. It's faster than redis and traditional databases, but mongodb is better at storing large text data and some unstructured data. Mongodb has more data types than redis

redis application scenario

  • Caching (data queries, short connections, news content, merchandise content, etc.)
  • Online Friends List in Chat Room
  • Task queue (seconds killing, snapping, 12306, etc.)
  • Apply leaderboards
  • Website Access Statistics
  • Data expiration processing (accurate to milliseconds)
  • session Separation in Distributed Cluster Architecture

Spring Data Redis

  • Spring-data-redis are part of the Spring family, providing access to redis services through simple configurations in srping applications, highly encapsulating reids underlying development packages (Jedis, JRedis, and RJC), providing redis operations, exception handling and serialization, supporting publishing subscriptions, and implementing spring 3.1 cache.

Jedis 

  • Jedis is Redis's official Java-oriented client that provides many interfaces for Java language calls.It can be downloaded on Redis's official website, and of course there are some clients from open source enthusiasts, such as Jredis, SRP, etc. Jedis is recommended

Case study with Jedis

Configuration file config.properties

host=localhost
port=6379
maxTotal=50
maxIdle=20

Tool class JedisUtiles

package com.ayyy.core.utils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.util.ResourceBundle;

/**

- Database Connection Pool Tool Class
- Purpose: To return the database connection object Jedis
- Read config configuration file
*/
public class JedisUtils {
//Declare Connection Pool Object
private static JedisPool pool ;
//Read Configuration File
static {
    ResourceBundle resourceBundle = ResourceBundle.getBundle("config");
    //Get the server IP address
    String host = resourceBundle.getString("host");
    //Get the port number
    int port = Integer.parseInt(resourceBundle.getString("port"));
    //Get the maximum number of connections
    int maxTotal = Integer.parseInt( resourceBundle.getString("maxTotal"));
    //Get the maximum idle connection
    int maxIdle = Integer.parseInt( resourceBundle.getString("maxIdle"));
    //Create Configuration Information Object for Connection Pool
    JedisPoolConfig config = new JedisPoolConfig();
    //Set up related information
    config.setMaxTotal(maxTotal);
    config.setMaxIdle(maxIdle);
    //Create Connection Pool Object
    pool = new JedisPool(config,host,port);
}
/**
  - Creation Method
  - Connect pool object, return Jedis object
*/
public static Jedis getJedis(){
return pool.getResource();
}
//Release Resource Method
public static void close(Jedis jedis){
if(jedis!=null)
    jedis.close();
}
  public static void close(JedisPool pool){
    if(pool!=null)
        pool.close();
}
}

Service interface

package com.ayyy.core.service;
import com.ayyy.core.pojo.Category;
import java.util.List;

public interface CategoryService {
    //Query all categorical data
    List<Category> findAll();
}


Service Implementation Class

package com.ayyy.core.service.impl;
import com.ayyy.core.dao.CategoryDao;
import com.ayyy.core.pojo.Category;
import com.ayyy.core.service.CategoryService;
import com.ayyy.core.utils.BeanFactory;
import com.ayyy.core.utils.JedisUtils;
import net.sf.json.JSONArray;
import redis.clients.jedis.Jedis;

import java.sql.SQLException;
import java.util.List;
public class CategoryServiceImpl implements CategoryService {
    //bean factory, get dao layer interface implementation class
    private CategoryDao categoryDao = BeanFactory.newInstance(CategoryDao.class);

    /**
     *  Query navigation data from redis database
     *  No data exists
     *    Query MySQL data and fetch category table data
     *    Data converted to JSON string, storing redis
     *
     *  Data stored in
     *    redis The database stores strings
     *    String to Collection Return
     */
    public List<Category> findAll(){
        List<Category> categoryList = null;
        //Get Redis Database Connection Object
        Jedis jedis = JedisUtils.getJedis();
        //Get String
        String category =  jedis.get("category");
        try {
            //Determine if there is data
            if (category == null) {
                //Query MySQL database to fetch category table data
                categoryList = categoryDao.findAll();
                //Data collection, converted to JSON and stored in redis
                //JSONArray.fromObject(categoryList).toString();
                jedis.set("category",JSONArray.fromObject(categoryList).toString());
            } else {
                //redis database has data
                //category to Collection Return
                /**
                 * toList,JSON Format String to Collection List
                 * Parameter: JSONArray object
                 * Generic class object of the converted set
                 */
               // JSONArray.fromObject(category);
                categoryList = JSONArray.toList( JSONArray.fromObject(category),Category.class );
            }
        }catch (Exception ex){
            ex.printStackTrace();
        }finally {
            JedisUtils.close(jedis);
        }
        return  categoryList;
    }
}

Spring Data Redis Case

Appearance layer

package com.ayyy.core.controller;
import com.ayyy.core.pojo.ad.Content;
import com.ayyy.core.service.ContentService;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
@RequestMapping("/content")
public class ContentController {

    @Reference
    private ContentService contentService;

    @RequestMapping("/findByCategoryId")
    public List<Content> findByCategoryId(Long categoryId) {
        List<Content> list = contentService.findByCategoryIdFromRedis(categoryId);
        return list;
    }
}

Service interface

package com.ayyy.core.service;
import com.ayyy.core.pojo.ad.Content;
import com.ayyy.core.pojo.ad.ContentCategory;
import com.ayyy.core.pojo.entity.PageResult;
import javax.naming.Context;
import java.util.List;

public interface ContentService {

    public List<Content> findByCategoryIdFromRedis(Long categoryId);


}

Service Implementation Class

package com.ayyy.core.service;

import com.ayyy.core.dao.ad.ContentDao;
import com.ayyy.core.pojo.ad.Content;
import com.ayyy.core.pojo.ad.ContentQuery;
import com.ayyy.core.pojo.entity.PageResult;
import com.ayyy.core.util.Constants;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import javax.naming.Context;
import java.util.List;

/**
 * Use the redis distributed caching principle:
 * General relational databases store data as our primary database. If you are concerned with using distributed cached redis, make sure the data is in redis
 * Be consistent with the data in the database.
 */
@Service
public class ContentServiceImpl implements ContentService {

    @Autowired
    private ContentDao contentDao;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * The entire redis correspond to a large hashMap in which the key is not duplicated, so the key is a scarce resource
     * key      value(value Use hash type because it takes as little key as possible)
     *          field           value
     *          List of advertising collection data for this category corresponding to category id <Content>
     *            001               List<Content>
     *            002               List<Content>
     *
     *
     */
    @Override
    public List<Content> findByCategoryIdFromRedis(Long categoryId) {
        //1. First get the data from the classification id to redis
        List<Content> contentList = (List<Content>)redisTemplate.boundHashOps(Constants.CONTENT_LIST_REDIS).get(categoryId);
        //2. Get data from the database if there is no data in redis
        if (contentList == null) {
            //3. If you get data in the database, put it in a redis
            contentList = findByCategoryId(categoryId);
            redisTemplate.boundHashOps(Constants.CONTENT_LIST_REDIS).put(categoryId, contentList);
        }
        return contentList;
    }
}

 

Posted by gurhy on Sun, 28 Apr 2019 23:30:36 -0700