Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Тема
Описание
Доп.

Cloudflare R2 — это объектное хранилище, очень похожее на Amazon S3 от AWS, но с одним ключевым отличием: отсутствием платы за исходящий трафик (egress fees), плата только за хранения. Объекты это файлы: изображения, видео, документы, бэкапы, логи, статичные файлы сайта (CSS, JS).

Paddle.com — это платформа, которая предоставляет полный комплект услуг для продажи программного обеспечения (SaaS) и цифровых продуктов. Простыми словами, Paddle выступает как ваш отдел продаж, платежный отдел и отдел поддержки в одном лице. Вместо того чтобы самостоятельно подключать кучу разных сервисов (платежные системы, налоги, генерация лицензий), вы используете одну платформу — Paddle.

Umami — это современный, простой и ориентированный на конфиденциальность инструмент для веб-аналитики с открытым исходным кодом. Если говорить просто, Umami — это легкая и удобная альтернатива Google Analytics, которая уважает приватность ваших пользователей.

PostHog — это платформа для продуктовой аналитики с открытым исходным кодом (open-source). Если простыми словами, то это инструмент, который помогает компаниям понять, как пользователи взаимодействуют с их продуктом (веб-сайтом или приложением), чтобы принимать решения на основе данных.

Базы данных, пулы соединений и ORM

rustcamp

Важно понимать концепцию пула соединений. Он широко применяется в ситуациях, когда программа представляет собой долго работающее приложение (например, демоны или серверы). Ключевой момент заключается в том, что вместо того, чтобы создавать новое соединение с базой данных каждый раз, когда нам нужно с ней взаимодействовать, мы предпочитаем заранее создать пул таких подключений и использовать их повторно. Поскольку создание соединения — довольно дорогостоящая операция, применение этого шаблона приводит к значительному повышению производительности. Нет необходимости каждый раз тратить время на handshake или аутентификацию. Ограничение числа одновременно открытых соединений предотвращает перегрузку базы данных. Позволяет серверу работать стабильно под высокой нагрузкой.

К счастью, экосистема Rust предоставляет общие реализации независимого от базы данных пула соединений в обоих вариантах: синхронном и асинхронном.

Синхронный

Работают в обычном блокирующем режиме. Подходит для приложений, где нет асинхронного кода. Для синхронных соединений есть r2d2 (пионер среди таких крейтов, существовал задолго до того, как асинхронный ввод-вывод появился в Rust). Вы можете легко адаптировать его для своего конкретного случая использования (или базы данных), просто реализовав его особенности. Очевидно, что уже существуют реализации для распространенных драйверов.

Асинхронный

Совместимы с async/await, например, bb8, deadpool, mobc. Используются в высоконагруженных веб-серверах и микросервисах на Tokio или async-std. Для асинхронных подключений в экосистеме Rust гораздо больше возможностей по историческим причинам и большей конкурентоспособности (в результате большей популярности асинхронного ввода-вывода ).

Самым первым, исторически, был crate bb8 . Он отражает crate r2d2 для асинхронных соединений (только tokio) и изначально был основан на нем. Точно так же уже реализованы мосты для обычных драйверов.

deadpool — это альтернативная и очень зрелая реализация шаблона пула соединений , поддерживающая как tokio и async-std, снабженная собственной большой экосистемой .

Другая альтернативная реализация — crate mobc, но вдохновленная crates deadpool and r2d2. Аналогично, поддерживает tokio и async-std и предоставляет некоторые мосты для общих драйверов.

qp (Быстрый пул) — это очень простая и ограниченная реализация шаблона пула соединений, использующая примитивы без блокировки и ориентированная на производительность.

Построитель запросов — это, по сути, шаблон построителя, применяемый для построения запросов SQL (или других языков запросов к данным) и позволяющий писать их как обычный код Rust (и, следовательно, используя встроенный DSL вместо внешнего DSL)

Каноническая реализация этого шаблона в экосистеме Rust представлена ​​crates sea-query и sql_query_builder crate barrel, с другой стороны, позволяет писать миграции схемы, а не запрашивать данные.

crate sqlx Асинхронный crate SQL с проверяемыми во время компиляции запросами без DSL.

sqlx, хотя и является многофункциональным набором инструментов для SQL, здесь использует совершенно противоположный подход : он фокусируется на написании чистых SQL- запросов (без специального DSL, без построения запросов), корректность которых статически проверяется во время компиляции.

