Strona główna / Artykuły

Przenieś stan wektorowy LangGraph z pamięci do trwałego przechowywania w Redis

Przenieś stan wektorowy LangGraph z pamięci do Redis za pomocą fabryki get_vector_store, z metadanymi sesji przy pobieraniu danych, filtrowanym wyszukiwaniem oraz usuwaniem według sesji.

Wydawca: REACTAPP.TOP13 min czytania3102 słów

Źródła: From In-Memory to Redis: Vector Persistence

Zbiory wektorów w pamięci są najprostszym poprawnym rozwiązaniem tylko wtedy, gdy jeden proces kontroluje całą rozmowę. Prawdziwe backendy podważają to założenie: nowe uruchomienia CLI, nowe pracowniki HTTP, restarty oraz wdrożenia z wieloma instancjami. Trwałość oznacza przeniesienie tych samych węzłów LangGraph do Redis (lub innego trwałego indeksu wektorowego) bez konieczności przepisywania logiki produktu.

1. get_vector_store() — jedyna funkcja, która musiała ulec zmianie

Abstrakcyjna struktura stojąca za mechanizmem tworzenia obiektów. Użycie pamięci operacyjnej do testów; adres URL Redis oraz nazwa indeksu w środowiskach produkcyjnych.

_SESSION_STORES: Dict[str, InMemoryVectorStore] = {}

def get_vector_store(session_id: str) -> InMemoryVectorStore:
    if session_id not in _SESSION_STORES:
        _SESSION_STORES[session_id] = InMemoryVectorStore(embeddings)
    return _SESSION_STORES[session_id]
def get_vector_store(session_id: str) -> RedisVectorStore:
    redis_config = RedisConfig(
        index_name=f"session:{session_id}",
        redis_url=config.REDIS_URL,
        embedding_dimensions=config.EMBEDDING_DIMENSIONS,
        metadata_schema=[
            {"name": "session_id", "type": "tag"},
            {"name": "file_name", "type": "tag"},
        ],
    )
    return RedisVectorStore(embeddings, config=redis_config, ttl=config.SESSION_TTL_SECONDS)
docs = [
    Document(
        page_content=c["text"],
        metadata={
            "session_id": state["session_id"],  # <-- added back
            "file_name": c["file_name"],
            "chunk_index": c["chunk_index"],
        },
    )
    for c in chunks
]
state["retrieved"] = vs.similarity_search(
    state["query"],
    k=config.TOP_K,
    filter=Tag("session_id") == state["session_id"],
)
def clear_session(session_id: str) -> None:
    get_vector_store(session_id).index.delete(drop=True)
uv add langgraph langchain-core langchain-openai langchain-text-splitters \
       azure-ai-documentintelligence azure-core \
       langchain-redis redisvl \
       python-dotenv
REDIS_PASSWORD=changeme docker compose up -d
[+] Running 3/3
 ✔ Network redismanualvectorization_default      Created                                                                                       0.0s
 ✔ Volume "redismanualvectorization_redis-data"  Created                                                                                       0.0s
 ✔ Container usb-redis-vector-store              Started
AZURE_OPENAI_ENDPOINT=https://aif-cus-aisearchegs-dev-01.cognitiveservices.azure.com/
AZURE_OPENAI_API_KEY=<Redacted>
# AZURE_OPENAI_API_VERSION = os.environ.get("AZURE_OPENAI_API_VERSION", "2024-10-21")
AZURE_OPENAI_EMBEDDING_DEPLOYMENT=text-embedding-3-small
AZURE_OPENAI_CHAT_DEPLOYMENT="gpt-5-mini"
# --- Azure Document Intelligence (used for all file text extraction) ---
DOCUMENTINTELLIGENCE_ENDPOINT=https://adi-cus-aisearchegs-dev-01.cognitiveservices.azure.com/
DOCUMENTINTELLIGENCE_KEY=<Redacted>
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=changeme
SESSION_TTL_SECONDS=14400
uv run python -m src.redismanualvectorization.main \
  --session demo1 \
  --files ./source/sample_bank_statement.pdf ./source/sample_loan_agreement.pdf
