- 数据库
- 后端
- 流处理
【免费下载链接】EventStore
KurrentDB is a database that's engineered for modern software applications and event-driven architectures. Its event-native design simplifies data modeling and preserves data integrity while the integrated streaming engine solves distributed messaging challenges and ensures data consistency.
本指南基于 KurrentDB 官方文档 db-config.md 编写,系统讲解数据库服务器三大类运行参数:Database(存储与事务行为)、Threading(线程模型)与Runtime(.NET 垃圾回收)。读者将掌握每个参数的命令行、YAML 与环境变量三种配置写法、默认值及其对性能与数据安全的影响,并了解这些参数在 ClusterVNodeOptions.cs 中的底层实现。文中所有参数都建议仅在明确了解后果、或经 Kurrent 技术支持人员指导时修改。
配置方式与生效优先级
在深入具体参数前,先明确 KurrentDB 的配置注入方式。官方文档 configuration.md 给出了完整的配置体系,按优先级从低到高排列如下:
| 方式 | 示例 | 说明 |
|---|---|---|
| YAML 配置文件 | 默认文件为/etc/kurrentdb/kurrentdb.conf(Linux)或安装目录(Windows),顶部需带--- | 如Db: "/volumes/data"、ReaderThreadsCount: 4 |
| JSON 配置文件 | 位于<安装目录>/config/或/etc/kurrentdb/config/ | 所有选项嵌套在KurrentDB键下,覆盖同项 YAML 配置 |
| 环境变量 | KURRENTDB_DB、KURRENTDB_READER_THREADS_COUNT | 以KURRENTDB_为前缀,嵌套用双下划线__(如KURRENTDB_USER_CERTIFICATES__ENABLED),覆盖配置文件 |
| 命令行参数 | kurrentd --db /var/lib/kurrentdb | 嵌套同样用__(如--user-certificates__enabled),优先级最高,覆盖上述所有来源 |
若多种配置来源混用,可用--what-if参数让服务器打印"生效配置"(含默认值、各来源覆盖情况)后直接退出,便于核对最终参数,例如输出中的CACHED CHUNKS: -1 (<DEFAULT>)、CHUNKS CACHE SIZE: 536871424 (<DEFAULT>)等条目。
Database:存储布局与事务行为
本节参数控制数据库文件的存放位置、内存数据库、文件校验以及 chunk 缓存等核心存储行为。这些参数在源码中集中定义于 DatabaseOptions 记录类型,并经由 ClusterVNodeOptionsValidator.cs 在启动时校验合法性。
数据库位置(Db)
KurrentDB 是一个单数据库,数据以不断增长的物理文件(chunk)形式分布在文件系统上:新数据始终追加到最新 chunk 的末尾,当 chunk 超过 256 MiB 时,服务器关闭当前 chunk 并开启新的 chunk。这个 256 MiB 上限定义在 TFConsts.cs 中:
public const int ChunkSize = 256 * 1024 * 1024; // 256MiBDb参数指定 chunk 文件的存放位置;如果指定位置不存在,服务器会自动创建一个全新数据库。
| 格式 | 语法 |
|---|---|
| 命令行 | --db |
| YAML | Db |
| 环境变量 | KURRENTDB_DB |
默认值:默认位置随平台而异,具体逻辑见 Locations.cs:
- Linux/macOS:
/var/lib/kurrentdb(旧版 EventStore 兼容路径为/var/lib/eventstore) - Windows:KurrentDB 安装目录下的
data目录
从源码可以看出(ClusterVNodeOptions.cs),该选项默认值正是Locations.DefaultDataDirectory。实践建议是让数据库文件与操作系统及其他应用文件分离存放;注意 KurrentDB不会展开~,如果路径以~开头,节点将直接拒绝启动(验证逻辑)。
内存数据库(MemDb,已弃用)
在教学演示或自动化测试环境中,可以禁止服务器落盘,让数据仅驻留内存——只要 RAM 足够即可。使用内存数据库时,实例一旦关闭,全部数据即丢失。
| 格式 | 语法 |
|---|---|
| 命令行 | --mem-db |
| YAML | MemDb |
| 环境变量 | KURRENTDB_MEM_DB |
默认值:false
⚠️弃用警告:自25.1.0起
--mem-db已被弃用,未来版本将移除,以便简化和统一核心代码路径。若仍希望在内存中运行 KurrentDB,可改用 ramfs 等内存文件系统方案。源码中该选项同样被标注了Deprecated特性(ClusterVNodeOptions.cs)。
跳过数据库校验(SkipDbVerify)
节点重启时会检查数据库文件是否损坏。这是一个耗时过程,在大数据库上可能持续数小时。由于 KurrentDB 通常会对每次写入执行刷盘,文件损坏概率很低;因此在节点频繁重启的环境中,可以关闭该校验以加快启动。
| 格式 | 语法 |
|---|---|
| 命令行 | --skip-db-verify |
| YAML | SkipDbVerify |
| 环境变量 | KURRENTDB_SKIP_DB_VERIFY |
默认值:false
从源码看,该参数直接控制TFChunkDb打开时是否执行完整性校验:ClusterVNode.cs 中Db.Open(!options.Database.SkipDbVerify, ...)——SkipDbVerify为true时跳过哈希校验,换取更快的启动速度。
Chunk 缓存(ChunksCacheSize与CachedChunks)
如果节点有空闲内存,可以增加缓存的 chunk 文件数量以提升读性能。官方文档 diagnostics/README.md 说明可通过 HTTP 端点https://<host>:2113/stats获取统计信息;其中两个关键字段由 StorageReaderService.cs 输出:
es-readIndex-cachedRecord:chunk 文件命中缓存的次数es-readIndex-notCachedRecord:chunk 文件从磁盘读取的次数
通常最新的两个 chunk(当前 chunk 与上一个 chunk)访问最频繁、最值得缓存。若观察到es-readIndex-notCachedRecord显著高于es-readIndex-cachedRecord,可考虑调整 chunk 缓存。
ChunksCacheSize指定服务器用于缓存 chunk 的内存量(字节)。chunk 上限为 256 MiB,因此默认缓存 2 个 chunk 约 0.5 GiB;要缓存 4 个 chunk,可设为 1 GiB(1073741824字节)。
| 格式 | 语法 |
|---|---|
| 命令行 | --chunks-cache-size |
| YAML | ChunksCacheSize |
| 环境变量 | KURRENTDB_CHUNKS_CACHE_SIZE |
默认值:536871424
该默认值并非简单的2 × 256MiB,而是把 chunk 头尾开销一并计入。源码 TFConsts.cs:
public const int ChunkHeaderSize = 128; public const int ChunkFooterSize = 128; public const int ChunksCacheSize = 2 * (ChunkSize + ChunkHeaderSize + ChunkFooterSize);即2 × (268435456 + 128 + 128) = 536871424字节,与文档默认值完全吻合。
CachedChunks则直接指定希望缓存的 chunk 文件数量,例如设为4即翻倍缓存。
| 格式 | 语法 |
|---|---|
| 命令行 | --cached-chunks |
| YAML | CachedChunks |
| 环境变量 | KURRENTDB_CACHED_CHUNKS |
默认值:-1(全部,即由ChunksCacheSize决定)
两个参数的配合逻辑在 ClusterVNode.cs 中清晰可见:当CachedChunks >= 0时,缓存上限按CachedChunks × (ChunkSize + 头 + 尾)计算;否则回退到ChunksCacheSize。实际的缓存淘汰策略在 TFChunkManager.cs 中实现:从最新 chunk 开始向前累计大小,直到达到缓存上限,再卸载更早的只读 chunk——印证了"只有最新 chunk 会被缓存"这一文档说明。
需要提醒两点:只有最新 chunk 会被缓存;同时操作系统本身也有文件缓存,单纯增大 chunk 缓存未必带来预期收益。
Prepare 与 Commit 超时(PrepareTimeoutMs/CommitTimeoutMs)
默认 2000 ms 的 prepare/commit 超时意味着:集群中的任何写入最多等待 2000 ms,之后服务器才会向客户端回复写入超时。
| 格式 | 语法 |
|---|---|
| 命令行 | --prepare-timeout-ms |
| YAML | PrepareTimeoutMs |
| 环境变量 | KURRENTDB_PREPARE_TIMEOUT_MS |
默认值:2000(毫秒)
| 格式 | 语法 |
|---|---|
| 命令行 | --commit-timeout-ms |
| YAML | CommitTimeoutMs |
| 环境变量 | KURRENTDB_COMMIT_TIMEOUT_MS |
默认值:2000(毫秒)
需要注意联动的代价:客户端操作超时默认 7 秒,增大上述超时会令客户端最长阻塞到两者中的较小值;同时服务器需要在内存中跟踪这些未完成写入及其重试直到超时结束,若大量超时写入累积,会拖慢整体处理速度。
禁用刷盘(UnsafeDisableFlushToDisk)
⚠️使用此选项可能导致数据丢失:它将阻止 KurrentDB 在每次写入后强制刷盘(flush to disk)。启用后数据仍会以应用层方式写入磁盘,但不一定到达 OS 层;OS 通常会在固定间隔或进程退出时刷新缓冲区,但这对 KurrentDB 是不透明的。在断电场景下该选项不安全。
| 格式 | 语法 |
|---|---|
| 命令行 | --unsafe-disable-flush-to-disk |
| YAML | UnsafeDisableFlushToDisk |
| 环境变量 | KURRENTDB_UNSAFE_DISABLE_FLUSH_TO_DISK |
默认值:false
从源码看,该选项在ClusterVNodeOptions构造函数中即被用于全局配置文件流的刷盘行为(ClusterVNodeOptions.cs),并最终作用于 chunk 写路径中 WriterWorkItem.cs 的FlushToDisk()调用。
最小刷盘延迟(MinFlushDelayMs)
写入磁盘刷盘操作之间的最小延迟(毫秒),用于节流刷盘频率、减少小文件 I/O 带来的开销。
| 格式 | 语法 |
|---|---|
| 命令行 | --min-flush-delay-ms |
| YAML | MinFlushDelayMs |
| 环境变量 | KURRENTDB_MIN_FLUSH_DELAY_MS |
默认值:2(毫秒)
源码中该值来自 TFConsts.cs 的MinFlushDelayMs = TimeSpan.FromMilliseconds(2),并在 ClusterVNode.cs 中转换为TimeSpan供写路径使用。
SQL 引擎临时文件(SqlEngineTempDirectory/SqlEngineTempDirectorySizeLimit)
KurrentDB 内置的 SQL 引擎(DuckDB)负责服务二级索引和用户自定义查询等请求。当中间结果超出内存时,会溢出(spill)到磁盘临时文件,本节两个参数控制临时文件的写入位置与空间上限。
SqlEngineTempDirectory:
| 格式 | 语法 |
|---|---|
| 命令行 | --sql-engine-temp-directory |
| YAML | SqlEngineTempDirectory |
| 环境变量 | KURRENTDB_SQL_ENGINE_TEMP_DIRECTORY |
默认值:数据库目录内的kurrent.ddb.tmp;相对路径会基于服务器进程的工作目录解析。
该目录有两条硬性约束(文档与 源码说明 一致):
- 不得与其他用途共享:节点启动时,上一次运行遗留的任何
*.tmp文件都会被删除。清理逻辑位于 DuckDBConnectionPoolLifetime.cs。 - 不能与
Db或Index同目录:否则节点拒绝启动。 - 同样地,路径以
~开头会导致启动失败(验证逻辑)。
SqlEngineTempDirectorySizeLimit:
| 格式 | 语法 |
|---|---|
| 命令行 | --sql-engine-temp-directory-size-limit |
| YAML | SqlEngineTempDirectorySizeLimit |
| 环境变量 | KURRENTDB_SQL_ENGINE_TEMP_DIRECTORY_SIZE_LIMIT |
默认值:0,含义为临时目录所在卷可用磁盘空间的 90%。也可显式设置字节数进一步收紧;超出限额的查询会直接失败而不是填满磁盘。源码要求该值必须大于等于 0(验证逻辑)。
从实现层面看,DuckDBConnectionPoolLifetime.cs 将二者映射为 DuckDB 连接参数:临时目录缺省为<数据库路径>.tmp(即kurrent.ddb.tmp),当SizeLimit > 0时注入max_temp_directory_size;同时该实现还限制了 DuckDB 的内存上限为可用 RAM 的 25%(memory_limit),并关闭社区扩展与外部访问以增强安全性。
Threading:线程模型
本节参数控制 KurrentDB 的线程使用方式。
工作线程(WorkerThreads)
通用型工作线程承担多种无差别任务,包括网络发送、认证以及 HTTP 请求的完成处理。把线程数增加到超出系统其他组件工作负载所需之外,只会带来额外的上下文切换开销。
| 格式 | 语法 |
|---|---|
| 命令行 | --worker-threads |
| YAML | WorkerThreads |
| 环境变量 | KURRENTDB_WORKER_THREADS |
默认值:文档描述为5;但从当前仓库源码看,该设置已被标记为Deprecated,默认值改为0(自动按需扩展),且注释明确说明"该设置不再有任何效果,工作线程会自动按需伸缩"(ClusterVNodeOptions.cs)。因此在新版本中通常无需、也无法手动调节此参数。
读线程数(ReaderThreadsCount)
读线程用于所有针对数据文件的读操作,无论请求来自客户端还是数据库内部。以下场景都会把操作派发到读线程:
- 所有索引读取,包括服务基于流/事件号的读取,以及在指定期望版本时对写入做幂等处理;
- 来自 HTTP 或客户端 API 的数据请求;
- 投影(Projections)处理所需的数据读取;
- 授权机制从流元数据中读取访问控制列表。
| 格式 | 语法 |
|---|---|
| 命令行 | --reader-threads-count |
| YAML | ReaderThreadsCount |
| 环境变量 | KURRENTDB_READER_THREADS_COUNT |
默认值:文档描述为4;但从当前仓库源码看,默认值已改为0,表示自动缩放(ClusterVNodeOptions.cs)。自动计算的规则定义在 ThreadCountCalculator.cs:
- 显式配置
> 0:直接采用配置值; - 容器环境:采用
ContainerizedEnvironment.ReaderThreadCount; - 其他情况:
Math.Clamp(处理器数 × 2, 4, 16),即下限 4、上限 16。
理解读线程的调优要点(文档原意,与源码行为相互印证):
- 读操作会排队,直到某个读线程可用;若操作在内部截止窗口内未完成,负责处理的 worker 线程将不再派发磁盘操作。
- 读操作的大小取决于所追加事件的大小,而非固定逻辑大小的数据库 chunk;更大的读取(受限于 OS 页大小)会消耗更多系统调用时间,降低读线程的可用性。
- 当磁盘能支持更多并发操作时,提高读线程数才有意义;上下文切换本身有性能代价。若磁盘已饱和,增加读线程会加剧问题并导致更多请求失败。
- 增加读线程数可以在一定程度上改善性能,但到达临界点后收益会快速衰减。
Runtime:.NET 运行时
垃圾回收(Garbage Collection)
.NET 运行时提供两种 GC 策略:Workstation GC(工作站)与Server GC(服务器)。在 KurrentDB 25.1 中,Server GC 已成为默认配置,并附带HeapHardLimitPercent为 60% 的限制,目的是通过多线程 GC 减少争用、缩短 GC 耗时,从而提升整体性能。
该默认值可以从仓库的工程文件中直接验证:KurrentDB.csproj 同时设置了<ServerGarbageCollection>true</ServerGarbageCollection>与<RuntimeHostConfigurationOption Include="System.GC.HeapHardLimitPercent" Value="60" />。
节点启动时会打印当前 GC 配置,形如:
[107584, 1,13:11:28.780,INF] KurrentDB GC Configuration settings: ServerGC: True ConcurrentGC: True RetainVM: False NoAffinitize: False GCCpuGroup: False GCLargePages: False HeapCount: 24 MaxHeapCount: 0 GCHeapAffinitizeMask: 0 GCHeapAffinitizeRanges: GCHighMemPercent: 0 GCHeapHardLimit: 0 GCHeapHardLimitPercent: 0 GCHeapHardLimitSOH: 0 GCHeapHardLimitLOH: 0 GCHeapHardLimitPOH: 0 GCHeapHardLimitSOHPercent: 0 GCHeapHardLimitLOHPercent: 0 GCHeapHardLimitPOHPercent: 0 GCConserveMem: 0 GCName: GCDynamicAdaptationMode: 0可通过环境变量DOTNET_gcServer关闭 Server GC:
0→ Workstation GC1→ Server GC
更多 GC 值的设置方式可参考 .NET 运行时官方文档;注意这些值经常以十六进制形式指定。
HeapHardLimitPercent
- KurrentDB 将
HeapHardLimitPercent默认设为60%。.NET 运行时默认是"普通部署无上限、容器化环境 75%"。 - Server GC 执行回收的意愿不如 Workstation GC 积极,60% 的默认上限可防止堆无限膨胀、挤占页缓存(page cache)空间。
- 动态缓存调整(
StreamInfoCacheCapacity = 0时)会把这个堆上限纳入考量。
虚拟 / 物理环境
上述默认值是为KurrentDB 作为机器上的主进程设计的。若同一台机器还运行其他重要的资源密集型进程,建议:
- 考虑关闭
ServerGC:Server GC 回收时默认使用全部核心,可能影响其他进程; - 考虑调低
HeapHardLimitPercent(对两种 GC 模式均适用):当内存占用过高时,其余关键内存参数还包括StreamInfoCacheCapacity与CachedChunks/ChunksCacheSize。
容器化环境
- 为容器设置合理的资源限制(CPU、内存上限),否则 GC 的线程数与堆上限无法与容器实际配额匹配,可能造成资源浪费或内存压力。
小结
本文覆盖的数据库服务器运行参数可归纳为三组:存储行为(Db、MemDb、SkipDbVerify、ChunksCacheSize/CachedChunks、PrepareTimeoutMs/CommitTimeoutMs、UnsafeDisableFlushToDisk、MinFlushDelayMs、SqlEngineTempDirectory/SqlEngineTempDirectorySizeLimit)、线程模型(WorkerThreads、ReaderThreadsCount)与.NET 运行时 GC(DOTNET_gcServer、HeapHardLimitPercent)。修改任何参数前,请先通过--what-if核对生效配置,并牢记:MemDb、UnsafeDisableFlushToDisk等选项带有弃用或数据安全风险,务必在理解后果后使用。如需了解集群、网络等其他维度,可继续阅读 cluster.md 与 networking.md。
- 数据库
- 后端
- 流处理
【免费下载链接】EventStore
KurrentDB is a database that's engineered for modern software applications and event-driven architectures. Its event-native design simplifies data modeling and preserves data integrity while the integrated streaming engine solves distributed messaging challenges and ensures data consistency.
相关推荐
ARC运行器启动参数:命令行参数与配置
ARC运行器启动参数:命令行参数与配置 概述 Actions Runner Controller(ARC)是一个Kubernetes控制器,用于编排和扩展Git
后端云原生容器编排CI/CD弹性伸缩Deep Lake 数据库技术全解析:面向 AI 的数据存储、向量检索与模型训练运行时
Deep Lake 数据库技术全解析:面向 AI 的数据存储、向量检索与模型训练运行时 导读 Deep Lake 是 GitHub 加速计划 de/deepla
数据库向量数据库数据湖人工智能RAGPowerJob数据库设计详解:任务元数据与运行状态存储架构
PowerJob数据库设计详解:任务元数据与运行状态存储架构 引言:分布式任务调度系统的数据基石 在企业级分布式任务调度系统(Distributed Task
任务调度后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考