A recent system that involves frequent calls to basic data, massive network overhead, and data-read-to-write systems brings great performance pressure, and we've decided to introduce caching mechanisms to mitigate system stress.
What is a cache
to mention the caching mechanism, about ten programmers have 5 different explanations (let's say that only half of the programmers are copied and pasted to learn knowledge), I can not mundane to say that I understand.
Before we answer this question, we need to figure out why we should use caching.
Historical materialism reveals that the basic motive force of social development is the contradiction of Social Foundation.
Application to the field of software is also applicable, the emergence of a new technology is necessarily accompanied by specific contradictions, and the advent of the cache is precisely because the media provides the actual processing response speed and the contradiction between the software requirements, the final caching mechanism of the proposed greatly alleviate this contradiction, but also confirmed a computer field famous saying:
Any problem in computer science can is solved by anther layer of indirection.
Cache
Together we can see that the cache is a kind of agent in a sense, through the advantages of one aspect of itself to compensate for the limitations of the actual response, in theory, the trade-offs between time and space.
Several common caches are listed below
1, Database Cache
Reduce file system read and write times and program response time by caching query statements into memory
2, application cache
Reduce database access by caching application-frequently used data to memory, reducing the time to destroy connections when created
3, user-side Caching
The user -side technologies such as browsers and local cookies are used to cache users ' common data, reduce the creation and destruction of network connections, and avoid the consumption of network transmissions .
Springthe cache in
Spring has introduced annotation-based caching support from the 3.1 version, which has evolved quite steadily. Spring mainly provides JSR107-based abstraction, and the specific implementation of the cache can be EhCache or Redis. Here is a simple way to move through the definitions of several annotations:
@Cacheable the cached entry, first check the cache if no hit executes the method and caches the method result
@CacheEvict Cache collection, emptying the corresponding cache data
@CachePut Cache Updates, execute methods, and update the results of the method execution to the cache
@Caching combine multiple cache operations
@CacheConfig Class-level public configuration
Original link:
Https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#cache
application in the real system
after understanding some of the basics of caching and the support of the framework, we started to put it into practice and we used Redis acts as a specific implementation of the cache.
project is based on spring boot <version>2.0.0.RC1</version>,maven 's main configuration information is as follows:
<parent> <groupid >org.springframework.boot</groupId> <artifactId> Spring-boot-starter-parent</artifactid> <version> 2.0.0.rc1</version></parent><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>1.5.7.RELEASE</version> </dependency></dependencies>
First explicitly cache the location, the cached party may be on the following four levels
A) client
b) interface Layer
c) service layer
d) Data tier
in the selection of the location of the divergence is closer to the client or to the cache of all parties closer, specifically to our system is the cache placed in a or b, each has advantages and disadvantages.
placed on the client can reduce network consumption, placed on the server can be clear management responsibilities, and finally we chose to put in B sacrifice part of the performance consumption to ensure the integrity and consistency of the data.
Below are two scenarios to illustrate the maintenance of a cache
1, cache Creation (interface layer @Cacheable)
2, Cache Update (service tier @CacheEvict, @Caching)
Note: Consider that configuration data is less frequently modified and the cache structure of the configuration data is complex, and each data modification and addition deletes the corresponding cache, which is then called by the interface layer to reload the cache
And then there's the realization,
first, you need to turn on the caching function, add @EnableCaching annotations on the main program
Then the code for the relevant annotations:
@Cacheable (value= "icare_region", key= "(' c_ '). Concat (#companyId)") public list<region> loadregionbycompidrest (@RequestParam ("CompanyID") integer companyid) { List<Region> regions = Regionservice.selectregionsbycompid (CompanyID); return regions; } @CacheEvict (cacheNames= "icare _region ", key=" (' c_ '). Concat (#region. CompanyID) ") public void saveregion ( Region region) { regionmapper.insert (region); } @Caching (evict = { @CacheEvict (cachenames= "Icare_region", key= "(' R_ '). Concat (#region. RegionID)"), @CacheEvict (cachenames= "icare_region", key= "(' c_ '). Concat (#region. CompanyID) ") }) public void updateregion (region region) { region existregion = regionmapper.selectbyprimarykey (Region.getRegionId ()); region.setstatus (Existregion.getstatus ()); region.setcreatetime (Existregion.getcreatetime ()); region.setupdatetime (New date ()); Regionmapper.updatebyprimarykey (region); }
Finally, it's testing.
When it comes to determining how the program will go to the cache instead of the original database call, we use druid 's SQL monitoring function to directly observe the number of SQL executions:
problems and Extensions
Let 's talk about a specific problem we're using Redis chose to copy a redisconfig file from the Web to expand keygenerator,redistemplate and CacheManager . However, when we introduced the spring boot dev-tool , the above cache implementation will indicate the error classcast Exception.
finally found the answer on the official website: in the old version of the The ClassLoader problem of serialization and deserialization is not considered in CacheManager , resulting in ClassLoader inconsistency between serialization and deserialization ; The latest fix is to specify the CacheManager used by ClassLoader. And the internet is now circulating the old version of the CacheManager, instead of the latest version of the repair covered out ...
problem Link:https://github.com/spring-projects/spring-boot/issues/11822
In addition, there are many limitations to the cache we are now implementing and the direction we want to expand
1, Unable to set expiration time
Redis supports setting the expiration time, but no support is provided in spring abstraction.
2, Unable to statistic the hit rate and other indicators
There is no way to determine the invalidation and replacement of the cache when the hit rate is not available, and of course these are the things to consider when the cache gets bigger.
Redis cache in Spring boot combat