Ingested 2 file(s) into session 'demo1' (persisted in Redis).
docker exec -it usb-redis-vector-store redis-cli -a changeme
FT._LIST
# Execution results
1) session:demo2
2) session:demo1
FT.INFO session:demo1

# Execution results
1) index_name
 2) session:demo1
 3) index_options
 4) (empty array)
 5) index_definition
 6) 1) key_type
    2) HASH
    3) prefixes
    4) 1) session:demo1:
    5) default_score
    6) "1"
 7) attributes
 8) 1) 1) identifier
       2) text
       3) attribute
       4) text
       5) type
       6) TEXT
       7) WEIGHT
       8) "1"
    2)  1) identifier
        2) embedding
        3) attribute
        4) embedding
        5) type
        6) VECTOR
        7) algorithm
        8) FLAT
        9) data_type
       10) FLOAT32
       11) dim
       12) (integer) 1536
       13) distance_metric
       14) COSINE
    3) 1) identifier
       2) _index_name
       3) attribute
       4) _index_name
       5) type
       6) TEXT
       7) WEIGHT
       8) "1"
    4) 1) identifier
       2) _metadata_json
       3) attribute
       4) _metadata_json
       5) type
       6) TEXT
       7) WEIGHT
       8) "1"
    5) 1) identifier
       2) session_id
       3) attribute
       4) session_id
       5) type
       6) TAG
       7) SEPARATOR
       8) |
    6) 1) identifier
       2) file_name
       3) attribute
       4) file_name
       5) type
       6) TAG
       7) SEPARATOR
       8) |
 9) num_docs
10) (integer) 24
11) max_doc_id
12) (integer) 24
13) num_terms
14) (integer) 850
15) num_records
16) (integer) 1921
17) inverted_sz_mb
18) "0.09056949615478516"
19) vector_index_sz_mb
20) "6.0091552734375"
21) total_inverted_index_blocks
22) (integer) 853
23) offset_vectors_sz_mb
24) "0.0028848648071289063"
25) doc_table_size_mb
26) "0.017791748046875"
27) sortable_values_size_mb
28) "0"
29) key_table_size_mb
30) "7.74383544921875e-4"
31) tag_overhead_sz_mb
32) "1.10626220703125e-4"
33) text_overhead_sz_mb
34) "0.028371810913085938"
35) total_index_memory_sz_mb
36) "0.14574527740478516"
37) geoshapes_sz_mb
38) "0"
39) records_per_doc_avg
40) "80.04166412353516"
41) bytes_per_record_avg
42) "49.43727111816406"
43) offsets_per_term_avg
44) "1.5065070390701294"
45) offset_bits_per_record_avg
46) "8.362128257751465"
47) hash_indexing_failures
48) (integer) 0
49) total_indexing_time
50) "11.055999755859375"
51) indexing
52) (integer) 0
53) percent_indexed
54) "1"
55) number_of_uses
56) (integer) 3
57) cleaning
58) (integer) 0
59) gc_stats
60)  1) bytes_collected
     2) "0"
     3) total_ms_run
     4) "0"
     5) total_cycles
     6) "0"
     7) average_cycle_time_ms
     8) "nan"
     9) last_run_time_ms
    10) "0"
    11) gc_numeric_trees_missed
    12) "0"
    13) gc_blocks_denied
    14) "0"
61) cursor_stats
62) 1) global_idle
    2) (integer) 0
    3) global_total
    4) (integer) 0
    5) index_capacity
    6) (integer) 128
    7) index_total
    8) (integer) 0
63) dialect_stats
64) 1) dialect_1
    2) (integer) 0
    3) dialect_2
    4) (integer) 1
    5) dialect_3
    6) (integer) 0
    7) dialect_4
    8) (integer) 0
65) Index Errors
66) 1) indexing failures
    2) (integer) 0
    3) last indexing error
    4) N/A
    5) last indexing error key
    6) "N/A"
    7) background indexing status
    8) OK
