Distributed Lock Service over MySql/GigaSpaces/Netapp [closed]

冷暖自知 提交于 2020-01-05 05:09:26

问题


Disclaimer: I already asked this question, but without the deployment requirement. I got an answer that got 3 upvotes, and when I edited the question to include the deployment requirement the answer then became irrelevant. The reason I'm resubmitting is because SO considers the original question 'answered', even though I got no meaningful upvoted answer. I opened a uservoice submission about this problem. The reason I reposted is so StackOverflow consider the original question answered, so it doesn't show up on the 'unanswered questions' tab.

Which distributed lock service would you use?

Requirements are:

  1. A mutual exclusion (lock) that can be seen from different processes/machines
  2. lock...release semantics
  3. Automatic lock release after a certain timeout - if lock holder dies, it will automatically be freed after X seconds
  4. Java implementation
  5. Easy deployment - must not require complicated deployment beyond either Netapp, MySql or GigaSpaces. Must play well with those products (especially GigaSpaces - this is why TerraCotta was ruled out).
  6. Nice to have: .Net implementation
  7. If it's free: Deadlock detection / mitigation

I'm not interested in answers like "it can be done over a database", or "it can be done over JavaSpaces" - I know. Relevant answers should only contain a ready, out-of-the-box, proven implementation.


回答1:


Here's the outline of a GigaSpaces based answer that meets your criteria, depending on exactly what you mean in criteria 3. I work with GigaSpaces from .Net, not Java:

Create a locking class with a SpaceID+SpaceRouting property IDing what is locked and a DataMember bool property Unlocked:

sealed public class IdLockTrans
{
    [SpaceID]
    [SpaceRouting]
    public string ID
    {
        get;
        set;
    }

    [DataMember]
    public bool Unlocked
    {
        get;
        set;
    }

    public IdLockTrans(Id id)
    {
        ID = id.ID;
    }

    public IdLockTrans()
    {
    }
}

You will use GigaSpaces' lease time for lock release after a certain timeout. This will cause GigaSpaces to remove IdLockTrans objects from the space automatically after they have been idle for the timeout period. The lack of an IdLockTrans for an ID means the ID is unlocked.

Your locker class will define and initialize these class members

    private readonly ISpaceProxy _proxy;
    private readonly long _leaseTime;

    public override bool Lock(Id id, long timeout)
    {
        bool locked;
        IdLockTrans lockTransTemplate = new IdLockTrans(id);
        // Assume that this is a new id.
        try
        {
            _proxy.Write(lockTransTemplate, null, _leaseTime, 0, UpdateModifiers.WriteOnly);
            locked = true;
        }
        catch (EntryAlreadyInSpaceException)
        {
            using (ITransaction tx = _proxy.CreateLocalTransaction())
            {
                try
                {
                    lockTransTemplate.Unlocked = true;
                    IdLockTrans lockTrans = _proxy.Take(lockTransTemplate, tx, timeout);
                    locked = (lockTrans != null);
                    if (lockTrans != null)
                    {
                        lockTrans.Unlocked = false;
                        _proxy.Write(lockTrans, tx, _leaseTime, 0, UpdateModifiers.WriteOnly);
                    }
                    tx.Commit();
                }
                catch
                {
                    tx.Abort();
                    throw;
                }
            }
        }
        return locked;
    }

    public override void Unlock(Id lockedId)
    {
        IdLockTrans lockTrans = new IdLockTrans(lockedId);
        lockTrans.Unlocked = true;
        try
        {
            _proxy.Update(lockTrans, null, _leaseTime, 0, UpdateModifiers.UpdateOnly);
        }
        catch (EntryNotInSpaceException)
        {
            throw new Exception("IdLockTrans for " + lockTrans.ID
                + " not found on Unlock. Lock time exceeded lease time.");
        }
    }



回答2:


Your .Net implementation is very close the existing out of the box lock/unlock API provided with the Java API. See: http://www.gigaspaces.com/docs/JavaDoc8.0/org/openspaces/core/DefaultGigaMap.html

You may found the source code for this Java class as part of the gs-openspaces-src.zip file provided with the product. Having the same with Gigaspaces .Net API should be straightfwd.




回答3:


In case you are still looking, take a look at Apache Zookeeper:

ZooKeeper is a centralized service for maintaining configuration information, naming, providing distributed synchronization, and providing group services. All of these kinds of services are used in some form or another by distributed applications.

The Zookeeper documentation provides examples of how to build a Lock service on top of Zookeeper.




回答4:


Use mysql to lock a unique key is very simple.

Assumption 1:

You use transaction and your isolation level is read committed.

Assumption 2: You lock you processing thread by a unique key, and release it when your transaction committed.

Then you can use this sql as a distribute lock:

Insert into distributed_lock(key) values(#{key}) ON DUPLICATE KEY UPDATE key=key;



来源:https://stackoverflow.com/questions/1070495/distributed-lock-service-over-mysql-gigaspaces-netapp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!