Table of Contents

Session 使用指南——组合域的统一协调协议

给谁看:组合多个结构(Ring × 索引 × Log)做跨结构原子提交/排序/检查点的人。 回答什么:Session 是什么、什么时候用、怎么建域、怎么写/读/检查点、故障怎么走、什么不要做。 机制细节(管线内部/seq 语义/恢复协议)见文末链接;本篇只讲怎么用。 前置:结构层用法见 structures.md(本篇示例的 Ring/索引装配同款)。


0. 快速上手(四步,可运行)

using TC.Tier.Core.IO;
using TC.Tier.Runtime.Storage;
using TC.Tier.Runtime.Transactions;
using TC.Tier.Runtime.Structures.Ring;
using TC.Tier.Runtime.Structures.ProbingIndex;
using TC.Tier.Contracts.Structures;

// ① 建结构(照常——结构对会话零感知;装配见 structures.md §1.2)
using var fs = TierFs.New("memory:");
await using var ring = await RingOfLong.CreateAsync(new BlittableRingSettings(new StorageEngineOptions("kv-ring", 64L << 20))
    { PageSize = 4096, MemorySize = 64 * 1024, MutableFraction = 0.5 }, fs);
await using var index = await HashOfLong.CreateAsync(fs, new HashIndexSettings(new StorageEngineOptions("kv-hash", 64L << 20)), ring);

// ② 建域:fs + 名字 + 参与者全集(同结构写必经同一域)
var mgr = SessionManager.Create(fs, "kv",
    HangingResolution.ForwardCommit,          // 悬挂裁决域声明(缺省 forward-commit,可省)
    ("ring", ring), ("index", index));
mgr.Initialize();                             // 悬挂裁决 + 管线启动
mgr.WaitForReady();

// ③ 写(档 B 协调):Stage 物化委托 → CommitAsync 入管线
using var session = mgr.OpenSession("writer-1");
session.Stage(() => ring.Write(key, value), tag: key);   // tag = 组合层自管标识(如 key),管线不解读
session.Stage(() => index.Insert(key, addr, begin), tag: key);
long seq = await session.CommitAsync();       // 入管线 → await 自己的回执(域 seq)

// ④ 读(两档):
using (var scope = session.EnterReadScope())  // 会话读:聚合域内 epoch(零拷贝 span 护栏)
    ring.GetValueSpan(addr);
var direct = ring.GetValueSpan(addr);          // 地址直达:无会话零税(默认推荐)

检查点(管线串行——时机归协议,内容归组合层):

long watermark = await mgr.EnqueueCheckpoint(seq =>
{
    index.CheckpointFrame();   // 内容组合层自定(Hash/SortedIndex 主存储 dump)
    meta.WriteAnchor(seq);     // seq = 当前已提交水位(管线传入)
});

1. 概念(术语在此定义)

  • Session = 零自有存储的协调层:不做任何持久化决策——持久化真源是参与者各自的 meta 水位 (2PC 六件套本就持久)。Session 只提供排序(FIFO 全序)+ 原子性(全有或全无)+ 检查点串行
  • 域(domain):一组参与者的集合(一个 SessionManager)。同结构写必经同一域—— 跨域共享结构写 = 破坏窗口契约(§3)。
  • :写有两档——A 直写(直接调结构写 API,无协调,须过规则 W)与 B 协调(Stage 委托 → 提交管线)。读有两档——地址直达(默认,零税)与会话读(scope 聚合 epoch)。
  • staged 物化委托Stage 只登记委托(结构零触碰);管线线程按 FIFO 序执行(纯缓冲写, 尽力不抛——抛 = 域报废)。
  • 悬挂裁决(HangingResolution):恢复时"已 Prepare 未 Confirm"的悬干事务怎么处理—— ForwardCommit(缺省,前推到 prepared seq,宁可前推不丢)或 DropTail(截断回已确认水位)。
  • seq:域内内存排序序(每域独立);批合并下同批共享一个 seq。
  • 规则 W:存在开放事务会话期间(OpenTxCount > 0),该域参与者结构的档 A 直写必须 fail-fast ——产品面写入口统一调 mgr.EnsureNoOpenTransaction()