67) field statistics
68) 1) 1) identifier
       2) text
       3) attribute
       4) text
       5) Index Errors
       6) 1) indexing failures
          2) (integer) 0
          3) last indexing error
          4) N/A
          5) last indexing error key
          6) "N/A"
    2) 1) identifier
       2) embedding
       3) attribute
       4) embedding
       5) Index Errors
       6) 1) indexing failures
          2) (integer) 0
          3) last indexing error
          4) N/A
          5) last indexing error key
          6) "N/A"
    3) 1) identifier
       2) _index_name
       3) attribute
       4) _index_name
       5) Index Errors
       6) 1) indexing failures
          2) (integer) 0
          3) last indexing error
          4) N/A
          5) last indexing error key
          6) "N/A"
    4) 1) identifier
       2) _metadata_json
       3) attribute
       4) _metadata_json
       5) Index Errors
       6) 1) indexing failures
          2) (integer) 0
          3) last indexing error
          4) N/A
          5) last indexing error key
          6) "N/A"
    5) 1) identifier
       2) session_id
       3) attribute
       4) session_id
       5) Index Errors
       6) 1) indexing failures
          2) (integer) 0
          3) last indexing error
          4) N/A
          5) last indexing error key
          6) "N/A"
    6) 1) identifier
       2) file_name
       3) attribute
       4) file_name
       5) Index Errors
       6) 1) indexing failures
          2) (integer) 0
          3) last indexing error
          4) N/A
          5) last indexing error key
          6) "N/A"
num_docs            24
vector_index_sz_mb   6.0091552734375
24 × 1536 × 4 bytes = 147,456 bytes ≈ 0.14 MB
FT.SEARCH session:demo1 "*" LIMIT 0 5 RETURN 3 file_name session_id text
# Execution Results
1) (integer) 24
 2) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2V"
 3) 1) "file_name"
    2) "sample_bank_statement.pdf"
    3) "session_id"
    4) "demo1"
    5) "text"
    6) "##### Monthly Maintenance Fee\n\nA $12.00 monthly maintenance fee applies unless one of the following waiver conditions is met during the statement period: (a) a minimum daily balance of\n$1,500 is maintained, (b) total qualifying direct deposits of $500 or more are received, or (c) the account holder is enrolled in a linked student or senior\naccount program. Fee waiver eligibility is evaluated at the end of each statement cycle based on the criteria above.\n\n\n##### Error Resolution & Your Rights"
 4) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G31"
 5) 1) "file_name"
    2) "sample_loan_agreement.pdf"
    3) "session_id"
    4) "demo1"
    5) "text"
    6) "\"Scheduled Payment Date\" means the 15th calendar day of each month during the Loan Term, or the next Business Day\nif the 15th falls on a non-Business Day.\n\n<!-- PageBreak -->\n\n\n# SAMPLE AGREEMENT - SYNTHETIC TEST DATA - NOT A REAL LOAN DOCUMENT\n\n\n## 4. Amortization Schedule (First 12 Payments)"
 6) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G34"
 7) 1) "file_name"
    2) "sample_loan_agreement.pdf"
    3) "session_id"
    4) "demo1"
    5) "text"
    6) "A complete 48-month amortization schedule is available from the Lender upon request. Figures above are rounded to the\nnearest cent and may differ slightly from actual billed amounts due to daily interest accrual conventions.\n\n\n## 5. Prepayment\n\nBorrower may prepay all or part of the outstanding Principal Amount at any time without penalty. Partial prepayments will be\napplied first to accrued interest, then to outstanding fees, then to Principal, and will not change the Scheduled Payment\nDate or Monthly Payment amount unless the Borrower requests and the Lender approves a loan re-amortization in writing.\n\n\n### 6. Late Payments and Default"
 8) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2T"
 9) 1) "file_name"
    2) "sample_bank_statement.pdf"
    3) "session_id"
    4) "demo1"
    5) "text"
    6) "##### Interest Rate & Annual Percentage Yield\n\nThis account earns interest at a variable rate, currently 0.15% with an Annual Percentage Yield (APY) of 0.15%, applied to the average daily balance.\nInterest is compounded monthly and credited to your account on the last business day of the statement period, shown in the Transaction History as 'Interest\nPayment'. Rates are subject to change without notice at the bank's discretion and are current as of the statement date shown on page one.\n\n\n##### Monthly Maintenance Fee"
10) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2W"
11) 1) "file_name"
    2) "sample_bank_statement.pdf"
    3) "session_id"
    4) "demo1"
    5) "text"
    6) "##### Error Resolution & Your Rights\n\nIn case of errors or questions about electronic transfers, telephone the bank at the number on your card or write to the address on file as soon as possible.\nThe bank must hear from you no later than 60 days after the first statement on which the problem appears. You will need to provide your name and account\nnumber, describe the error, and state the dollar amount of the suspected error. The bank will investigate and report results within 10 business days, or\nwithin 45 days for transactions initiated outside a 30-day period after the first deposit to the account.\n\n\n##### Funds Availability"
127.0.0.1:6379> SCAN 0 MATCH session:demo1:*
1) "22"
2)  1) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2S"
    2) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2X"
    3) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2R"
    4) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G33"
    5) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2V"
    6) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G30"
    7) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2Z"
    8) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G36"
    9) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2P"
   10) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2Y"
1) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2V"
   file_name    sample_bank_statement.pdf
   session_id   demo1
   text         "##### Monthly Maintenance Fee
A $12.00 monthly maintenance fee applies unless one of the
                 following waiver conditions is met during the statement
                 period: (a) a minimum daily balance of $1,500 is
                 maintained..."
2) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G31"
   file_name    sample_loan_agreement.pdf
   session_id   demo1
   text         "\"Scheduled Payment Date\" means the 15th calendar day of
                 each month during the Loan Term...
<!-- PageBreak -->
                 # SAMPLE AGREEMENT - SYNTHETIC TEST DATA - NOT A REAL LOAN
                 DOCUMENT"
SCAN 0 MATCH session:demo1:*
# Execution Results
1) "22"
2) 1) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2S"
   2) "session:demo1:01M1MN5JG8DDCXP7K2XHP54G2X"
   ... (8 more)
import redis
from src.redismanualvectorization.graph import get_vector_store

session_id = "demo1"
vs = get_vector_store(session_id)
r = redis.Redis(host="localhost", port=6379, password="changeme")
keys = r.keys(f"session:{session_id}:*")
print(f"{len(keys)} chunk(s) in this session")
raw = r.hgetall(keys[0])
vector = vs.convert_vector({"embedding": raw[b"embedding"]})
print("Vector length:", len(vector))          # expect 1536
print("First 8 dims:", [round(v, 5) for v in vector[:8]])
print("Chunk text:", raw[b"text"][:120])

# Results for execution
uv run python -m src.redismanualvectorization.raw_vector_check
24 chunk(s) in this session
Vector length: 1536
First 8 dims: [-0.01327, -0.06799, 0.00346, 0.01323, -0.01469, 0.0217, -0.01146, 0.05652]
Chunk text: b'<td>Lumen Electric Utility</td>\n<td>Bill Payment</td>\n<td>-$24.03</td>\n<td>$7,265.31</td>\n</tr>\n<tr>\n<td>02/14/2026</td>'
krishnansriram@mac RedisManualVectorization % uv run python -m src.redismanualvectorization.main \
  --session demo1 \
  --query "What's the overdraft protection fee?"

Q: What's the overdraft protection fee?

A: The overdraft protection transfer fee is $10.00 per occurrence.

Sources:
  - sample_bank_statement.pdf (chunk 7): #### Important Account Disclosures   ##### Overdraft Protection  If a transaction is presented that ...
  - sample_bank_statement.pdf (chunk 9): ##### Monthly Maintenance Fee  A $12.00 monthly maintenance fee applies unless one of the following ...
  - sample_bank_statement.pdf (chunk 8): ##### Interest Rate & Annual Percentage Yield  This account earns interest at a variable rate, curre...
  - sample_bank_statement.pdf (chunk 3): <td>-$10.44</td> <td>$8,096.52</td> </tr> <tr> <td>02/07/2026</td> <td>Greenfield Grocers</td> <td>D...
