summary

At present, almost many large-scale websites and applications are distributed deployment , Data consistency in distributed scenarios is always an important topic . A distributed CAP Theory tells us “ No distributed system can satisfy the consistency at the same time (Consistency)、 Usability (Availability) And partition fault tolerance (Partition tolerance), At most two items can be satisfied at the same time .” therefore , Many systems have to choose between the three at the beginning of design . In most scenarios in the Internet field , All need to sacrifice strong consistency for high availability of the system , Systems often only need to guarantee “ Final consistency ”, As long as the final time is within the acceptable range of users .

In many scenarios , In order to ensure the final consistency of data , A lot of technical solutions are needed to support , For example, distributed transaction 、 Distributed locks, etc .

choose Redis Reasons for implementing distributed locks

  • Redis It has very high performance
  • Redis The command supports this better , It's more convenient to realize

I will not introduce Redis Installed. , Specific in Linux and Windows You can see the blog in front of me .

http://www.cnblogs.com/liuyang0/p/6504826.html

Introduction to using commands

SETNX

SETNX key val

If and only if key When there is no ,set One key by val String , return 1; if key There is , Then do nothing , return 0.

expire

expire key timeout

by key Set a timeout , Unit is second, After this time, the lock will release automatically , Avoid deadlock .

delete

delete key

Delete key

In the use of Redis When implementing distributed locks , These three commands are mainly used .

Realization

It uses jedis To connect Redis.

Realization thought

  • When getting the lock , Use setnx Lock , And use expire Command to add a timeout to the lock , After that time, the lock will be released automatically , The lock value Value is a randomly generated UUID, Judge when releasing the lock through this .
  • When acquiring the lock, a timeout for acquiring is also set , If it exceeds this time, give up acquiring lock .
  • When you release the lock , adopt UUID Decide whether to lock , If it's time to lock , execute delete Lock release .

The core code of distributed lock is as follows :

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.exceptions.JedisException; import java.util.List;
import java.util.UUID; /**
* Created by liuyang on 2017/4/20.
*/
public class DistributedLock {
private final JedisPool jedisPool; public DistributedLock(JedisPool jedisPool) {
this.jedisPool = jedisPool;
} /**
* Lock
* @param locaName The lock key
* @param acquireTimeout Get timeout
* @param timeout The timeout of the lock
* @return Lock logo
*/
public String lockWithTimeout(String locaName,
long acquireTimeout, long timeout) {
Jedis conn = null;
String retIdentifier = null;
try {
// Get the connection
conn = jedisPool.getResource();
// Randomly generate one value
String identifier = UUID.randomUUID().toString();
// Lock name , namely key value
String lockKey = "lock:" + locaName;
// Timeout time , After locking, the lock will be released automatically
int lockExpire = (int)(timeout / 1000); // The timeout for obtaining the lock , After this time, the lock is abandoned
long end = System.currentTimeMillis() + acquireTimeout;
while (System.currentTimeMillis() < end) {
if (conn.setnx(lockKey, identifier) == 1) {
conn.expire(lockKey, lockExpire);
// return value value , Used to release lock time confirmation
retIdentifier = identifier;
return retIdentifier;
}
// return -1 representative key No timeout set , by key Set a timeout
if (conn.ttl(lockKey) == -1) {
conn.expire(lockKey, lockExpire);
} try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} catch (JedisException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.close();
}
}
return retIdentifier;
} /**
* Release the lock
* @param lockName The lock key
* @param identifier Release the lock logo
* @return
*/
public boolean releaseLock(String lockName, String identifier) {
Jedis conn = null;
String lockKey = "lock:" + lockName;
boolean retFlag = false;
try {
conn = jedisPool.getResource();
while (true) {
// monitor lock, Get ready to start
conn.watch(lockKey);
// Go back through the value Value to determine whether the lock should be , If it's time to lock , Delete , Release the lock
if (identifier.equals(conn.get(lockKey))) {
Transaction transaction = conn.multi();
transaction.del(lockKey);
List<Object> results = transaction.exec();
if (results == null) {
continue;
}
retFlag = true;
}
conn.unwatch();
break;
}
} catch (JedisException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.close();
}
}
return retFlag;
}
}

