You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@zookeeper.apache.org by Martin Waite <wa...@googlemail.com> on 2010/02/23 13:05:47 UTC

how to lock one-of-many ?

Hi,

I have a set of resources each of which has a unique identifier.  Each
resource element must be locked before it is used, and unlocked afterwards.

The logic of the application is something like:

lock any one element;
if (none locked) then
   exit with error;
else
   get resource-id from lock
   use resource
   unlock resource
end

Zookeeper looks like a good candidate for managing these locks, being fast
and resilient, and it seems quite simple to recover from client failure.

However, I cannot think of a good way to implement this sort of one-of-many
locking.

I could create a directory called "available" and another called "locked".
Available would have one entry for each resource id ( or one entry
containing a list of the resource-ids).  For locking, I could loop through
the available ids, attempting to create a lock for that in the locked
directory.  However this seems a bit clumsy and slow.  Also, the locks are
held for a relatively short time (1 second on average), and by time I have
blundered through all the possible locks, ids that were locked at the start
might be available by time I finished.

Can anyone think of a more elegant and efficient way of doing this ?

regards,
Martin

Re: how to lock one-of-many ?

Posted by Martin Waite <wa...@googlemail.com>.
Thanks Ted.   The randomization should work well in this case.

regards,
Martin

On 23 February 2010 18:27, Ted Dunning <te...@gmail.com> wrote:

> I think that the crux of Mahadev's suggestion is that you do as you say,
> but
> you should try the resources in randomized order.
>
> That will have very robust properties, especially with more than a handful
> of resources and is easy to code and to analyze.
>
> It won't work if you really mean "lock first available from this sequence".
>
> On Tue, Feb 23, 2010 at 4:05 AM, Martin Waite <waite.134@googlemail.com
> >wrote:
>
> > For locking, I could loop through
> > the available ids, attempting to create a lock for that in the locked
> > directory.  However this seems a bit clumsy and slow.  Also, the locks
> are
> > held for a relatively short time (1 second on average), and by time I
> have
> > blundered through all the possible locks, ids that were locked at the
> start
> > might be available by time I finished.
> >
>
>
>
> --
> Ted Dunning, CTO
> DeepDyve
>

Re: how to lock one-of-many ?

Posted by Ted Dunning <te...@gmail.com>.
I think that the crux of Mahadev's suggestion is that you do as you say, but
you should try the resources in randomized order.

That will have very robust properties, especially with more than a handful
of resources and is easy to code and to analyze.

It won't work if you really mean "lock first available from this sequence".

On Tue, Feb 23, 2010 at 4:05 AM, Martin Waite <wa...@googlemail.com>wrote:

> For locking, I could loop through
> the available ids, attempting to create a lock for that in the locked
> directory.  However this seems a bit clumsy and slow.  Also, the locks are
> held for a relatively short time (1 second on average), and by time I have
> blundered through all the possible locks, ids that were locked at the start
> might be available by time I finished.
>



-- 
Ted Dunning, CTO
DeepDyve

Re: how to lock one-of-many ?

Posted by Patrick Hunt <ph...@apache.org>.
Actually you can do it today, but not as easily. Look at the patch for 
544 - in your test you need to create your own subclass of ZooKeeper, 
then you can use the cnxn in a similar way as the patch does in order to 
access the data. Not particularly hard, but we've wrapped it up in a 
nice package for 3.3.0.

I wouldn't stress out too much about this particular issue though. If 
you implement a reasonable recipe ZooKeeper is doing the heavy 
lifting/theory and things should just work out in the end. I'd be 
interested to hear if you do find anything interesting though.

Regards,

Patrick

