English 中文(简体)
与AppazoKeeper一道进行僵局探测
原标题:Implementing deadlock detection with Apache ZooKeeper

我为一家小型软件公司工作,我的任务是研究一个分配给我们使用的24小时经理。 它必须与 Java和C++进行接口。

根据文件,我与动物园家合作了数周,并且发生的任何变化,因此不可能维持准确的图表。 这意味着,每次我打破僵局时,我都需要下载许多似乎不切实际的锁。

另一项解决办法是,在目前我工作过的动物园艺服务器内进行僵局探测。 每个客户都将在其会议设计书后点名出一个点子,其数据将是等待的锁定。 由于每24小时都有一位phe人,我将有足够的信息来发现僵局。

我面临的问题是,动物园地服务器没有同步保障,而动物园地主的客户就是这样。 此外,动物园地服务器像客户一样,有很强的记录,因为一般说来,你不会触及它。

因此,我的问题是:如何与阿帕奇·霍克谢伯一道进行僵局探测? 我认为,这里的许多人建议将动物园得主作为分配的24小时管理人员,但如果它能够支持发现僵局,那么没有人应该为此目的使用。


EDIT:

我有一个可行的解决办法。 我不能保证其正确性,但经过了我的所有考验。

I am sharing my checkForDeadlock method, which is the heart of the deadlock detection algorithm. Here s the additional information that you need to know:

  • Only one client should be running deadlock detection at a time.
  • First a client tries to acquire a lock on a resource. If the resource is already locked and the client wants to wait until it becomes available, then the client next checks for a deadlock. If waiting for the resource would not cause a deadlock, then it next creates a znode in a special directory which identifies that this client is waiting for that resource. That line looks like this: waitNode = zooKeeper.create(waitingPath + "/" + sessionID, resource.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
  • No other client should begin checking for deadlock until after this client has created the wait node.
  • If two clients attempt to acquire locks at almost the same time, but granting both would cause a deadlock, then it is slightly possible that, instead of the first client getting the lock and the second client being rejected, the first client could be rejected and the second client could get the lock. This shouldn t be a problem.
  • checkForDeadlock throws a DeadlockException if it discovers a deadlock. Otherwise, it returns normally.
  • Locks are granted strictly in order. If a resource has a granted read lock and a waiting write lock, and another client wants to acquire a read lock, it has to wait until after the write lock is granted and then released.
  • bySequenceNumber is a comparator that sorts znodes by the sequence that ZooKeeper appends to the end of sequential znodes.

法典:

private void checkForDeadlock(String pathToResource) throws DeadlockException {
    // Algorithm:
    //   For each client who holds a lock on this resource:
    //     If this client is me, announce deadlock.
    //     Otherwise, if this client is waiting for a reserved resource, recursively check for deadlock on that resource.
    try {
        List<String> lockQueue = zooKeeper.getChildren(pathToResource, false); // Last I checked, children is implemented as an ArrayList.
        // lockQueue is the list of locks on this resource.
        // FIXME There is a slight chance that lockQueue could be empty.
        Collections.sort(lockQueue, bySequenceNumber);
        ListIterator<String> lockQueueIterator = lockQueue.listIterator();
        String grantedLock = lockQueueIterator.next(); // grantedLock is one lock on this resource.
        do {
            // lockQueue must contain a write lock, because there is a lock waiting.
            String lockOwner = null;
            try {
                lockOwner = Long.toString(zooKeeper.exists(pathToResource + "/" + grantedLock, false).getEphemeralOwner());
                // lockOwner is one client who holds a lock on this resource.
            }
            catch (NullPointerException e) {
                // Locks may be released while I m running deadlock detection. I got a NullPointerException because
                // the lock I was currently looking at was deleted. Since the lock was deleted, its owner was obviously
                // not part of a deadlock. Therefore I can ignore this lock and move on to the next one.
                // (Note that a lock can be deleted if and only if its owner is not part of a deadlock.) 
                continue;
            }
            if (lockOwner.equals(sessionID)) { // If this client is me.
                throw new DeadlockException("Waiting for this resource would result in a deadlock.");
            }
            try {
                // XXX: Is is possible that reservedResource could be null?
                String reservedResource = new String(zooKeeper.getData(waitingPath + "/" + lockOwner, false, new Stat()));
                // reservedResource is the resource that this client is waiting for. If this client is not waiting for a resource, see exception.
                // I only recursively check the next reservedResource if I havn t checked it before.
                // I need to do this because, while I m running my deadlock detection, another client may attempt to acquire
                // a lock that would cause a deadlock. Without this check, I would loop in that deadlock cycle indefinitely.
                if (checkedResources.add(reservedResource)) {
                    checkForDeadlock(reservedResource); // Depth-first-search
                }
            }
            catch (KeeperException.NoNodeException e) {
                // lockOwner is not waiting for a resource.
            }
            catch (KeeperException e) {
                e.printStackTrace(syncOut);
            }
            // This loop needs to run for each lock that is currently being held on the resource. There are two possibilities:
            // A. There is exactly one write lock on this resource. (Any other locks would be waiting locks.)
            //      In this case, the do-while loop ensures that the write lock has been checked.
            //      The condition that requires that the current lock is a read lock ensures that no locks after the write lock will be checked.
            // B. There are one or more read locks on this resource.
            //      In this case, I just check that the next lock is a read lock before moving on.
        } while (grantedLock.startsWith(readPrefix) && (grantedLock = lockQueueIterator.next()).startsWith(readPrefix));
    }
    catch (NoSuchElementException e) {
        // The condition for the do-while loop assumes that there is a lock waiting on the resource.
        // This assumption was made because a client just reported that it was waiting on the resource.
        // However, there is a small chance that the client has since gotten the lock, or even released it before
        // we check the locks on the resource.
        // FIXME (This may be a problem.)
        // In such a case, the childrenIterator.next() call could throw a NoSuchElementException.
        // We can safely assume that we are finished searching this branch, and therefore return.
    }
    catch (KeeperException e) {
        e.printStackTrace(syncOut);
    }
    catch (InterruptedException e) {
        e.printStackTrace(syncOut);
    }

}
最佳回答

你们需要两件事才能发现僵局,一份锁定人名单,一份锁定人名单,标准zk lock recipe,只要你写给你创建的某种节点。

你们不需要看到 every鱼的每一种变化,才能发现僵局。 僵局是一纸空文,很快消失。 定论,除非你对此有所作为,否则僵局将继续存在。 因此,如果你写成法典,使你的客户能够每天看望他们感兴趣的锁定点,客户将最终看到每个锁的所有人和等候者,客户将看到僵局。

然而,你确实必须小心。 客户可能无法看到最新情况,因为当客户重新登记观察时,可能会出现最新情况。 因此,如果客户确实发现僵局,客户就应当加倍检查僵局是否真的,让所有人/观察者重新接近陷入僵局的锁点,并确保僵局是真实的。

问题回答

暂无回答




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签