Redis клиент для Rust: библиотека redis-rs
Библиотека redis-rs — это основной и наиболее популярный клиент для работы с Redis в экосистеме Rust. Она предоставляет полный набор функций для взаимодействия с Redis: от простых команд GET/SET до сложных транзакций, пайплайнов и Pub/Sub. Благодаря поддержке как синхронного, так и асинхронного (async/await) режимов, redis-rs подходит для любых проектов — от скриптов до высоконагруженных веб-серверов.
Библиотека написана на чистом Rust, использует безопасную работу с памятью и типобезопасность, что минимизирует ошибки времени выполнения. Поддерживаются все популярные типы данных Redis: строки, списки, множества, хеши, отсортированные множества, битовые карты, HyperLogLog и потоки.
Установка и подключение
Добавьте зависимость в файл Cargo.toml:
[dependencies]
redis = { version = "0.27", features = ["tokio-comp"] }
Для синхронного использования достаточно просто redis = "0.27". Для асинхронного — выберите один из исполнителей: tokio-comp (по умолчанию) или async-std-comp.
Базовое использование (синхронный режим)
Пример подключения к локальному Redis и выполнения простых команд:
use redis::Commands;
fn main() -> redis::RedisResult<()> {
let client = redis::Client::open("redis://127.0.0.1:6379/")?;
let mut con = client.get_connection()?;
con.set("my_key", "hello world")?;
let value: String = con.get("my_key")?;
println!("Получено значение: {}", value);
// Работа с хешами
con.hset("user:1", "name", "Alice")?;
con.hset("user:1", "age", "30")?;
let name: String = con.hget("user:1", "name")?;
println!("Имя пользователя: {}", name);
Ok(())
}
Обратите внимание на автоматическую десериализацию: вы указываете тип, в который нужно преобразовать результат (String, i32, Vec<String> и т.д.), и библиотека делает всё сама.
Асинхронный режим с Tokio
Для высокопроизводительных приложений используйте асинхронный API:
use redis::AsyncCommands;
use tokio;
#[tokio::main]
async fn main() -> redis::RedisResult<()> {
let client = redis::Client::open("redis://127.0.0.1:6379/")?;
let mut con = client.get_multiplexed_async_connection().await?;
// Установка с TTL (время жизни ключа)
con.set_ex("temp_key", "временное значение", 60).await?;
let val: Option<String> = con.get("temp_key").await?;
println!("Значение: {:?}", val);
// Работа со списками
con.lpush("queue", "task1").await?;
con.lpush("queue", "task2").await?;
let tasks: Vec<String> = con.lrange("queue", 0, -1).await?;
println!("Задачи в очереди: {:?}", tasks);
Ok(())
}
Асинхронный клиент использует мультиплексированные соединения (один TCP-сокет для множества запросов), что значительно повышает производительность.
Расширенные возможности
Пайплайны (конвейерная обработка)
Позволяют отправить несколько команд за один сетевой вызов, что ускоряет пакетные операции:
use redis::pipe;
fn main() -> redis::RedisResult<()> {
let client = redis::Client::open("redis://127.0.0.1:6379/")?;
let mut con = client.get_connection()?;
let (val1, val2): (i32, i32) = redis::pipe()
.cmd("INCR").arg("counter_a").ignore()
.cmd("INCR").arg("counter_b").ignore()
.cmd("GET").arg("counter_a").query(&mut con)?
.cmd("GET").arg("counter_b").query(&mut con)?;
println!("Счётчики: {}, {}", val1, val2);
Ok(())
}
Pub/Sub (издатель-подписчик)
Пример подписки на каналы:
use redis::pubsub::PubSubCommands;
fn main() -> redis::RedisResult<()> {
let client = redis::Client::open("redis://127.0.0.1:6379/")?;
let mut con = client.get_connection()?;
con.subscribe(&["news", "updates"], |msg| {
let channel = msg.get_channel_name();
let payload: String = msg.get_payload()?;
println!("Канал: {}, сообщение: {}", channel, payload);
Ok(())
}