GH GambleHub

Теңсіздік және кілттер

Демпотенттік дегеніміз не?

Теңсіздік - сол сәйкестендіргішпен қайталау қорытынды әсерді өзгертпейтін операция сипаты. Таратылған жүйелерде бұл нәтижені ретраға, хабарламалардың телнұсқаларына және таймауттарға қарамастан «дәл бір өңдеуге» баламалы етудің негізгі тәсілі.

Түйінді идея: әрбір әлеуетті қайталанатын операция жүйе «мұны жасады» деп танитын және нәтижені бір реттен артық қолданбайтын кілтпен белгіленуі тиіс.

Бұл қайда маңызды

Төлемдер және баланстар: 'operation _ id' бойынша есептен шығару/есепке алу.
Брондау/квоталар/лимиттер: бір слот/ресурс.
Вебхактар/ескертулер: қайталап жеткізу әсерді қайталамауы керек.
Импорттау/көшіру: файлдарды/пакеттерді қайталап жіберу.
Стрим-процессинг: брокерден/CDC.

Кілттердің түрлері және олардың қолданылу аясы

1. Operation key - бизнес-операцияның нақты әрекетінің сәйкестендіргіші

Мысалдар: 'idempotency _ key' (HTTP), 'operation _ id' (RPC).
Саласы: сервис/агрегат; дедупликация кестесінде сақталады.

2. Event key - оқиғаның/хабардың бірегей сәйкестендіргіші

Мысалдар: 'event _ id' (UUID), '(producer_id, sequence)'.
Облыс: тұтынушы/тұтынушылар тобы; проекцияларды қорғайды.

3. Business key - пәндік саланың табиғи кілті

Мысалдар: 'payment _ id', 'invoice _ number', '(user_id, day)'.
Аумағы: агрегат; бірегейлік/нұсқа тексерулерінде қолданылады.

💡 Көбінесе бірге қолданылады: 'operation _ id' команданы қорғайды, 'event _ id' - жеткізу, 'business key' - агрегаттың инварианттары.

TTL және сақтау саясаты

TTL кілттері ≥ мүмкін болатын қайталау терезесі: логтың ретенциясы + желілік/процестік кідірістер.
Сыни домендер (төлемдер) үшін TTL - күндер/апталар; телеметрия үшін - сағат.
Дедуп-кестелерді бэкграунд-джобтармен тазалаңыз; аудит үшін - мұрағаттаңыз.

Кілттер қоймасы (дедупликация)

Транзакциялық ДБ (ұсынылады): сенімді upsert/unique-индекстер, әсері бар бірлескен транзакция.
KV/Redis: жылдам, қысқа TTL үшін ыңғайлы, бірақ OLTP-мен бірлескен транзакциясыз - абайлаңыз.
State store стрим-процессоры: жергілікті + брокердегі чейнджлог; жақсы Flink/KStreams.

Схема (ДҚ-дағы нұсқа):
  • idempotency_keys

`consumer_id` (или `service`), `op_id` (PK на пару), `applied_at`, `ttl_expires_at`, `result_hash`/`response_status` (опц.) .

Индекстер: '(consumer_id, op_id)' - бірегей.

Іске асырудың базалық тәсілдері

1) «Нәтиже + прогресс» транзакциясы

Нәтижені жазу және оқу/позиция прогресін тіркеу - бір транзакцияда.

pseudo begin tx if not exists(select 1 from idempotency_keys where consumer=:c and op_id=:id) then
-- apply effect atomically (upsert/merge/increment)
apply_effect(...)
insert into idempotency_keys(consumer, op_id, applied_at)
values(:c,:id, now)
end if
-- record reading progress (offset/position)
upsert offsets set pos=:pos where consumer=:c commit

2) Optimistic Concurrency (агрегаттың нұсқасы)

Жарыс кезінде қосарлы әсерден қорғайды:
sql update account set balance = balance +:delta,
version = version + 1 where id=:account_id and version=:expected_version;
-- if 0 rows are updated → retry/conflict

3) Іспеттес sinks (upsert/merge)

Бір рет есептеу "әрекеті:
sql insert into bonuses(user_id, op_id, amount)
values(:u,:op,:amt)
on conflict (user_id, op_id) do nothing;

