Arhitektūra

Redis "CROSSSLOT Keys in request don't hash to the same slot": pareizi lietoti hash tagi

Kods, kas lieliski strādāja vienā Redis instancē, salūzt dienā, kad pārejat uz Redis Cluster vai Valkey Cluster. Iemesls ir CROSSSLOT kļūda, un risinājums ir hash tagi, ja vien nesakraujat visu datu kopu vienā slotā.

· 10 min lasīšanai · AG Data komanda

Redis "CROSSSLOT Keys in request don't hash to the same slot" ir kļūda, ko saņemat, kad viena komanda, transakcija vai skripts skar atslēgas, kas atrodas dažādos Redis Cluster hash slotos. Vienā instancē tas pats kods strādā. Klasterī atslēgas ir sadalītas pa mezgliem, un Redis atsakās izpildīt operācijas ar vairākām atslēgām, kuras tas nevar atomāri izpildīt vienā mezglā. Valkey Cluster atgriež tieši tādu pašu ziņojumu.

Kāpēc šī kļūda pastāv

Redis Cluster specifikācija sadala atslēgu telpu 16384 hash slotos, HASH_SLOT = CRC16(key) mod 16384. Katram primārajam mezglam pieder daļa slotu. Komanda, piemēram, MGET a b, ir droša tikai tad, ja abas atslēgas ir vienā mezglā, un Redis to pārbauda slotu līmenī: visām pieprasījuma atslēgām jāatbilst vienam slotam, nevis tikai vienam mezglam. Ja tā nav, mezgls atbild ar CROSSSLOT un neko neizpilda.

127.0.0.1:7000> MGET user:1000:name user:1001:name
(error) CROSSSLOT Keys in request don't hash to the same slot

127.0.0.1:7000> CLUSTER KEYSLOT user:1000:name
(integer) ...
127.0.0.1:7000> CLUSTER KEYSLOT user:1001:name
(integer) ...    # a different slot

Kur tā parādās

Risinājums: hash tagi

Hash tags liek Redis hešot tikai daļu atslēgas. Specifikācija dod precīzus noteikumus: ja atslēgā ir {, pa labi no tās ir } un starp pirmo { un pirmo sekojošo } ir vismaz viena rakstzīme, tad hešo tikai šo apakšvirkni.

{user:1000}.name       -> hešo "user:1000"
{user:1000}.cart       -> hešo "user:1000"   (tas pats slots)
foo{}{bar}             -> hešo visu atslēgu (pirmais tags tukšs)
foo{{bar}}zap          -> hešo "{bar"
foo{bar}{zap}          -> hešo "bar" (skaitās tikai pirmais tags)

Tāpēc tipisks labojums ir ielikt entītijas ID figūriekavās tām atslēgām, kuras jāizmanto kopā:

# pirms: atslēgas nonāk nejaušos slotos
MSET user:1000:name Anna user:1000:email anna@example.com

# pēc: viens hash tags, viens slots, MSET klasterī strādā
MSET {user:1000}:name Anna {user:1000}:email anna@example.com

# pārbaudiet pirms izlaišanas
CLUSTER KEYSLOT {user:1000}:name
CLUSTER KEYSLOT {user:1000}:email

CLUSTER KEYSLOT parāda slotu jebkuram atslēgas nosaukumam. Ielieciet to testā, lai pārdēvēta atslēga vēlāk klusi nesalauztu transakciju.

Citi risinājumi

  1. Sadaliet pieprasījumu pa slotiem. Ja atomaritāte nav vajadzīga, izpildiet vienu komandu katram slotam. Daži klienti to dara jūsu vietā; piemēram, redis-py klastera klientam ir mget_nonatomic un mset_nonatomic, kas sagrupē atslēgas pa slotiem un katram slotam sūta vienu MGET vai MSET. Nosaukums ir godīgs: rezultāts vairs nav atomārs.
  2. Pārdomājiet datu modeli. Vairākas atslēgas, kas vienmēr mainās kopā, bieži labāk glabāt vienā hash. Lietotāja profilam HSET {user:1000} name ... email ... atomaritāte starp atslēgām vispār nav vajadzīga.
  3. Skripta karogs allow-cross-slot-keys. Redis 7+ skripti un funkcijas var deklarēt šo karogu, lai piekļūtu nedeklarētām atslēgām no vairākiem slotiem. Dokumentācijā teikts, ka deklarētajām atslēgām joprojām jāhešojas uz vienu slotu, un piekļuve vairākiem slotiem nav ieteicama; pirmkodā atslēga, ko apkalpo cits mezgls, joprojām izraisa kļūdu. Uztveriet to kā migrācijas palīglīdzekli, nevis dizainu.
Nerisiniet CROSSSLOT, uzliekot visam vienu konstantu tagu. Prefikss, piemēram, {app}: uz katras atslēgas nosūta visu datu kopu vienā slotā, tāpēc viens mezgls glabā visu un saņem visu slodzi. Klasteris joprojām darbojas, bet jūs esat atpakaļ pie viena servera, tikai ar papildu sarežģītību.

Hash tagi lielās datu kopās

Ja klasteris pats pārstāj apkalpot slotus, tā ir cita problēma: skatiet mūsu ceļvedi par Redis CLUSTERDOWN.

Galvenās atziņas

Redis Valkey Redis Cluster Hash tagi
Sadarbība ar mums

Pārejat uz Redis Cluster?

Pirms migrācijas pārskatām atslēgu dizainu, komandas ar vairākām atslēgām un skriptus, lai klasteris vienmērīgi sadalītu slodzi un pirmajā izlaidumā nekas nesalūztu.

Sazināties Vairāk no emuāra