krishnansriram@mac RedisManualVectorization % uv run python -m src.redismanualvectorization.main \
  --session demo2 \
  --query "What's the overdraft protection fee?"

Q: What's the overdraft protection fee?

A: I don't know — no relevant content about an overdraft protection fee was found in the uploaded files.

2. ingest_node — session_id ponownie łączy się z metadanymi

Każdy fragment musi zawierać klucz sesji (lub użytkownika), który będzie później używany do filtrowania. Utrata metadanych podczas importu jest przyczyną wycieków danych.

3. retrieve_node — wyraźne filtrowanie w połączeniu z dyscypliną indeksu

Filtrować według sesji, nawet jeśli nazwa indeksu jest specyficzna dla danej sesji. Bezpieczeństwo poprzez dodatkowe zabezpieczenia jest lepsze od optymistycznego izolowania.

5. Zależności — bezpośrednie importy dają bezpośrednie wpisy

Ustal stałe wersje klienta Redis oraz integracji wektorowej. Poprzednie aktualizacje transytywne powodowały błędy w typach pól indeksu.

Inspekcja zapisanych danych

1. Jakie istnieją indeksy

Lista indeksów po wdrożeniu; nieudane próby utworzenia pozostają niewidoczne aż do pierwszego pustego pobrania.

2. Schemat

Potwierdź, że wymiary wektorów, pola tekstowe oraz pola tagów odpowiadają kodowi.

3. Lista rekordów bez wyświetlania surowych wektorów

4. Pełne metadane rekordu

Rzeczywiste zobaczenie wektora — dekodowanie liczb zmiennoprzecinkowych podczas debugowania niezgodności wymiarów

Uwagi końcowe

Ograniczenia nawet przy zarządzanym Redis

Nadal potrzebujesz kopii zapasowych, mechanizmów autoryzacji, ograniczeń pamięci oraz procedur usuwania danych po zakończeniu sesji. Persistencja rozwiązuje problemy z restartami, ale nie tworzy systemów zarządzania.

Traktuj ścieżkę pamięciową jako narzędzie edukacyjne, a Redis jako standard dla wszelkich wspólnych lub wieloproszowych implementacji tego samego grafu.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwie sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwie sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwie sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwie sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwie sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwie sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwie sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwie sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Dodaj test sprawdzający, który pobiera dwa sesje, odczytuje dane z każdej z nich i upewnia się, że nie ma żadnej interferencji. Uruchom go wobec Redis w środowisku CI przy użyciu kontenera jednorazowego, aby błędy nie trafiały do wspólnych środowisk.

Persistentne przechowywanie zmienia również sposoby występowania błędów: częściowe przetwarzanie może pozostawić „sieroty” – dokumenty bez powiązań. Upewnij się, że operacje insert/upsert są idempotentne pod względem identyfikatorów fragmentów, oraz dostarcz zadanie reindexingu, które odbuduje sesję na podstawie dokumentów źródłowych.

W celach lokalnego rozwoju przechowuj fabrykę w pamięci tymczasowej za pomocą flagi środowiskowej, aby inżynierowie nie musieli uruchamiać Redis tylko po to, by edytować jakiś prompt. W przypadku wspólnych środowisk testowych całkowicie zabronij używania pamięci tymczasowej do przechowywania danych.

Pomierz opóźnienie pobierania na poziomie p95 przed i po przeniesieniu danych do Redis. Poprawne rozwiązanie persistencji, choć trzy razy wolniejsze, może skłonić ludzi do powrotu do niebezpiecznych obejść.

Rozbieranie sesji musi odbywać się poprzez usuwanie według filtrów, a nie przez wyczyszczenie bazy danych. Podręczniki operacyjne powinny zawierać dokładne polecenia CLI/FT.DROP lub delete-query wraz z przykładami.

