MongoDB – Guia rápido

Saudações.

Esse tutorial é um guia rápido de instalação e uso do MongoDB, serviço de banco de dados baseado em documentos que não utiliza SQL (NO-SQL).

Pré-requisitos (constam em outros artigos aqui do blog):

  • Instalação do Linux (Debian ou Alpine);
  • Internet no servidor (sua VPS ou host);
  • Docker CE instalado (opcional);

1 – Sobre MongoDB

MongoDB é um programa de banco de dados orientado a documentos e com código disponível (source-available).

Opera como banco de dados NoSQL, ele utiliza documentos no estilo JSON (armazenados em um formato binário chamado BSON).

Permite esquemas opcionais, o que o torna flexível para gerenciar grandes volumes de dados não estruturados ou semi estruturados.

1.1 – Recursos

Recursos mais usados:

  • Consultas Ad-hoc (Ad-hoc Queries): Buscas por campos, intervalo, expressões regulares e funções JavaScript;
  • Indexação (Indexing): Permite criar índices primários e secundários em qualquer campo de um documento para otimizar a performance das consultas;
  • Replicação (Replication): Fornece alta disponibilidade através de conjuntos de réplicas (replica sets). Um conjunto tem um nó primário (para escritas e leituras por padrão) e um ou mais nós secundários (que copiam os dados), se o primário falha, um secundário é eleito automaticamente como novo primário;
  • Balanceamento de Carga (Load Balancing) – Sharding: Escala horizontalmente distribuindo dados entre múltiplos servidores (shards);
  • Armazenamento de Arquivos (GridFS): Permite usar o MongoDB como um sistema de arquivos, chamado GridFS, que divide arquivos em partes (chunks) e os armazena como documentos separados;
  • Aggregation (Agregação): Oferece três formas de processar dados e obter resultados agregados (semelhante a GROUP BY do SQL):
    • Aggregation Pipeline (recomendada, melhor performance).
    • Map-Reduce (obsoleto desde a versão 5.0).
    • Métodos de propósito único.
  • Coleções com Tamanho Fixo (Capped Collections): Coleções que mantêm a ordem de inserção e, ao atingir o tamanho limite, comportam-se como uma fila circular (os documentos mais antigos são sobrescritos), útil para logs ou dados temporários.
  • Transações (Transactions): Suporta transações ACID de múltiplos documentos, garantindo atomicidade, consistência, isolamento e durabilidade mesmo em operações que envolvem vários documentos ou coleções.

1.2 – Exigências

O MongoDB não roda em qualquer servidor. Principais exigências para execução:

  • em processadores x86_64 (AMD64) requer conjunto de Instruções AVX ;
  • Em processadores ARM requer instruções ARMv8.2-A;
  • A versão 8 não funciona no kernel linux 6.19 por conta do TCMalloc;
  • Pode exigir a desativação do CET em kernel superior a 6.19:
    • export GLIBC_TUNABLES=”glibc.cpu.hwcaps=-SHSTK”
  • Pode apresentar problemas com sistema de arquivos EXT4;

2 – Ajustes no sistema

O MongoDB requer alguns ajustes no sistema para evitar problemas de performance. Esses ajustes são opcionais mas altamente recomendados.

2.1 – Ajustes básicos

Você deve, previamente:

  • Data/hora do servidor finamente sincronizada com NTP/NTS
  • Manter a coerência entre o IP do servidor e o nome de DNS (real ou fictício) no arquivo /etc/hosts
  • Possuir um DNS funcionando bem e rápido, configure o IP em /etc/resolv.conf

2.2 – Ajustes no sysfs

É necessário desativar o “transparent hugepages” pois ele tentará fazer agregação de páginas na memória RAM e isso pode interromper o Valkey por alguns micro-ssegundos.

Bash
# - Criar manifesto de preenchimento de configs durenate o boot:
(
    echo 'w /sys/kernel/mm/transparent_hugepage/enabled  - - - - never';
) > /etc/tmpfiles.d/transp-hugepage-disable.conf;

# Desativar hugepages transparente imediatamente
echo never > /sys/kernel/mm/transparent_hugepage/enabled;

2.3 – Ajustes no sysctl

Esses ajustes mudam o comportamento padrão do Kernel Linux.

Bash
# Gestao de overcommit de memoria
echo  "vm.overcommit_memory=1"     > /etc/sysctl.d/076-ram-overcommit.conf;

