Estratégia de Cache - C-Suite
Visão Geral
Este documento descreve a estratégia de cache centralizada para o ecossistema C-Suite. O objetivo é reduzir carga no banco de dados, melhorar performance, e padronizar o uso de cache em todos os serviços.
Módulo de Cache
Localização
O módulo principal está em: common_cache.py (raiz do projeto)
Características
- Interface padronizada: API simples e consistente
- Redis como backend: Usa Redis para armazenamento
- TTL configurável: Time to live por chave
- Decorators: Cache automático de funções
- Invalidação: Suporte a invalidação por chave ou padrão
- Fallback graceful: Continua funcionando mesmo se Redis estiver indisponível
- Helpers específicos: Funções prontas para políticas e features
Uso Básico
1. Cache Simples
from common_cache import get_cache
cache = get_cache()
# Armazenar valor
cache.set("user:123", {"name": "João", "email": "joao@example.com"}, ttl=300)
# Obter valor
user = cache.get("user:123")
# Remover valor
cache.delete("user:123")
2. Cache com Decorator
from common_cache import cache_result
@cache_result(ttl=300, key_prefix="policy")
def load_policies(org_id: int):
# Lógica de carregamento do banco
policies = db.query("SELECT * FROM policy_rules WHERE org_id = ?", org_id)
return policies
# Primeira chamada: busca do banco e cacheia
policies = load_policies(org_id=1)
# Segunda chamada: retorna do cache
policies = load_policies(org_id=1)
# Invalidar cache manualmente
load_policies.invalidate(org_id=1)
3. Cache de Políticas
from common_cache import (
cache_policy,
get_cached_policy,
invalidate_policy_cache
)
# Cachear política
cache_policy(org_id=1, policy_key="min_margin", value=0.15, ttl=300)
# Obter política do cache
min_margin = get_cached_policy(org_id=1, policy_key="min_margin")
# Invalidar cache de políticas
invalidate_policy_cache(org_id=1) # Todas as políticas da org
invalidate_policy_cache(org_id=1, policy_key="min_margin") # Política específica
4. Cache de Features
from common_cache import (
cache_feature,
get_cached_feature,
invalidate_feature_cache
)
# Cachear feature
cache_feature(customer_id=123, feature_name="intent_score", value=0.85, ttl=600)
# Obter feature do cache
intent_score = get_cached_feature(customer_id=123, feature_name="intent_score")
# Invalidar cache de features
invalidate_feature_cache(customer_id=123) # Todas as features do cliente
invalidate_feature_cache(feature_name="intent_score") # Feature específica de todos os clientes
Configuração
Variáveis de Ambiente
# Host do Redis
REDIS_HOST=localhost
# Porta do Redis
REDIS_PORT=6379
# Database do Redis (0-15)
REDIS_DB=0
# Senha do Redis (opcional)
REDIS_PASSWORD=
# Habilitar/desabilitar cache
REDIS_ENABLED=true
Usando core_config
from common_cache import CacheConfig, get_cache
# Configuração automática de variáveis de ambiente
cache = get_cache()
# Ou configuração customizada
config = CacheConfig(
host="redis.example.com",
port=6379,
password="senha_secreta",
enabled=True
)
cache = get_cache(config)
Estratégias de Cache por Serviço
1. Policy Engine (C-Suite)
O que cachear:
- Políticas por organização (policy:{org_id}:{rule_key})
- Lista completa de políticas (policies:{org_id})
TTL recomendado: 300 segundos (5 minutos)
Exemplo:
from common_cache import cache_result
@cache_result(ttl=300, key_prefix="policies")
def load_policies(org_id: int):
# Carrega do banco
policies = db.query("SELECT * FROM policy_rules WHERE org_id = ?", org_id)
return policies
# Invalidar quando política for atualizada
def update_policy(org_id: int, rule_key: str, value: Any):
# Atualiza no banco
db.update("UPDATE policy_rules SET rule_value = ? WHERE org_id = ? AND rule_key = ?",
value, org_id, rule_key)
# Invalida cache
from common_cache import invalidate_policy_cache
invalidate_policy_cache(org_id=org_id, policy_key=rule_key)
2. Feature Service (4C)
O que cachear:
- Features calculadas por cliente (feature:{customer_id}:{feature_name})
- Features agregadas (feature:agg:{feature_name})
TTL recomendado: 600 segundos (10 minutos)
Exemplo:
from common_cache import cache_result
@cache_result(ttl=600, key_prefix="feature")
def calculate_intent_score(customer_id: int):
# Cálculo pesado
score = complex_calculation(customer_id)
return score
3. Sales Manager
O que cachear:
- Tasks por vendedor (tasks:{agent_id})
- Métricas consolidadas (metrics:{org_id})
TTL recomendado: 300 segundos (5 minutos)
4. Decision API (4C)
O que cachear:
- Candidatos filtrados (candidates:{customer_id}:{hash})
- Resultados de scoring (score:{customer_id}:{offer_id})
TTL recomendado: 60 segundos (1 minuto) - dados mais voláteis
Padrões de Chave
Convenção de Nomenclatura
{entity}:{id}:{subentity}:{subid}
Exemplos:
- policy:1:min_margin - Política min_margin da organização 1
- feature:123:intent_score - Feature intent_score do cliente 123
- tasks:5:pending - Tasks pendentes do agente 5
- metrics:1:daily - Métricas diárias da organização 1
Prefixos Recomendados
policy:- Políticas do C-Suitefeature:- Features calculadastasks:- Tasks do sales managermetrics:- Métricas consolidadasdecision:- Resultados de decisõescache:- Cache genérico
Invalidação
Quando Invalidar
- Dados atualizados: Sempre que dados são modificados no banco
- TTL expirado: Automático pelo Redis
- Mudanças relacionadas: Invalidar cache relacionado
Estratégias de Invalidação
1. Invalidação Imediata
def update_policy(org_id: int, rule_key: str, value: Any):
# Atualiza banco
db.update(...)
# Invalida cache imediatamente
invalidate_policy_cache(org_id=org_id, policy_key=rule_key)
2. Invalidação por Padrão
# Invalidar todas as políticas de uma organização
invalidate_policy_cache(org_id=1)
# Invalidar todas as features de um cliente
invalidate_feature_cache(customer_id=123)
3. Invalidação em Lote
from common_cache import get_cache
cache = get_cache()
# Invalidar múltiplas chaves
keys = ["policy:1:min_margin", "policy:1:max_contacts", "policy:1:blocked_skus"]
for key in keys:
cache.delete(key)
Monitoramento
Health Check
from common_cache import get_cache
cache = get_cache()
health = cache.health_check()
print(health)
# {
# "enabled": True,
# "status": "healthy",
# "redis_available": True,
# "connected_clients": 5,
# "used_memory_human": "2.5M",
# "keyspace": {"keys": 1234, "expires": 567}
# }
Integração com Health Checks
from common_health import create_health_router
from common_cache import get_cache
def check_cache_health():
cache = get_cache()
health = cache.health_check()
return health["status"] == "healthy"
health_router = create_health_router(
app_name="my-app",
dependencies=["database", "cache"] # Adiciona verificação de cache
)
Boas Práticas
- Use TTL apropriado:
- Dados estáticos: TTL longo (1 hora+)
- Dados dinâmicos: TTL curto (1-5 minutos)
-
Dados em tempo real: TTL muito curto (30-60 segundos)
-
Invalide quando necessário: Sempre invalide cache quando dados são atualizados
-
Use chaves descritivas: Facilita debugging e invalidação
-
Não cacheie dados sensíveis: Evite cachear senhas, tokens, etc.
-
Monitore uso de memória: Configure limites no Redis
-
Teste fallback: Certifique-se de que app funciona sem Redis
-
Use padrões de chave consistentes: Facilita invalidação em lote
Troubleshooting
Cache não está funcionando
- Verifique se Redis está rodando:
redis-cli ping - Verifique variáveis de ambiente:
REDIS_HOST,REDIS_PORT,REDIS_ENABLED - Verifique health check:
cache.health_check()
Cache retornando None
- Verifique se chave está correta
- Verifique se TTL não expirou
- Verifique se valor foi cacheado corretamente
Performance ruim
- Verifique se Redis está na mesma rede
- Verifique se há muitas chaves (considere limpar)
- Verifique uso de memória do Redis
Próximos Passos
- ✅ Módulo de cache criado
- ⏳ Migrar Policy Engine para usar
common_cache - ⏳ Adicionar cache em Feature Service
- ⏳ Adicionar cache em Sales Manager
- ⏳ Configurar monitoramento de cache
- ⏳ Documentar TTLs recomendados por serviço