Cache schematic
Reids introduction
- Completely open source and free
- Data persistence is supported
- Support for multiple data structures
- Data backup (master-slave)
Reids – start to use
Spring – the boot – starter – data – redis jars
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency>Copy the code
Application.properties defines redis-related properties
Port =8379 spring.redis.password=qwer1234 spring.redis.host=127.0.0.1 spring.redis.database=0Copy the code
RedisConfig injects a custom RedisTemplate
@Configuration public class RedisConfiguration { @Bean public RedisTemplate<String,Object> redisTemplate(LettuceConnectionFactory factory){ RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new StringRedisSerializer()); redisTemplate.setConnectionFactory(factory); return redisTemplate; }}Copy the code
Write RedisUtil for CRUD using the redisTemplate
@Component public class RedisUtil { @Autowired private RedisTemplate redisTemplate; public boolean set(String key,Object value){ try { redisTemplate.opsForValue().set(key,value); return true; }catch (Exception e){ e.printStackTrace(); return false; } } public boolean set(String key,Object value,long time){ try { redisTemplate.opsForValue().set(key,value,time, TimeUnit.SECONDS); return true; }catch (Exception e){ e.printStackTrace(); return false; } } public Object get(String key){ return Optional.ofNullable(redisTemplate.opsForValue().get(key)).orElse(null); }}Copy the code
Enterprise-level caching is easy to use
Define the service interface API
public interface LabelService {
Label selectById(int id);
}
Copy the code
@Service public class LabelServiceImpl implements LabelService { @Resource(name = "labelRepositoryCacheImpl") private LabelRepository labelRepository; @Override public Label selectById(int id) { return Optional.ofNullable(labelRepository.selectById(id)).orElse(null); }}Copy the code
Define the warehouse layer interface
public interface LabelRepository {
Label selectById(int id);
}
Copy the code
@Component public class LabelRepositoryImpl implements LabelRepository { @Autowired private LabelMapper labelMapper; @Override public Label selectById(int id) { return labelMapper.selectByPrimaryKey(id); }}Copy the code
Warehouse layer implementation
@Component public class LabelRepositoryCacheImpl implements LabelRepository { private static final String CACHE_PREFIX = "cache_prefix"; @Autowired private RedisUtil redisUtil; @Resource(name = "labelRepositoryImpl") private LabelRepository labelRepository; private Label nullLabel = new Label(-1); private static final Random random = new Random(); @Override public Label selectById(int id) { Label label = getLabelFromCache(id); if (label == null){ System.out.println("cache not hit"); / / get the label from the persistence layer = labelRepository selectById (id); cacheLabel(label,id); }else if (label.getId() == -1){ System.out.println("cache hit null"); return null; }else { System.out.println("cache hit id"); } return label; } private void cacheLabel(Label res,int id) { if (res ! Set (generateCacheKey(id), json.tojSONString (res),10 + random.nextInt(5)); Set (generateCacheKey(id), json.tojSONString (nullLabel),10 + random.nextint (5)); }} private Label getLabelFromCache(int id) {// Get String Label = (String) redisUtil. Get (generateCacheKey(id)); // If (stringutils.isempty (label)){return null; } return JSON.parseObject(label,Label.class); } private static String generateCacheKey(int id){ return CACHE_PREFIX + id; }}Copy the code
Cache penetration: malicious attacks to query data that is not in the database, causing stress to the database, or even overwhelm the database
Solution: Use a special cache null value to indicate that the object does not exist
Cache avalanche: At some point in time, the cache set expires, causing periodic pressure peaks for the database
Solution: Set expiration time plus a random factor to spread the cache expiration time as much as possible