Gdy kilka instancji aplikacji pisze jednocześnie, wybierz projekt indeksu, który toleruje równoczesne operacje insert/upsert, a jeśli stosujesz shardowanie, uwzględnij ograniczenia związane z tagami haszowymi w klastrze Redis.

Zapisuj nazwę indeksu oraz filtr sesji przy każdym pobieraniu danych w celach wsparcia. Puste wyniki często wynikają z błędnego indeksu lub błędnego filtru, a nie z awarii modelu.

Persystencja również wpływa na sposoby występowania błędów: częściowe przetwarzanie danych może pozostawić „sieroty” w bazie. Upewnij się, że operacje insert/update są idempotentne pod względem identyfikatorów fragmentów, oraz dostarcz zadanie ponownego indeksowania, które odbuduje sesję na podstawie dokumentów źródłowych.

Dla rozwoju lokalnego przechowuj fabrykę w pamięci tymczasowej za pomocą flagi środowiskowej, aby inżynierowie nie musieli uruchamiać Redis tylko po to, by edytować prompt. W środowisku wspólnym całkowicie zabronij używania pamięci tymczasowej.

Pomierz opóźnienie pobierania danych na poziomie p95 przed i po przeniesieniu do Redis. Persystencja, która jest poprawna, ale trzy razy wolniejsza, skłoni ludzi do powrotu do niebezpiecznych obejść.

Rozbieranie sesji musi odbywać się poprzez usunięcie według filtru, a nie przez wyczyszczenie bazy danych. Podręczniki operacyjne powinny zawierać dokładne polecenia CLI/FT.DROP lub zapytania usuwające wraz z przykładami.

Gdy kilka instancji aplikacji pisze jednocześnie, wybierz projekt indeksu, który toleruje jednoczesne operacje upsert oraz uwzględnij ograniczenia typu hash-tag w klastrze Redis, jeśli stosujesz shardowanie.

Zapisuj nazwę indeksu i filtr sesji przy każdym pobieraniu danych w celach wsparcia. Puste wyniki często wynikają z błędnego indeksu lub filtru, a nie z awarii modelu.

Persystencja również zmienia sposoby występowania błędów: częściowe przetwarzanie może pozostawić „sieroty” w bazie danych. Upewnij się, że operacje upsert są idempotentne pod względem identyfikatorów fragmentów, oraz dostarcz zadanie reindexingu, które odbuduje sesję na podstawie oryginalnych dokumentów.

Dla rozwoju lokalnego przechowuj fabrykę w pamięci tymczasowej za pomocą flagi środowiskowej, aby inżynierowie nie musieli uruchamiać Redis tylko po to, by edytować prompt. W środowisku wspólnym całkowicie zabronij użycia ścieżek w pamięci tymczasowej.

Pomierz opóźnienie pobrań na poziomie p95 przed i po przeniesieniu danych do Redis. Persystencja, która jest poprawna, ale trzy razy wolniejsza, skłoni ludzi do powrotu do niebezpiecznych obejść.

Podczas zamykania sesji należy użyć metody usuwania przez filtr, a nie opróżniania bazy danych. Podręczniki operacyjne powinny zawierać dokładne polecenia CLI/FT.DROP lub zapytania usuwające wraz z przykładami.

Gdy kilka instancji aplikacji pisze jednocześnie, należy wybrać taką strukturę indeksu, która toleruje jednoczesne operacje insert/upsert, a w przypadku shardowania uwzględnić ograniczenia typu hash-tag w klastrze Redis.

Dla ułatwienia obsługi należy rejestrować nazwę indeksu oraz filtr sesji przy każdym pobieraniu danych. Puste wyniki często wynikają z błędnego indeksu lub filtru, a nie z awarii modelu.

Persistentne przechowywanie również zmienia sposoby występowania błędów: częściowe przetwarzanie może pozostawić „sieroty” w bazie danych. Operacje insert/upsert powinny być idempotentne pod względem identyfikatorów fragmentów, a także należy zapewnić zadanie reindeksowania, które odbuduje sesję na podstawie oryginalnych dokumentów.

Literatura pokrewna