test

Let's test the distributed lock just implemented with a simple example .

Use... In the example 50 Thread simulation second kill a product , Use -- Operator to achieve product reduction , From the order of the results, we can see whether it is a locked state .

Simulated seckill service , It's equipped with jedis Thread pool , It is passed to the distributed lock during initialization , For its use .

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; /**
* Created by liuyang on 2017/4/20.
*/
public class Service {
private static JedisPool pool = null; static {
JedisPoolConfig config = new JedisPoolConfig();
// Set the maximum number of connections
config.setMaxTotal(200);
// Set the maximum number of idle
config.setMaxIdle(8);
// Set the maximum waiting time
config.setMaxWaitMillis(1000 * 100);
// stay borrow One jedis When an instance , Is it necessary to verify , if true, Then all jedis Instances are available
config.setTestOnBorrow(true);
pool = new JedisPool(config, "127.0.0.1", 6379, 3000);
} DistributedLock lock = new DistributedLock(pool); int n = 500; public void seckill() {
// Back to the lock value value , For judgment when releasing the lock
String indentifier = lock.lockWithTimeout("resource", 5000, 1000);
System.out.println(Thread.currentThread().getName() + " For the lock ");
System.out.println(--n);
lock.releaseLock("resource", indentifier);
}
}

// Simulation thread for seckill service

public class ThreadA extends Thread {
private Service service; public ThreadA(Service service) {
this.service = service;
} @Override
public void run() {
service.seckill();
}
} public class Test {
public static void main(String[] args) {
Service service = new Service();
for (int i = 0; i < 50; i++) {
ThreadA threadA = new ThreadA(service);
threadA.start();
}
}
}

give the result as follows , The result is orderly .

If you comment out the part that uses the lock

public void seckill() {
// Back to the lock value value , For judgment when releasing the lock
//String indentifier = lock.lockWithTimeout("resource", 5000, 1000);
System.out.println(Thread.currentThread().getName() + " For the lock ");
System.out.println(--n);
//lock.releaseLock("resource", indentifier);
}

It can be seen from the results , Some of them are asynchronous .

In a distributed environment , Locking resources is sometimes important , For example, snapping up a certain resource , At this time, using distributed locks can control resources very well .

Of course , In specific use , There are many factors to consider , For example, the selection of timeout , The selection of lock acquisition time has a great influence on the concurrency , The distributed lock implemented above is just a simple implementation , It's mainly an idea .

I'll use it next time zookeeper Implement distributed locks , Use zookeeper Reliability is greater than the use of redis Implementation of distributed lock , But by comparison ,redis Better performance .

The above code can be found in my GitHub To see , The address is as follows :

https://github.com/yangliu0/DistributedLock