ormx — это легкое расширение крейта sqlx, призванное предоставить ему функции, подобные ORM

SQLx — позволяет делать проверки времени компиляции. crate SQLx обеспечивает довольно хорошие проверки для наших запросов, если мы используем только эту функцию.

Проверенным запросом является запрос, который может быть статически проверен во время компиляции. SQLx сравнивает имена столбцов и таблиц со схемой базы данных, проверяет синтаксис и типы данных без запуска какого-либо кода.

Непроверенный запрос не имеет никаких гарантий вообще. Он может содержать любое количество опечаток и проблем с типами, и компилятор не может их отловить.

Как правило, запросы, созданные с использованием функций sqlx::query() и sqlx::query_as(), не проверяются, а созданные с использованием макросов sqlx::query! и sqlx::query_as! (и нескольких других) проверяются. Если вы видите, что используется QueryBuilder, этот запрос не проверяется.


fn main(){
// Postgres version
let ids = sqlx::query_as!(
    Uuid,
    "SELECT id FROM users \
     WHERE ($1::timestamptz IS NULL OR updated_at < $1) \
       AND ($2::timestamptz IS NULL OR updated_at > $2) \
       AND ($3::boolean IS NULL OR is_guest = $3)",
    updated_before_option,
    updated_after_option,
    is_guest_option,
    )
    .fetch_all(&pool)
    .await;

let records = sqlx::query!("SELECT name, email, created_at \
    FROM users WHERE id = ANY($1)",
    ids,
    )
    .fetch_all(&pool)
    .await;

}

Migrations

Ресурсы по миграциям баз данных в Rust

Общие ресурсы

Миграции для Diesel

  • diesel_migrations: Управление схемой базы данных с помощью миграций в Diesel.
  • diesel_cli: Командная строка для управления миграциями и схемой базы данных в Diesel.

Миграции для SQLx

  • sqlx-cli: Утилита командной строки для управления миграциями и базами данных с использованием SQLx.
  • SQLx CLI — Create and Run Migrations: Официальная документация по созданию и запуску миграций с использованием SQLx CLI.

Другие инструменты для миграций

  • refinery: Мощный инструмент для миграций в Rust, поддерживающий SQL-миграции.
  • migrant: Лёгкий инструмент для миграций, поддерживающий различные базы данных.
  • barrel: Утилита для создания схемы базы данных с использованием Rust.

diesel_migrations - Для diesel пользователей очевидным выбором является diesel_migrations ящик (который можно использовать напрямую через diesel_cli). Тем не менее, он не требует diesel использования самого себя и может использоваться как полностью отдельный инструмент.

Аналогичным образом, для sqlx пользователей sqlx-cli инструмент обеспечивает миграцию «из коробки», а также может использоваться непосредственно в коде приложения.

refinery и migrant являются еще одним автономным инструментом Rust для миграции, позволяющим использовать как CLI, так и «код внутри приложения». Интересная особенность крейта refinery заключается в том, что он также позволяет писать миграции «в коде приложения» с помощью barrel построителя миграции схемы.

Миграции пишутся вручную, чтобы обеспечить их оптимальную работу под высокой нагрузкой с большими объемами данных, а также обратную совместимость. На терабайтах данных вы не можете быстро переключаться между миграциями.

Под обратной совместимостью подразумевается поэтапное внесение изменений, при котором соседние этапы совместимы друг с другом.

То есть, вместо того чтобы просто заменить одну колонку в таблице, вы сначала добавляете новую колонку и заполняете её данными. Затем вы разворачиваете новую версию сервиса, которая работает одновременно и с новой, и со старой колонкой. Если всё в порядке, вы разворачиваете ещё одну новую версию сервиса, которая использует только новую колонку, и удаляете старую колонку с помощью новой миграции.

crate sqlx-cli

Создает файлы для миграций с возможностью откатить их, SQL пишешь сам

crate sqlx-cli

Install:

# supports all databases supported by SQLx
$ cargo install sqlx-cli

# only for postgres
$ cargo install sqlx-cli --no-default-features --features postgres

$ sqlx <command> --help

URL должен быть:

  • либо в строке запроса --database-url
  • либо в .env файле DATABASE_URL
  • либо в переменных среды DATABASE_URL