Mahadev Konar wrote:
> Hi martin,
>  Currently you cannot access the server that the client is connected to.
> This was fixed in this jira
> 
> http://issues.apache.org/jira/browse/ZOOKEEPER-544
> 
> But again this does not tell you if you are connected to the primary or the
> other followers. So you will anyway have to do some manual testing with
> specifying the client host:port address as just the primary or just the
> follower (for the follower test case).
> 
> Leaking information like (if the server is primary or not) can cause
> applications to use this information in a wrong way. So we never exposed
> this information! :)
> 
> Thanks
> mahadev
> 
> 
> 
> 
> On 2/24/10 11:25 AM, "Martin Waite" <wa...@googlemail.com> wrote:
> 
>> Hi,
>>
>> I take the point that the watch is useful for stopping clients unnecessarily
>> pestering the zk nodes.
>>
>> I think that this is something I will have to experiment with and see how it
>> goes.  I only need to place about 10k locks per minute, so I am hoping that
>> whatever approach I take is well within the headroom of Zookeeper on some
>> reasonable boxes.
>>
>> Is it possible for the client to know whether it has connected to the
>> current primary or not ?   During my testing I would like to make sure that
>> the approach works both when the client is attached to the primary and when
>> attached to a lagged non-primary node.
>>
>> regards,
>> Martin
>>
>> On 24 February 2010 18:42, Ted Dunning <te...@gmail.com> wrote:
>>
>>> Random back-off like this is unlikely to succeed (seems to me).  Better to
>>> use the watch on the locks directory to make the wait as long as possible
>>> AND as short as possible.
>>>
>>> On Wed, Feb 24, 2010 at 8:53 AM, Patrick Hunt <ph...@apache.org> wrote:
>>>
>>>> Anyone interested in locking an explicit resource attempts to create an
>>>> ephemeral node in /locks with the same ### as they resource they want
>>> access
>>>> to. If interested in just getting "any" resource then you would
>>>> getchildren(/resources) and getchildren(/locks) and attempt to lock
>>> anything
>>>> not in the intersection (avail). This could be done efficiently since
>>>> resources won't change much, just cache the results of getchildren and
>>> set a
>>>> watch at the same time. To lock a resource randomize "avail" and attempt
>>> to
>>>> lock each in turn. If all avail fail to acq the lock, then have some
>>> random
>>>> holdoff time, then re-getchildren(locks) and start over.
>>>>
>>>
>>>
>>> --
>>> Ted Dunning, CTO
>>> DeepDyve
>>>
> 

Re: how to lock one-of-many ?

Posted by Mahadev Konar <ma...@yahoo-inc.com>.
Hi martin,
 Currently you cannot access the server that the client is connected to.
This was fixed in this jira

http://issues.apache.org/jira/browse/ZOOKEEPER-544

But again this does not tell you if you are connected to the primary or the
other followers. So you will anyway have to do some manual testing with
specifying the client host:port address as just the primary or just the
follower (for the follower test case).

Leaking information like (if the server is primary or not) can cause
applications to use this information in a wrong way. So we never exposed
this information! :)

Thanks
mahadev




On 2/24/10 11:25 AM, "Martin Waite" <wa...@googlemail.com> wrote:

> Hi,
> 
> I take the point that the watch is useful for stopping clients unnecessarily
> pestering the zk nodes.
> 
> I think that this is something I will have to experiment with and see how it
> goes.  I only need to place about 10k locks per minute, so I am hoping that
> whatever approach I take is well within the headroom of Zookeeper on some
> reasonable boxes.
> 
> Is it possible for the client to know whether it has connected to the
> current primary or not ?   During my testing I would like to make sure that
> the approach works both when the client is attached to the primary and when
> attached to a lagged non-primary node.
> 
> regards,
> Martin
> 
> On 24 February 2010 18:42, Ted Dunning <te...@gmail.com> wrote:
> 
>> Random back-off like this is unlikely to succeed (seems to me).  Better to
>> use the watch on the locks directory to make the wait as long as possible
>> AND as short as possible.
>> 
>> On Wed, Feb 24, 2010 at 8:53 AM, Patrick Hunt <ph...@apache.org> wrote:
>> 
>>> Anyone interested in locking an explicit resource attempts to create an
>>> ephemeral node in /locks with the same ### as they resource they want
>> access
>>> to. If interested in just getting "any" resource then you would
>>> getchildren(/resources) and getchildren(/locks) and attempt to lock
>> anything
>>> not in the intersection (avail). This could be done efficiently since
>>> resources won't change much, just cache the results of getchildren and
>> set a
>>> watch at the same time. To lock a resource randomize "avail" and attempt
>> to
>>> lock each in turn. If all avail fail to acq the lock, then have some
>> random
>>> holdoff time, then re-getchildren(locks) and start over.
>>> 
>> 
>> 
>> 
>> --
>> Ted Dunning, CTO
>> DeepDyve
>> 


Re: how to lock one-of-many ?

Posted by Martin Waite <wa...@googlemail.com>.
Hi,

