ホームページ  >  記事  >  Java  >  Java で分散ロックを使用して分散システムの同期を実現するにはどうすればよいですか?

Java で分散ロックを使用して分散システムの同期を実現するにはどうすればよいですか?

王林
王林オリジナル
2023-08-03 08:43:481384ブラウズ

Java で分散ロックを使用して分散システムの同期を実現するにはどうすればよいですか?

はじめに:
分散システムでは、複数のノードが共有リソースに同時にアクセスすると、データの競合や同時実行性の問題が発生する可能性があります。データの一貫性を確保するには、分散ロックを使用して分散システムの同期を実現する必要があります。 Java には分散ロックを実装するためのさまざまな方法が用意されていますが、この記事では ZooKeeper と Redis に基づく分散ロックの実装方法をコード例とともに紹介します。

1. ZooKeeper に基づく分散ロックの実装
ZooKeeper は、分散システムにおける同期の問題を解決するための分散ロック メカニズムを提供する分散調整サービスです。以下は、ZooKeeper を使用して分散ロックを実装するサンプル コードです。

import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

public class ZooKeeperDistributedLock implements Watcher {
    private ZooKeeper zooKeeper;
    private String lockPath;
    private String currentPath;
    private String waitPath;

    public ZooKeeperDistributedLock(String connectString, int sessionTimeout, String lockPath) throws IOException {
        zooKeeper = new ZooKeeper(connectString, sessionTimeout, this);
        this.lockPath = lockPath;
    }

    public void lock() throws KeeperException, InterruptedException {
        if (tryLock()) {
            return;
        }

        while (true) {
            List<String> children = zooKeeper.getChildren(lockPath, false);
            Collections.sort(children);

            int index = children.indexOf(currentPath.substring(lockPath.length() + 1));
            if (index == 0) {
                return;
            }

            waitPath = lockPath + "/" + children.get(index - 1);
            zooKeeper.exists(waitPath, true);
            synchronized (this) {
                wait();
            }
        }
    }

    public void unlock() throws KeeperException, InterruptedException {
        zooKeeper.delete(currentPath, -1);
    }

    private boolean tryLock() throws KeeperException, InterruptedException {
        currentPath = zooKeeper.create(lockPath + "/lock", new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        List<String> children = zooKeeper.getChildren(lockPath, false);
        Collections.sort(children);
        if (currentPath.endsWith(children.get(0))) {
            return true;
        }
        String currentPathName = currentPath.substring(lockPath.length() + 1);
        int index = children.indexOf(currentPathName);
        if (index < 0) {
            throw new IllegalStateException("Node " + currentPathName + " no longer exists.");
        } else {
            waitPath = lockPath + "/" + children.get(index - 1);
            zooKeeper.exists(waitPath, true);
            synchronized (this) {
                wait();
            }
            return false;
        }
    }

    @Override
    public void process(WatchedEvent event) {
        if (waitPath != null && event.getType() == Event.EventType.NodeDeleted && event.getPath().equals(waitPath)) {
            synchronized (this) {
                notifyAll();
            }
        }
    }
}

2. Redis ベースの分散ロックの実装
Redis は、いくつかのアトミック操作を提供する高性能のキーと値のストレージ システムです。分散ロック。以下は、Redis を使用して分散ロックを実装するサンプル コードです:

import redis.clients.jedis.Jedis;

public class RedisDistributedLock {
    private Jedis jedis;
    private String lockKey;
    private String requestId;

    public RedisDistributedLock(String host, int port, String password, String lockKey, String requestId) {
        jedis = new Jedis(host, port);
        jedis.auth(password);
        this.lockKey = lockKey;
        this.requestId = requestId;
    }

    public boolean lock(long expireTimeMillis) {
        String result = jedis.set(lockKey, requestId, "NX", "PX", expireTimeMillis);
        return "OK".equals(result);
    }

    public boolean unlock() {
        Long result = (Long) jedis.eval(
                "if redis.call('get', KEYS[1]) == ARGV[1] then " +
                "return redis.call('del', KEYS[1]) " +
                "else " +
                "return 0 " +
                "end",
                1,
                lockKey,
                requestId);
        return result != null && result == 1;
    }
}

結論:
この記事では、Java で分散ロックを使用して分散システムの同期を実現する 2 つの方法 ( ZooKeeper と Redis に基づく) を紹介します。 ZooKeeper と Redis のどちらを使用しても、分散システムの同期を効果的に実現し、データの一貫性を確保できます。実際のプロジェクトでは、適切な分散ロック ソリューションの選択は、特定のニーズとパフォーマンス要件に基づいて検討する必要があります。この記事があなたのお役に立てれば幸いです、読んでいただきありがとうございます!

以上がJava で分散ロックを使用して分散システムの同期を実現するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。