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