I want to avoid duplicate key in my Hazelcast, so I am planning to use putIfAbsent. But before I perform the test, I would like to know is IMap still thread safe if my application is hosted on two servers? For example, I have my application hosted on two servers and assume both applications receive the same key and both try to use putIfAbsent to insert.
Yes, it is thread-safe - see http://docs.hazelcast.org/docs/3.10.4/manual/html-single/index.html#locking-maps or http://docs.hazelcast.org/docs/3.10.4/javadoc/com/hazelcast/core/IMap.html
If you do putIfAbsent("hello","world") from any two places, at most one will succeed.
Any two places could be two threads in the same JVM, two threads in two JVMs, whatewver.
You don't need to do any kind of locking to ensure this, it's handled for you.
Related
I want to build the chat servers in nodejs using express.I have used cluster module for scaling the server among the multiple cores but how do I scale up to different system?
Since Node.js does not support shared memory, distributing Node.js processes across multiple machines provides for the same experience as using a cluster to distribute processes across multiple cores—if your application can run as multiple independent processes within a single system, then it can also be distributed to run as multiple independent processes across multiple systems.
Great, so that's one less thing to worry about! Now, there are many infrastructure solutions out there that would abstract running clusters on several systems, but your application is otherwise oblivious to any one you might pick.
What will concern you, though, within the realm of your application and any single process, is discovering external services, communicating to processes across the infrastructure and communicating with processes within a cluster. Again, there are many solutions out there that will curtail to any particular requirement your application needs to address.
So far, the Node.js community has favored simple approaches that are highly specialized for solving a particular problem and then get out of your way. For instance:
Web socket clients and servers: low latency within a cluster; also works well across the whole network when you can just send some data and get on with your life, but it will bring things down to a crawl if you need to synchronize processes, such as sending some data, waiting and idling until a result eventually comes back
Redis: clusters are easy to set up, instances handle discovery on their own, enough atomic operations to provide a solid approach to sharing data among different instances and the pub-sub support provides for low-latency IPC
ZMQ: lauded for it's intelligent, highly-available connections, you can devise any messaging protocol with a few dozen lines of code that the next human being maintaining your application will be able to reason about
etcd: distributed, consistent key-value store; low infrastructural overhead, allows for implementing straightforward service discovery on top that will integrate nicely with every infrastructure solution out there
Consul: based on serf, like etcd, but strongly opinionated, provides for service discovery on steroids with many additional niceties; if you like managing things on your own and have the time to invest up front, I would heartily recommend further investigation
While this certainly doesn't cover all the options available, it should be enough to get you going in the right direction. With just these simple building blocks that are ridiculously easy to reason about, you should be able to distribute your application across several systems, running across several machines in several datacenters.
If you're using a process manager like PM2, it will take care of starting up your node app on different or same machines but to handle multiple machines you should look into Puppet, Chef or Ansible to scale. If you're on AWS, EC2 can be set to do it automatically.
Actually there can be multiple answers to this question because the answer depends on how you want to communicate amongst nodes, how you want to assign tasks to nodes and how you manage failures.
You may want to research on how other cluster managers work and then try to design something similar in your application.
Few Approaches:
1) Use a load balancer in the front and distribute load amongst the machine. This I think can be the simplest approach.
2) Use a messaging system like RabbitMQ/ActiveMQ (or any other AMQP) system for inter node communication and let there be a pool of master nodes who assigns tasks to specific nodes and communicates to node via AMQP Protocol.
I understand how and what happens when we use MODE_THREADLOCAL and MODE_INHERITABLETHREADLOCAL in Spring Security Strategy. What I don't understand is, why would someone use MODE_THREADLOCAL over MODE_INHERITABLETHREADLOCAL.
Is there a memory impact with using one over the other. If so, is it
significant enough?
What is a typical business/functional usecase for using MODE_INHERITABLETHREADLOCAL?
Any performance different with using one over the other?
The memory impact of using the two is negligible
In some environments, it is common to spin up new Threads to do background tasks. Sometimes developers do not want the Thread that is created to contain a SecurityContext automatically. In these instances, MODE_THREADLOCAL is preferable. If you spin up a task on behalf of the current user, then it may be desirable to propagate the SecurityContext. In this instance MODE_INHERITABLETHREADLOCAL would be preferrable.
Performance between the two strategies is negligible
I would like to implement a mutex inside my node.js application, here is the mutex in wiki http://en.wikipedia.org/wiki/Mutual_exclusion.
Is there any ready module for this topic? if not, any idea can help me to implement it?
There are many ways to accomplish this. Two easy ways are via Redis or Zookeeper servers. Node.js has very good modules for both of them.
In Redis you can use WATCH + MULTI commands to implement locking. In Zookeeper you can create ephemeral nodes. In both way no two processes will execute the critical operation at the same time.
I have recently implemented Redis approach in a node-ratelimiter module which is a critical part of our production applications where we need to guarantee no two processes increment the same value in Redis. Refer to WATCH and MULTI for details. The code is in fact very easy to understand and read.
For Zookeeper example, refer to Locks Recipe. It is possible to implement much more complex logic for distributed locks with Zookeeper ephemeral nodes. Redis solution is just a special case and works very well if you don't need more than that.
Using these two approaches you can implement mutexes for any app and any logic.
Here is my scenario:
I have two servers with a multi-threaded message queuing consumer on each (two consumers total).
I have many message types (CreateParent, CreateChild, etc.)
I am stuck with bad legacy code (creating a child will partially creates a parent. I know it is bad...But I cannot change that.)
Message ordering cannot be assume (message queuing principle!)
RabbitMQ is my message queuing broker.
My problem:
When two threads are running simultaneous (one executing a CreateParent, the other executing a CreateChild), they generate conflicts because the two threads try to create the Parent in the database (remember the legacy code!)
My initial solution:
Inside the consumer, I created an "entity locking" concept. So when the thread processes a CreateChild message for example, it locks the Child and the Parent (legacy code!!) so the CreateParent message processing can wait. I used basic .net Monitor and list of Ids to implement this concept. It works well.
My initial solution limitation:
My "entity locking" concept works well on a single consumer in a single process on a single server. But it will not works across multiple servers running multiple consumers.
I am thinking of using a shared database to "store" my entity locking concept, so each processes (and threads) could access the database to verify which entities are locked.
My question (finally!):
All this is becoming very complex and it increases the bugs risk and code maintenance problems. I really don`t like it!
Does anyone already faced this kind of problem? Are they acceptable workarounds for it?
Does anyone have an idea for a clean solution for my scenario?
Thanks!
Finally, simple solutions are always the better ones!
Instead of using all the complexity of my "entity locking" concept, I finally turn down to pre-validate all the required data and entities states before executing the request.
More precisely, instead of letting CreateChild process crashes by itself when it encounter already existing data created by the CreateParent, I fully validate that everything is okay in the databases BEFORE executing the CreateChild message.
The drawback of this solution is that the implementation of the CreateChild must be aware of what of the specific data the CreateParent will produces and verify it`s presence before starting the execution. But seriously, this is far better than locking all the stuff in cross-system!
While using multiple instances in worker role will there not be thread synchronization issues. My doubt is whether two instances might try to pick the same record and process the same. How to solve this issue.
Thanks
Not threading issues, but concurrency issues. Yes, there will be issues.
However, these issues are not different from normal concurrency issues that you might have with even a single web server receiving simultaneous requests.
The most common way to deal with concurrency issues is through the use of Optimistic Concurrency.
a common solution within the Windows Azure Platform for allocating work out to multiple worker processes is the use of Azure Storage Queues. This helps minimize the risk of two threads or even two roles working on a single item concurrently. However, there is a wee bit of additional work that is required to make this fully functional and ensure that the queue behavior is properly accounted for.
I wouldn't recomend use multiple single-thread roles in order to avoid threading. It would be more expensive, and as #Mark has pointed out, you will end facing almost the same problems.