Создать / удалить базу данных

sqlx database create --database-url postgres://{user}:{password}@{host}:{port}/{dbname}
sqlx database drop --database-url postgres://{user}:{password}@{host}:{port}/{dbname}

Создание двух файлов миграции .up.sql / .down.sql (попытка смешать "простые" миграции с обратимыми -r миграциями приводит к ошибке)

$ sqlx migrate add -r <name>

$ sqlx migrate run

отмена миграции
$ sqlx migrate add -r <name>

отмена всех миграции (созданных с флагом -r т.е. отработают .down.sql миграции)
$ sqlx migrate revert

Имя таблицы: refinery_schema_history

Имя файла миграции: [U|V]{1}__{2}.sql

где {1} номер версии
      {2} имя файла
      V - с поддержкой точной версии , синхронно 1,2,3
      U - без поддержки точного версионирования, асинхронно 1,3,2

Пример: V1__init.sql

Для запуска миграций через отдельный файл

Cargo.toml:

[package]
....
default-run = "main"

[[bin]]
name = "main"
path = "src/main.rs"

[[bin]]
name = "migrations"
path = "src/migrations.rs"

Запуск миграции: $ cargo run --bin migrations

File src/migrations.rs:



use tokio_postgres::{NoTls, Error,Client,Connection};
use refinery::config::Config;

mod embedded {
    use refinery::embed_migrations;
    embed_migrations!("migrations");// Dir migrations
}

#[tokio::main] // По умолчанию tokio_postgres использует crate tokio в качестве runtime (среды выполнения).
async fn main() -> std::result::Result<(), tokio_postgres::Error> {
    // Connect to the database.
    // "postgres://rust:job_queue@localhost:5432/rust"
    let (mut client, connection):(Client,Connection<_,_>) =
            tokio_postgres::connect("host=localhost user=rust port=5432 password='job_queue'  dbname=rust", NoTls).await?;

    // Объект подключения выполняет фактическую связь с базой данных, поэтому запускает его самостоятельно.
    tokio::spawn(async move {
        if let Err(e) = connection.await {
            eprintln!("connection error: {}", e);
        }
    });
   
    run_migrations(&mut client).await.expect("can run DB migrations: {}");
    Ok(())
}

// type Error = Box;
async fn run_migrations(client:&mut Client) -> std::result::Result<(), refinery::Error> {
    println!("Running DB migrations...");
     
    // let migration_report:Result = embedded::migrations::runner().run_async(client).await?;
    match embedded::migrations::runner().run_async(client).await {
        Ok(migration_report) => {
            for migration in migration_report.applied_migrations() {
                println!("Migration Applied - Name: {}, Version: {}", migration.name(), migration.version());
            }
        },
        Err(err) => {
            use std::error::Error;
            // refinery::Error
            if let Some(err) = err.source().map(|source| source.downcast_ref::())
            {
               // handle err
            }else{
                println!("Show error: {:?}",err);
            }
        }
    }
    println!("DB migrations finished!");
    Ok(())
}

async fn drop_migrations_table(client:&mut Client) -> std::result::Result<(), tokio_postgres::Error> {
    client.execute("DROP TABLE refinery_schema_history", &[]).await?;
    Ok(())
}

File migrations/V1__initial.sql

CREATE TABLE IF NOT EXISTS todo
(
    id SERIAL PRIMARY KEY NOT NULL,
    name VARCHAR(255),
    created_at timestamp with time zone DEFAULT (now() at time zone 'utc'),
    checked boolean DEFAULT false
);

File migrations/V2__add_checked_date.sql

ALTER TABLE todo
    ADD COLUMN checked_date timestamp with time zone;

File migrations/V3__init.sql

CREATE TABLE IF NOT EXISTS queues (
  id UUID PRIMARY KEY,
  created_at TIMESTAMP WITH TIME ZONE NOT NULL,
  updated_at TIMESTAMP WITH TIME ZONE NOT NULL,

  scheduled_for TIMESTAMP WITH TIME ZONE NOT NULL,
  failed_attempts INT NOT NULL,
  status INT NOT NULL,
  message JSONB NOT NULL
);
CREATE INDEX IF NOT EXISTS index_queue_on_scheduled_for ON queues (scheduled_for);
CREATE INDEX IF NOT EXISTS index_queue_on_status ON queues (status);

ORM

