Linux 如何自动更新Docker实例之间共享的计数器 我有一个简单的C++服务(API端点),每次调用API时都会增加计数器。当调用者向计数器发送数据时,计数器必须递增1,并将计数器的值返回给调用者
当服务被停靠时,事情变得更加复杂。当同一服务的两个实例运行时,必须以原子方式进行添加,即计数器值存储在数据库中,每个docker实例必须获取锁获取旧值,添加一个,返回调用方并解锁 当实例是同一台Linux机器上的进程时,我们使用共享内存来高效地锁定、读取、写入和解锁共享数据,性能得到了认可。然而,当我们使用dockers和数据库时,性能很低。结果正常,但性能较低Linux 如何自动更新Docker实例之间共享的计数器 我有一个简单的C++服务(API端点),每次调用API时都会增加计数器。当调用者向计数器发送数据时,计数器必须递增1,并将计数器的值返回给调用者,linux,performance,docker,shared-memory,Linux,Performance,Docker,Shared Memory,当服务被停靠时,事情变得更加复杂。当同一服务的两个实例运行时,必须以原子方式进行添加,即计数器值存储在数据库中,每个docker实例必须获取锁获取旧值,添加一个,返回调用方并解锁 当实例是同一台Linux机器上的进程时,我们使用共享内存来高效地锁定、读取、写入和解锁共享数据,性能得到了认可。然而,当我们使用dockers和数据库时,性能很低。结果正常,但性能较低 停靠属性实例之间执行上述操作的规范方式是什么?容器化进程是否有“共享内存”功能 您的案例数据库似乎需要开销。您只需要一些具有共享密钥锁
停靠属性实例之间执行上述操作的规范方式是什么?容器化进程是否有“共享内存”功能 您的案例数据库似乎需要开销。您只需要一些具有共享密钥锁支持的分布式轻量级密钥值存储。以下是一些候选人:
- etcd()
- 领事(尤其是)
- redis()
--ipc=”“
:设置容器的ipc模式
“容器:”
:重用另一个容器的IPC命名空间
“主机”
:在容器内使用主机的IPC命名空间
默认情况下,所有容器都启用了IPC命名空间
IPC(POSIX/SysV IPC)命名空间提供了命名共享
内存段、信号量和消息队列
共享内存段用于加速进程间通信
以内存速度通信,而不是通过管道或
网络堆栈。共享内存通常由数据库和应用程序使用
定制(通常为C/OpenMPI、C++/使用boost库)高
科学计算和金融的性能应用
服务业。如果将这些类型的应用程序分为
多个容器,您可能需要共享
容器
提供了一些关于其用法的演示。我遇到了一个类似的问题,决定从头开始 唯一快速发展的是域套接字。所以我创建了一个小型c程序,它在一个域套接字上侦听,在一个共享卷/套接字上侦听 请参阅gitlab.com上的工作概念
counter.c
执行任务,监听sockets/count.sock并
在接收到数据报中的单个字符时:
- “+”:它将增加计数并将计数作为u_int64_t返回
- “0”:重置计数并将0值作为u\u int64\t返回
- “=”:以u_int64_t的形式返回计数,不带增量
- “-”:使用1递减计数,并将计数作为u_int64_t返回
=>启动计数器计数器--interval=1000000
=>向插座发送100k请求测试\u计数器--重复=100000个应力
将计数器设置为0测试\计数器重置
返回不带test\u计数器——quiet——strip result
的计数器\n
递增计数器并返回结果test\u counter[count]
count
&test
为了进行测试,我在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
概念测试成功!!!看
空腔:
对于客户端实现,客户端套接字不能绑定为自动,但需要指定一个名称,请参阅测试中的“我们使用主机名”,映射到同一/sockets卷中。
此外,它们对于每个客户端都需要不同。concur.io取决于进程和KV存储之间的http通信。这将引入延迟,不是吗?通常来说,与共享内存和单个主机相比,是的,但实际上,延迟远低于使用数据库。与@Vyacheslav的想法相关,您可以使用容器来存储数据。建立一个docker网络,将每个容器放在同一个网络上,以便于访问和服务发现。是的,忘了它,但它也相对轻量级。添加到答案中。您是否需要始终准确计算请求数?让每个容器跟踪本地,然后让另一个进程偶尔聚合它们(例如,作为Prometheus或Grafana度量)可能更容易。任何时候都要精确计数,即我不能依赖“本地”数据。让我们假设这个计数器是一个银行帐户的更新,即我不能定期更新钱。你在这里问的可能是一个简化的情况。它在规模上应该如何表现?@ovanes,实际上这就是问题所在。多个进程必须共享一个公共源,并且还应根据源的值进行同步。为了扩展,共享值的最佳/规范方法是什么?然后可以使用x86指令fetch和add来增加计数器。这是否意味着docker映像位于同一主机(同一内核)上?。如果docker容器位于不同的机器上,它是否工作?共享内存仅适用于同一机器上的容器。如果必须同步在不同计算机上运行的容器,则无法避免网络访问。这是否要求docker映像位于同一主机上?域套接字意味着我们在同一个“kermel”是的,它需要在同一个主机上这在正常情况下是不可能的。生产中的容器将位于不同的主机中。