2. 三 op 怎么用

2.1 写(两档)

形态 何时用
A 直写 直接调结构写 API(ring.Write 等) 无协调需求;须过规则 W 检查
B 协调 Stage(物化委托) ×N → CommitAsync() 需要原子性/排序/跨结构一致

档 B 要点:

  • 业务校验放 Stage 之前(此时抛无副作用);物化委托内只做纯缓冲写。
  • 批合并:管线排空积压为一批——同批共享 seq、一次 Prepare-all + Confirm-all(FIFO 全序不变)。
  • 回执 = 域 seq;失败后会话 Faulted(重开 OpenSession),staged 已清空——重试须重新 Stage。
  • 复制域(Raft WAL):CommitReplicatedAsync(awaitDecision, …)——物化 → Prepare-all → await awaitDecision(候选 seq)(多数派共识注入位)→ true: Confirm-all(不可回退点); false/超时: Abort → RollbackException

2.2 读(两档)

形态 何时用
地址直达 自缓冲句柄直接读结构(GetValueSpan 等) 默认——地址即句柄,零会话税
会话读 session.EnterReadScope() 需要协调的读:RYW 覆盖层 / scope 批量

会话读规范:

  • scope 聚合域内全部 epoch 读保护参与者(一次进出);
  • 区内只做零拷贝读GetValueSpan 族);自带 epoch 进出的 API(Ring 写、Index 逐次 Find/Insert) 区内调用 = 同实例重入,Debug 绊线立即抛——用 IndexScope.Find 等 scope 内单查形态;
  • RYW 覆盖层:组合层在 session.State 上自管(staged 命令表/批号映射)——读序 = 先查覆盖层再下结构。

2.3 检查点

EnqueueCheckpoint(Action<long> plan):plan 收当前已提交水位(不消耗新 seq),与事务回合天然串行; plan 抛 = 回执原异常,管线续跑(检查点无结构悬干)。


3. 故障模型(速查)

故障 行为
回合物化 Faulted(续跑会被后续批"洗白"悬干)——恢复 = 进程重启/新域
回合 Prepare 自动 Abort 已 Prepare 者 → 批回执异常、会话 Faulted → 管线续跑
复制决策 false/超时 Abort 已 Prepare 者 → RollbackException 回执
崩溃(任意时点) 无中央 record——恢复 = 参与者自身语义 + 域声明裁决(悬挂裁决)
排队中 Abort/Dispose/ct 出队丢弃——结构零触碰、seq 零消耗

mgr.IsFaulted / mgr.FaultReason 观测;Faulted 后 OpenSession/入队抛。


4. 反模式(必守)

  1. 产品面自带排序/可见性/提交语义——协调语义只在 Session 一处定义。
  2. 给 Session 加任何自有存储/持久化决策(record/oracle/独立文件)——纯协调层。
  3. 保护区(EnterReadScope/EnterEpoch)内调自带 epoch 的 API——同实例重入,Debug 立即抛。
  4. 物化委托里做业务校验/可抛逻辑——校验放 Stage 前;物化抛 = 域报废。
  5. 给地址直达读加会话——地址即句柄,直达读永远零会话税。
  6. 多域共享结构写——同结构写必经同一域(窗口契约)。
  7. 单线程会话契约(FASTER 同款):一个会话同一时刻单线程使用(staged 缓冲与覆盖层无锁)—— 违规立即抛。

5. 想深入?指路

想懂什么 去哪
2PC 六件套与 Abort 窗口契约 各子族 API 详表 §4(ring.md §4.8 / log.md §4.5 / index.md §5)
恢复协议(悬挂裁决/注入档/Confirm 不落盘语义) 源码 Transactions/SessionManager.cs 注释
吞吐基线(回合/s 口径) benchmarks/.../Kv/SessionPipelineProbe.cs
结构层装配(Ring/索引/Log) structures.md