Асинхронные ORM и библиотеки

  • diesel-async: Асинхронная обёртка для Diesel, предоставляющая async-версии основных методов.
  • sea-orm: Асинхронный и динамичный ORM, ориентированный на простоту использования и поддержку нескольких баз данных.
  • sea-query: Конструктор SQL-запросов, поддерживающий MySQL, PostgreSQL и SQLite.
  • ormx: Лёгкие derive-макросы для добавления ORM-подобных возможностей в sqlx.
  • rustorm: SQL-центрированный ORM с акцентом на удобство преобразования типов базы данных в соответствующие типы Rust.

Дополнительные ресурсы

Самым первым ORM, созданным в Rust, был diesel. Благодаря расширению diesel-async, его по-прежнему можно использовать с асинхронными соединениями.

sea-orm (построенный поверх sea-query) — альтернативная многофункциональная и зрелая реализация паттерна [ORM] в Rust, ориентированная на динамические запросы, чтобы избежать сложности статических проверок («борьба с ORM»).

ormx — это легкое расширение крейта sqlx, призванное предоставить ему функции, подобные ORM

rustorm — это очень простой и ориентированный на SQL ORM, ориентированный на упрощение преобразования типов баз данных в соответствующие типы Rust.

ORM barrel

ORM для миграций

Мощный API для построения миграции схемы для Rust

Cargo.toml:
barrel= {version ="0.6", features = ["pg"]}

use barrel::{Table,types, Migration};
use barrel::backend::Pg;

use sqlx::postgres::PgPoolOptions;
use sqlx_example::settings;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(),sqlx::Error> {
    // Create a connection pool
    //  for MySQL, use sqlx::mysql::MySqlPoolOptions::new()
    //  for SQLite, use SqlitePoolOptions::new(), SqliteConnection::connect("sqlite::memory:") 
    //  etc.

    let config:String = settings::config().expect("Error parse config");
    let pool = PgPoolOptions::new()
        .max_connections(5)
        .max_lifetime(Duration::from_secs(30 * 60))
        .connect(&config)
        .await?;
    
    migrate(&pool).await?;
     
    Ok(())
}

pub async fn migrate(pool: &sqlx::Pool) -> Result<(),sqlx::Error> {
    let mut m = Migration::new();

    m.create_table("posts", |t| {
        t.add_column("id", types::primary());
        t.add_column("post", types::varchar(255));
        t.add_column("url", types::varchar(255).indexed(true));
    });
    
    let res:sqlx::postgres::PgQueryResult =  sqlx::query(&m.make::()).execute(pool).await?;
    println!("{:?}",res);

    let mut m = Migration::new();
    // A new table is automatically created with an "id" primary key
    // To disable that call `without_id` on the return of `create_table`
    m.create_table("users", |t: &mut Table| {
        t.add_column("name", types::varchar(255)); // Default name is "Anonymous"
        t.add_column("description", types::text().nullable(true)); // Can be null
        t.add_column("age", types::integer());
        t.add_column("posts", types::foreign("posts", vec!["id"]));
        t.add_column("owns_plushy_sharks", types::boolean());
    });

    // CREATE TABLE "users" (
    //     "name" VARCHAR(255) NOT NULL, 
    //     "description" TEXT, 
    //     "age" INTEGER NOT NULL, 
    //     "posts" INTEGER REFERENCES 
    //     "posts"(id,url) NOT NULL, 
    //     "owns_plushy_sharks" BOOLEAN NOT NULL);
    //println!("{}", m.make::());

    let res:sqlx::postgres::PgQueryResult = sqlx::query(&m.make::()).execute(pool).await?;
    println!("{:?}",res);
    Ok(())
}

Полнотекстовые поисковые движки

Tantivy

  • Аналог Lucene, но написанный на Rust.
  • Поддерживает индексацию больших объёмов данных, быстрый поиск, ранжирование по релевантности.
  • Используется в MeiliSearch и Quickwit.

MeiliSearch

  • Построен на Tantivy.
  • Упрощённый движок для полнотекстового поиска с нечётким поиском (fuzzy matching) и typo tolerance «из коробки».
  • Очень быстрый, с REST API.

Quickwit

  • Движок поиска для логов и аналитики.
  • Распределённый, тоже использует Tantivy.

Библиотеки для нечеткого поиска (fuzzy search)

