ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

KeyDB 依赖之 jemalloc 5.2.1 构建与安装完全指南:从 configure 参数到源码级集成实践

2026/9/15 19:13:51 拓冰建站 浏览量
KeyDB 依赖之 jemalloc 5.2.1 构建与安装完全指南:从 configure 参数到源码级集成实践 KeyDB 依赖之 jemalloc 5.2.1 构建与安装完全指南从 configure 参数到源码级集成实践【免费下载链接】KeyDBA Multithreaded Fork of Redis项目地址: https://gitcode.com/GitHub_Trending/ke/KeyDB本指南以 KeyDB 仓库内置的 jemalloc 依赖版本 5.2.1构建文档 [deps/jemalloc/INSTALL.md](https://link.gitcode.com/i/a7697b4df536f145738f222582c6e2dd) 为骨架系统讲解 jemalloc 从基础编译、全套 configure 配置参数、环境变量、make 目标到高级安装的完整链路并结合 KeyDB 的 [deps/Makefile](https://link.gitcode.com/i/caa19e0e384b4efaf90e13a33bc5bd1d)、[src/zmalloc.cpp](https://link.gitcode.com/i/77061aab8e1308e8aa6dd306ad2103ef) 等真实集成代码展示这些配置选项在大型多线程数据库项目中的实际落地方式。读完本文你将能独立完成 jemalloc 的定制构建与安装并理解 KeyDB 为何以 --with-lg-quantum3 --disable-cxx 等参数编译其内置 jemalloc。一、背景jemalloc 在 KeyDB 中的角色KeyDB 是 Redis 的多线程分支其默认内存分配器正是仓库内置的 jemalloc。从 deps/Makefile 可以看到KeyDB 构建系统实际执行的配置命令为jemalloc: .make-prerequisites cd jemalloc ./configure --with-version5.2.1-0-g0 --with-lg-quantum3 --disable-cxx CFLAGS$(JEMALLOC_CFLAGS) LDFLAGS$(JEMALLOC_LDFLAGS) cd jemalloc $(MAKE) CFLAGS$(JEMALLOC_CFLAGS) LDFLAGS$(JEMALLOC_LDFLAGS) lib/libjemalloc.a其中版本号5.2.1-0-g0与 deps/jemalloc/VERSION 文件完全一致。随后 src/Makefile 通过-DUSE_JEMALLOC -I../deps/jemalloc/include引入头文件并静态链接../deps/jemalloc/lib/libjemalloc.a。也就是说虽然 INSTALL.md 面向的是 jemalloc 的通用构建但本文涉及的每一个选项--with-version、--with-lg-quantum、--disable-cxx都在 KeyDB 的构建流程中被真实使用是理解整个项目编译体系的最佳切入点。二、快速开始两种标准构建路径INSTALL.md 指出构建并安装一个已打包发布的 jemalloc 版本只需在源码树根目录依次执行./configure make make install而如果是从未经打包的开发者源码unpackaged developer sources构建最简单且可能可行的命令序列是./autogen.sh make dist make make install这里需要注意一个关键差异默认构建目标不会生成文档。原因在于生成文档会引入对xsltproc的依赖这是打包发布所不希望的。因此要么先执行make dist它会触发生成文档所需的源文件与 Makefile 依赖要么通过下文介绍的各种install_*目标跳过文档安装。构建完成后还可以用 deps/jemalloc/README 与 deps/jemalloc/ChangeLog 核对版本特性KeyDB 使用的 5.2.1 版本对应的运行期调优建议可参考同目录的 deps/jemalloc/TUNING.md。三、高级配置configure 全参数解析configure脚本支持大量选项用于控制启用的功能、安装位置等。以下选项列表并非穷尽./configure --help会打印权威的完整列表但覆盖了绝大多数实际场景。这些选项的实际定义与校验逻辑可对照 deps/jemalloc/configure.ac 阅读。3.1 基础安装与版本控制--help打印完整的选项列表是查阅其余未列出选项的第一入口。--prefixinstall-root-dir设置安装根目录。例如./configure --prefix/usr/local会将文件分别安装到/usr/local/include、/usr/local/lib和/usr/local/man。--with-version(major.minor.bugfix-nrev-ggid|VERSION)VERSION 文件是配置成功的前提configure 按以下步骤保证其存在若显式指定--with-versionmajor.minor.bugfix-nrev-ggid则用该值生成 VERSION 文件若未以任何形式指定--with-version且源码目录位于 git 仓库内则尝试通过git describe匹配发布标签来生成 VERSION若 VERSION 仍缺失则用伪造版本0.0.0-0-g0000000000000000000000000000000000000000生成。特别地--with-versionVERSION会跳过第 1、2 步这简化了把 jemalloc 发布版嵌入到其他项目 git 仓库时的配置流程——KeyDB 正是使用该选项--with-version5.2.1-0-g0来固化版本号的。3.2 符号与命名空间控制--with-rpathcolon-separated-rpath嵌入一个或多个库搜索路径使 libjemalloc 能定位其链接的依赖库。该选项仅对 ELF 架构系统生效。--with-manglingmap对map中指定的公共符号进行改名。map是逗号分隔的name:mangled对列表。例如要用 ld 的--wrap选项作为覆盖 libc malloc 实现的替代方案--with-manglingmalloc:__wrap_malloc,free:__wrap_free[...]注意mangling 发生在--with-jemalloc-prefix前缀应用之前且 mangled 后的符号在应用前缀时会被忽略。--with-jemalloc-prefixprefix为所有公共 API 添加prefix前缀。例如prefix为prefix_时会发生如下改名malloc() -- prefix_malloc() malloc_conf -- prefix_malloc_conf /etc/malloc.conf -- /etc/prefix_malloc.conf MALLOC_CONF -- PREFIX_MALLOC_CONF这使得 jemalloc 可以与系统分配器共存甚至可以在同一进程内同时使用多份 jemalloc。默认前缀为空字符串但在 OS X 上为je_——OS X 上 jemalloc 覆盖默认 malloc zone但不会真正替换malloc、calloc等符号。--without-export不导出公共 API。当把 jemalloc 构建为静态库、或需要在 OSX 上使用 zone allocator 而避免导出公共 API 时很有用。--with-private-namespaceprefix为所有库私有 API 添加prefixje_前缀。共享库通过符号可见性机制即可防止私有符号被导出但静态库存在真实的命名冲突可能。默认prefix为空即符号前缀为je_。--with-install-suffixsuffix在所有安装文件的基础名后追加suffix使多个版本的 jemalloc 可以共存于同一安装目录。例如libjemalloc.so.0会变为libjemallocsuffix.so.0。3.3 运行时默认配置与调试--with-malloc-confmalloc_conf将malloc_conf作为运行时选项字符串内嵌其优先级高于malloc_conf全局变量、/etc/malloc.conf符号链接和MALLOC_CONF环境变量。例如将默认 decay惰性回收时间改为 30 秒--with-malloc-confdecay_ms:30000--enable-debug启用断言与校验代码。会带来显著性能损失但在应用开发阶段非常有用。--disable-stats禁用统计信息收集功能详见opt.stats_print选项文档。KeyDB 的INFO memory与MEMORY allocator-stats命令依赖这部分统计见 src/object.cpp 附近代码。--enable-prof启用堆剖析heap profiling与泄漏检测功能详见opt.prof选项文档。启用后configure 会按以下顺序选择第一个可正常工作的回溯backtrace方案libunwind需--enable-prof-libunwindlibgcc除非--disable-prof-libgccgcc intrinsics除非--disable-prof-gcc配套选项--enable-prof-libunwind使用 libunwind 库进行栈回溯--disable-prof-libgcc禁用 libgcc 的回溯功能--disable-prof-gcc禁用 gcc intrinsics 的回溯--with-static-libunwindlibunwind.a静态链接指定的 libunwind.a而非用-lunwind动态链接。--disable-fill禁用内存的 junk/zero 填充支持详见opt.junk与opt.zero选项文档。--disable-zone-allocator禁用 Darwin 的 zone allocator。这意味着 jemalloc 将不会被挂钩为 OSX/iOS 上的默认分配器。--enable-utrace启用基于utrace(2)的分配追踪。该功能可移植性差FreeBSD 有Linux 与 OS X 没有。--enable-xmalloc启用因内存不足而立即终止进程的可选支持类似常见的 xmalloc malloc 包装函数详见opt.xmalloc选项文档。--enable-lazy-lock启用包裹pthread_create()的代码用于检测应用从单线程切换到多线程模式从而在单线程模式下避免互斥锁的加锁/解锁操作。实践中该特性通常对性能影响很小除非线程本地缓存tcache被禁用。3.4 内存布局与系统调用--disable-cache-oblivious禁用大型分配无对齐约束时的 cache-oblivious 对齐。若禁用所有大型分配将按页对齐这是实现附带结果可能严重损害 CPU 缓存利用率。但 cache-oblivious 布局的代价是每个大型分配多占用一页最极端情况下 16 KiB 大小类别的物理内存占用会升至 20 KiB。--disable-syscall禁用对syscall(2)的使用改用{open,read,write,close}(2)。这是针对那些对syscall(2)施加安全限制的系统的规避手段。--with-lg-pagelg-page指定分配器页大小的以 2 为底的对数该值必须不小于系统页大小。默认情况下 configure 会探测主机页大小并将分配器页大小设为等于系统页大小只有当系统页大小可能在配置与运行之间变化如交叉编译时才需要显式指定。--with-lg-hugepagelg-hugepage指定系统大页huge page大小的以 2 为底的对数。交叉编译或需要覆盖不支持大页的系统的默认值时有用。--with-lg-quantumlg-quantum指定最小分配对齐的以 2 为底的对数。jemalloc 需要知道满足 C 标准要求的最小对齐C11 草案要求返回指针满足可赋给任意具有基础对齐要求的类型指针。该设置与架构相关jemalloc 已内置常见现代架构的安全值但 glibc 的选择可能影响你的决策大多数现代架构要求 16 字节对齐lg-quantum4glibc 出于性能原因未满足该要求jemalloc 默认遵循 C 标准但对小于 quantum 的大小类别存在技术性变通由于 Linux 系统普遍已适配 glibc 的非合规行为实践中让 jemalloc 的最小对齐跟随 glibc 通常也是安全的。如果配置时指定--with-lg-quantum3jemalloc 将额外提供非 16 字节对齐的大小类别24、40 和 56。KeyDB 的 deps/Makefile 正是使用了--with-lg-quantum3以换取更细粒度的大小类别这对 KeyDB 大量小对象分配如字符串对象、EMBSTR 编码的内存利用效率有直接影响。--with-lg-vaddrlg-vaddr指定有效虚拟地址位数。configure 会在已知如何探测的平台自动检测虚拟地址大小其余平台使用默认值。交叉编译时可能有用。3.5 链接与加载行为--disable-initial-exec-tls禁用 jemalloc 内部线程本地存储的 initial-exec TLS 模型在支持显式设置的平台上。这允许 jemalloc 在程序启动后被动态加载例如通过 dlopen。注意此时同一进程内将存在两份 malloc 实现若指针在两者之间泄漏几乎必然导致难以排查的运行时崩溃。--disable-libdl禁用对 libdl 的使用即dlsym(3)lazy lock 选项依赖它。这可用于构建静态二进制。--disable-cxx禁用 C 集成即不生成new和delete运算符实现。KeyDB 正是通过--disable-cxx构建 jemalloc 的deps/Makefile因为 KeyDB 的 C 分配需求由自身的 src/new.cpp 与 src/zmalloc.cpp 统一接管无需 jemalloc 的 C 集成层。--with-xslrootpath构建文档时指定 DocBook XSL 样式表的位置。四、影响 configure 的环境变量以下环境变量同样并非穷尽列表会影响 configure 行为CFLAGS?/CXXFLAGS?传递给 C/C 编译器的标志。configure 脚本自己设置的标志会被前置prepend因此显式设置的标志通常优先。指定-Werror等标志时要小心可能以不良方式影响 configure 测试。EXTRA_CFLAGS?/EXTRA_CXXFLAGS?追加到 CFLAGS/CXXFLAGS 末尾但不会在配置阶段传给编译器。这使你可以在不干扰 configure 探测合适标志的前提下追加-Werror等标志。CPPFLAGS?传递给 C 预处理器的标志。注意 configure 查找头文件时不会把 CFLAGS 传给 cpp因此若需要帮助 configure 找到头文件必须使用 CPPFLAGS。LD_LIBRARY_PATH?ld 使用这个冒号分隔列表查找库。LDFLAGS?链接时传递的标志。PATH?configure 用它查找程序。KeyDB 在构建 jemalloc 时使用了CFLAGS$(JEMALLOC_CFLAGS)与LDFLAGS$(JEMALLOC_LDFLAGS)其中 deps/Makefile 定义为JEMALLOC_CFLAGS -stdgnu99 -Wall -pipe -g3 -O3 -funroll-loops $(CFLAGS) JEMALLOC_LDFLAGS $(LDFLAGS)用 config.cache 覆盖探测结果某些情况下需要修正与实际不符的配置探测结果。例如 Linux 4.5 为madvise(2)增加了 MADV_FREE 标志如果在支持 MADV_FREE 的主机构建、却要部署到不支持的目标机就会出问题。可用缓存文件覆盖 configure.ac 中定义的对应配置变量echo je_cv_madv_freeno config.cache ./configure -C五、高级编译按需构建 make 目标只构建 jemalloc 的特定部分可使用以下目标build_lib_shared build_lib_static build_lib build_doc_html build_doc_man build_doc只安装特定部分可使用install_bin install_include install_lib_shared install_lib_static install_lib_pc install_lib install_doc_html install_doc_man install_docKeyDB 只需要静态库因此在 deps/Makefile 中直接调用make lib/libjemalloc.a绕过了共享库与文档构建缩短了整体编译时间。按不同程度清理构建结果可使用clean distclean relcleanKeyDB 的 deps/Makefile 在distclean目标中会执行cd jemalloc [ -f Makefile ] $(MAKE) distclean确保依赖重新构建时从干净状态开始。六、高级安装make 变量调用 make 时还可以定义以下变量非穷尽INCLUDEDIR?头文件的安装前缀。LIBDIR?库文件的安装前缀。MANDIR?man 手册页的安装前缀。DESTDIR?前置到 INCLUDEDIR、LIBDIR、DATADIR、MANDIR 之前。当需要安装到与--prefix不同的路径时非常有用如打包、交叉安装。CC?指定 C 编译器。CFLAGS?传给编译器的标志。CPPFLAGS?传给 C 预处理器的标志。LDFLAGS?链接时传递的标志。PATH?配置与构建期间查找程序所用的路径。DESTDIR是打包场景的标配先用--prefix/usr配置再以make install DESTDIR/tmp/pkg-root把文件暂存到临时目录即可制作符合文件系统布局的安装包。七、开发与源码修改如果你打算对 jemalloc 做实质性修改应使用autogen.sh而非直接运行configure。它会重新生成configure、启用配置依赖规则并启用自动生成源文件的重生成。构建系统还支持与源码树分离的对象目录out-of-tree build。例如autoconf mkdir obj cd obj ../configure --enable-autogen make这种构建方式可以保持源码树干净方便并行维护多套配置。八、文档查看jemalloc 的手册页同时生成 html 与 roff 两种格式html 格式可用任意浏览器查看roff 格式可在安装前用以下命令排版nroff -man -t doc/jemalloc.3在 KeyDB 的构建中由于 deps/Makefile 只构建lib/libjemalloc.a文档不会默认生成——这与 INSTALL.md 中默认目标不构建文档以避免 xsltproc 依赖的说明一致。九、把 INSTALL.md 知识映射到 KeyDB 实践最后把文档中的配置选项与 KeyDB 源码中的实际使用一一对应形成完整的知识闭环INSTALL.md 选项KeyDB 使用位置效果说明--with-versiondeps/Makefile--with-version5.2.1-0-g0固化 VERSION避免依赖 git describe--with-lg-quantum3deps/Makefile启用 24/40/56 等非 16 字节对齐大小类别改善小对象内存效率--disable-cxxdeps/Makefile由 KeyDB 自管 C 分配跳过 jemalloc C 层--with-jemalloc-prefix默认src/zmalloc.cpp直接使用malloc/mallocx/dallocx等符号运行时 mallctl 接口src/zmalloc.cpp通过mallctl(epoch)、stats.resident、stats.active、stats.allocated采集分配器统计background_thread运行时选项src/config.cppjemalloc-bg-thread、src/server.h配置项调用set_jemalloc_bg_thread()控制异步回收线程arena.i.purgemallctlsrc/zmalloc.cppjemalloc_purge()强制把保留页归还操作系统内存回收联动src/db.cppFLUSHALL/FLUSHDB非 ASYNC后同步调用jemalloc_purge()弥补 jemalloc 5 无流量时不主动释放页的行为碎片分析src/defrag.cpp、src/zmalloc.cpp使用MALLOCX_TCACHE_NONE绕过线程缓存分配支撑在线 defragmentation其中值得特别强调的是jemalloc-bg-thread配置项它在 src/config.cpp 中注册类型为MODIFIABLE_CONFIG运行时可改并通过set_jemalloc_bg_thread()写入 jemalloc 的background_threadmallctl。这正对应 INSTALL.md 中--with-malloc-conf所嵌入的那类运行时选项——只是 KeyDB 选择在运行时动态控制而非编译期固化。若想进一步调优 jemalloc 在 KeyDB 中的表现如 decay 时间、arena 数量、percpu_arena 等可参考仓库内 deps/jemalloc/TUNING.md它给出了background_thread:true,metadata_thp:auto、dirty_decay_ms:5000,muzzy_decay_ms:5000、narenas:1等针对不同资源取向的推荐组合配合 INSTALL.md 的--with-malloc-conf或 KeyDB 运行时配置即可落地。【免费下载链接】KeyDBA Multithreaded Fork of Redis项目地址: https://gitcode.com/GitHub_Trending/ke/KeyDB创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考