feat(redis-projection): per-dict feature flag (CEO plan E2 tiered perf)
Per-dictionary opt-in для Redis projection materialization. Default false
— projection-writer пропускает event'ы того dict'а, никаких dead writes
в Redis. Включается админ'ом через UI checkbox в Metadata tab.
Migration 0017:
- ALTER TABLE dictionary_definitions ADD COLUMN redis_projection_enabled
BOOLEAN NOT NULL DEFAULT false.
- Index idx_dict_def_redis_proj для быстрого filtering в list queries.
Backend:
- DictionaryDefinition entity: new field + getter/setter.
- DictionaryResponse DTO: returns flag в response.
- CreateDictionaryRequest DTO: optional Boolean (null/missing = no change).
- DictionaryDefinitionService.create + updateSchema: применяет flag из request.
- ProjectionWriter (projection-writer service):
* upsert() — early-return + skip counter если flag=false на dict.
* delete() — symmetric: skip если flag=false (защита от stale keys
после flag-flip; полный cleanup TODO Phase 2).
* New metric: ordinis_projection_records_skipped_total.
Admin UI:
- DictionaryEditorDialog Metadata tab: checkbox "Включить Redis-проекцию"
с описанием. Apply через CreateDictionaryRequest payload.
- DictionaryDefinition + CreateDictionaryRequest types updated.
- i18n RU/EN: schema.redisProjection.{label,hint}.
Что НЕ делается (deferred Phase 2):
- read-api Redis routing — read-api сейчас всегда идёт в PG read replica.
Когда dict опт-инится в флаг, projection материализуется, но read-api
ещё не использует. Read routing — отдельная feature с benchmark proof
(через JMH + k6 SLO test).
- One-shot cleanup job для stale keys после flag-flip from true→false.
Behavior change в production:
- До patch: projection-writer пишет в Redis для ВСЕХ dict events (40
dictionaries). Default flag=false после migration → projection-writer
пропускает всё → Redis keys для existing dicts становятся stale.
Это OK потому что read-api НИКОГДА не читал из Redis (writes были
dead). Stale keys eventually evicted Redis maxmemory policy.
- После patch: только dicts с redis_projection_enabled=true получают
материализацию. По default — нет. Admin opt-ins per-dict через UI.
Verify:
- mvn test (full reactor): SUCCESS, all green.
- mvn -P e2e -pl ordinis-app -am test: 20/20 PASS (migration 0017 applied).
- pnpm tsc --noEmit: clean.
- pnpm test (vitest): 89/89 PASS.
- pnpm build: clean.
This commit is contained in:
+37
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<databaseChangeLog
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
|
||||
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.27.xsd">
|
||||
|
||||
<!--
|
||||
CEO plan E2 (Tiered perf): per-dictionary Redis projection feature flag.
|
||||
|
||||
`redis_projection_enabled` BOOLEAN на dictionary_definitions:
|
||||
- false (default) — projection-writer пропускает Kafka events этого
|
||||
dict'а, Redis для него не материализуется. read-api продолжает
|
||||
читать из PG read replica (current path).
|
||||
- true — projection-writer пишет updates в Redis. read-api в будущем
|
||||
сможет route'ить queries в Redis для 10k+ RPS dicts. Read-api
|
||||
routing — отдельная feature, не часть этой migration.
|
||||
|
||||
Default false — backward-compat: сейчас НИ ОДИН dict не помечен → Redis
|
||||
становится пустым после deploy + первого refresh cycle. Это OK
|
||||
потому что read-api сегодня НЕ читает из Redis (просто dead writes).
|
||||
-->
|
||||
<changeSet id="0017-redis-projection-flag" author="ordinis">
|
||||
<comment>Per-dict Redis projection feature flag (CEO plan E2)</comment>
|
||||
<addColumn tableName="dictionary_definitions">
|
||||
<column name="redis_projection_enabled" type="BOOLEAN" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
|
||||
<createIndex indexName="idx_dict_def_redis_proj"
|
||||
tableName="dictionary_definitions">
|
||||
<column name="redis_projection_enabled"/>
|
||||
</createIndex>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -26,5 +26,6 @@
|
||||
<include file="changes/0014-webhook-deliveries.xml" relativeToChangelogFile="true"/>
|
||||
<include file="changes/0015-backfill-latlon-geometry.xml" relativeToChangelogFile="true"/>
|
||||
<include file="changes/0016-record-dependents-index.xml" relativeToChangelogFile="true"/>
|
||||
<include file="changes/0017-redis-projection-flag.xml" relativeToChangelogFile="true"/>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
||||
Reference in New Issue
Block a user