I take the point that the watch is useful for stopping clients unnecessarily
pestering the zk nodes.

I think that this is something I will have to experiment with and see how it
goes.  I only need to place about 10k locks per minute, so I am hoping that
whatever approach I take is well within the headroom of Zookeeper on some
reasonable boxes.

Is it possible for the client to know whether it has connected to the
current primary or not ?   During my testing I would like to make sure that
the approach works both when the client is attached to the primary and when
attached to a lagged non-primary node.

regards,
Martin

On 24 February 2010 18:42, Ted Dunning <te...@gmail.com> wrote:

> Random back-off like this is unlikely to succeed (seems to me).  Better to
> use the watch on the locks directory to make the wait as long as possible
> AND as short as possible.
>
> On Wed, Feb 24, 2010 at 8:53 AM, Patrick Hunt <ph...@apache.org> wrote:
>
> > Anyone interested in locking an explicit resource attempts to create an
> > ephemeral node in /locks with the same ### as they resource they want
> access
> > to. If interested in just getting "any" resource then you would
> > getchildren(/resources) and getchildren(/locks) and attempt to lock
> anything
> > not in the intersection (avail). This could be done efficiently since
> > resources won't change much, just cache the results of getchildren and
> set a
> > watch at the same time. To lock a resource randomize "avail" and attempt
> to
> > lock each in turn. If all avail fail to acq the lock, then have some
> random
> > holdoff time, then re-getchildren(locks) and start over.
> >
>
>
>
> --
> Ted Dunning, CTO
> DeepDyve
>

Re: how to lock one-of-many ?

Posted by Patrick Hunt <ph...@apache.org>.
I think that depends on the "resources" and details of the use case we 
may not have. Martin mentioned that his lock frequency is high with very 
low hold times. This leads me to assume (ahem) in my response/thinking 
that the number of resources relative to the number of "lockers" is very 
high (many resources, few lockers each taking a lock at a time). If 
that's the case then I think it's fine. no?

An alternate in my mind, say you have resources ~= lockers (again, hard 
to say specifically based on info we have, if this makes sense or not) 
where the resources are heterogeneous then I would go with a scheme more 
like you suggest (to minimize starvation for example). If the resources 
are homogeneous then I'd go with something more along the lines of a 
long lived lock (or "master with failover" type scheme if you want to 
think about it that way).

Patrick

Ted Dunning wrote:
> Random back-off like this is unlikely to succeed (seems to me).  Better to
> use the watch on the locks directory to make the wait as long as possible
> AND as short as possible.
> 
> On Wed, Feb 24, 2010 at 8:53 AM, Patrick Hunt <ph...@apache.org> wrote:
> 
>> Anyone interested in locking an explicit resource attempts to create an
>> ephemeral node in /locks with the same ### as they resource they want access
>> to. If interested in just getting "any" resource then you would
>> getchildren(/resources) and getchildren(/locks) and attempt to lock anything
>> not in the intersection (avail). This could be done efficiently since
>> resources won't change much, just cache the results of getchildren and set a
>> watch at the same time. To lock a resource randomize "avail" and attempt to
>> lock each in turn. If all avail fail to acq the lock, then have some random
>> holdoff time, then re-getchildren(locks) and start over.
>>
> 
> 
> 

Re: how to lock one-of-many ?

Posted by Ted Dunning <te...@gmail.com>.
Random back-off like this is unlikely to succeed (seems to me).  Better to
use the watch on the locks directory to make the wait as long as possible
AND as short as possible.

On Wed, Feb 24, 2010 at 8:53 AM, Patrick Hunt <ph...@apache.org> wrote:

> Anyone interested in locking an explicit resource attempts to create an
> ephemeral node in /locks with the same ### as they resource they want access
> to. If interested in just getting "any" resource then you would
> getchildren(/resources) and getchildren(/locks) and attempt to lock anything
> not in the intersection (avail). This could be done efficiently since
> resources won't change much, just cache the results of getchildren and set a
> watch at the same time. To lock a resource randomize "avail" and attempt to
> lock each in turn. If all avail fail to acq the lock, then have some random
> holdoff time, then re-getchildren(locks) and start over.
>



-- 
Ted Dunning, CTO
DeepDyve

Re: how to lock one-of-many ?