fuzzy-matcher

  • Простая библиотека для нечеткого поиска строк.
  • Использует алгоритмы Skim и Sublime Text.
  • Хорошо подходит для CLI (например, автодополнение, поиск по файлам).

strsim

  • Реализация разных метрик сходства строк:

    • Levenshtein
    • Damerau-Levenshtein
    • Jaro, Jaro-Winkler
    • Sørensen-Dice
  • Подходит для оценки схожести строк и «поиска с ошибками».

fst

  • Реализация finite state transducers для поиска по словарям.
  • Очень быстрый поиск по огромным наборам строк.
  • Можно использовать для реализации автодополнения или похожих слов.

Другие варианты

  • nlprule — NLP-инструменты (грамматика, правила), можно расширить под поиск.
  • tantivy-fst — связка Tantivy + fst для быстрых префиксных/фаззи-запросов.

Сравнение поисковых библиотек

Библиотека / ДвижокТипОсновные возможностиГде применять
TantivyПолнотекстовый движок (аналог Lucene)Индексация больших объёмов данных, ранжирование, быстрый поиск, поддержка сложных запросовСвой поисковый движок, аналитика, логирование
MeiliSearchГотовый полнотекстовый движок (REST API)Построен на Tantivy, fuzzy search, typo tolerance, релевантность «из коробки»Быстро развернуть поисковый сервис, поиск по сайту/продуктам
fuzzy-matcherFuzzy search (по строкам)Алгоритмы Skim и Sublime Text для поиска с опечаткамиCLI тулзы, поиск по файлам, автодополнение
strsimМетрики сходства строкLevenshtein, Damerau-Levenshtein, Jaro(-Winkler), Sørensen-DiceСравнение строк, поиск похожих слов, проверка опечаток
fstПоиск по словарям (Finite State Transducers)Очень быстрый поиск по огромным наборам строк, поддержка префиксов и fuzzyАвтодополнение, словари, индексирование ключей

Вывод:

  • Если нужен готовый движок с API → бери MeiliSearch.
  • Если нужен низкоуровневый движок для индексацииTantivy.
  • Если нужен просто fuzzy matching по строкамfuzzy-matcher или strsim.
  • Если нужен массовый поиск по словарямfst.

Вывод:

  • Большие данные и сложные запросыTantivy
  • Готовый движок с REST API и fuzzyMeiliSearch
  • Лёгкий fuzzy-поиск по строкамfuzzy-matcher
  • Оценка похожести строкstrsim
  • Поиск по словарям/ключамfst

Серверные библиотеки (GraphQL в Rust)

async-graphql

  • Самая популярная и активно развиваемая библиотека.

  • Поддерживает GraphQL spec полностью, включая:

    • Subscriptions (через WebSocket)
    • DataLoader (batch-загрузки)
    • Federation
  • Подход: code-first — схема описывается через Rust типы и derive-макросы.

  • Отлично интегрируется с Actix, Axum, Warp.

juniper

  • Более «старый» проект, но до сих пор активно используется.
  • Даёт сильные статические гарантии благодаря типовой системе Rust.
  • Подход: code-first.
  • Хорошо подходит, если хочется «Rust-идентичности» и строгих проверок.

Клиентские библиотеки

graphql-client

  • Подход query → code.
  • Из GraphQL-запросов генерирует Rust-структуры, которые проверяются на этапе компиляции.
  • Полезно, если нужно жёсткое соответствие между схемой сервера и клиентом.

cynic

  • Подход code → query (обратный к graphql-client).
  • Запросы описываются Rust-типами, и библиотека генерирует валидные GraphQL-запросы.
  • Очень строгая типизация и compile-time проверки.
  • Локальный кэш внутри приложенияmoka, cached, stretto.
  • Встраиваемое KV-хранилищеsled, redb.
  • In-memory SQL → SQLite (rusqlite + :memory:).
  • Многопоточностьdashmap, evmap.
  • Распределённый кэш/хранилище → Redis, KeyDB, DragonflyDB.

Распределённые решения

Если нужно не только in-memory в одном процессе, а кластерное решение:

  • Redis (через redis-rs / deadpool-redis)
  • KeyDB (Redis-совместимый, но с multi-threading) — Rust клиенты те же.
  • DragonflyDB (Redis API-compatible, high-performance, поддержка клиентов через redis-rs).

