Грейды уже не гарантируют рост зарплаты, джоб-борды теряют эффективность, а AI вмешался в процесс собеседований так, что теперь компании делятся на лагеря — одни разрешают использовать ChatGPT, другие устраивают собесы с ручкой и листочком.
В карточках — пять главных трендов рынка найма: от умирания грейдинга до смещения фокуса на удержание сотрудников.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Продолжаем удалять данные из кэша.
6. Distributed Cache: TTL + массовая очистка
Выстраивайте строгую схему ключей и при удалении — удаляйте все производные ключи.
// go-redis: массовая очистка по шаблону (осторожно с KEYS/SCAN на больших объёмах)
func PurgeUserKeys(ctx context.Context, rdb *redis.Client, id int64) error {
pattern := fmt.Sprintf("user:%d*", id)
iter := rdb.Scan(ctx, 0, pattern, 1000).Iterator()
var batch []string
for iter.Next(ctx) {
batch = append(batch, iter.Val())
if len(batch) == 500 {
if err := rdb.Del(ctx, batch...).Err(); err != nil { return err }
batch = batch[:0]
}
}
if err := iter.Err(); err != nil { return err }
if len(batch) > 0 { return rdb.Del(ctx, batch...).Err() }
return nil
}
7. Full-Text Search: delete + refresh + мердж сегментов
Удалили документ в БД — обязательно удалите его копию в индексе и дождитесь применения.
// elastic/go-elasticsearch: удаление документа и ожидание refresh
func EsDeleteUser(ctx context.Context, es *elasticsearch.Client, id string) error {
res, err := es.Delete("users", id, es.Delete.WithRefresh("wait_for"))
if err != nil { return err }
defer res.Body.Close()
return nil
}
Периодически запускайте force merge (операционно, не на горячем трафике), чтобы физически убрать «мертвые» сегменты.
8. База данных: очистка данных и следов
В самой БД есть несколько мест, куда попадают копии: WAL/Redo, buffer pool, материализованные представления, транзакционные/репликационные логи.
Минимальный чек-лист (PostgreSQL в примерах):
• DELETE/UPDATE данных.
• Обновление/перестроение materialized views.
• Политики хранения логов (WAL/archive) и VACUUM (FULL), ANALYZE.
• Очистка репликационного слота/логов при необходимости.
-- 1) Удаление
DELETE FROM users WHERE id = $1;
-- 2) Обновление материализованных представлений
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_user_stats;
-- 3) Вакуум для физического освобождения (по оконным периодам, не на пике)
VACUUM (VERBOSE, ANALYZE) users;
-- В крайних случаях:
-- VACUUM FULL users; -- блокирует таблицу, используйте осторожно
-- 4) Политики логов/архива
-- настройте wal_keep_size, archive_timeout и ротацию архивов под SLA удаления
9. Согласованная оркестрация удаления: событийный подход
Надёжный способ: one-shot Use-Case «EraseUser», который последовательно триггерит очистку по всем слоям и ведёт аудит.
type Eraser interface {
EraseInDB(ctx context.Context, userID string) error
EraseInRedis(ctx context.Context, userID string) error
EraseInSearch(ctx context.Context, userID string) error
EraseInCDN(ctx context.Context, userID string) error
EraseInBrokers(ctx context.Context, userID string) error
}
func EraseUser(ctx context.Context, e Eraser, userID string) error {
steps := []func(context.Context, string) error{
e.EraseInDB,
e.EraseInRedis,
e.EraseInSearch,
e.EraseInCDN,
e.EraseInBrokers,
}
for _, step := range steps {
if err := step(ctx, userID); err != nil {
// логируем, шлём алерты, можно ретраить по политике
return fmt.Errorf("erase step failed: %w", err)
}
}
return nil
}
«Гарантированное» удаление — это оркестрация инвалидации по всем слоям с чёткой политикой хранения и короткими TTL, плюс периодическое физическое обслуживание (VACUUM/force-merge/compaction).
#буст
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2🔥1