Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to atomically update a counter shared between Docker instances

I have a simple C++ service (API endpoint) that increases a counter every time the API is called. When the caller posts data to http://10.0.0.1/add the counter has to be incremented by 1 and return the value of the counter to the caller.

Things get more complicated when the service is getting dockerized. When two instances of the same service run the addition has to be done atomically, ie the counter value is stored in a database and each docker instance has to acquire a lock get the old value, add one, return to the caller and unlock.

When the instances are processes in the same Linux machine, we used shared memory to efficiently lock, read, write and unlock the shared data and the performance was accepted. However when we use dockers and a database the performance is low. The results are OK, however the performance is low.

What is the canonical way between instances of dockerized properties to perform operations like the one described above? Is there a "shared memory" feature for containerized processes?

like image 930
cateof Avatar asked May 10 '17 10:05

cateof


People also ask

Can two Docker containers share the same volume?

Multiple containers can run with the same volume when they need access to shared data. Docker creates a local volume by default. However, we can use a volume diver to share data across multiple machines. Finally, Docker also has –volumes-from to link volumes between running containers.

How do I know if my CPU is allocated to a Docker container?

The first command to check is docker container inspect . With --format , you can even extract its value directly if exposed. Then, at runtime, check docker stats to see if, at runtime, the percentage of the host's CPU and memory the container is using.


2 Answers

It looks like for your case database is overhead. You just need some distribute lightweight key-value storage with shared key lock support. Here are some candidates:

  • etcd (https://coreos.com/etcd)
  • consul (https://www.consul.io, especially https://www.consul.io/docs/commands/lock.html)
  • redis (http://redis.io)
like image 117
Vyacheslav Enis Avatar answered Oct 19 '22 01:10

Vyacheslav Enis


The --ipc option of docker run enables shared-memory access between containers:

IPC settings (--ipc)

--ipc="" : Set the IPC mode for the container,

'container:<name|id>': reuses another container's IPC namespace

'host': use the host's IPC namespace inside the container

By default, all containers have the IPC namespace enabled.

IPC (POSIX/SysV IPC) namespace provides separation of named shared memory segments, semaphores and message queues.

Shared memory segments are used to accelerate inter-process communication at memory speed, rather than through pipes or through the network stack. Shared memory is commonly used by databases and custom-built (typically C/OpenMPI, C++/using boost libraries) high performance applications for scientific computing and financial services industries. If these types of applications are broken into multiple containers, you might need to share the IPC mechanisms of the containers.

This article provides some demonstration of its usage.

like image 1
Leon Avatar answered Oct 19 '22 00:10

Leon