Posted by Ted Dunning <te...@gmail.com>.
I was thinking of adding it on the client.  You can sub-class the client
connection and add any desired additional behaviors such as delays.  I am
fond of mocking the client connection as well in order to simulate severe
malfunctions or failure scenarios.

On Wed, Feb 24, 2010 at 11:18 AM, Martin Waite <wa...@googlemail.com>wrote:

> I really do not follow the delegator approach.  Is this something I would
> patch into Zookeeper ?  Or the client ?
>



-- 
Ted Dunning, CTO
DeepDyve

Re: how to lock one-of-many ?

Posted by Martin Waite <wa...@googlemail.com>.
I had not thought of adding latency to the network interface.  I have
skimmed descriptions of how to do this with iptables (or ipchains - I can't
remember which is the standard now) - so it sounds plausible.  Whether this
is within my capabilities is another matter.

I really do not follow the delegator approach.  Is this something I would
patch into Zookeeper ?  Or the client ?

regards,
Martin

On 24 February 2010 18:40, Ted Dunning <te...@gmail.com> wrote:

> I do believe that it is relatively easy to set up high latency/high error
> network interface clones in Linux.  I haven't looked into that for several
> years, but it used to be pretty easy.
>
> You can also build a delegater that wraps a real ZK connection.  That would
> be more compatible with a mocked object style of development.
>
> On Wed, Feb 24, 2010 at 8:53 AM, Patrick Hunt <ph...@apache.org> wrote:
>
> > Is there a feature to introduce deliberate lag between the primary and
> its
> >> replicas in the ensemble - for development purposes ?  That could be
> >> useful
> >> for exposing latency assumptions.
> >>
> >>
> > No feature but it does sound interesting. Are there any tools that allow
> > one to setup "slow pipes" ala stunnel but here for latency not encryp? I
> > believe freebsd has this feature at the os (firewall?) level, I don't
> know
> > if linux does.
>
>
>
>
> --
> Ted Dunning, CTO
> DeepDyve
>

Re: how to lock one-of-many ?

Posted by Ted Dunning <te...@gmail.com>.
I do believe that it is relatively easy to set up high latency/high error
network interface clones in Linux.  I haven't looked into that for several
years, but it used to be pretty easy.

You can also build a delegater that wraps a real ZK connection.  That would
be more compatible with a mocked object style of development.

On Wed, Feb 24, 2010 at 8:53 AM, Patrick Hunt <ph...@apache.org> wrote:

> Is there a feature to introduce deliberate lag between the primary and its
>> replicas in the ensemble - for development purposes ?  That could be
>> useful
>> for exposing latency assumptions.
>>
>>
> No feature but it does sound interesting. Are there any tools that allow
> one to setup "slow pipes" ala stunnel but here for latency not encryp? I
> believe freebsd has this feature at the os (firewall?) level, I don't know
> if linux does.




-- 
Ted Dunning, CTO
DeepDyve

Re: how to lock one-of-many ?

Posted by Martin Waite <wa...@googlemail.com>.
Hi Patrick,

Thanks for the info - the Fallacies link especially.  As you might have
guessed, I am one the programmers new to distributed computing who is very
much in danger of messing things up.

I am going to have to knuckle down and do some experiments.  Thankfully, I
don't think my requirements will stretch Zookeeper even if I take a heavy
handed approach.

regards,
Martin

On 24 February 2010 16:53, Patrick Hunt <ph...@apache.org> wrote:

>
> Martin Waite wrote:
>
>> The watch mechanism is a new feature for me.  This gives me a delayed
>> notification that something changed in the lock directory, and so is the
>> earliest time that it makes sense to retry my lock acquistion.  However,
>> given the time-delay in getting the notification, the freed lock might
>> have
>> be acquired by someone else before I get there.   In which case, I might
>> as
>> well just keep trying to acquire locks at random until my time budget is
>> exhausted and not bother with the watch ?
>>
>>
> I don't see the benefit of what Mahadev/Ted are suggesting vs Martin's
> original proposal. Perhaps I'm missing something, please correct me if I'm
> wrong but it seems to me that you want two "lists"; a list of resources and
> a list of locks. Resources might be added or removed dynamically over time
> (assuming they are not known a priori), locks are short lived and exclusive.
> To me this suggests:
>
> /resources/resource_###  (ephem? owned by the resource itself)
> /locks/resource_###   (ephem)
>
> where the available resources are managed by adding/removing from
> /resources. Anyone interested in locking an explicit resource attempts to
> create an ephemeral node in /locks with the same ### as they resource they
> want access to. If interested in just getting "any" resource then you would
> getchildren(/resources) and getchildren(/locks) and attempt to lock anything
> not in the intersection (avail). This could be done efficiently since
> resources won't change much, just cache the results of getchildren and set a
> watch at the same time. To lock a resource randomize "avail" and attempt to
> lock each in turn. If all avail fail to acq the lock, then have some random
> holdoff time, then re-getchildren(locks) and start over.
>
> Distributed computing is inherently "delayed" http://bit.ly/chhFrS right?
> ;-) The benefit of the watch is typically that it minimizes load on the
> service - notification vs polling.
>
>
>  Are watches triggered as soon as the primary controller applies a change
>> to
>> an object - or are they delivered whenever the client's local zk instance
>> replicates the change at some later time ?
>>
>>
> They are not synchonous in the sense you mean. You are guaranteed that all
> clients see all changes in the same order, but not
> synchronously/instantaneously.
>
> This stackoverflow page has some good detail, see Ben's comment here:
> http://bit.ly/aaMzHY
>
>
>  Is there a feature to introduce deliberate lag between the primary and its
>> replicas in the ensemble - for development purposes ?  That could be
>> useful
>> for exposing latency assumptions.
>>
>>
> No feature but it does sound interesting. Are there any tools that allow
> one to setup "slow pipes" ala stunnel but here for latency not encryp? I
> believe freebsd has this feature at the os (firewall?) level, I don't know
> if linux does.
>
> Patrick
>
>
>
>> On 24 February 2010 06:05, Ted Dunning <te...@gmail.com> wrote:
>>
>>  You have to be careful there of race conditions.  ZK's slightly
>>> surprising
>>> API makes it pretty easy to get this right, however.
>>>
>>> The correct way to do what you suggest is to read the list of children in
>>> the locks directory and put a watch on the directory at the same time.
>>>  If
>>> the number of locks equals the number of resources, you wait.  If it is
>>> less, you can randomly pick one of the apparently unlocked resources at
>>> random.  If you fail, start again by checking the number of resources.
>>>
>>> On Tue, Feb 23, 2010 at 9:09 PM, Martin Waite <waite.134@googlemail.com
>>>
>>>> wrote:
>>>> I guess another optimisation might be to count the number of locks held
>>>> first:  if the count equals the number of resources, try again later.
>>>>
>>>  But
>>>
>>>> I
>>>> suppose that might require a sync call first to ensure that zk instance
>>>>
>>> my
>>>
>>>> client is connected to is up to date.
>>>>
>>>>
>>>
>>> --
>>> Ted Dunning, CTO
>>> DeepDyve
>>>
>>>
>>

Re: how to lock one-of-many ?

Posted by Patrick Hunt <ph...@apache.org>.
Martin Waite wrote:
> The watch mechanism is a new feature for me.  This gives me a delayed
> notification that something changed in the lock directory, and so is the
> earliest time that it makes sense to retry my lock acquistion.  However,
> given the time-delay in getting the notification, the freed lock might have
> be acquired by someone else before I get there.   In which case, I might as
> well just keep trying to acquire locks at random until my time budget is
> exhausted and not bother with the watch ?
> 

I don't see the benefit of what Mahadev/Ted are suggesting vs Martin's 
original proposal. Perhaps I'm missing something, please correct me if 
I'm wrong but it seems to me that you want two "lists"; a list of 
resources and a list of locks. Resources might be added or removed 
dynamically over time (assuming they are not known a priori), locks are 
short lived and exclusive. To me this suggests:

/resources/resource_###  (ephem? owned by the resource itself)
/locks/resource_###   (ephem)

where the available resources are managed by adding/removing from 
/resources. Anyone interested in locking an explicit resource attempts 
to create an ephemeral node in /locks with the same ### as they resource 
they want access to. If interested in just getting "any" resource then 
you would getchildren(/resources) and getchildren(/locks) and attempt to 
lock anything not in the intersection (avail). This could be done 
efficiently since resources won't change much, just cache the results of 
getchildren and set a watch at the same time. To lock a resource 
randomize "avail" and attempt to lock each in turn. If all avail fail to 
acq the lock, then have some random holdoff time, then 
re-getchildren(locks) and start over.