Хаттамалардағы сәйкестік

HTTP/REST

'Idempotency-Key' атауы: <uid 'hash>'.
Сервер кілттің жазбасын сақтайды және сол жауапты қайтарады (немесе '409 '/' 422' коды инварианттар қайшылығында).
«Қауіпсіз емес» POST үшін - міндетті 'Idempotency-Key' + тұрақты таймаут/ретрай-саясат.

gRPC/RPC

'idempotency _ key', 'request _ id' + deadline метадеректері.
Серверлік іске асыру - REST-дегі сияқты: транзакциядағы дедуп кестесі.

Брокерлер/стриминг (Kafka/NATS/Pulsar)

Продюсер: тұрақты 'event _ id '/демпотенттік продюсер (қолдау көрсетілетін).
Консьюмер: '(consumer_id, event_id)' бойынша және/немесе агрегаттың бизнес-нұсқасы бойынша дедуп.
Демпотенттік емес/зақымдалған хабарлар үшін жеке DLQ.

Вебхактар және сыртқы әріптестер

Келісімшартта 'Idempotency-Key '/' event _ id' дегенді талап етіңіз; қайта жеткізу қауіпсіз болуы тиіс.
'notification _ id' және жіберу мәртебелерін сақтаңыз; ретра кезінде - қайталамаңыз.

Кілттерді жобалау

Детерминирленуі: ретраялар сол кілтті жіберуі тиіс (клиентке/оркестрге алдын ала генерациялаңыз).
Көріну аумағы: 'op _ id' дегенді 'service: aggregate: id: purpose' деп пішіңіз.
Коллизиялар: бизнес параметрлерінен UUIDv7/ULID немесе хэшті қолданыңыз (қажет болған жағдайда тұзбен).
Иерархия: фронтқа жалпы 'operation _ id' → барлық кіші операцияларға (идемпотенттік тізбек) трансляцияланады.

UX және азық-түлік аспектілері

Кілт бойынша қайта сұрау сол нәтижені (дене/мәртебені қоса алғанда) немесе анық «орындалды» қайтаруы тиіс.
Сәтті қайтадан әрекет жасаудың орнына «операция өңделеді/аяқталды» күйін көрсетіңіз.
Ұзақ операциялар үшін - кілт бойынша поллинг ('GET/operations/{ op _ id}').

Бақылау

'op _ id', 'event _ id', 'trace _ id' деп логин жасаңыз, нәтижесі: 'APPLIED '/' ALREADY _ APPLIED'.
Өлшемдер: қайталау үлесі, дедуп-кесте мөлшері, транзакция уақыты, нұсқа қайшылықтары, DLQ-ставка.
Трейс: кілт пәрмен арқылы өтуі керек → оқиға → проекция → сыртқы қоңырау.

Қауіпсіздік және комплаенс

PII кілттерде сақтамаңыз; кілт - идентификатор, payload емес.
Ұзақ TTL кезінде дедуп жазбаларындағы сезімтал өрістерді шифрлаңыз.
Сақтау саясаты: TTL және мұрағаттар; ұмыту құқығы - жауаптарды/метадеректерді (егер олар PII болса) крипто-өшіру арқылы.

Тестілеу

1. Телнұсқалар: бір хабарды/сұрауды 2-5 рет басып өту - дәл бір нәтиже.
2. Қадамдар арасындағы құлау: әсерді жазуға дейін/кейін, офсетті бекітуге дейін/кейін.
3. Тұтынушылардың қайта стандарты/ребалансы: екі рет қолданылмайды.
4. Бәсекелестік: бір 'op _ id' → бір әсері бар параллель сұраулар, екіншісі - 'ALREADY _ APPLIED/409'.
5. Ұзақ өмір сүретін кілттер: қалпына келтірілгеннен кейін TTL мен қайталаудың аяқталуын тексеру.

Антипаттерндер

