Many clients try to access one resource at the same time, but there should just be one client to access the resource at one time. Is it possible to implement it without lock or CAS provided by hardware?
Related
I have a requirement to synchronize concurrent access to a shared resource modified by different processes which run on different hosts. I am thinking to synchronize this by creating a lock table in a sql database which is accessible from a service that can access the database. All the process will first request for lock from the service and only the one getting the lock will go forward and change the shared resource. Processes will then release the lock after their computation. The lock table will hold information like host, pid, lock creation time of the process currently holding the lock so as to clear the lock if the current process holding the lock has died unexpectedly and some other process has requested for the lock.
I am not inclined for a zookeeper based solution as the traffic in my case is minimal(2-5 process may run in a single day and so the probability of concurrent access is already minimal) and so I am not thinking to maintain a separate service for lock but extend one of the existing service itself by adding an additional table in its database.
I wanted suggestions on this approach or if there is some other simpler solution for this problem.
I have a question regarding how does Couchbase internally handle concurrency.
I tried researching in their documentation and all I found was that it depends on which locking mechanism you use in your application, the two main being :
Optimistic locking
Pessimistic locking
However, both of the above are related to how we want our strategy to be for saving data , meaning if we prefer to lock it or not.
In our case, IF we are not using either of those locking in our application, how would couchbase serve the document in the scenario below :
If application A writes a document A
At the very same instance application B tries to read Document A
My question is will Application B have to queue up to read the document, or by default it will get served the older version (all of this is not going through sync gateway and we are using .Net DLL directly for writing and reading).
Couchbase version 4.5.0
If you are using the Couchbase SDK and connecting directly to the Data Service, Couchbase is strongly consistent. If application A writes the document and immediately after application B reads it, application B will get that version. The consistency comes from how Couchbase distributes the data and how the client SDK accesses it. Couchbase distributes each object to one of 1024 active shards (Couchbase calls them vBuckets). There are replicas, but I will not get into that here. When the SDK goes to read/write objects directly, it take the object ID you give, passed it into a consistent CRC32 hash. The output of that hash is a number between 0-1023, the vBucket number. The SDK then looks into the cluster map (a JSON document distributed by the cluster) and finds where in the cluster that vBucket lives. The SDK then goes and talks directly to that node and vBucket. That is how application A can write an object and then microseconds later application B reads it. They are both reading and writing to the same place. Couchbase does not scale reads from replicas. Replicas are only for HA.
Because, as Kirk mentioned in his reply, Couchbase is consistent, both the read and write requests in your scenario will go to the same node and access the same object in the server's memory. However, concepts like "at the same time" get fuzzy when talking about distributed systems with network latency and various IO queues involved. Ultimately, the order of execution of the two "simultaneous" requests will depend on the order that the server receives them, but there is no deterministic way to predict what it will be. There are too many variables on the way; what if the CLR of one of the client decides to do garbage collection just then, delaying the request, or one of the client machines experiences momentary network lag, etc. This is one of the reasons that the documentation recommends using explicit locking for concurrent writes, to enforce predictable behavior in the face of unpredictable request ordering.
In your scenario though, there is simply no way to know in which order the write and read will occur, because "at the same time" is not an exact concept. One possible solution in your case might be to use explicit versioning for the data. This can be a timestamp or some sort of revision number that's incremented every time the document is changed. Of course, using a timestamp runs into a similar problem as above, because it's recorded according to the clock of the machine application A runs on, which is most likely different from the clock where application B runs.
in our application, if user logged in as admin he can do any operation. supposed one admin modifying a route,if second admin at the same time checked the same route and creating an airwaybill for the same route.This will be a problem. I could not find how my application is handling these concurrent requests.
(we are simply using jdbc transactions)
I am getting different answers from my team 1. web/application server handles these transactions and it will handle concurrent requests without any issues.
2. locks will be happened on rows on database and there wont be any problem for concurrent requests.
bottomline : concurrent requests should be handled in code? or we shall do any setting in web/application for concurrent requests while deploying? or by default database will handle concurrent requests by row locking mechanism?
if anyone knows where to find the solution , please let me know.
As far as I'm aware most database engines use some kind of locking during queries, but it will differ depending on the engine. I know that InnoDB enforces transaction atomicity (see this stack exchange thread) so anything that is wrappend in a transaction wont be interfered with mid execution. However there is no guaruntee as to which request will reach the datbase first.
As for the webServer/appServer, assuming your using a threaded web server: apache tomcat, jetty etc then each request is handled as by a seperate thread so I would assume is no inherent thread saftey. In the majority of cases the database will handle your concurrency without complaining, however i would recommend including a some kind of serialisation on the application end in case you decide to change DB implementation somewhere down the road, you will also have more control over how requests are handled.
In short ..... do both.
As far as I know, most databases has some kind of locking during the transactions and queries, but you should check the database references to ensure the type of locking method it uses. As for your problem with your web server, I know that tomcat handles requests concurrently and offers some kind of thread safety for it's own resources, but it offers no thread safety for your application.Thus, you should do it on your own. For the problem you mentioned above, I think when you are accessing your route, you should query it against the database whether it exists or not. Also when your other admin is modifying the route, you can use some sort of lock on the block you are doing that so that when the other admin at the same time wants to access the route that is being modified, he waits for the transaction to be completed. if you are using java for the server side, I recommend to see java synchronization methods or if another language, check locking and thread safety methods for that language.
I am developing a multi-threaded application and using Cassandra for the back-end.
Earlier, I created a separate session for each child thread and closed the session before killing the thread after its execution. But then I thought it might be an expensive job so I now designed it like, I have a single session opened at the start of the server and any number of clients can use that session for querying purposes.
Question: I just want to know if this is correct, or is there a better way to do this? I know connection pooling is an option but, is that really needed in this scenario?
It's certainly thread safe in the Java driver, so I assume the C++ driver is the same.
You are encouraged to only create one session and have all your threads use it so that the driver can efficiently maintain a connection pool to the cluster and process commands from your client threads asynchronously.
If you create multiple sessions on one client machine or keep opening and closing sessions, you would be forcing the driver to keep making and dropping connections to the cluster, which is wasteful of resources.
Quoting this Datastax blog post about 4 simple rules when using the DataStax drivers for Cassandra:
Use one Cluster instance per (physical) cluster (per application
lifetime)
Use at most one Session per keyspace, or use a single
Session and explicitely specify the keyspace in your queries
If you execute a statement more than once, consider using a PreparedStatement
You can reduce the number of network roundtrips and also have atomic operations by using Batches
The C/C++ driver is definitely thread safe at the session and future levels.
The CassSession object is used for query execution. Internally, a session object also manages a pool of client connections to Cassandra and uses a load balancing policy to distribute requests across those connections. An application should create a single session object per keyspace as a session object is designed to be created once, reused, and shared by multiple threads within the application.
They actually have a section called Thread Safety:
A CassSession is designed to be used concurrently from multiple threads. CassFuture is also thread safe. Other than these exclusions, in general, functions that might modify an object’s state are NOT thread safe. Objects that are immutable (marked ‘const’) can be read safely by multiple threads.
They also have a note about freeing objects. That is not thread safe. So you have to make sure all your threads are done before you free objects:
NOTE: The object/resource free-ing functions (e.g. cass_cluster_free, cass_session_free, … cass_*_free) cannot be called concurrently on the same instance of an object.
Source:
http://datastax.github.io/cpp-driver/topics/
I'm trying with WSO2 products, and I'm thinking about a scenario where bad code could take up all the CPU time (e.g. dead loop or so). I did try it with WSO2 AS with 2 tenants, A and B. And A's bad code does affect B and B's app will have a very long reponse delay or even stuck. Is there a way to restrict the CPU usage of a tenant? Thanks!
At the moment, you will have to setup your environment in what is known as private jet mode, where each tenant gets its own JVM, if you need total isolation.
In a shared environment, we have stuck thread detection which will ensure that critical threads will not run for more than a specified time period. We have plans for CPU usage limiting on per tenant basis. This would be available in a future release.
My suggestion would be to not run two tenants in one application server. Run two separate processes on the same machine. Better yet, run two separate processes in separate OS-level containers (like a jail or an lxc container). Or separate virtual machines if you can't use containers.
Operating systems give you tools for controlling CPU use - rlimit and nice for processes, and implementation-specific facilities for containers and VMs. Because they're implemented in the OS (or virtual machine manager), they are capable of doing this job correctly and reliably. There's no way an application server can do it anywhere near as well.
In any case, having separate applications share an application server and JVM is a terrible idea which should have been put to death in the '90s. There's just no need for it, and it introduces so many potential headaches.