Valkey ultra rápido

Saudações.

Esse tutorial consolida minhas descobertas ao implementar o Valkey em operações de alta velocidade de latência sub-microssegundo.

A maioria desses ajustes melhoram quaisquer softwares extraindo o máximo do hardware.

Após alternar entre Redis e Valkey, descobri que o Valkey vence, especificamente a versão Valkey 9.1.

Melhorias técnicas que usei para ultra velocidade:

  • Não usar Redis, vantagens do Valkey:
    • Ganho de processamento, 8% mais throughput, 22% menor P99;
    • Memory Access Amortization (built-in), 10x em acesso aleatório;
    • Desabilitar persistência (save “”, appendonly no) Elimina forks e I/O de disco;
    • Melhor para ambientes compartilhados é Valkey 8.1.7 (stable de 6 mai 2026);
      • hashtable reduz o uso de memória, 20 bytes por par chave-valor;
      • I/O threads aumentam o throughput em 10% para SET e 22% para GET;
    • Para hardware modernos, prefira o Valkey 9.1 (meu caso);
      • Prefetching de memória no pipeline (40%+);
      • Usa instrução SIMD para BITCOUNT e HyperLogLog (200%+);
  • THP (Transparent Hugepages) jamais, elimina latency spikes de compactação;
  • KSM (Kernel Same Page) nem sonhando, mesmo problema do THP;
  • CPU governor em modo performance, elimina latência de frequency scaling, CPU fica sempre no clock máximo;
  • Desabilitar C-States (estados de inatividade da CPU) na BIOS/UEFI, eles fazem economia de energia ao induzir dormência na CPU;
  • Cpuset no processo, ele fica pinado em núcleos específicos, isso ajuda a rodar 100% na memória com Cache (L1/L2/L3) enriquecido e persistente;
  • SYS_NICE, permite renice -20, o núcleo fica dedicado ao processo, jamais é interrompido por outro programa;
  • Aplicar escalonador Real‑Time (RT) após dedicar os núcleos do processo Valkey;
  • Swap Off (vm.swappiness=0), proibir o processo de cair na swap (garante RAM locked), por garantia remova a memória swap do /etc/fstab;
  • Memlock=-1 e IPC_LOCK, permite mlock, evita swap (latência de swapping);
  • Overcommit de memória ativado, agiliza a liberação de memória virtual;
  • Softwares mínimos: remova todos os arquivos, desinstale todos os pacotes que você não usa, mesmo existindo sem usar eles podem ser lidos e ocupar memória buffer/shared e causa pressão de memória, que acaba por sujar a cache L1/L2/L3 da CPU;
  • TCP-Backlog e somaxconn elevado acima do padrão, aceita conexões sem atraso;
  • Pipeline ativado no client (requer suporte na biblioteca), amortiza roundtrips de rede a cada comando;
  • Quantos núcleos de CPU tem o servidor onde você vai rodar o Valkey? Posso te passar o número exato recomendado para o parâmetro io-threads com base no seu hardware.
  • x
  • Lazyfree para que a expiração de chaves aconteça em paralelo sem interromper a thread principal;
  • Acesso pela loopback (127.0.0.1 ou ::1), MTU máximo;
  • Sem VM e sem container, elimina NAT, veth, buffers de bridge, buffers de rede;
  • Sem autenticação e sem criptografia, a camada TLS induz latência de negociação e latência de transformação de dados (codificar e decodificar), prefira operar em intranet segura em vez de trafegar pela Internet selvagem;
  • Se o acesso for feito pela rede:
    • Colocar uma placa de rede PCI dedicada de preferência a 100g (não se trata de banda e sim da latência, 100x menor que 1g);
    • IP dedicado e fixo;
    • MTU jumbo-frame;
    • IRQs pinadas (sem irqbalance) e sem RPS, colocar as IRQs e o processo no mesmo NUMA node do processo Valkey mas não nos mesmos núcleos (4 núcleos para a rede [0-3] e 4 núcleos para o Valkey [4-7];
    • Tuning de Buffers de Rede, ajustar parâmetros como rmem_max, wmem_max, tcp_rmem e tcp_wmem;

É uma quantidade substancial de ajustes, quanto mais próximo deles você chegar mais rápido será seu servidor Redis/Valkey.

Para eu não repetir tunings gerais aqui, recomendo os tutoriais abaixo:

1 – Tuning Rápido

Ajustes de SYSCTL:

Bash
# Garantia na alocacao de memoria virtual
# - Para aplicar durante o boot:
echo  "vm.overcommit_memory = 1"  >  "/etc/sysctl.d/075-overcommit-memory.conf";
# - Aplicar imediatamente:
sysctl -w "vm.overcommit_memory=1";

# Liberar mais RAM para aceleração de rede
(
    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 capacidades de rede do protocolo TCP
(
    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;

# Ativar TCP-Fast-Open
(
    echo  "net.ipv4.tcp_fastopen=3";
)  >  /etc/sysctl.d/053-tcp-fast-open.conf;

# Ativar TCP-KeepAlive
(
    echo  "net.ipv4.tcp_keepalive_probes=9";
    echo  "net.ipv4.tcp_keepalive_intvl=75";
    echo  "net.ipv4.tcp_keepalive_time=7200";
)  >  /etc/sysctl.d/054-tcp-keepalive.conf;

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

Sem HugePages Transparente:

Bash
# Desabilitar THP
(
    echo 'w /sys/kernel/mm/transparent_hugepage/enabled - - - - never';
    echo 'w /sys/kernel/mm/transparent_hugepage/defrag - - - - never';
) > /etc/tmpfiles.d/disable-thp.conf;

# Aplicar imediatamente:
systemd-tmpfiles --create /etc/tmpfiles.d/disable-thp.conf;

Sem SWAP:

Bash
# Nao usar SWAP enquanto houver memoria RAM livre
# - Para aplicar durante o boot:
echo  "vm.swappiness=0"  >  /etc/sysctl.d/073-swappiness.conf;
# - Aplicar imediatamente:
sysctl -w "vm.swappiness=0";

# - Reiniciar swap (opcional):
swapoff -a; # Limpar e desligar
swapon  -a; # Ligar.

CPU em modo performance (somente em baremetal):

Bash
# CPU em modo performance
# Colocar no script de rc-local durante o boot
for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do
  echo performance | sudo tee "$f" >/dev/null;
done;

2 – Comparativos

Comparando Redis e Valkey em diferentes versões.

VersãoRPS (pico)P99 lat.Destaque
Redis 7.x / Valkey 7.2~360K~2.5msBaseline, single-threaded
Valkey 8.01.19M~1.1msI/O threading multi-core (+230% RPS)
Redis 8.0~730K~0.99msAdicionou JSON/vectors/search nativos
Valkey 8.1~1.0M0.80msNovo hashtable, +22% GET, +10% pipeline
Valkey 9.0~1.4M~0.70msPipeline prefetch (+40%), zero-copy, SIMD
Valkey 9.1.02.1M~0.62msNovo I/O threading model — escolha ideal

Resultado dos testes:

%%{init: {'theme': 'base', 'themeVariables': {'background': 'transparent', 'xyChart': {'backgroundColor': 'transparent', 'plotColorPalette': '#1e3a5f'}}}}%%
xychart-beta
    title "Throughput — Requisições por segundo (maior = melhor)"
    x-axis ["Redis 7.x", "Valkey 7.2", "Valkey 8.0", "Redis 8.0", "Valkey 8.1", "Valkey 9.0", "Valkey 9.1"]
    y-axis "RPS" 0 --> 2200
    bar [380, 360, 1190, 730, 1000, 1400, 2100]
%%{init: {'theme': 'base', 'themeVariables': {'background': 'transparent', 'xyChart': {'backgroundColor': 'transparent', 'plotColorPalette': '#1e3a5f'}}}}%%
xychart-beta
    title "Latência P99 — Milissegundos (menor = melhor)"
    x-axis ["Redis 7.x", "Valkey 7.2", "Valkey 8.0", "Redis 8.0", "Valkey 8.1", "Valkey 9.1"]
    y-axis "ms" 0 --> 3
    bar [2.5, 2.5, 1.1, 0.99, 0.80, 0.62]

3 – Rodando direto no Host

A primeira escolha é rodar o Valkey direto no host (sem container e sem cgroup), de preferência em um hardware bare-metal (sem máquina virtual, direto no hardware).

Usando o systemd num servidor com 8 núcleos [0-7], vou dedicar os núcleos [4-7] para ficarem dedicados ao Valkey. Qualquer software que tentar usar os núcleos de 4 a 7 se darão muito mal pois o tempo de CPU desses núcleos será ultra-prioritário para o Valkey.

Vou rodar esse processo na porta TCP 9991.

O Debian 13 até o momento em que escrevo esse tutorial possui a versão 8.1.1 do Valkey. Não é a ideal (9.1) mas vai servir de exemplo.

3.1 – Instalando Valkey

Instalando:

Bash
# Atualizar base local
apt  -y  update;
apt  -y  upgrade;
apt  -y  dist-upgrade;
apt  -y  full-upgrade;

# Instalar ambiente Valkey
apt  -y  install  valkey-server;
apt  -y  install  valkey-tools;
apt  -y  install  valkey-sentinel;

# Criar links para usar como se fosse o Redis
ln  -sf  $(which valkey-benchmark)   /usr/local/bin/redis-benchmark;
ln  -sf  $(which valkey-check-aof)   /usr/local/bin/redis-check-aof;
ln  -sf  $(which valkey-sentinel)    /usr/local/bin/redis-sentinel;
ln  -sf  $(which valkey-server)      /usr/local/bin/redis-server;
ln  -sf  $(which valkey-cli)         /usr/local/bin/redis-cli;

# Desativar servico nativo (vamos usar unity propria)
systemctl  disable  valkey-sentinel;
systemctl  disable  valkey-server;
systemctl  stop     valkey-sentinel;
systemctl  stop     valkey-server;

3.2 – Configuração Valkey

Configuração em /etc/valkey/valkey-ultra-fast.conf

/etc/valkey/valkey-ultra-fast.conf
# VALKEY 9.1.0 via SYSTEMD - LOOPBACK 127.0.0.1:9991 - MINIMA LATENCIA

# Rede
bind                 127.0.0.1
port                 9991
tcp-backlog          65535
timeout              0
tcp-keepalive        60
protected-mode       no

# Unix socket opcional (latencia ~30µs vs ~200µs TCP — cliente mesmo host)
unixsocket           /run/valkey/valkey.sock
unixsocketperm       770

# Processo (integração systemd)
#   systemd gerencia o processo
daemonize            no
#   ativa sd_notify (READY=1 + watchdog)
supervised           systemd
loglevel             warning
logfile              /var/log/valkey/valkey.log

# I/O Threading (4 cores disponíveis: 1 main + 3 I/O threads)
#   cores 5, 6, 7 para I/O; core 4 = main thread
io-threads           3
io-threads-do-reads  yes

# Persistência DESABILITADA (mínima latencia)
save                 ""
appendonly           no

# Memoria
maxmemory                   1gb
maxmemory-policy            allkeys-lru
maxmemory-samples           10

# Lazy free - DEL/EXPIRE/eviction sem bloquear main thread
lazyfree-lazy-eviction      yes
lazyfree-lazy-expire        yes
lazyfree-lazy-server-del    yes
lazyfree-lazy-user-del      yes
lazyfree-lazy-user-flush    yes

# Tuning do event loop
hz                          100
dynamic-hz                  yes
# rehashing e defrag  causam micro-pauses
activerehashing             no
activedefrag                no

# Clientes e limites
maxclients                  10000

# Diagnostico de latência
latency-tracking            yes
#   loggar eventos > 1ms
latency-monitor-threshold     1
slowlog-log-slower-than     500
slowlog-max-len             256

# Desabilitar recursos nao usados
cluster-enabled              no
replica-read-only            no

3.3 – Unit SystemD

Unit do systemd em /etc/systemd/system/valkey-ultra-fast.service

/etc/systemd/system/valkey-ultra-fast.service
[Unit]
Description=Valkey - Ultra Fast Real-Time In-Memory Store
Documentation=https://valkey.io/topics/
After=network.target local-fs.target
Wants=network.target

[Service]
Type=notify
NotifyAccess=main
User=valkey
Group=valkey
# PROCESSO
ExecStart=/usr/bin/valkey-server /etc/valkey/valkey-ultra-fast.conf \
          --supervised systemd \
          --pidfile /run/valkey/valkey.pid
ExecStop=/usr/bin/valkey-cli -p 9991 SHUTDOWN NOSAVE
ExecReload=/bin/kill -s HUP $MAINPID
PIDFile=/run/valkey/valkey.pid

# REINICIO E WATCHDOG
# systemd mata e reinicia se Valkey travar
Restart=always
RestartSec=500ms
TimeoutStartSec=3s
TimeoutStopSec=5s
#-WatchdogSec=60s

# CPU - ISOLAMENTO E AFINIDADE (requer minimo 8 nucleos para enxergar 4-7)
CPUAffinity=4 5 6 7

# AGENDAMENTO REAL-TIME - SCHED_FIFO
#   SCHED_FIFO: processo RT não é preemptado por NENHUM processo normal.
#   Um processo SCHED_FIFO prio 90 está ACIMA de qualquer nice -20 (CFS).
#   Hierarquia: SCHED_FIFO 99 (watchdog kernel) > SCHED_FIFO 90 (Valkey)
#               > SCHED_OTHER nice -20 (qualquer processo normal)
#   threads filhas (I/O threads) herdam SCHED_FIFO
#   90 = máximo seguro; 99 reservado ao watchdog kernel
#  -20 = redundante com RT, mas definido para clareza
CPUSchedulingPolicy=fifo
CPUSchedulingPriority=90
CPUSchedulingResetOnFork=no
Nice=-20

# MEMORIA - LOCK TOTAL NA RAM
#   mlockall(MCL_CURRENT|MCL_FUTURE): TODO o address space do processo
#   e' fixado na RAM. Nenhuma pagina pode ser movida para swap.
 #  -1000 = OOM killer NUNCA mata o Valkey
OOMScoreAdjust=-1000

# I/O — SCHEDULING REAL-TIME
#   0 = mais alta prioridade de I/O RT
IOSchedulingClass=realtime
IOSchedulingPriority=0

# LIMITES DE RECURSOS
#   file descriptors
#   sem limite de processos/threads
#   core dumps ilimitados (debug)
#   necessário para LockMemory=yes funcionar
#   permite ao user valkey usar RT priority até 99
LimitNOFILE=1000000
LimitNPROC=infinity
LimitCORE=infinity
LimitMEMLOCK=infinity
LimitRTPRIO=99

# CAPABILITIES (rodar como user não-root com poderes RT + mlock)
#   AmbientCapabilities: preservadas quando o processo roda como não-root
#   via exec(). O systemd injeta esses caps no processo filho.
#   CAP_SYS_NICE     -> nice negativo + SCHED_FIFO como user
#   CAP_IPC_LOCK     -> mlockall() sem ser root
#   CAP_SYS_RESOURCE -> ultrapassar limites de rlimit quando necessário
AmbientCapabilities=CAP_SYS_NICE CAP_IPC_LOCK CAP_SYS_RESOURCE
CapabilityBoundingSet=CAP_SYS_NICE CAP_IPC_LOCK CAP_SYS_RESOURCE

# CRITICO: NoNewPrivileges=no e' OBRIGATORIO para AmbientCapabilities
#   + RT scheduling funcionarem juntos como user não-root.
NoNewPrivileges=no

# SEGURANÇA (minima compativel com RT + capabilities)
#   /usr /boot /etc somente-leitura
PrivateTmp=yes
ProtectSystem=full
ProtectHome=yes
ReadWritePaths=/var/lib/valkey /var/log/valkey /run/valkey

# DIRETORIOS GERENCIADOS PELO SYSTEMD
# cria /run/valkey automaticamente
# /var/lib/valkey
# /var/log/valkey
RuntimeDirectory=valkey
RuntimeDirectoryMode=0750
StateDirectory=valkey
StateDirectoryMode=0750
LogsDirectory=valkey
LogsDirectoryMode=0750
WorkingDirectory=/var/lib/valkey

[Install]
WantedBy=multi-user.target

3.4 – Concluindo preparativos

Preparar arquivos e diretórios:

Bash
# Garantir diretorios e arquivos com permissao para o usuario 'valkey'
# - Diretorios
mkdir -p /etc/valkey;
mkdir -p /run/valkey;
mkdir -p /var/lib/valkey;
mkdir -p /var/log/valkey;

# - Propriedade
chown -R valkey:valkey  /etc/valkey;
chown -R valkey:valkey  /run/valkey;
chown -R valkey:valkey  /var/lib/valkey;
chown -R valkey:valkey  /var/log/valkey;

# - Acesso exclusivo
chmod -R 0750           /etc/valkey;
chmod -R 0750           /run/valkey;
chmod -R 0750           /var/lib/valkey;
chmod -R 0750           /var/log/valkey;

3.5 – Ativar serviço

Ativar serviço:

Bash
# Recarregar configuraçoes do systemd
systemctl   daemon-reload;

# Habilitar na inicialização e iniciar agora
#systemctl enable --now valkey-ultra-fast.service;
systemctl   enable  valkey-ultra-fast.service;
systemctl   stop    valkey-ultra-fast.service;
systemctl   start   valkey-ultra-fast.service;

# Verificar status
systemctl   status  valkey-ultra-fast.service;

# Verificar logs
#journalctl -u  valkey-ultra-fast.service -f;
journalctl  -u     valkey-ultra-fast.service;
journalctl  -xeu   valkey-ultra-fast.service

3.6 – Testar performance

Validação e benchmark pós-deploy:

Bash
# Verificar que está rodando na porta correta
valkey-cli -p 9991 ping;
    # → PONG

# Medir latência intrínseca do sistema (rode NO servidor)
valkey-cli -p 9991 --intrinsic-latency 100;
    # Max latency so far: 1 microseconds.
    # Max latency so far: 7 microseconds.
    # Max latency so far: 14 microseconds.
    # Max latency so far: 33 microseconds.
    # Max latency so far: 91 microseconds.
    # Max latency so far: 887 microseconds.
    # Max latency so far: 1020 microseconds.
    # Max latency so far: 1076 microseconds.

# Benchmark de latencia e throughput
valkey-cli -p 9991 --latency -i 1;
    # min: 0, max: 1, avg: 0.09 (813 samples)

# Benchmark completo (ajuste -c conforme seus clientes)
valkey-benchmark \
    -h 127.0.0.1 -p 9991 \
    -t set,get \
    -n 1000000 \
    -c 100 \
    -P 10 \
    --threads 4 -q;
    # SET: 796812.75 requests per second, p50=1.095 msec                    
    # GET: 991080.31 requests per second, p50=0.735 msec  

# Verificar I/O threads ativos
valkey-cli \
    -p 9991 INFO \
    | grep -E "io_threads|connected_clients|used_memory_human";

# Monitorar latência em tempo real
valkey-cli -p 9991 LATENCY LATEST;

# Checar configurações aplicadas e informacoes
valkey-cli -p 9991 CONFIG GET io-threads;
valkey-cli -p 9991 CONFIG GET bind;
valkey-cli -p 9991 CONFIG GET hz;
valkey-cli -p 9991 INFO memory;
valkey-cli -p 9991 INFO persistence;
valkey-cli -p 9991 LATENCY DOCTOR;
valkey-cli -p 9991 SLOWLOG GET 20;

Em ambiente simples, esse serviço deve alcançar facilmente 900 mil requisições por segundo e operar com 0.5 ms (500 microssegundos).

4 – Valkey rápido no Docker

Agora pisamos num solo arenoso, nem firme, nem mole. Containers operam dentro de cgroups e namespaces, envolvem muitas camadas de software entre o serviço cliente e o container servidor (bridge, firewall, nat, buffers, IPVS, VXLAN, userland proxy, etc).

O máximo que conseguimos aqui é melhorar bastante a performance com alguns argumentos do Docker para minimizar essas camadas.

Primeiro, vamos rodar na rede host, nela o container não entra em um namespace de redes e fica disponível na loopback do servidor.

Em seguida vamos colocar todos os argumentos no docker container run para aproximar o container das configurações que usamos no systemd.

Pare e desative o serviço valkey-ultra-fast se for testar no mesmo servidor:

Bash
# Desativar o servico do HOST para subir no container
systemctl   stop     valkey-ultra-fast.service;
systemctl   disable  valkey-ultra-fast.service;

# Verificar status de parado
systemctl   status  valkey-ultra-fast.service;

4.1 – Volumes

Vamos preparar o diretório do volume para o container:

Bash
# - Diretorios
mkdir -p /storage/valkey-ultra-fast;

# - Propriedade do usuario valkey dentro da imagem 'valkey/valkey:9.1.0-trixie'
#   tem o UID=999 e GID=999
chown -R 999:999  /storage/valkey-ultra-fast;

# - Acesso exclusivo
chmod -R 0750     /storage/valkey-ultra-fast;

4.2 – Personalizando a imagem do Valkey

A imagem oficial do Valkey não possui alguns binários necessários para escalar o processo para prioridade máxima de CPU e su-exec (gosu).

Vamos criar uma continuação da imagem oficial valkey/valkey:9.1.0-trixie com essas ferramentas. Crie a pasta valkey-ultra-fast para esse projeto e trabalhe nela.

Arquivo: Dockerfile

Dockerfile – Projeto valkey-fast
#-------------------------------------------------------------- Stage: builder
# Imagem base
FROM        valkey/valkey:9.1.0-trixie AS builder

# Atualizar debian
RUN         apt -y update && \
            apt -y upgrade && \
            apt -y dist-upgrade && \
            apt -y full-upgrade && \
            apt -y autoremove && \
            apt-get install \
                -y \
                --no-install-recommends \
                util-linux gosu; \
            ldconfig

# Entrypoint com ajustes
RUN         ( \
                echo '#!/usr/bin/bash'; \
                echo; \
                echo '_run(){ echo "Running: $@"; eval "$@"; };'; \
                echo '_run mkdir -p /data;'; \
                echo '_run chown valkey:valkey /data;'; \
                echo; \
                echo 'PRECMD="chrt -f 90 gosu valkey /usr/local/bin/valkey-server"'; \
                echo 'echo "CMD: $PRECMD --logfile "" --save "" $@";'; \
                echo 'exec $PRECMD $@;'; \
                echo; \
            ) > /opt/entrypoint.sh; \
            chmod +x /opt/entrypoint.sh

# Limpar tudo que e' dispensavel
RUN         rm -rf \
                /var/log \
                /var/cache \
                /var/lib/apt \
                /var/lib/dpkg \
                /var/lib/shells.state \
                /usr/share/base-files \
                /usr/share/common-licenses \
                /usr/share/info \
                /usr/share/doc \
                /usr/share/debianutils \
                /usr/lib/x86_64-linux-gnu/gconv

#-------------------------------------------------------------- Stage: [image]
FROM        scratch
COPY        --from=builder  /  /
USER        root
WORKDIR     /data
ENV         PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin
HEALTHCHECK \
            --start-interval=3s \
            --start-period=3s \
            --interval=5s \
            --timeout=1s \
            --retries=2 \
            CMD [ \
                    "valkey-cli", \
                    "-h", "127.0.0.1", \
                    "-p", "6379", \
                    "ping" \
                ]
STOPSIGNAL  SIGTERM
ENTRYPOINT  ["/opt/entrypoint.sh"]
CMD         [ "valkey-server", "*:6379" ]
EXPOSE      6379/tcp
LABEL       org.opencontainers.image.authors="patrickbrandao@gmail.com"
LABEL       com.patrickbrandao.blog.version="1.0"
LABEL       com.patrickbrandao.blog.description="Valkey Ultra Fast"
LABEL       com.patrickbrandao.owner="Patrick Brandao"
LABEL       com.patrickbrandao.email="patrickbrandao@gmail.com"

Agora vamos produzir nossa imagem valkey-ultra-fast:9.1.0-trixie

Bash – build.sh
# Construir imagem docker
docker build . \
    -t valkey-ultra-fast:latest \
    -t valkey-ultra-fast:9.1.0-trixie;

4.3 – Criando e iniciando o container

Agora vamos colocar o container, já na versão 9 do valkey:

Bash – run.sh
# Variaveis
    NAME="valkey-ultra-fast";
    DATADIR=/storage/valkey-ultra-fast;
    IMAGE="valkey-ultra-fast:9.1.0-trixie";

# Renovar/rodar:
    docker container rm -f $NAME 2>/dev/null;
    docker container run \
        --detach    \
        --read-only \
        --name                $NAME \
        --hostname            $NAME.intranet.br \
        --network             host \
        --restart             always \
        --stop-timeout        3 \
        --cap-add             SYS_NICE \
        --cap-add             IPC_LOCK \
        --cap-add             SYS_RESOURCE \
        --security-opt        no-new-privileges:false \
        --ulimit              nofile=1000000:1000000 \
        --ulimit              nproc=-1:-1 \
        --ulimit              core=-1:-1 \
        --ulimit              memlock=-1:-1 \
        --ulimit              rtprio=99:99 \
        \
        --cpuset-cpus         4,5,6,7 \
        --cpus                    4.0 \
        --cpuset-mems               0 \
        --memory                   2g \
        --memory-swap              2g \
        --memory-reservation       1g \
        --shm-size                 1g \
        --oom-score-adj         -1000 \
        \
        -v $DATADIR:/data \
        -w          /data \
        \
        --tmpfs                /run:rw,dev,noexec,nosuid,mode=1777,size=8m \
        --tmpfs                /tmp:rw,dev,exec,suid,mode=1777,size=8m \
        \
        --health-cmd="valkey-cli -p 9991 ping" \
        --health-start-period=3s \
        --health-start-interval=1s \
        --health-interval=5s \
        --health-timeout=1s \
        --health-retries=2 \
        \
        $IMAGE \
            --bind                       127.0.0.1 \
            --port                       9991 \
            --tcp-backlog                65535 \
            --timeout                    0 \
            --tcp-keepalive              60 \
            --protected-mode             no \
            --unixsocket                 /run/valkey.sock \
            --unixsocketperm             770 \
            --daemonize                  no \
            --supervised                 no \
            --loglevel                   warning \
            --io-threads                 3 \
            --io-threads-do-reads        yes \
            --appendonly                 no \
            --maxmemory                  1gb \
            --maxmemory-policy           allkeys-lru \
            --maxmemory-samples          10 \
            --lazyfree-lazy-eviction     yes \
            --lazyfree-lazy-expire       yes \
            --lazyfree-lazy-server-del   yes \
            --lazyfree-lazy-user-del     yes \
            --lazyfree-lazy-user-flush   yes \
            --hz                         100 \
            --dynamic-hz                 yes \
            --activerehashing            no \
            --activedefrag               no \
            --maxclients                 10000 \
            --latency-tracking           yes \
            --latency-monitor-threshold  1 \
            --slowlog-log-slower-than    500 \
            --slowlog-max-len            256 \
            --cluster-enabled            no \
            --replica-read-only          no;

Agora utilize-o no HOST, repita os comandos de teste e benchmark do capítulo anterior.

Para usar esse Valkey em rede bridge ou overlay, altere os argumentos:

  • Parâmetro –network: mude o valor de “host” para sua rede, ex: network_public
  • Argumento –bind: mude o valor de “127.0.0.1” para 0.0.0.0

5 – Usage imagem pronta

Fiz uma imagem com a expertise explicada neste tutorial.

Imagem: tmsoftbrasil/valkey-fast

Diferenças:

  • ENV VALKEY_USER: valor padrão valkey, usuário que roda o processo;
  • ENV VALKEY_PRIO: valor padrão 90, prioridade RTC FIFO do processo (limite 99);
  • ENV VALKEY_EXTRA_FLAGS: argumentos do valkey-server (sobrepõe sobre a config padrão);
  • Configuração pronta em /etc/valkey/valkey.conf;
    • Porta TCP 6379;
    • Listen 0.0.0.0 abre a porta em todos os IPs (requer proteção);
      • env: VALKEY_EXTRA_FLAGS=”–listen 127.0.0.1″;
  • Entrypoint e CMD prontos;
  • Simplificação das camadas OCI e limpeza de arquivos dispensáveis resultou na redução da imagem final para apenas 40 MB.

Rodando no modo HOST com env para escutar somente em 127.0.0.1 porta 9991:

Bash – run.sh
# Variaveis
    NAME="valkey-fast";
    IMAGE="tmsoftbrasil/valkey-fast";
    DATADIR="/storage/$NAME";

# Renovar/rodar:
    docker container rm -f $NAME 2>/dev/null;
    docker container run \
        --detach    \
        --read-only \
        --name                $NAME \
        --hostname            $NAME.intranet.br \
        --network             host \
        --restart             always \
        --stop-timeout        3 \
        --cap-add             SYS_NICE \
        --cap-add             IPC_LOCK \
        --cap-add             SYS_RESOURCE \
        --security-opt        no-new-privileges:false \
        --ulimit              nofile=1000000:1000000 \
        --ulimit              nproc=-1:-1 \
        --ulimit              core=-1:-1 \
        --ulimit              memlock=-1:-1 \
        --ulimit              rtprio=99:99 \
        \
        --cpuset-cpus         4,5,6,7 \
        --cpus                    4.0 \
        --cpuset-mems               0 \
        --memory                   2g \
        --memory-swap              2g \
        --memory-reservation       1g \
        --shm-size                 1g \
        --oom-score-adj         -1000 \
        \
        --tmpfs                /run:rw,dev,noexec,nosuid,mode=1777,size=8m \
        \
        -v $DATADIR:/data \
        \
        -e VALKEY_USER=valkey \
        -e VALKEY_PRIO=95 \
        -e VALKEY_EXTRA_FLAGS="--bind 127.0.0.1 --port 9991" \
        \
        $IMAGE;

Você também pode personalizar o CMD do container para executar “valkey-server …opcoes…” a gosto.

Rodando em rede bridge “network_public“:

Bash – run.sh
# Variaveis
    NAME="valkey-fast";
    IMAGE="tmsoftbrasil/valkey-fast";
    DATADIR="/storage/$NAME";
    mkdir -p $DATADIR;

# Renovar/rodar:
    docker container rm -f $NAME 2>/dev/null;
    docker container run \
        --detach    \
        --read-only \
        --name                $NAME \
        --hostname            $NAME.intranet.br \
        --network             network_public \
        --restart             always \
        --stop-timeout        3 \
        --cap-add             SYS_NICE \
        --cap-add             IPC_LOCK \
        --cap-add             SYS_RESOURCE \
        --security-opt        no-new-privileges:false \
        --ulimit              nofile=1000000:1000000 \
        --ulimit              nproc=-1:-1 \
        --ulimit              core=-1:-1 \
        --ulimit              memlock=-1:-1 \
        --ulimit              rtprio=99:99 \
        \
        --cpuset-cpus         4,5,6,7 \
        --cpus                    4.0 \
        --cpuset-mems               0 \
        --memory                   2g \
        --memory-swap              2g \
        --memory-reservation       1g \
        --shm-size                 1g \
        --oom-score-adj         -1000 \
        \
        --tmpfs                /run:rw,dev,noexec,nosuid,mode=1777,size=8m \
        \
        -v $DATADIR:/data \
        \
        -e VALKEY_USER=valkey \
        -e VALKEY_PRIO=95 \
        \
        $IMAGE;

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com

Vocês não conseguiram conviver
com a própria falha.
Onde isso os trouxe?
De volta a mim.
Thanos