{"id":29009736,"url":"https://github.com/claytonfelipe/altilium-db","last_synced_at":"2026-04-21T16:34:35.716Z","repository":{"id":301082191,"uuid":"1008102993","full_name":"ClaytonFelipe/Altilium-db","owner":"ClaytonFelipe","description":"Banco de dados key-value em memória, construído em Rust e compatível com o protocolo Redis (RESP), com persistência AOF e Snapshot.","archived":false,"fork":false,"pushed_at":"2025-06-25T03:21:51.000Z","size":71,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-25T04:27:07.669Z","etag":null,"topics":["aof","persistent-storage","python-script","redis","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ClaytonFelipe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-25T03:17:58.000Z","updated_at":"2025-06-25T03:24:51.000Z","dependencies_parsed_at":"2025-06-25T04:27:12.988Z","dependency_job_id":"bcef1050-ec78-489f-a519-cb170caeb510","html_url":"https://github.com/ClaytonFelipe/Altilium-db","commit_stats":null,"previous_names":["claytonfelipe/altilium-db"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ClaytonFelipe/Altilium-db","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClaytonFelipe%2FAltilium-db","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClaytonFelipe%2FAltilium-db/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClaytonFelipe%2FAltilium-db/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClaytonFelipe%2FAltilium-db/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ClaytonFelipe","download_url":"https://codeload.github.com/ClaytonFelipe/Altilium-db/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClaytonFelipe%2FAltilium-db/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261897082,"owners_count":23226655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aof","persistent-storage","python-script","redis","rust"],"created_at":"2025-06-25T15:14:17.209Z","updated_at":"2026-04-21T16:34:35.661Z","avatar_url":"https://github.com/ClaytonFelipe.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"screenshot/altilium.png\" alt=\"icone\"/\u003e\n\u003c/p\u003e\n\n# Altilium-DB: Um Banco de Dados Key-Value em Rust\n\nAltilium-DB é um banco de dados em memória do tipo chave-valor, construído do **zero** em Rust. Ele foi projetado para ser leve, performático e compatível com o protocolo RESP, o que permite que qualquer cliente Redis se comunique com ele.\n\n### Características \n✅ **Rápido e leve:** Executa localmente sem consumir recursos excessivos.\n\n✅ **Compatível com comandos Redis-like:** Fácil migração para testes.\n\n✅ **Persistência opcional:** Salva dados em disco quando necessário.\n\n✅ **Open Source:** Decidimos compartilhar para ajudar outras equipes a evitar as mesmas dores que tivemos.\n\nDepois de enfrentar alguns erros em teste locais, percebi que precisávamos de uma solução leve e poderosa. Foi assim que nasceu o Altilium DB, um banco de dados **inspirado** no Redis, mas otimizado para ambientes específicos, focado em simplicidade e desempenho.\n\n\n## ✨ Funcionalidades\n\n```mermaid\n graph TD\n    %% Elementos principais\n    Cliente[\"Cliente\\n(Express, redis-cli, etc.)\"]\n    Listener[\"TCP Listener\\n(main.rs)\"]\n    Parser[\"RESP Parser\\n(resp.rs)\"]\n    Processor[\"Command Processor\\n(main.rs)\"]\n    Serializer[\"RESP Serializer\\n(resp.rs)\"]\n    CommandBus[[Command Bus\\ntokio::broadcast]]\n    WriterTask[\"Writer Task\\n(store.rs)\"]\n    DataStore[(\"In-Memory Data\\nArc\u003cRwLock\u003cHashMap\u003e\u003e\")]\n    AOF[\"AOF Task\\n(persistence.rs)\"]\n    Snapshot[\"Snapshot Task\\n(persistence.rs)\"]\n    AOFFile[(\"AOF File\\ndata.aof\")]\n    SnapshotFile[(\"Snapshot File\\ndata.snapshot.json\")]\n    Config[(\"Config File\\nConfig.toml\")]\n\n    %% Agrupamentos\n    subgraph \"Client Side\"\n        Cliente\n    end\n\n    subgraph \"Rust Server\"\n        subgraph \"Connection Handler\"\n            Listener --\u003e Parser --\u003e Processor --\u003e Serializer\n        end\n        \n        subgraph \"Data Layer\"\n            CommandBus --\u003e WriterTask --\u003e DataStore\n        end\n\n        subgraph \"Persistence\"\n            AOF --\u003e AOFFile\n            Snapshot --\u003e SnapshotFile\n        end\n    end\n\n    subgraph \"Storage\"\n        AOFFile\n        SnapshotFile\n        Config\n    end\n\n    %% Fluxo principal\n    Cliente --\u003e|TCP Connection| Listener\n    Processor --\u003e|Read| DataStore\n    DataStore --\u003e|Response| Processor\n    Processor --\u003e|Write| CommandBus\n    Serializer --\u003e|Response| Cliente\n\n    %% Fluxo de persistência\n    CommandBus -.-\u003e AOF\n    WriterTask --\u003e DataStore\n    Snapshot -.-\u003e DataStore\n    Config -.-\u003e Listener\n```\n\n* **Compatibilidade com o Protocolo Redis (RESP):** Permite o uso de clientes Redis existentes em diversas linguagens (Node.js, Python, etc.).\n* **Comandos Suportados:** Implementa um subconjunto dos comandos mais comuns do Redis: `GET`, `SET`, `HSET`, `DEL`, `KEYS`, `PING` e `AUTH`.\n* **Persistência de Dados Híbrida:**\n    * **Snapshotting:** Salva periodicamente todo o estado do banco em um arquivo JSON.\n    * **Append-Only File (AOF):** Registra todos os comandos de escrita em um arquivo, garantindo maior durabilidade.\n* **Autenticação:** Suporta autenticação por senha via comando `AUTH`.\n* **Expiração de Chaves:** Permite definir um tempo de vida para as chaves (usando `PX` e `EX` no comando `SET`).\n* **Configuração Externa:** As configurações de rede e senha são gerenciadas através de um arquivo `Config.toml`.\n\n## ⚙️ Arquitetura e Lógica de Funcionamento\n\nO banco de dados é construído sobre a plataforma assíncrona do Rust, o **Tokio**, e é dividido em vários módulos, cada um com uma responsabilidade clara.\n\n### 1. `main.rs`: O Ponto de Entrada\n\nÉ o coração do servidor. Suas principais responsabilidades são:\n-   **Carregar Configurações:** Lê o arquivo `Config.toml` para obter host, porta e senha.\n-   **Inicializar Componentes:** Cria as instâncias do `Store` (armazenamento) e do `PersistenceManager`.\n-   **Gerenciar Tarefas (Tasks):** Utiliza o `tokio::spawn` para iniciar tarefas de longa duração que rodam em background e de forma concorrente:\n    - A task principal do `Store` para processar comandos de escrita.\n    - A task do `PersistenceManager` para criar snapshots periódicos.\n    - A task do `PersistenceManager` para persistência AOF.\n    - A task de limpeza para remover chaves expiradas.\n-   **Escutar Conexões TCP:** Abre um `TcpListener` na porta configurada e, para cada nova conexão, gera uma nova task para gerenciá-la (`handle_connection`).\n\n### 2. `store.rs`: O Armazenamento Central de Dados\n\nEste módulo gerencia o estado do banco de dados de forma segura entre múltiplas threads.\n-   **Estrutura de Dados:** Usa um `Arc\u003cRwLock\u003cHashMap\u003cString, Value\u003e\u003e\u003e` para armazenar os dados.\n    -   `Arc` (Atomically Reference Counted) permite que múltiplos donos acessem os dados de forma segura.\n    -   `RwLock` (Read-Write Lock) permite múltiplas leituras concorrentes ou uma única escrita exclusiva, garantindo a consistência dos dados.\n-   **Padrão \"Command Bus\":** Para evitar locks de escrita prolongados e complexos, o `Store` utiliza um canal de `broadcast` do Tokio (`tokio::sync::broadcast`).\n    1.  Quando um comando de escrita (`SET`, `HSET`, `DEL`) é recebido em `handle_connection`, ele não modifica o estado diretamente.\n    2.  Em vez disso, ele envia o comando para o canal de broadcast.\n    3.  Uma única task de background (`process_commands`) escuta esse canal, recebe os comandos em ordem e os aplica ao `HashMap` principal. Isso centraliza todas as operações de escrita em uma única fila, simplificando a concorrência.\n\n### 3. `persistence.rs`: A Persistência de Dados\n\nGarante que os dados não sejam perdidos quando o servidor é reiniciado.\n-   **Snapshotting (`create_snapshot`):**\n    -   Periodicamente, uma task obtém um lock de leitura no `Store`.\n    -   Clona todo o `HashMap` de dados.\n    -   Serializa os dados para o formato JSON.\n    -   Para garantir atomicidade, ele primeiro escreve em um arquivo temporário (`.tmp`). Se a escrita for bem-sucedida, ele renomeia o arquivo para o nome final (`data.snapshot.json`), evitando corrupção.\n-   **Append-Only File (AOF) (`run_aof_persistence`):**\n    -   Uma task se inscreve no mesmo canal de `broadcast` de comandos do `Store`.\n    -   Toda vez que um comando de escrita é recebido, ele é convertido para o formato RESP (`command_to_resp`) e anexado ao final do arquivo `data.aof`.\n    -   Isso oferece uma durabilidade maior que o snapshotting, pois cada operação é salva imediatamente.\n-   **Carregamento (`load_from_disk`):** Na inicialização, o servidor primeiro tenta carregar o snapshot mais recente para restaurar o estado principal. A recuperação a partir do AOF pode ser implementada para \"reproduzir\" os comandos ocorridos após o último snapshot.\n\n### 4. `resp.rs`: O Parser do Protocolo\n\nEste módulo é a interface entre os bytes da rede e as estruturas de dados do Rust.\n-   **Parsing (`parse_resp`):** Utiliza a biblioteca `nom` para criar um parser de \"parser combinators\". Ele lê o fluxo de bytes de entrada e o transforma em uma enum `RespValue`, que representa os tipos de dados do protocolo (SimpleString, BulkString, Array, etc.).\n-   **Serialização (`serialize_resp`):** Faz o processo inverso. Pega uma enum `RespValue` (a resposta de um comando) e a converte de volta em uma sequência de bytes no formato RESP, pronta para ser enviada pela rede.\n\n### 5. `connection.rs` e `handle_connection`\n\nA lógica de `handle_connection` em `main.rs` gerencia o ciclo de vida de uma única conexão de cliente.\n-   **Loop de Leitura-Análise:**\n    1.  Lê dados do socket TCP para um buffer.\n    2.  Entra em um loop para tentar analisar um comando completo do buffer usando `parse_resp`.\n    3.  Se um comando é analisado com sucesso, ele é passado para `process_command`.\n    4.  A resposta retornada por `process_command` é serializada por `serialize_resp` e enviada de volta ao cliente.\n    5.  O loop continua para o caso de o cliente ter enviado múltiplos comandos de uma vez (pipelining). Se o buffer estiver com dados parciais, o loop é interrompido para aguardar mais dados do socket.\n\n## 🚀 Como Executar\n\n1.  **Pré-requisitos:**\n    -   Instale a toolchain do [Rust](https://www.rust-lang.org/tools/install).\n\n2.  **Configuração:**\n    -   Copie ou renomeie `Config.toml.example` para `Config.toml`.\n    -   Ajuste `host`, `port` e `requirepass` conforme necessário.\n\n3.  **Compilar e Executar:**\n    ```bash\n    # Compila o projeto em modo de release (otimizado)\n    cargo build --release\n\n    # Executa o binário gerado\n    ./target/release/altilium_server\n    ```\n    O servidor será iniciado e começará a escutar conexões.\n\n## 🔌 Como Conectar\n\n```mermaid\ngraph LR\n    %% Elementos principais\n    Usuario[Usuário]\n    CLI[\"CLI Altilium\\n(redis-cli like)\"]\n    App[\"Aplicação\\n(Driver oficial)\"]\n    Servidor[\"Servidor AltiliumDB\"]\n    Dados[(\"Seus Dados\")]\n\n    %% Fluxo simplificado\n    Usuario --\u003e|Comandos| CLI\n    Usuario --\u003e|Integração| App\n    CLI --\u003e|TCP/IP| Servidor\n    App --\u003e|TCP/IP| Servidor\n    Servidor --\u003e|Persiste| Dados\n\n    %% Estilização\n    style Usuario fill:#000,stroke:#fff\n    style CLI fill:#7af,stroke:#333\n    style App fill:#7af,stroke:#333\n    style Servidor fill:#2ecc71,stroke:#333\n```\n\nVocê pode usar qualquer cliente Redis. O `redis-cli` é o mais comum para testes:\n\n```bash\n# Conecte ao servidor usando a porta e a senha do seu Config.toml\nredis-cli -p 6379 -a \"123456\"\n\n# -- Comandos de Exemplo --\n\n# Autenticar (se você não usou -a)\n\u003e AUTH 123456\nOK\n\n# Ping para testar a conexão\n\u003e PING\nPONG\n\n# Salvar uma chave\n\u003e SET nome \"Alice\"\nOK\n\n# Buscar uma chave\n\u003e GET nome\n\"Alice\"\n\n# Usar um hashmap\n\u003e HSET usuario:1 nome \"Bob\"\n(integer) 1\n\n\u003e HSET usuario:1 email \"bob@example.com\"\n(integer) 1\n```\n---\n## Test-Client.py: Seu Companheiro para Testar o Altilium DB Localmente\n### O que ele faz?\nÉ um client Pyhton minimalista que:\n- Conecta no seu Altilium DB local ```(127.0.0.1:6379)```\n- Manda comandos tipo Redis ```(SET, GET, DEL, VIEW)```\n- Tem um modo interativo (pra você testar sem recompilar 50x)\n\n### Como usar?\n\n### 1. Garanta que o Altilium DB tá rodando:\n```bash\ncargo run --release\n```\n### 2. Rode o client:\n```bash\npython3 test-client.py \n```\n### 3. Teste:\n```bash\n\u003e SET nome Altilium  \nOK  \n\u003e GET nome  \n\"Altilium\"  \n\u003e DEL nome  \n1  \n\u003e VIEW  \n(Banco vazio)  \n```\n---\n## Mas isso é um Redis?\"\n❌ Não (e nem quer ser)\n\n✅ Mas é um baita ajudante pra desenvolvimento.\n\n### O que ele NÃO faz?\n- Substituir Redis em produção (nem tente, sério)\n\n- Lidar com 1M de requests por segundo\n\n### Por que abrimos o código?\nPorque:\n\nJá nos salvou de várias enrascadas\n\nSe ajudou a gente, pode ajudar outros devs.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclaytonfelipe%2Faltilium-db","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclaytonfelipe%2Faltilium-db","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclaytonfelipe%2Faltilium-db/lists"}