Әрбір ретрайдың кездейсоқ жаңа кілті: жүйе қайталауды танымайды.
Екі бөлек коммита: алдымен әсер, содан кейін офсет - олардың арасындағы құлау әсерді қайталайды.
Тек брокерге ғана сенім: синкада/агрегатта дедуптың болмауы.
Агрегат нұсқасының болмауы: қайталанған оқиға күйді екінші рет өзгертеді.
Fat keys: кілт бизнес-өрістерді/PII → ағып кетуді және күрделі индекстерді қамтиды.
Қайталанатын жауаптардың болмауы: клиент қауіпсіз ретрациялай алмайды.

Мысалдар

Төлем POST

Клиент: 'POST/payments' + 'Idempotency-Key: k-789'.
Сервер: транзакция - 'payment' және 'idempotency _ keys' жазбасын жасайды.
Қайталау: сол '201 '/денені қайтарады; инвариант қақтығысы кезінде - '409'.

Бонусты есептеу (sink)

sql insert into credits(user_id, op_id, amount, created_at)
values(:u,:op,:amt, now)
on conflict (user_id, op_id) do nothing;

Оқиғалар проекциясы

Консьюмер 'seen (event_id)' және 'version' агрегатын сақтайды; қайталау - ignor/idempotent upsert.
Оқу прогресі проекцияны жаңарту сияқты транзакцияда тіркеледі.

Шығарылған чек-парақ

  • Барлық қауіпсіз емес операциялар үшін идемпотенттік кілт және оның көріну аумағы анықталған.
  • TTL және бірегей индекстері бар дедуп кестелері бар.
  • Оқудың әсері мен прогресі атомдық түрде қосылады.
  • Write-модельде оптимистік бәсекелестік бар (нұсқа/sequence).
  • API келісімшарттары 'Idempotency-Key '/' operation _ id' және қайталау мінез-құлқын белгілейді.
  • Метриктер мен логдарда 'op _ id '/' event _ id '/' trace _ id' бар.
  • Телнұсқа, құлау және жарыс тестілері - CI.
  • TTL/мұрағат саясаты және PII қауіпсіздігі сақталған.

FAQ

'Idempotency-Key' дегеннің 'Request-Id' дегеннен айырмашылығы неде?
'Request-Id' - трассировка; ол ретраяларда өзгеруі мүмкін. 'Idempotency-Key' - қайталау кезінде бірдей семантикалық идентификатор.

ДБ-сыз теңсіздік жасауға бола ма?
Қысқа терезе үшін - иә (Redis/процессішілік кэш), бірақ бірлескен транзакциясыз дубль қаупі артады. Сындарлы домендерде - бір БД-транзакциясында жақсы.

Сыртқы серіктестермен не істеу керек?
Кілттер мен қайталанатын жауаптар туралы келісіңіз. Егер серіктес қолдамаса, қоңырауды теңсіздік қабатыңызға айналдырып, «қолданылған» күйінде сақтаңыз.

TTL қалай таңдауға болады?
Максималды кідірістерді қосыңыз: логтың ретенциясы + worst-case желісі/ребаланс + буфер. Қор қосыңыз (× 2).

Жиынтығы

Теңсіздік - бұл кілттердің, транзакциялардың және нұсқалардың тәртібі. Операциялардың тұрақты сәйкестендіргіштері + оқу әсері мен прогресін атомарлық бекіту + демпотенттік sinks/проекциялар көлік деңгейінің сиқырынсыз «тура бір әсер» береді. Кілттерді детерминирленген, TTL - шынайы, ал тестілерді - жаман ниетті етіңіз. Сонда ретрациялар мен дубликаттар қақтығыс емес, дағдыға айналады.

Contact

Бізбен байланысыңыз

Кез келген сұрақ немесе қолдау қажет болса, бізге жазыңыз.Біз әрдайым көмектесуге дайынбыз!

Интеграцияны бастау

Email — міндетті. Telegram немесе WhatsApp — қосымша.

Сіздің атыңыз міндетті емес
Email міндетті емес
Тақырып міндетті емес
Хабарлама міндетті емес
Telegram міндетті емес
@
Егер Telegram-ды көрсетсеңіз — Email-ге қоса, сол жерге де жауап береміз.
WhatsApp міндетті емес
Пішім: +ел коды және номер (мысалы, +7XXXXXXXXXX).

Батырманы басу арқылы деректерді өңдеуге келісім бересіз.