Back to questions
Senior
7
Как синхронизировать воркеры через Redis, чтобы два воркера не обрабатывали один объект одновременно?
Companies where asked
Не указано
Answer from AI
sobes.tech AI
Для синхронизации воркеров через Redis и предотвращения одновременной обработки одного объекта можно использовать механизм распределённых блокировок (distributed locks). Один из распространённых подходов — использовать команду SET с параметрами NX (установить, если ключ не существует) и PX (время жизни ключа) для создания блокировки.
Пример на Go с использованием библиотеки go-redis:
import (
"context"
"time"
"github.com/go-redis/redis/v8"
)
func acquireLock(ctx context.Context, rdb *redis.Client, key string, ttl time.Duration) (bool, error) {
// Попытка установить ключ с уникальным значением и временем жизни
ok, err := rdb.SetNX(ctx, key, "locked", ttl).Result()
return ok, err
}
func releaseLock(ctx context.Context, rdb *redis.Client, key string) error {
return rdb.Del(ctx, key).Err()
}
// В воркере:
ctx := context.Background()
lockKey := "lock:object_id"
lockTTL := 30 * time.Second
locked, err := acquireLock(ctx, rdb, lockKey, lockTTL)
if err != nil {
// обработка ошибки
}
if !locked {
// другой воркер уже обрабатывает объект
return
}
// Обработка объекта
// После обработки снимаем блокировку
_ = releaseLock(ctx, rdb, lockKey)
Важно, чтобы время жизни блокировки (TTL) было достаточно большим, чтобы покрыть время обработки, но не слишком большим, чтобы избежать долгой блокировки при сбое воркера. Для более надёжных решений можно использовать алгоритм Redlock.