Redis

Redis — это in-memory data store (хранилище данных в памяти), который чаще всего используется как:

  • Кэш — быстрый доступ к данным, чтобы не ходить каждый раз в базу данных.
  • Хранилище ключ-значение — удобно для быстрых lookup’ов.
  • Брокер сообщений — очереди задач, pub/sub.
  • Сессии — хранение данных пользователя (например, токенов).

Redis работает в памяти → быстрый, но при необходимости можно настроить сохранение данных на диск (RDB, AOF).

Клиенты Redis:

1. crate redis-rs

Основной и самый популярный клиент.

Поддерживает синхронный и асинхронный (Tokio) режимы.

Умеет работать с:

  • Ключ-значение
  • Pub/Sub
  • Pipelines
  • Скрипты Lua

2. crate deadpool-redis

Асинхронный клиент с пулом соединений (на базе Tokio).

Удобно, если у тебя веб-сервер (Actix, Axum), где много запросов к Redis одновременно.

Кэш и структуры данных в памяти

  • moka

    • Асинхронный/синхронный кэш с TTL и LFU/LRU стратегиями.
    • Отлично подходит как локальный кэш внутри одного приложения.
  • cached

    • Макросы для автоматического кэширования функций.
    • Есть поддержка LRU/TTL.
    • Удобно для простого мемоизации.
  • stretto

    • Высокопроизводительный in-memory кэш (порт Go-библиотеки Dgraph Stretto).
    • TTL, LFU, асинхронная поддержка.

Key-Value хранилища

  • sled

    • Иногда называют «embedded Redis для Rust».
    • Это персистентное хранилище, но очень быстрое, работает как KV store в памяти + на диске.
    • Поддерживает транзакции, деревья, итераторы.
  • redb

    • Современная встраиваемая key-value база данных.
    • ACID-гарантии, высокая производительность.
    • Может использоваться и как in-memory, и как persistent store.

In-memory SQL

  • SQLite in-memory mode

    • Через rusqlite можно запустить sqlite::memory: и получить полноценную SQL-базу без файлов.
    • Отлично подходит для тестов и временных данных.

Структуры данных для многопоточности

  • dashmap

    • Потокобезопасный HashMap с быстрым доступом.
    • Хорош для in-memory KV-хранилища с многопоточностью.
  • evmap

    • HashMap с lock-free обновлениями.
    • Подходит, если нужны частые чтения и редкие записи.

Встраиваемые БД SQLite

rusqlite самый популярный и зрелый биндинг к SQLite C API.

crate rusqlite

1. Документные базы

Хранят данные в виде документов (JSON/BSON).

  • MongoDB

    • mongodb — официальный драйвер, async, поддерживает всё: CRUD, агрегаты, транзакции.
    • wither — ODM (Object Document Mapper).
    • bson — работа с BSON напрямую.
  • CouchDB

    • couch_rs — клиент для CouchDB, поддерживает REST API.

2. Key-Value (KV) базы

Хранят данные как ключ-значение, простые и быстрые.

  • Redis

  • RocksDB

  • sled

    • Встраиваемая, ACID key-value база, написана на Rust. Иногда называют «SQLite для KV».
  • redb

    • Современное встраиваемое KV-хранилище с ACID и транзакциями.
  • LMDB

    • Через heed — безопасный Rust-интерфейс.

3. Wide-column (таблицы как в Bigtable / Cassandra)

Хранят данные в виде строк и столбцов, масштабируются горизонтально.

  • ScyllaDB (совместим с Cassandra)

  • Cassandra

    • Можно работать через cdrs-tokio.

4. Графовые базы

Работают с данными в виде графов (узлы + связи).

  • Neo4j

    • neo4rs — async драйвер для Neo4j.
    • Использует протокол Bolt.

5. Поисковые движки (близко к NoSQL)

  • Tantivy — Rust-аналог Lucene.
  • MeiliSearch — поисковая база, написана на Rust, простой REST API.
  • Quickwit — распределённый поисковый движок, тоже на Rust.

Итог

  • Документные: MongoDB (через mongodb), CouchDB (couch_rs).
  • KV: Redis (redis-rs), sled (Rust-native), RocksDB, redb, LMDB.
  • Wide-column: ScyllaDB, Cassandra (cdrs-tokio).
  • Графовые: Neo4j (neo4rs).
  • Поиск (semi-NoSQL): Tantivy, MeiliSearch, Quickwit.