# Aumentar capacidades de rede do protocolo TCP
(
    echo  "net.core.rmem_default=31457280";
    echo  "net.core.wmem_default=31457280";
    echo  "net.core.rmem_max=134217728";
    echo  "net.core.wmem_max=134217728";
    echo  "net.core.netdev_max_backlog=250000";
    echo  "net.core.optmem_max=33554432";
    echo  "net.core.default_qdisc=fq";
    echo  "net.core.somaxconn=65535";
) > /etc/sysctl.d/051-net-core.conf;

# Aumentar buffers e acelerar o inicio das conexoes
(
    echo "net.ipv4.tcp_sack = 1";
    echo "net.ipv4.tcp_timestamps = 1";
    echo "net.ipv4.tcp_low_latency = 1";
    echo "net.ipv4.tcp_max_syn_backlog = 65535";
    echo "net.ipv4.tcp_rmem = 4096 87380 67108864";
    echo "net.ipv4.tcp_wmem = 4096 65536 67108864";
    echo "net.ipv4.tcp_mem = 6672016 6682016 7185248";
    echo "net.ipv4.tcp_congestion_control=htcp";
    echo "net.ipv4.tcp_mtu_probing=1";
    echo "net.ipv4.tcp_moderate_rcvbuf =1";
    echo "net.ipv4.tcp_no_metrics_save = 1";
)  >  /etc/sysctl.d/052-net-tcp-ipv4.conf;

Aplicar alterações de sysctl:

