Why cache? In the final analysis, it is to improve the running speed of the system. Store the content frequently accessed by users in the place closest to the user and with the fastest access speed, so as to improve the response speed of users. The simple structure of a web application is shown in the figure below.
Typical architecture of web application
In this structure, the user's request comes to the business layer through the user layer. The business layer obtains data from the data layer and returns it to the user layer. When the number of users is small and the amount of data is not too large, the system runs smoothly. However, with the increasing number of users and more and more data in the database, the user response speed of the system becomes slower and slower. The bottleneck of the system is usually database access. At this time, the above architecture may be changed to the following to relieve the pressure on the database.
[image upload failed... (image-313f3b-1595918224482)]
One master multi slave structure
In this architecture, the read request and write request of the database are separated. A large number of read requests are allocated to the slave database, and the master database is only responsible for write requests. The slave library keeps active synchronization with the master library. This architecture is a great improvement over the previous one, general Internet applications. This architecture can be well supported. One of its disadvantages is that it is complex. It is not easy to maintain efficient real-time or quasi real-time synchronization between master and slave libraries. So we have another idea. We use a cache server to store hot data, and relational data is used to store persistent data. The structure is shown in the figure below
[image upload failed... (image-6c743c-1595918224482)]
Cache server read architecture
[image upload failed... (image-6de251-1595918224482)]
Cache server read architecture
In this architecture, when reading data, first get the data from the cache server. If you get the call, you will directly return the data. If no call is obtained, the data is obtained from the database. After the data is obtained, the data is cached in the swap out database for the next access. When inserting or updating data, first write the data to the relational database, and then update the data in the cache database.
Of course, in order to cope with more large-scale visits, we can also combine the above two improved architectures, including a read-write separated relational database and a cache service that can be accessed at high speed.
The premise of the above cache server architecture is that the efficiency of obtaining data from the cache server is much higher than that from the relational database. Otherwise, the cache server makes no sense. Redis data is stored in memory, which can ensure that the time efficiency of obtaining data from redis is much higher than that from relational database.
By the way, I recommend a Java technology exchange group: 473984645, which will share some video materials recorded by senior architects: Spring, MyBatis, Netty source code analysis, the principles of high concurrency, high performance, distributed and micro service architecture, JVM performance optimization, distributed architecture, etc. These have become the necessary knowledge system for architects. You can also get free learning resources. At present, you benefit a lot!
Implementation of cache service based on redis
This chapter uses an example to illustrate how to implement a redis cache service in Java.
Establish maven project and introduce dependency
Define interface class com x9710. common. redis. CacheService
In this interface class, the following interfaces are defined
· void putObject(String key, Object value);
· void putObject(String key, Object value, int expiration);
· Object pullObject(String key);
· Long ttl(String key);
· boolean delObject(String key);
· boolean expire(String key, int expireSecond);
· void clearObject();
By the way, I recommend a Java technology exchange group: 473984645, which will share some video materials recorded by senior architects: Spring, MyBatis, Netty source code analysis, the principles of high concurrency, high performance, distributed and micro service architecture, JVM performance optimization, distributed architecture, etc. These have become the necessary knowledge system for architects. You can also get free learning resources. At present, you benefit a lot!
These interfaces are used to store non expired objects, store future expired objects, obtain cache objects, obtain the remaining lifetime of cache objects, delete cache objects, set the expiration time of cache objects, and clear all cache objects
package com.x9710.common.redis; /** * Cache service interface * */ public interface CacheService { /** * Store objects in cache * * @param key Stored key * @param value Stored value */ void putObject(String key, Object value); /** * Store objects in cache * * @param key Stored key * @param value Stored value * @param expiration Expiration time in seconds */ void putObject(String key, Object value, int expiration); /** * Get object from cache * * @param key key to get object * @return If it exists, the object is returned; otherwise, null is returned */ Object pullObject(String key); /** * Sets the expiration seconds for the cache object * * @param key key to get object * @param expireSecond Seconds expired * @return If it exists, the object is returned; otherwise, null is returned */ boolean expire(String key, int expireSecond); /** * Gets the number of seconds the cache object has expired * * @param key key to get object * @return If the object does not exist, - 2 is returned. If the object does not have an expiration time, - 1 is returned. Otherwise, the actual expiration time is returned */ Long ttl(String key); /** * Delete object from cache * * @param key key to delete object * @return If an error occurs, it returns false; otherwise, it returns true */ boolean delObject(String key); /** * Purge objects from cache */ void clearObject(); }
Define serial number auxiliary class com x9710. common. redis. SerializeUtil
All objects to be saved to the redis database need to be binary arrays first. This class is used to convert the Java object serial number into a secondary array or deserialize the secondary array into an object.
package com.x9710.common.redis; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * Object serialization tool class * */ public class SerializeUtil { /** * Serializes an object into a binary array * * @param object To serialize an object, the must implement Java io. Serializable interface * @return Serialized binary array */ public static byte[] serialize(Object object) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(object); return baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * Deserialize a binary array into an object. The program does not check object types during deserialization. * * @param bytes Binary number to deserialize * @return Deserialized object */ public static Object unserialize(byte[] bytes) { try { ByteArrayInputStream bais = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bais); return ois.readObject(); } catch (Exception e) { e.printStackTrace(); } return null; } }
Implement redis cache service class com x9710. common. redis. impl. CacheServiceRedisImpl
package com.x9710.common.redis.impl; import com.x9710.common.redis.CacheService; import com.x9710.common.redis.RedisConnection; import com.x9710.common.redis.SerializeUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import redis.clients.jedis.Jedis; /** * redis implementation class of cache service * */ public class CacheServiceRedisImpl implements CacheService { private static Log log = LogFactory.getLog(CacheServiceRedisImpl.class); private RedisConnection redisConnection; private Integer dbIndex; public void setRedisConnection(RedisConnection redisConnection) { this.redisConnection = redisConnection; } public void setDbIndex(Integer dbIndex) { this.dbIndex = dbIndex; } public void putObject(String key, Object value) { putObject(key, value, -1); } public void putObject(String key, Object value, int expiration) { Jedis jedis = null; try { jedis = redisConnection.getJedis(); jedis.select(dbIndex); if (expiration > 0) { jedis.setex(key.getBytes(), expiration, SerializeUtil.serialize(value)); } else { jedis.set(key.getBytes(), SerializeUtil.serialize(value)); } } catch (Exception e) { log.warn(e.getMessage(), e); } finally { if (jedis != null) { jedis.close(); } } } public Object pullObject(String key) { log.trace("strar find cache with " + key); Jedis jedis = null; try { jedis = redisConnection.getJedis(); jedis.select(dbIndex); byte[] result = jedis.get(key.getBytes()); if (result == null) { log.trace("can not find caceh with " + key); return null; } else { log.trace("find cache success with " + key); return SerializeUtil.unserialize(result); } } catch (Exception e) { log.warn(e.getMessage(), e); } finally { if (jedis != null) { jedis.close(); } } return null; } public boolean expire(String key, int expireSecond) { log.trace("strar set expire " + key); Jedis jedis = null; try { jedis = redisConnection.getJedis(); jedis.select(dbIndex); return jedis.expire(key, expireSecond) == 1; } catch (Exception e) { log.warn(e.getMessage(), e); } finally { if (jedis != null) { jedis.close(); } } return false; } public Long ttl(String key) { log.trace("get set expire " + key); Jedis jedis = null; try { jedis = redisConnection.getJedis(); jedis.select(dbIndex); return jedis.ttl(key); } catch (Exception e) { log.warn(e.getMessage(), e); } finally { if (jedis != null) { ### last Starting with the key architecture of building a key value database, this document not only takes you to establish a global view, but also helps you quickly grasp the core main line. In addition, it will also explain the data structure, thread model, network framework, persistence, master-slave synchronization and slice clustering to help you understand the underlying principles. I believe this is for all levels Redis Users are a very perfect tutorial. ![image](https://img-blog.csdnimg.cn/img_convert/7805d83c42241b9dd545c57087fd4fbb.png) **Fast track:([Stamp here and download it for free](https://codechina.csdn.net/m0_60958482/java-p7) sincere** **It's not easy to organize. Friends who think it's helpful can help praise, share and support Xiaobian~** **Your support is my motivation; I wish you a bright future, offer constantly!!!** It will explain the data structure, thread model, network framework, persistence, master-slave synchronization and slice cluster to help you understand the underlying principles. I believe this is for all levels Redis Users are a very perfect tutorial. [External chain picture transfer...(img-JgHlnHUF-1629232147951)] **Fast track:([Stamp here and download it for free](https://codechina.csdn.net/m0_60958482/java-p7) sincere** **It's not easy to organize. Friends who think it's helpful can help praise, share and support Xiaobian~** **Your support is my motivation; I wish you a bright future, offer constantly!!!**