Distributed lock and implementation ( One )—— be based on Redis More articles on Implementation

  1. Distributed lock and implementation ( One )—— be based on Redis Realization 【 More reliable 】

    turn : Distributed lock and implementation ( One )—— be based on Redis Realization summary At present, almost many large-scale websites and applications are distributed deployment , Data consistency in distributed scenarios is always an important topic . A distributed CAP Theory tells us “ Any distributed system ...

  2. Distributed lock and implementation ( One ) be based on Redis Realization

    At present, almost many large-scale websites and applications are distributed deployment , Data consistency in distributed scenarios is always an important topic . A distributed CAP Theory tells us “ No distributed system can satisfy the consistency at the same time (Consistency). Usability ( ...

  3. Distributed lock and implementation ( One )—— be based on Redis Realization ( Reprint )

    php The whole process of , Packet protection queue operation :http://www.cnblogs.com/candychen/p/5736128.html summary At present, almost many large-scale websites and applications are distributed deployment , Data consistency in distributed scenarios ...

  4. Distributed lock practice ( One )-Redis Summary of programming implementation

    Let me write it first When I summarized idempotency before , I have written an implementation of distributed lock , Unfortunately, it wasn't really used at that time , I really feel guilty . Just during this period of time, I practiced this part , That's right. I filled the hole before . Distributed lock according to the conclusion on the Internet , There are roughly three kinds of :1. data ...

  5. be based on redis Distributed lock implementation Distributed locks with Redis debug Check for mistakes

    Summary : 1. How locks are implemented , According to the implementation architecture of the application , There may be the following types : If the handler is single process multithreaded , stay python Next , You can use threading Modular Lock Object to restrict synchronous access to shared variables ...

  6. redis How to implement distributed lock ,redis The implementation of distributed locks ,redis Do distributed locks Positive and just youth

    Preface Distributed lock can be implemented in three ways :1. Database optimistic lock :2. be based on Redis Distributed locks for :3. be based on ZooKeeper Distributed locks for . This blog will introduce the second way , be based on Redis Implement distributed locks . Although there are all kinds of media on the Internet ...

  7. Implementation of distributed lock 【 be based on ZooKeeper】

    introduction ZooKeeper It's a distributed one , Open source distributed application coordination service , yes Google Of Chubby An open source implementation , yes Hadoop and Hbase Important components . It is a software that provides consistency services for distributed applications , carry ...

  8. Universal distributed consumption framework , Add based on redis The way of middleware .

    The purpose of the framework is to dispatch all functions in a distributed way ( Of course, it also includes scheduling everything, any method ). What I wrote before is based on rabbitmq Of , As a dedicated message queue, it's better than redis Of list The structure is much better . But some people still like to use redis, as well as r ...

  9. be based on redis Implement reliable distributed locks

    What is a lock Today we are going to talk about how to implement a global lock in a distributed environment , Before we start, let's talk about locks in non distributed environment : stand-alone – Single process programs use mutex mutex, Solve the synchronization problem between multiple threads stand-alone – Multiprocess programs use semaphores sem, Explain ...

Random recommendation

  1. CSS3 Animation Frame animation steps()

    @keyframes fn{ 0%{} 100%{} } CSS3 Of Animation There are eight attributes animation-name : Animation name fn animation-duration: Time 1s ani ...

  2. android studio Basic animation implementation on ( Chapter one )

    hello, Dear friends , A lot of kids are just beginning to learn android When , There are always some project There needs to be some basic animation insertions , So how to realize it ? Let's take a look at android Some of the bases in ...

  3. form Submit some of the array trick

    When passing values to the server form utilize $.post( "/member/member/book/" + event_id, { tickets: tickets, csrf_ppw_tok ...

  4. mysql Calculate the date difference

    There are two ways to get   1. utilize TO_DAYS function   select to_days(now()) - to_days('20140831')   2. utilize DATEDIFF function   select dat ...

  5. Velocity(9)—— macro

    Defining and using macros #macro Instructions are used to define a VTL Duplicate code blocks for templates —— macro . Here's a simple example of defining a macro : #macro( d ) <tr><td></td>< ...

  6. Python Data visualization programming practice —— Import data

    1. from csv File import data principle :with Statement to open a file and bind to an object f. You don't have to worry about closing the data file after operating the resource ,with The context manager will help handle . then ,csv.reader() Method returns reader object , adopt ...

  7. 【 turn 】 Update and FixedUpdate The difference between

    MonoBehaviour.Update  to update When MonoBehaviour When enabled , Its Update Called at every frame . MonoBehaviour.FixedUpdate  Fixed update When MonoBehavi ...

  8. game of life

    class Solution { public: void gameOfLife(vector<vector<int>>& board) { queue<int& ...

  9. .NET There are three ways to implement interfaces in

    Excerpt from :http://www.cnblogs.com/zhangronghua/archive/2009/11/25/1610713.html Generally speaking .NET Three different interface implementations are provided , They are implicitly connected ...

  10. oracle Database remote export

    exp user name / password @IP: port / Database name file= File path full=y; exp scebm1/ebm@10.3.10.16:1521/scebm file=D:scebm20140527.dm ...