如何自动更新 Docker 个实例之间共享的计数器
How to atomically update a counter shared between Docker instances
我有一个简单的 C++ 服务(API 端点),每次调用 API 时都会增加一个计数器。当调用者将数据发布到 http://10.0.0.1/add 时,计数器必须递增 1,并且 return 计数器的值必须传递给调用者。
当服务 docker 化时,事情会变得更加复杂。当同一服务的两个实例 运行 添加必须以原子方式完成,即计数器值存储在数据库中并且每个 docker 实例必须获取一个锁获取旧值,添加一个, return 给来电者并解锁。
当实例是同一台Linux机器上的进程时,我们使用共享内存来高效地锁定、读取、写入和解锁共享数据,并且性能被接受。然而,当我们使用 dockers 和数据库时,性能很低。结果还可以,就是性能低下
docker化属性实例之间执行上述操作的规范方式是什么?容器化流程是否有 "shared memory" 功能?
您的案例数据库似乎有开销。您只需要一些具有共享键锁支持的分布式轻量级键值存储。以下是一些候选人:
- etcd (https://coreos.com/etcd)
- 领事 (https://www.consul.io, especially https://www.consul.io/docs/commands/lock.html)
- redis (http://redis.io)
--ipc
option of docker run
启用容器之间的共享内存访问:
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 提供了一些用法演示。
我也遇到过类似的问题,决定一探究竟。
唯一快速的是域套接字。所以我创建了一个小的 c 程序,它在共享卷 /sockets 上侦听域套接字。
在 gitlab.com 上查看关于 test 的工作概念。
counter.c
完成工作,监听 sockets/count.sock 和
收到数据报中的单个字符时:
- '+' :它将增加计数和 return 作为 u_int64_t
的计数
- '0' : 重置计数和 return 0 值作为 u_int64_t
- '=' : returns 计数为 u_int64_t,没有递增
- '-' : 计数减一,returns 计数为 u_int64_t
用于概念测试:
counter --interval=1000000
=> 启动计数器
test_counter --repeats=100000 stress
=> 向套接字发送 100k 请求
test_counter reset
将计数器设置为 0
test_counter --quiet --strip result
returns 没有 \n
的计数器
test_counter [count]
递增计数器和 returns 结果。
2 docker 个容器正在构建:count
& test
repo
为了测试,我在 gitlab-runner 中使用了 docker-compose.yml:
my-test:
image: dockregi.gioxa.com/dgoo2308/dockersocket:test
links:
- counter
entrypoint:
- /test_counter
- --repeats=${REPEATS}
- --timeout=200
- stress
volumes:
- './sockets:/sockets'
counter:
image: dockregi.gioxa.com/dgoo2308/dockersocket:count
volumes:
- './sockets:/sockets'
entrypoint:
- /counter
- --start_delay=100
- --interval=${TARGET}
开始测试:
mkdir sockets
docker-compose pull --parallel
docker-compose up -d
docker-compose scale my-test=$SCALE
概念测试成功!参见 test Job
洞穴猫:
对于客户端实现,客户端套接字不能绑定为自动,但需要给定一个名称,在测试中看到我们使用主机名,映射在同一个 /sockets 卷中。
他们也需要为每个客户不同。
我有一个简单的 C++ 服务(API 端点),每次调用 API 时都会增加一个计数器。当调用者将数据发布到 http://10.0.0.1/add 时,计数器必须递增 1,并且 return 计数器的值必须传递给调用者。
当服务 docker 化时,事情会变得更加复杂。当同一服务的两个实例 运行 添加必须以原子方式完成,即计数器值存储在数据库中并且每个 docker 实例必须获取一个锁获取旧值,添加一个, return 给来电者并解锁。
当实例是同一台Linux机器上的进程时,我们使用共享内存来高效地锁定、读取、写入和解锁共享数据,并且性能被接受。然而,当我们使用 dockers 和数据库时,性能很低。结果还可以,就是性能低下
docker化属性实例之间执行上述操作的规范方式是什么?容器化流程是否有 "shared memory" 功能?
您的案例数据库似乎有开销。您只需要一些具有共享键锁支持的分布式轻量级键值存储。以下是一些候选人:
- etcd (https://coreos.com/etcd)
- 领事 (https://www.consul.io, especially https://www.consul.io/docs/commands/lock.html)
- redis (http://redis.io)
--ipc
option of docker run
启用容器之间的共享内存访问:
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 containerBy 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 提供了一些用法演示。
我也遇到过类似的问题,决定一探究竟。
唯一快速的是域套接字。所以我创建了一个小的 c 程序,它在共享卷 /sockets 上侦听域套接字。
在 gitlab.com 上查看关于 test 的工作概念。
counter.c
完成工作,监听 sockets/count.sock 和
收到数据报中的单个字符时:
- '+' :它将增加计数和 return 作为 u_int64_t 的计数
- '0' : 重置计数和 return 0 值作为 u_int64_t
- '=' : returns 计数为 u_int64_t,没有递增
- '-' : 计数减一,returns 计数为 u_int64_t
用于概念测试:
counter --interval=1000000
=> 启动计数器test_counter --repeats=100000 stress
=> 向套接字发送 100k 请求test_counter reset
将计数器设置为 0test_counter --quiet --strip result
returns 没有\n
的计数器
test_counter [count]
递增计数器和 returns 结果。
2 docker 个容器正在构建:count
& test
repo
为了测试,我在 gitlab-runner 中使用了 docker-compose.yml:
my-test:
image: dockregi.gioxa.com/dgoo2308/dockersocket:test
links:
- counter
entrypoint:
- /test_counter
- --repeats=${REPEATS}
- --timeout=200
- stress
volumes:
- './sockets:/sockets'
counter:
image: dockregi.gioxa.com/dgoo2308/dockersocket:count
volumes:
- './sockets:/sockets'
entrypoint:
- /counter
- --start_delay=100
- --interval=${TARGET}
开始测试:
mkdir sockets
docker-compose pull --parallel
docker-compose up -d
docker-compose scale my-test=$SCALE
概念测试成功!参见 test Job
洞穴猫:
对于客户端实现,客户端套接字不能绑定为自动,但需要给定一个名称,在测试中看到我们使用主机名,映射在同一个 /sockets 卷中。 他们也需要为每个客户不同。