Distributed computing is inherently "delayed" http://bit.ly/chhFrS 
right? ;-) The benefit of the watch is typically that it minimizes load 
on the service - notification vs polling.

> Are watches triggered as soon as the primary controller applies a change to
> an object - or are they delivered whenever the client's local zk instance
> replicates the change at some later time ?
> 

They are not synchonous in the sense you mean. You are guaranteed that 
all clients see all changes in the same order, but not 
synchronously/instantaneously.

This stackoverflow page has some good detail, see Ben's comment here: 
http://bit.ly/aaMzHY

> Is there a feature to introduce deliberate lag between the primary and its
> replicas in the ensemble - for development purposes ?  That could be useful
> for exposing latency assumptions.
> 

No feature but it does sound interesting. Are there any tools that allow 
one to setup "slow pipes" ala stunnel but here for latency not encryp? I 
believe freebsd has this feature at the os (firewall?) level, I don't 
know if linux does.

Patrick

> 
> On 24 February 2010 06:05, Ted Dunning <te...@gmail.com> wrote:
> 
>> You have to be careful there of race conditions.  ZK's slightly surprising
>> API makes it pretty easy to get this right, however.
>>
>> The correct way to do what you suggest is to read the list of children in
>> the locks directory and put a watch on the directory at the same time.  If
>> the number of locks equals the number of resources, you wait.  If it is
>> less, you can randomly pick one of the apparently unlocked resources at
>> random.  If you fail, start again by checking the number of resources.
>>
>> On Tue, Feb 23, 2010 at 9:09 PM, Martin Waite <waite.134@googlemail.com
>>> wrote:
>>> I guess another optimisation might be to count the number of locks held
>>> first:  if the count equals the number of resources, try again later.
>>  But
>>> I
>>> suppose that might require a sync call first to ensure that zk instance
>> my
>>> client is connected to is up to date.
>>>
>>
>>
>> --
>> Ted Dunning, CTO
>> DeepDyve
>>
> 

Re: how to lock one-of-many ?

Posted by Martin Waite <wa...@googlemail.com>.
I am comfortable with the locking approach.

The watch mechanism is a new feature for me.  This gives me a delayed
notification that something changed in the lock directory, and so is the
earliest time that it makes sense to retry my lock acquistion.  However,
given the time-delay in getting the notification, the freed lock might have
be acquired by someone else before I get there.   In which case, I might as
well just keep trying to acquire locks at random until my time budget is
exhausted and not bother with the watch ?

Are watches triggered as soon as the primary controller applies a change to
an object - or are they delivered whenever the client's local zk instance
replicates the change at some later time ?

Is there a feature to introduce deliberate lag between the primary and its
replicas in the ensemble - for development purposes ?  That could be useful
for exposing latency assumptions.

regards,
Martin

On 24 February 2010 06:05, Ted Dunning <te...@gmail.com> wrote:

> You have to be careful there of race conditions.  ZK's slightly surprising
> API makes it pretty easy to get this right, however.
>
> The correct way to do what you suggest is to read the list of children in
> the locks directory and put a watch on the directory at the same time.  If
> the number of locks equals the number of resources, you wait.  If it is
> less, you can randomly pick one of the apparently unlocked resources at
> random.  If you fail, start again by checking the number of resources.
>
> On Tue, Feb 23, 2010 at 9:09 PM, Martin Waite <waite.134@googlemail.com
> >wrote:
>
> > I guess another optimisation might be to count the number of locks held
> > first:  if the count equals the number of resources, try again later.
>  But
> > I
> > suppose that might require a sync call first to ensure that zk instance
> my
> > client is connected to is up to date.
> >
>
>
>
> --
> Ted Dunning, CTO
> DeepDyve
>

Re: how to lock one-of-many ?

Posted by Ted Dunning <te...@gmail.com>.
You have to be careful there of race conditions.  ZK's slightly surprising
API makes it pretty easy to get this right, however.

The correct way to do what you suggest is to read the list of children in
the locks directory and put a watch on the directory at the same time.  If
the number of locks equals the number of resources, you wait.  If it is
less, you can randomly pick one of the apparently unlocked resources at
random.  If you fail, start again by checking the number of resources.

On Tue, Feb 23, 2010 at 9:09 PM, Martin Waite <wa...@googlemail.com>wrote:

