docs(keycloak-session-store): import the session-storage lab as a new project
The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
43bccd08a8
commit
b2963105a8
+70
@@ -0,0 +1,70 @@
|
||||
# 탐침이 자기를 소개하는 문단
|
||||
/**
|
||||
* Asks the server what it is, once, at startup.
|
||||
*
|
||||
* <p>Configuration says what the deployment intends; only the server says what is true. The version
|
||||
* a managed Redis advertises does not imply the modules are present, and a replicated deployment's
|
||||
* write durability is a server setting no client can compensate for. Both are cheap to ask and
|
||||
* expensive to discover later — a missing capability found at the first request is an outage, found
|
||||
* here it is a failed deploy.
|
||||
|
||||
# 그것이 확인하는 넷
|
||||
RedisCapabilities capabilities =
|
||||
probe.probe(
|
||||
serverFacts.version(),
|
||||
settings.getMode(),
|
||||
settings.getDatabase(),
|
||||
commandPresence(serverFacts.commands()),
|
||||
requiredCapabilities);
|
||||
probe.requireWriteDurability(
|
||||
settings.getMode(),
|
||||
serverFacts.minReplicasToWrite(),
|
||||
serverFacts.minReplicasMaxLagSeconds(),
|
||||
settings.isAcknowledgedWriteLossAccepted());
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
|
||||
# 넷째의 javadoc — 실측과 결론
|
||||
* Refuses to start against a replicated deployment that cannot keep the writes it acknowledges.
|
||||
*
|
||||
* <p>This is the one server-side setting the SDK cannot compensate for. When a primary is
|
||||
* superseded by a promotion it does not find out immediately, and until it does it keeps
|
||||
* answering {@code +OK} to writes that are discarded when it resyncs from the new primary. The
|
||||
* Sentinel lane measured eleven seconds and 2,086 acknowledged-then-discarded writes, with
|
||||
* exactly one command failing. No client can see it: the server answered, so the driver, this
|
||||
* SDK, and the caller all record a success. There is no metric to add, no failure to retry, and
|
||||
* no certainty value that describes it.
|
||||
*
|
||||
* <p>{@code min-replicas-to-write} with a bounded {@code min-replicas-max-lag} is what turns that
|
||||
* into a {@code NOREPLICAS} refusal the caller can act on — the same promotion then lost one
|
||||
* write instead of 2,086. So a replicated deployment without it is a startup failure rather than
|
||||
* a warning, on the same principle as every other guardrail here: a setting that makes a
|
||||
* guarantee meaningless stops the context instead of degrading quietly.
|
||||
# 그리고 검사가 두 겹인 이유
|
||||
* <p>Both halves of the guarantee are checked. A replica count on its own decides only how many
|
||||
* replicas must be <em>connected</em>; how far behind they may be is {@code
|
||||
* min-replicas-max-lag}, and Redis treats {@code 0} there as "no lag requirement". A deployment
|
||||
* with {@code min-replicas-to-write 2} and {@code min-replicas-max-lag 0} therefore accepts a
|
||||
* write once two arbitrarily stale replicas are attached, which is the same lost-write exposure
|
||||
* the count was supposed to remove. Checking the count alone let that configuration pass while
|
||||
* the failure message told the operator to set the lag bound.
|
||||
|
||||
# 그 실패는 일어나지 않는다
|
||||
두 탐침 밖에서 그것들을 언급하는 main 코드: 1
|
||||
RedisSdkSettings.java:888: * signal exists for it; see {@link RedisCapabilityProbe#requireWriteDurability}.
|
||||
confirm( 을 부르는 main 코드: 0
|
||||
|
||||
# 자동설정이 만드는 빈
|
||||
85 public RedisSdkSettings redisSdkSettings() {
|
||||
102 public RedisSdkSettingsValidation redisSdkSettingsValidation(
|
||||
157 public RedisResolvedCredentials redisResolvedCredentials(
|
||||
227 public RedisRuntimeClient redisRuntimeClient(
|
||||
274 public RedisRuntimeOwner redisRuntimeOwner(RedisRuntimeClient client, RedisSdkSettings settings) {
|
||||
298 public HealthIndicator redisOptional(RedisRuntimeOwner owner, RedisSdkSettings settings) {
|
||||
326 public HealthIndicator redisRequired(RedisRuntimeOwner owner, RedisSdkSettings settings) {
|
||||
그중 탐침: 0
|
||||
|
||||
# 로직을 고정하는 테스트 케이스 수
|
||||
RedisCapabilityProbeTest: 11
|
||||
RedisStartupProbeTest: 7
|
||||
Reference in New Issue
Block a user