Estou investigando o impacto da memória ao conteinerizar dois processos que dependem do mesmo objeto compartilhado. Minha principal dúvida é se o objeto compartilhado será carregado na memória duas vezes ou não.
Essa pergunta já foi feita antes, mas as respostas não eram completas e contradiziam meus experimentos. Vou citar o que já encontrei:
Carregamento de bibliotecas compartilhadas e uso de RAM --> Use -fPIC para seu .so
Os contêineres docker compartilham RAM para arquivos mapeados na memória da mesma camada, mas de uma imagem diferente? --> Sim, mas depende da sua configuração. Você pode provar isso verificando o dispositivo e o id do inode do objeto compartilhado carregado. Nenhuma indicação de qual configuração usar.
https://stackoverflow.com/questions/35863608/shared-library-in-containers --> Sim, depende do seu driver de armazenamento. Os drivers de armazenamento aufs, overlay ou overlay2 oferecem suporte a isso.
https://stackoverflow.com/questions/63145223/about-loading-dynamic-library-in-container --> Cada contêiner é sua própria unidade de execução. Nenhum compartilhamento ocorre. Contradizendo com o anterior.
Usei a seguinte configuração:
- camada base --> Contém o SO e dois objetos compartilhados (G e S - Pré-compilados usando -fPIC)
- camada dependsOnG --> Começa da base, contém o executável que depende apenas de G (pré-compilado)
- camada dependsOnGandS --> Começa da base, contém o executável que depende de G e S (pré-compilado)
Driver de armazenamento: Sobreposição
Abaixo você pode ver as informações de grep glib /proc/PID/maps. Os PIDs são os processos dos executáveis dentro do contêiner.
| /proc/17/maps:7efd3b630000-7efd41980000 | r-xp | 00000000 | 00:a2 | 16802420 | /app/libglib.so |
| /proc/17/maps:7efd41980000-7efd41b7f000 | ---p | 06350000 | 00:a2 | 16802420 | /app/libglib.so |
| /proc/17/maps:7efd41b7f000-7efd41b80000 | r--p | 0634f000 | 00:a2 | 16802420 | /app/libglib.so |
| /proc/17/maps:7efd41b80000-7efd41b81000 | rw-p | 06350000 | 00:a2 | 16802420 | /app/libglib.so |
| /proc/39/maps:7fca97208000-7fca9d558000 | r-xp | 00000000 | 00:bb | 16802420 | /app/libglib.so |
| /proc/39/maps:7fca9d558000-7fca9d757000 | ---p | 06350000 | 00:bb | 16802420 | /app/libglib.so |
| /proc/39/maps:7fca9d757000-7fca9d758000 | r--p | 0634f000 | 00:bb | 16802420 | /app/libglib.so |
| /proc/39/maps:7fca9d758000-7fca9d759000 | rw-p | 06350000 | 00:bb | 16802420 | /app/libglib.so |
Se eu interpretar o resultado corretamente, os dois processos visualizam arquivos completamente diferentes (o ID do dispositivo é diferente), portanto, o objeto compartilhado será carregado duas vezes na memória (parece consistente com o que vejo com o comando free).
De acordo com as informações que encontrei online, isso não deveria acontecer.
Tenho as seguintes perguntas:
- O objeto compartilhado deve ser carregado apenas uma vez?
- O driver de armazenamento de sobreposição suporta essa funcionalidade?
- Devo construir minhas imagens/contêineres de uma maneira diferente? (Fiz os mesmos experimentos usando volumes em vez de camadas comuns e, de fato, os arquivos eram idênticos, no entanto, não é bem isso que eu quero)
Desde já, obrigado!