import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.RetryOneTime;
public class Lock {
private static ExecutorService service;
static final CuratorFramework curator;
//A re-entrant mutex
static final InterProcessMutex zkMutex;
static {
// curator = CuratorFrameworkFactory.newClient("server1:2182,server2:2181,server3:2181", new RetryOneTime(2000));
curator = CuratorFrameworkFactory.newClient("localhost:2181", new RetryOneTime(2000));
curator.start();
zkMutex = new InterProcessMutex(curator,"/mutex");
}
public static void count(int threadNum,final int workers) throws Exception{
final CountDownLatch latch = new CountDownLatch(threadNum);
service = Executors.newFixedThreadPool(threadNum);
long start=System.currentTimeMillis();
for (int i = 0; i < threadNum; ++i) {
service.execute(new Runnable() {
@Override
public void run() {
for (int i = 0; i < workers; ++i) {
try {
zkMutex.acquire();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
zkMutex.release();
} catch (Exception e) {
e.printStackTrace();
}
}
}
latch.countDown();
}
});
}
service.shutdown();
latch.await();
long end=System.currentTimeMillis();
System.out.println("Thread Num:"+threadNum+" workers per Thread:"+workers+" cost time:"+(end-start) +" avg "+ (threadNum*workers)*1000/(end-start));
}
public static void main(String[] args) throws Exception {
Lock.count(1, 500);
Lock.count(10, 500);
Lock.count(20, 500);
Lock.count(30, 500);
Lock.count(40, 500);
Lock.count(50, 500);
Lock.count(60, 500);
Lock.count(70, 500);
Lock.count(80, 500);
Lock.count(90, 500);
Lock.count(100, 500);
}
}
测试条件:
1)zk服务端,三台公司开发机搭建的zk集群,4CPU_4G_40G
2)zk客户端,另外一台开发机 , 4CPU_4G_40G
3)分布式锁使用的是curator框架提供的可重入锁 InterProcessMutex
说明:
1)红色线代表3台zk组成的集群模式,蓝色代表独立模式
2)一次锁的获取与释放代表一次事物
从图中可知,并发的线程数越大,由于zk服务端需要处理排队、watch创建与销毁越频繁,TPS 则越低。
在集群模式下,线程数为1时,tps为309,线程数为100时,tps为44
相同的线程数来说,zk集群相对于独立模式,需要处理集群节点间的状态同步,TPS 比独立模式要低
线程数为1时,集群模式下,tps为309,独立模式下,tps为280