1

We have an architecture setup where we have the client application running in a server and we would want to have a Micro Service responsible for offering the Distributed Lock/Map/Cache functionality. This Micro service internally uses Redisson , a java based client that can talk to Redis. Now we would want to provide apis lock, unlock, get,put from the Micro service which the client application can consume.For application to micro service communication, we would use gRPC protocol.

What is the right way to offer lock/unlock apis from Microservice to the client? Currently, we use Redisson's Semapbased on RedissonMap RMap.getLock(..)) and it follows java Lock specification so thread that acquires a Distributed lock only can unlock. One issue with this is Since Locking is handled by a Microservice, client has to make separate lock and unlock requests which may or may not be served by same node (Microservice) and same thread. this can be worked around by using Semaphore (with 1 permit). So, essentially we use Rsemaphore of redisson to server the usecase of mutual exclusion

I am more interested to find out what should be the factors that need to be considered when we come up with API spec for acquire/release, like whether the call to acquire/release permits at the Microservice should be synchronous or asynchronous.

M. Shashanka
  • 39
  • 1
  • 8
  • I question why you would want "to have a Micro Service responsible for offering the Distributed Lock/Map/Cache functionality". There are preexisting coordination services you can deploy that already can give you such functionality, like ZooKeeper or etcd. As for "async vs sync", it's irrelevant at the API level if you're using gRPC since gRPC supports both and the client can use whichever one they want. – Mark A Feb 05 '20 at 15:02
  • 1
    when i say offering locking feature from a microservice, i am not reinventing anything new.. this is just to get rid of 3rd party service dependancies from core application. Regarding sync vs async, concern i had was is it a good practise to make acquire/lock api sync since it can potentially hold to the connection longer under high concurrency.. does this deviate from standard practises of microservices – M. Shashanka Feb 05 '20 at 17:50

2 Answers2

1

I have a similar problem -- At some point -- unless it is 'poll' only the microservice will have to block the client to wait for the semaphore completion. If blocking is not acceptable then there is no need for a semaphore. The following logic should work fine even if each invocation comes from a different JVM (with possibly the initial connection to redis from that JVM) -- Use one of the RLock objects or a Atomic only temporarily -- long enough to update a key or map entry with some unique ID (supplied by client or by microservice). That is then stored 'safely' in Redis and indicates something like a 'lock'. If you use expiration on the key then that gives you a TTL on the 'lock'.

If your app can block in the microservice while waiting for the semaphore to release then calls from different microservices should work fine. This is the same model as if you had 2 long running JVMs directly connected to redis/redisson but each using the semaphore only once.

What you cant do (easily) is have a 'Lock' still 'held' while you return to the client then later call a (different JVM) microservice to release the Lock.

DALDEI
  • 3,722
  • 13
  • 9
0

like whether the call to acquire/release permits at the Microservice should be synchronous or asynchronous

That depends on logic enforced by semaphore. Use async way only for asynchronous logic executed inside acquire/release block.

Nikita Koksharov
  • 10,283
  • 1
  • 62
  • 71