How do I manipulate Redis and zookeeper to implement distributed locking
- 2020-05-24 06:26:29
- OfStack
How do I manipulate Redis and zookeeper to implement distributed locking
In a distributed scenario, there are many situations where final 1 tropism needs to be implemented. Events in the field of design of the remote context, in order to ensure the consistency in the end, in the way of communication through the field events, can be Shared storage (domain model and the persistence of data sources), or to do global XA transaction (two-phase commit, the data source can be separated), can also use the message middleware (consumers need to be able to power, etc.). Publishing domain events in Observer mode provides high concurrency, and the event store can trace event data to a smaller level of granularity, giving each application more autonomy.
1. Distributed locks
Distributed locks are generally used in distributed systems or multiple applications to control whether the same task is executed or in what order. In the project, multiple tomcat applications have been deployed. When executing the timed task, the same task may be executed many times. We can ensure that only one tomcat application executes the timed task at the same time with the help of distributed locking.
2. Implementation of distributed locks
setnx() and expire() using redis getset() using redis Create node node using zookeeper Create temporary sequence nodes using zookeeper's3. Use setnx() and expire() of redis to implement distributed locking
setnx(key,value) if key Does not exist, set to current key The value of value; if key Exists, returns directly.
expire() To set the timeout
Define the annotation class:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Lockable{
// redis The cache key
String key();
// redis The cache key The data in the
String value() default "";
// Expiration time ( seconds ) By default, 1 minutes
long expire() default 60;
}
Scheduled tasks added annotation @Lockable:
@Lockable(key = "DistributedLock:dealExpireRecords")
public void dealExpireRecords() {
}
Define one aop section, LockAspect, and use @Around to handle all annotations @Lockable. Confirm that this annotation is used on the method through the join point. Get the annotation information through the method, and use setIfAbsent to judge whether to acquire the distributed lock. If a distributed lock is acquired, set the expiration time through expire and call the specified method.
@Component
@Slf4j
@Aspect
public class LockAspect {
@Autowired
private RedisTemplate redisTemplate;
@Around("@annotation(com.records.aop.Lockable)")
public Object distributeLock(ProceedingJoinPoint pjp) {
Object resultObject = null;
// Make sure this annotation is used on the method
Signature signature = pjp.getSignature();
if (!(signature instanceof MethodSignature)) {
log.error("Lockable is method annotation!");
return resultObject;
}
MethodSignature methodSignature = (MethodSignature) signature;
Method targetMethod = methodSignature.getMethod();
// Get annotation information
Lockable lockable = targetMethod.getAnnotation(Lockable.class);
String key = lockable.key();
String value = lockable.value();
long expire = lockable.expire();
// Distributed locks without this key , set this value and return true ; If you have this key , the return false
boolean result = redisTemplate.boundValueOps(key).setIfAbsent(value);
if (!result) {
// Other programs have acquired distributed locks
return resultObject;
}
// Set expiration time, default 1 minutes
redisTemplate.boundValueOps(key).expire(expire, TimeUnit.SECONDS);
try {
resultObject = pjp.proceed(); // Call the corresponding method to execute
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return resultObject;
}
}
4. Use redis's getset() to implement distributed locking
This method makes the redisTemplate.boundValueOps (key).getAndSet (value) method, if it returns null, to indicate that the distributed lock has been acquired; If the return is not empty, the distributed lock has been occupied by another program
5. Create node node using zookeeper
Use zookeeper to create the node node. If the node is successfully created, the distributed lock is acquired. If the node creation fails, it means that the distributed lock has been occupied by other programs (multiple programs create 1 node node at the same time, only 1 can be successfully created)
6. Create temporary sequence nodes using zookeeper
Use zookeeper node to implement distributed lock, create a temporary sequence is suitable for the sequential program, general idea is to create a temporary sequence nodes, find out the minimum sequence nodes, access to distributed lock, after completion of the program execution sequence nodes will disappear, to monitor the change of the nodes by watch, find the smallest sequence from the rest of the node, the access to distributed lock, to perform the corresponding processing, and so forth...
Thank you for reading, I hope to help you, thank you for your support of this site!