> I guess another optimisation might be to count the number of locks held
> first:  if the count equals the number of resources, try again later.  But
> I
> suppose that might require a sync call first to ensure that zk instance my
> client is connected to is up to date.
>



-- 
Ted Dunning, CTO
DeepDyve

Re: how to lock one-of-many ?

Posted by Martin Waite <wa...@googlemail.com>.
Thanks Mahadev.  Randomising the look-up is a good fit for what I am trying
to do, and should minimise the number of look-ups performed.

I guess another optimisation might be to count the number of locks held
first:  if the count equals the number of resources, try again later.  But I
suppose that might require a sync call first to ensure that zk instance my
client is connected to is up to date.

regards,
Martin

On 23 February 2010 17:50, Mahadev Konar <ma...@yahoo-inc.com> wrote:

> Hi Martin,
>  How about this-
>
>  you have resources in the a directory (say /locks)
>
>  each process which needs to lock, lists all the children of this directory
> and then creates an ephemeral node called /locks/resource1/lock depending
> on
> which resource it wants to lock.
>
> This ephemeral node will be deleted by the process as soon as its done
> using
> the resource. A process should only use to resource_{i} if its been able to
> create /locks/resource_{i}/locks.
>
> Would that work?
>
> Thanks
> mahadev
>
> On 2/23/10 4:05 AM, "Martin Waite" <wa...@googlemail.com> wrote:
>
> > Hi,
> >
> > I have a set of resources each of which has a unique identifier.  Each
> > resource element must be locked before it is used, and unlocked
> afterwards.
> >
> > The logic of the application is something like:
> >
> > lock any one element;
> > if (none locked) then
> >    exit with error;
> > else
> >    get resource-id from lock
> >    use resource
> >    unlock resource
> > end
> >
> > Zookeeper looks like a good candidate for managing these locks, being
> fast
> > and resilient, and it seems quite simple to recover from client failure.
> >
> > However, I cannot think of a good way to implement this sort of
> one-of-many
> > locking.
> >
> > I could create a directory called "available" and another called
> "locked".
> > Available would have one entry for each resource id ( or one entry
> > containing a list of the resource-ids).  For locking, I could loop
> through
> > the available ids, attempting to create a lock for that in the locked
> > directory.  However this seems a bit clumsy and slow.  Also, the locks
> are
> > held for a relatively short time (1 second on average), and by time I
> have
> > blundered through all the possible locks, ids that were locked at the
> start
> > might be available by time I finished.
> >
> > Can anyone think of a more elegant and efficient way of doing this ?
> >
> > regards,
> > Martin
>
>

Re: how to lock one-of-many ?

Posted by Mahadev Konar <ma...@yahoo-inc.com>.
Hi Martin,
  How about this- 

  you have resources in the a directory (say /locks)

  each process which needs to lock, lists all the children of this directory
and then creates an ephemeral node called /locks/resource1/lock depending on
which resource it wants to lock.

This ephemeral node will be deleted by the process as soon as its done using
the resource. A process should only use to resource_{i} if its been able to
create /locks/resource_{i}/locks.

Would that work?

Thanks
mahadev

On 2/23/10 4:05 AM, "Martin Waite" <wa...@googlemail.com> wrote:

> Hi,
> 
> I have a set of resources each of which has a unique identifier.  Each
> resource element must be locked before it is used, and unlocked afterwards.
> 
> The logic of the application is something like:
> 
> lock any one element;
> if (none locked) then
>    exit with error;
> else
>    get resource-id from lock
>    use resource
>    unlock resource
> end
> 
> Zookeeper looks like a good candidate for managing these locks, being fast
> and resilient, and it seems quite simple to recover from client failure.
> 
> However, I cannot think of a good way to implement this sort of one-of-many
> locking.
> 
> I could create a directory called "available" and another called "locked".
> Available would have one entry for each resource id ( or one entry
> containing a list of the resource-ids).  For locking, I could loop through
> the available ids, attempting to create a lock for that in the locked
> directory.  However this seems a bit clumsy and slow.  Also, the locks are
> held for a relatively short time (1 second on average), and by time I have
> blundered through all the possible locks, ids that were locked at the start
> might be available by time I finished.
> 
> Can anyone think of a more elegant and efficient way of doing this ?
> 
> regards,
> Martin