This project is a Spring boot project
Redis Cutting Programming
Target: Add a comment to the method to cache when querying
Method: Custom Note+AOP Section Programming
step
Say nothing but go directly to the code demonstration
Step One
Definition Notes
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface RedisCache { //Storage prefix String name() default "Spl---"; //The key to store defaults to the first parameter of the query condition String key() default ""; //Default 5 minutes int expireTime() default 5; //The default value is in minutes TimeUnit unit() default TimeUnit.MINUTES; }
Step 2
Where notes are used
Step 3
AOP Face-to-Face Thought
@Component @Aspect @Slf4j /** * AOP Cut programming */ public class RedisCacheAop { @Autowired private StringRedisTemplate stringRedisTemplate; /** * breakthrough point */ @Pointcut("@annotation(com.trc.study.annotation.RedisCache)") public void pointCup(){} /** * Enhancement Method-Wrapping * @param joinPoint * @return * @throws Throwable */ @Around(value = "pointCup()") public Object cache(ProceedingJoinPoint joinPoint) throws Throwable{ //Get method signature from entry point Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); //The method of getting the byte code of the target object from the point of tangency.Parameters: (method name, all parameters of method) RedisCache redisCache = method.getAnnotation(RedisCache.class); String key = redisCache.key(); Object[] args = joinPoint.getArgs(); String prefix = redisCache.name(); String methodName = method.getName(); //Get key value String cacheKey = getCacheKey(key, args, prefix, methodName); Object proceed = null; //Get value from cache based on key String value = stringRedisTemplate.opsForValue().get(cacheKey); //Determine if value is empty if (StringUtils.isNotBlank(value)){ log.info("from redis Get data inside!"); return getValueActualTypeData(method,value); }else { log.info("from mysql Get data inside!"); //Query the database and execute the original method proceed = joinPoint.proceed(); //Encapsulation Result String results = JSONObject.toJSONString(proceed); int expireTime = redisCache.expireTime(); TimeUnit timeUnit = redisCache.unit(); //Save in Cache stringRedisTemplate.opsForValue().set(cacheKey,results,expireTime,timeUnit); return proceed; } } /** * Get key value * @param key * @param args * @param prefix * @param methodName * @return */ private String getCacheKey(String key,Object[] args,String prefix,String methodName){ String cacheKey = ""; if (StringUtils.isNotBlank(prefix)) { cacheKey = "/" + prefix + "/"; } if (StringUtils.isNotBlank(key)) { return cacheKey += key; } if (null != args && 0 < args.length) { return cacheKey += args[0]; } return methodName; } /** * get data * @param method * @param value * @return * @throws ClassNotFoundException */ private Object getValueActualTypeData(Method method, String value) throws ClassNotFoundException { Class returnActualType = getReturnActualType(method); if (null != returnActualType) { return JSONObject.parseArray(value, returnActualType); } return null; } /** * Get the return value type * @param method * @return * @throws ClassNotFoundException */ private Class getReturnActualType(Method method) throws ClassNotFoundException { Type genericReturnType = method.getGenericReturnType(); if (genericReturnType instanceof ParameterizedType) { Type[] actualTypes = ((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualType : actualTypes) { return Class.forName(actualType.getTypeName()); } } return null; } }
Other: Engineering Structure
mvc pattern
configuration file
server.port=9009 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true spring.datasource.username=root spring.datasource.password=root mybatis.type-aliases-package=com.trc.study.common mapper.mappers=com.trc.study.dao.RedisCacheMapper logging.level.info #redis configuration #Redis Server Address spring.redis.host=127.0.0.1 #Redis Server Connection Port spring.redis.port=6379 #Redis database index (default 0) spring.redis.database=0 #Maximum number of connections in connection pool (use a negative value to indicate no limit) spring.redis.jedis.pool.max-active=50 #Maximum blocking wait time for connection pool (use a negative value to indicate no limit) spring.redis.jedis.pool.max-wait=3000 #Maximum idle connection in connection pool spring.redis.jedis.pool.max-idle=20 #Minimum idle connection in connection pool spring.redis.jedis.pool.min-idle=2 #Connection timeout (milliseconds) spring.redis.timeout=5000
redis basic data type
data type String:String Can be used to store strings, integers, floating-point numbers cache Data Sharing Distributed Distributed Lock Global ID Counter Current Limiting Hash:Hash An unordered Hash list containing key-value pairs.Value can only be a string and cannot nest other types Store data of object type List:List Stores an ordered string (left to right) with elements that can be repeated.Can act as queues and stacks User message timeline Set:Set Unordered collection of String type with a maximum storage of 2^32-1 (around 4 billion) Random acquisition of elements ZSet: Ordered Set sorted set, ordered set, each element has a score. When score is the same, sort by ASCII code of key. BitMaps Is a bit operation defined above a string type.A byte consists of eight binary bits. Hyperloglogs Provides a less accurate cardinality statistics method Streams Data types introduced in 5.0.A persistent message queue that supports multicast for publishing and subscribing
Why is Redis so fast
1) Pure memory structure KV-structured in-memory database, time complexity O(1) 2) Single Thread 1. Consumption of not creating or destroying threads 2. Avoid CPU consumption caused by online text switching 3. Avoid competing issues between threads, such as locking to release deadlocks, etc. 3) Multiplex "Multiplex" refers to multiple network connections and "multiplex" refers to multiplexing the same thread I/O of multiple streams can be monitored simultaneously using select, poll, epollThe ability to event blocks the current thread when idle, wakes up from the blocking state when one or more streams have I/O events, and the program polls all streams once (epolls are only those that actually emit events), sequentially processing ready streams, which avoids a lot of useless operations
Master, Sentry
colony Availability, data security, performance Master-subordinate Data cannot be written (read-only) from a node and can only be synchronized from the master node Principle of master-slave replication Connection Phase Data Synchronization Phase Command Propagation Phase insufficient Synchronization can be time consuming when the RDB file is too large If the primary server hangs up, the external services will not be available Sentry Ensure service availability by running a monitoring server Cluster deployments will be made to Sentinel.Sentinel monitors all Redis services and Sentinel monitors each other Signal communication SDOWN and ODOWN conversion process Sentinel and slaves Autodiscovery mechanism Leader election Distributed scheme Fragmentation of Redis data Implement related logic on the client side, such as slicing keys with a modulus or consistency hash, where queries and modifications determine the path of the key first Pull out the logic of the fragmentation process and run a separate proxy service where the client connects and the proxy service forwards requests Server-based implementation