Очереди сообщений и брокеры в Rust

1. RabbitMQ (AMQP)

  • lapin

    • Популярный async AMQP 0.9.1 клиент.
    • Поддержка tokio, async-std.
    • Работает с RabbitMQ и совместимыми брокерами.
  • amiquip

    • Более старый sync-клиент для AMQP.

2. Kafka

  • rdkafka (официально: rust-rdkafka)

    • Обёртка над librdkafka (C-библиотека).

    • Очень производительная, production-ready.

    • Поддержка:

      • Consumer / Producer
      • Streaming API
      • Commit offset-ов
      • Async + интеграция с tokio.

3. NATS

  • nats

    • Лёгкий и быстрый брокер (часто называют "Redis для сообщений").
    • Поддержка Pub/Sub, очередей, JetStream (хранение сообщений).
    • Есть sync и async API.

4. MQTT (IoT и лёгкие брокеры)

  • rumqttc

    • Популярный MQTT v3/v5 клиент.
    • Есть async-версия (tokio).
  • mqtt-async-client

    • Асинхронный MQTT клиент.
  • Работает с брокерами: Mosquitto, HiveMQ, EMQX.


5. ZeroMQ / Nanomsg

  • zmq

    • Bindings к ZeroMQ (через C-библиотеку).
  • nng-rs

    • Rust-интерфейс к nanomsg-next-gen.
  • Хорошо подходят для быстрых одноузловых и распределённых систем.


6. Native Rust проекты (экспериментальные)

  • redis-pubsub

    • Redis можно использовать как брокер сообщений (через redis-rs).
  • Apache Pulsar

    • Есть async клиент для Pulsar.
  • Nats.io JetStream

    • Нативная поддержка персистентных очередей и стримов.

Итог

  • RabbitMQ / AMQPlapin (async, production-ready).
  • Kafkarust-rdkafka (производительность, масштабируемость).
  • NATSnats (лёгкий, быстрый, Pub/Sub + JetStream).
  • MQTTrumqttc или mqtt-async-client (IoT).
  • ZeroMQ/Nanomsgzmq, nng-rs (низкоуровневый messaging).
  • Экзотика → Pulsar (pulsar-rs), Redis Pub/Sub.

Сравнительная таблица: Очереди сообщений в Rust

Сравнительная таблица: Очереди сообщений в Rust

🐙 Брокер / Очередь🔗 Протокол📦 Основной crate⚡ Поддержка async🚀 Особенности / когда применять
RabbitMQAMQP 0.9.1lapin✅ Tokio / async-stdКлассическая очередь сообщений, подтверждения, маршрутизация, стабильность
amiquip❌ только syncСтарый клиент, можно для простых случаев
KafkaKafka APIrdkafka✅ TokioВысокая производительность, большие кластеры, стриминг данных
NATSNATSnats✅ sync + asyncЛёгкий брокер, Pub/Sub, очереди, JetStream (персистентность)
MQTT (Mosquitto, HiveMQ, EMQX)MQTT v3/v5rumqttc✅ TokioIoT, лёгкие устройства, стабильный клиент
mqtt-async-clientБолее минималистичный async MQTT клиент
ZeroMQZeroMQzmq❌ sync (через C)Высокая скорость, flexible messaging, подходит для P2P и микро-протоколов
Nanomsg / NNGNNGnng-rs✅ (частично)Простая альтернатива ZeroMQ, поддержка разных паттернов обмена
PulsarPulsar APIpulsar-rs✅ TokioАльтернатива Kafka, масштабируемые очереди и стримы
Redis (Pub/Sub, Streams)RESPredis-rs + deadpool-redisИспользуется как лёгкий брокер, Pub/Sub или очереди через Streams

Как выбрать?

  • Классический брокер → RabbitMQ (lapin)
  • Big Data, стриминг → Kafka (rdkafka)
  • Лёгкий брокер / Cloud-native → NATS (nats)
  • IoT и устройства → MQTT (rumqttc)
  • Низкоуровневый messaging → ZeroMQ (zmq) или Nanomsg (nng-rs)
  • Масштабируемая альтернатива Kafka → Pulsar (pulsar-rs)
  • Если уже есть Redis → использовать Pub/Sub или Streams (redis-rs)