Bash
# Comando (sysctl -p) requer tudo em um unico arquivo:
(
    echo "# NAO EDITAR";
    echo "# Gerado automaticamente via:";
    echo "# cat /etc/sysctl.d/*.conf > /etc/sysctl.conf";
    echo;
    cat /etc/sysctl.d/*.conf;
    echo;
) > /etc/sysctl.conf;

# Aplicar imediatamente:
sysctl -q --system  2>/dev/null;
sysctl -q -p        2>/dev/null;

3 – MongoDB no Debian (host)

Esse capítulo aborda o uso do MongoDB direto no HOST em um servidor Debian (VPS, VM).

3.1 – Preparando o Debian

Bash
# Atualizar sistema local
apt  -y  update;
apt  -y  upgrade;
apt  -y  dist-upgrade;
apt  -y  autoremove;

# Instalar ferramentas
apt  -y install ca-certificates;
apt  -y install gnupg;
apt  -y install curl;
apt  -y install wget;

3.2 – Instalando via repositório

Bash
# Instalar MongoDB

# Adicionar chave do repositorio mongodb-org
curl \
    -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \
    gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor;

# Adicionar link do repositorio mongodb-org
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] http://repo.mongodb.org/apt/debian bookworm/mongodb-org/8.0 main" | tee /etc/apt/sources.list.d/mongodb-org-8.0.list;

# Atualizar indice
apt -y update;

# Instalar mongodb-org (servidor mongod)
apt -y install mongodb-org;

# Ativar servico durante o boot:
systemctl enable mongod;

# Ativar imediatamente:
systemctl start mongod;

3.3 – Alternativa: Instalando manualmente usando pacote DEB

Bash
# Instalar MongoDB
# - Arquitetura da CPU
arch=$(dpkg --print-architecture);
# - Variaveis
BASEURL="https://repo.mongodb.org/apt/debian/dists/bookworm/mongodb-org";
VERSIONS="8.2";
VERSIONF="8.2.7";
PACKAGE="mongodb-org-server_${VERSIONF}_${arch}.deb";

# - Baixar
URL="$BASEURL/$VERSIONS/main/binary-amd64/$PACKAGE";
wget $URL -c -O /tmp/$PACKAGE;

# - Instalar
dpkg -i /tmp/$PACKAGE;

# Ativar servico durante o boot:
systemctl enable mongod;

# Ativar imediatamente:
systemctl start mongod;

4 – MongoDB no Alpine

O suporte a Alpine foi removido. É possível usar apenas o MongoDB-Tools.

Bash
# Atualizar sistema local
apk  update;
apk  upgrade;

# Instalar o MongoDB-tools
apk  add  mongodb-tools;

5 – Configurações básicas

Configuração padrão:

Arquivo: /etc/mongod.conf
# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb
#  engine:
#  wiredTiger:

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# network interfaces
net:
  port: 27017
  bindIp: 127.0.0.1


# how the process runs
processManagement:
  timeZoneInfo: /usr/share/zoneinfo

#security:

#operationProfiling:

#replication:

#sharding:

## Enterprise-Only Options:

#auditLog:

6 – Rodando MongoDB no Docker

Vamos explorar o uso mais difundido do Mongo que é em stacks de aplicativos que o utilizam como banco de dados.

6.1 – Rede Docker

Padrão “network_public” que costumo usar nos meus tutoriais:

Bash
# Rede de containers
docker network create network_public \
    -d bridge \
    -o com.docker.network.bridge.name=br-net-public \
    -o com.docker.network.driver.mtu=1500 \
    -o com.docker.network.bridge.gateway_mode_ipv4=nat-unprotected \
    --subnet 10.249.0.0/16 \
    --gateway 10.249.255.254;

6.2 – Container do MongoDB

Criando container optimizado com restrição de recursos:

Bash
# Rodar MonboDB em container
# - Limite de RAM: 1024 MB (1 GB)
# - Reserva de RAM: 512 MB

# Pasta para o volume
    DATADIR=/storage/mongodb;
    mkdir -p $DATADIR;

# Baixar imagem
    docker pull mongo:8.2.7;

# Renovar/rodar
    docker rm -f mongodb 2>/dev/null;
    #    --read-only
    docker run \
        -d --restart=always \
        --name mongodb \
        -h mongodb.intranet.br \
        \
        --tmpfs /run:rw,noexec,nosuid,size=4m \
        --tmpfs /tmp:rw,noexec,nosuid,size=4m \
        \
        --cpus=1 \
        --memory=1024m \
        --memory-swap=1024m \
        --memory-reservation=512m \
        --oom-score-adj=-500 \
        \
        --ulimit nofile=1048576:1048576 \
        --ulimit memlock=-1 \
        --sysctl net.core.somaxconn=16384 \
        \
        --network network_public \
        \
        -v $DATADIR:/data \
        \
        -e MONGO_INITDB_ROOT_USERNAME=root \
        -e MONGO_INITDB_ROOT_PASSWORD=tulipanosql \
        \
        mongo:8.2.7;

Analisando e rodando testes no container:

Bash
# Analisando
    docker inspect  mongodb;
    docker diff     mongodb;
    docker logs     mongodb;
    docker logs -f  mongodb;

# Testar se o container está funcionando:
    #docker exec -it mongodb valkey-cli -p 6379 ping;

# Obter terminal valkey-cli:
    #docker exec -it mongodb valkey-cli;

6.2 – Container do Mongo Express

Vamos rodar o Mongo Express, um sistema de gerenciamento via interface Web para facilitar o acesso ao MongoDB:

Bash
# Rodar Monbo-Express em container
# - Limite de RAM: 1024 MB (1 GB)
# - Reserva de RAM: 64 MB

# Baixar imagem
    docker pull mongo-express:1.0.2-20-alpine3.19;

# Renovar/rodar
    docker rm -f mongo-express 2>/dev/null;
    docker run \
        -d --restart=always \
        --name mongo-express \
        -h mongo-express.intranet.br \
        \
        --tmpfs /run:rw,noexec,nosuid,size=16m \
        --read-only \
        \
        --cpus=1 \
        --memory=1024m \
        --memory-swap=1024m \
        --memory-reservation=64m \
        --oom-score-adj=-500 \
        \
        --ulimit nofile=1048576:1048576 \
        --ulimit memlock=-1 \
        --sysctl net.core.somaxconn=16384 \
        \
        --network network_public \
        -p 8081:8081 \
        \
        -e ME_CONFIG_MONGODB_URL=mongodb://root:tulipanosql@mongodb:27017/ \
        -e ME_CONFIG_BASICAUTH_ENABLED=true \
        -e ME_CONFIG_BASICAUTH_USERNAME=admin \
        -e ME_CONFIG_BASICAUTH_PASSWORD=tulipanosql \
        \
        mongo-express:1.0.2-20-alpine3.19;

Analisando e rodando testes no container “mongo-express“:

Bash
# Analisando
    docker inspect  mongo-express;
    docker diff     mongo-express;
    docker logs     mongo-express;
    docker logs -f  mongo-express;

.

A rapidez, que é uma virtude,
gera um vício, que é a pressa.
Gregório Marañón

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com