PageSourceSearch

https://montplex.com/static/js/async/4851.bc43a65c.js

js montplex.com collected 2026-10-03 21:17:03 UTC 15,006 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkengula_website=self.webpackChunkengula_website||[]).push([["4851"],{6108:function(e,n,s){s.r(n),s.d(n,{default:()=>h});var r=s(2676),i=s(453);function d(e){let n=Object.assign({h1:"h1",a:"a",p:"p",strong:"strong",h2:"h2",ul:"ul",li:"li",h3:"h3",code:"code",table:"table",thead:"thead",tr:"tr",th:"th",tbody:"tbody",td:"td",blockquote:"blockquote"},(0,i.ah)(),e.components);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.h1,{id:"engula-简介",children:["Engula 简介",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#engula-简介",children:"#"})]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Engula"})," 是一款高性能、内存高效的 Redis 兼容内核。它基于 Redis Server 代码库构建,在保持协议与行为兼容的前提下,用 ",(0,r.jsx)(n.strong,{children:"Engula 内存引擎"})," 替换了 Redis 的内存对象存储模块,从而让现有 Redis 部署可以更低成本地迁移与验证。"]}),"\n",(0,r.jsxs)(n.h2,{id:"核心设计理念",children:["核心设计理念",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#核心设计理念",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"Engula 的架构遵循三条核心原则:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Redis 行为高一致"}),":官方 runtest 与客户端验证持续公开,迁移成本极低"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"内存效率优先"}),":通过压缩与紧凑的元数据编码降低占用"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"优先保障延迟"}),":典型读写负载下,前台请求 P99 延迟与 Redis 7.2 同等条件实测相当(亚毫秒级)"]}),"\n"]}),"\n",(0,r.jsxs)(n.h2,{id:"架构概览",children:["架构概览",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#架构概览",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"Engula Server 延续 Redis Server 的整体架构,主要改动是将内存对象存储替换为 Engula 内存引擎。其他模块只需少量适配,即可在保留既有 Redis 功能的同时维持兼容性。"}),"\n",(0,r.jsxs)(n.h3,{id:"内存表示",children:["内存表示",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#内存表示",children:"#"})]}),"\n",(0,r.jsxs)(n.p,{children:["在 Redis Server 中,数据访问围绕 ",(0,r.jsx)(n.strong,{children:"Redis Object (robj)"})," 展开。"]}),"\n",(0,r.jsxs)(n.p,{children:["在 Engula Server 中,内存数据以 ",(0,r.jsx)(n.strong,{children:"Engula Object (eobj)"})," 表示:该结构更紧凑,并针对压缩/解压效率做了专门优化。"]}),"\n",(0,r.jsx)(n.p,{children:"在键值操作过程中,Engula 会将 eobj 按需转换为临时的 robj:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"惰性加载"}),":仅在需要时创建临时 ",(0,r.jsx)(n.code,{children:"robj"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"自动释放"}),":通过编译器级保障,确保临时对象在各种路径下都能被正确回收"]}),"\n"]}),"\n",(0,r.jsxs)(n.h2,{id:"内存效率",children:["内存效率",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#内存效率",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"Engula 通过高度优化的数据结构与编码方式显著降低内存开销。在典型场景下:"}),"\n",(0,r.jsxs)(n.table,{children:["\n",(0,r.jsxs)(n.thead,{children:["\n",(0,r.jsxs)(n.tr,{children:["\n",(0,r.jsx)(n.th,{children:"数据结构"}),"\n",(0,r.jsx)(n.th,{align:"right",children:"Redis 元数据开销(字节)"}),"\n",(0,r.jsx)(n.th,{align:"right",children:"Engula 元数据开销(字节)"}),"\n",(0,r.jsx)(n.th,{children:"优化点"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.tbody,{children:["\n",(0,r.jsxs)(n.tr,{children:["\n",(0,r.jsx)(n.td,{children:"HashTable"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"32(dictEntry)"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"14"}),"\n",(0,r.jsx)(n.td,{children:"Swiss table"}),"\n"]}),"\n",(0,r.jsxs)(n.tr,{children:["\n",(0,r.jsx)(n.td,{children:"Key + robj"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"3(key sds)+ 16(robj)"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"10"}),"\n",(0,r.jsx)(n.td,{children:"eobj 存储"}),"\n"]}),"\n",(0,r.jsxs)(n.tr,{children:["\n",(0,r.jsx)(n.td,{children:"Value
1(String)"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"3(value sds)"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"1"}),"\n",(0,r.jsx)(n.td,{children:"eobj 存储"}),"\n"]}),"\n",(0,r.jsxs)(n.tr,{children:["\n",(0,r.jsx)(n.td,{children:"TTL"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"8"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"5"}),"\n",(0,r.jsx)(n.td,{children:"变长整数编码"}),"\n"]}),"\n",(0,r.jsxs)(n.tr,{children:["\n",(0,r.jsx)(n.td,{children:"Jemalloc"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"≥ 4(8 字节对齐)"}),"\n",(0,r.jsx)(n.td,{align:"right",children:"2"}),"\n",(0,r.jsx)(n.td,{children:"Memory Block 管理"}),"\n"]}),"\n",(0,r.jsxs)(n.tr,{children:["\n",(0,r.jsx)(n.td,{children:(0,r.jsx)(n.strong,{children:"合计"})}),"\n",(0,r.jsx)(n.td,{align:"right",children:(0,r.jsx)(n.strong,{children:"66"})}),"\n",(0,r.jsx)(n.td,{align:"right",children:(0,r.jsx)(n.strong,{children:"32"})}),"\n",(0,r.jsx)(n.td,{children:(0,r.jsx)(n.strong,{children:"约 50% 元数据开销降低"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"说明"}),":上表对比的是 per-key 内部元数据开销(不含 value 数据本身)。value 越大,元数据节省对总内存的贡献越小;value 越小、key 数量越多,整体节省率越接近上表。典型负载的实测总内存节省为 40%–75%,建议用 ValueSight 导入自己的 RDB 实测。"]}),"\n"]}),"\n",(0,r.jsxs)(n.h2,{id:"memory-block-管理",children:["Memory Block 管理",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#memory-block-管理",children:"#"})]}),"\n",(0,r.jsxs)(n.p,{children:["Engula 将键值数据存储在 ",(0,r.jsx)(n.strong,{children:"Memory Blocks"})," 中,并划分为:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Mutable Zone"}),":可修改的数据区域"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Immutable Zone"}),":仅允许删除的数据区域"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["后台任务会周期性地对 Immutable Zone 中的 block 做压缩与替换。这些后台任务会被拆分为细粒度、",(0,r.jsx)(n.strong,{children:"可中断的协程"}),",并在原生 Redis 的主线程与 I/O 线程中执行。"]}),"\n",(0,r.jsx)(n.p,{children:"Engula 会根据系统负载动态调整响应时间预算,优先保障前台请求的延迟目标;后台工作则会根据各 I/O 线程的利用率进行分配,以提升整体 CPU 效率。"}),"\n",(0,r.jsxs)(n.h2,{id:"性能与可扩展性",children:["性能与可扩展性",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#性能与可扩展性",children:"#"})]}),"\n",(0,r.jsxs)(n.h3,{id:"横向扩展",children:["横向扩展",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#横向扩展",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"Engula 通过增加 I/O 线程支持近线性的横向扩展。整体吞吐可达到或超过 Redis,并保持更可预测的 CPU 扩展性。"}),"\n",(0,r.jsxs)(n.h3,{id:"io-模型优化",children:["I/O 模型优化",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#io-模型优化",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Redis(Busy Polling 模型)"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"理念"}),":默认独占 CPU 与内存资源"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"机制"}),":I/O 线程先 busy polling(≈ 100 万 cycles ≈ 0.1ms)再进入 sleep"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"表现"}),":高负载下 CPU 消耗呈非线性增长"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Engula(自适应 Signal/Wait 模型)"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"理念"}),":面向共享环境的资源效率"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"机制"}),":用原子操作与 ",(0,r.jsx)(n.code,{children:"pthread"})," 条件变量实现的 signal/wait 替代 busy polling"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"优化"}),":降低 signal 频率,减少冗余上下文切换"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"结果"}),":在达到 Redis 级峰值吞吐的同时,CPU 扩展更平滑、更可预测"]}),"\n"]}),"\n",(0,r.jsxs)(n.h3,{id:"cpu内存权衡",children:["CPU–内存权衡",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#cpu内存权衡",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"Engula 通过实时压缩/解压,用可控的 CPU 开销换取显著的内存节省,在维持性能的同时降低总体内存成本。"}),"\n",(0,r.jsxs)(n.h2,{id:"redis-与-valkey-兼容性",children:["Redis\xae 与 Valkey 兼容性",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#redis-与-valkey-兼容性",children:"#"})]}),"\n",(0,r.jsxs)(n.p,{children:["Engula 与 Redis、Valkey 保持 ",(0,r.jsx)(n.strong,{children:"wire protocol 高一致性"}),"。通过复用这些生态的原生计算层,Engula 能为标准数据操作命令提供一致的行为表现;已知差异项会在 proof-live 中公开原因与影响。"]}),"\n",(0,r.jsx)(n.p,{children:"在存储集成点高度隔离的模块化设计下,Engula 可以在一个月内对齐新的 Redis/Valkey 版本发布,确保兼容性更新节奏。"}),"\n",(0,r.jsxs)(n.h3,{id:"版本支持",children:["版本支持",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#版本支持",children:"#"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Redis"}),":以 7.2.11 为当前公开验证基线"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Valkey"}),":全版本支持"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"持续演进"}),":正在向 Valkey 8/9 迁移"]}),"\n"]}),"\n",(0,r.jsxs)(n.h2,{id:"增强特性",children:["增强特性",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#增强特性",children:"#"})]}),"\n",(0,r.jsxs)(n.h3,{id:"性能增强",children:["性能增强",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#性能增强",children:"#"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"私有 RDB 格式"}),":缩短 ",(0,r.jsx)(n.code,{children:"SAVE"}),"/",(0,r.jsx)(n.code,{children:"LOAD"})," 耗时,并加速全量复制同步"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"大 Value 优化"}),":在多线程(≥4 线程)配置下,大 value 读性能提升 50% 以上"]}),"\n"]}),"\n",(0,r.jsxs)(n.h3,{id:"功能增强",children:["功能增强",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#功能增强",children:"#"})]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"ZSet 压缩"}),":对有序集合做压缩以进一步降低内存开销"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"增强线程模型"}),":按线程/协程的调度与优先级体系,提升 CPU 利用率与尾延迟表现"]}),"\n"]}),"\n",(0,r.jsxs)(n.h2,{id:"总结",children:["总结",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#总结",children:"#"})]}),"\n",(0,r.jsxs)(n.p,{children:["Engula 将 ",(0,r.jsx)(n.strong,{children:"创新的内存管理"}),"、",(0,r.jsx)(n.strong,{children:"强压缩策略"})," 与 ",(0,r.jsx)(n.strong,{children:"协议级互操作性"})," 结合在一起,为 Redis 兼容数据库带来显著提升。"]}),"\n",(0,r.jsxs)(n.p,{children:["其自适应 I/O 模型与可横向扩展的架构能提供更稳定、更线性的性能表现,并在不牺牲兼容性的前提下实现 ",(0,r.jsx)(n.strong,{children:"约 40%–75% 的内存占用降低"}),"(典型负载实测,随数据结构与 value 大小变化),适用于希望降低内存成本且对稳定性要求极高的生产场景。"]}),"\n",(0,r.jsxs)(n.h2,{id:"license-与版本",children:["License 与版本",(0,r.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#license-与版本",children:"#"})]}),"\n",(0,r.jsx)(n.p,{children:"Engula 提供两个版本:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Engula Developer Edition"})," — 永久免费,最多 6 个 Engula 节点(master/replica 比例不限),单实例内存不限。"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Engula Enterprise"}
1)," — 面向更大规模与生产,包含企业支持、SLA 与正式合同。"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["完整版本差异与 EULA 详情见 ",(0,r.jsx)(n.a,{href:"/eula",children:"License 与 EULA 页面"}),"。更大规模或企业支持请联系销售:",(0,r.jsx)(n.a,{href:"mailto:[email protected]?subject=%E7%94%B3%E8%AF%B7%20Engula%20Enterprise",children:"[email protected]"}),"。"]})]})}function l(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,i.ah)(),e.components);return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}let h=l;l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["zh%2Fdocs%2Fabout-engula%2Fintroduction.mdx"]={toc:[{text:"核心设计理念",id:"核心设计理念",depth:2},{text:"架构概览",id:"架构概览",depth:2},{text:"内存表示",id:"内存表示",depth:3},{text:"内存效率",id:"内存效率",depth:2},{text:"Memory Block 管理",id:"memory-block-管理",depth:2},{text:"性能与可扩展性",id:"性能与可扩展性",depth:2},{text:"横向扩展",id:"横向扩展",depth:3},{text:"I/O 模型优化",id:"io-模型优化",depth:3},{text:"CPU–内存权衡",id:"cpu内存权衡",depth:3},{text:"Redis\xae 与 Valkey 兼容性",id:"redis-与-valkey-兼容性",depth:2},{text:"版本支持",id:"版本支持",depth:3},{text:"增强特性",id:"增强特性",depth:2},{text:"性能增强",id:"性能增强",depth:3},{text:"功能增强",id:"功能增强",depth:3},{text:"总结",id:"总结",depth:2},{text:"License 与版本",id:"license-与版本",depth:2}],title:"Engula 简介",headingTitle:"Engula 简介",frontmatter:{}}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.