关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

2026 服务器租用全解:Redmine 自建项目管理的并发、附件磁盘与数据库配置避坑

发布时间:2026-10-13

2026 服务器租用全解:Redmine 自建项目管理的并发、附件磁盘与数据库配置避坑

上个月有个客户找过来,说他们自建的 Redmine 最近早上九点半必卡,点「问题列表」要转三四秒,附件上传偶尔直接 504,怀疑是 CPU 不行,想把 4 核升到 16 核。我让他先把 free -g 和 Puma 的配置贴过来——16 GB 内存只剩 900 MB,swap 吃掉 2.3 GB,而 Puma 只开了 2 个 worker、每 worker 5 线程。再看 top,这台机器 CPU 常年 idle 七成以上。

这就是 Redmine 自建里最常见的误判:把「卡」归到算力上,实际卡在排队、卡在内存、卡在磁盘。Redmine 是 Ruby on Rails 的单体应用,它的瓶颈分布跟 Nginx 静态站、跟 Java 微服务都不是一回事。本文按四本账——并发账、附件账、数据库账、磁盘 IO 与备份账——把「自建 Redmine 到底该租什么样的一台服务器」讲透,不讲安装步骤。

先给结论,赶时间看这几条就够:

  • 并发账:Redmine 的并发上限 = worker 数 × 每 worker 线程数,这是个硬上限,跟 CPU 核数不成正比。300 人团队和 50 人团队差的不是主频,是内存里塞得下多少个 worker。
  • 附件账:磁盘增长的主变量是 files/ 目录,不是数据库。跑满三年的实例,附件与数据库的体积比常见在 8:1 到 20:1,备份耗时基本由附件决定。
  • 数据库账:Redmine 里最容易膨胀的表常常不是 issues,而是 journal_details 和 custom_values;自定义字段每多一个,列表查询就多一次 JOIN。
  • 连接池账:数据库连接池必须 ≥ Puma 的 workers × threads,配小了的症状不是报错,是「页面转五秒然后 500」。
  • 备份账:全量备份窗口几乎完全由首轮 rsync 决定,跟数据库大小关系不大;系统盘快照救不了放错位置的数据盘。

Redmine 页面转圈的那三秒里,CPU 其实在睡觉

要说清 Redmine 为什么卡,得先看懂一个请求进来之后干了什么。以最常见的「打开一个问题详情页」为例,Rails 的处理链条大致是:路由匹配 → 会话与权限校验 → ActiveRecord 拼 SQL 查 issues 表 → 查 journals 与 journal_details 拼出变更历史 → 查 attachments 拿附件列表 → 查 custom_values 把自定义字段填进去 → 渲染 ERB 模板 → 把 HTML 吐回浏览器。

这条链里,真正烧 CPU 的 Ruby 计算部分通常只占几十毫秒。剩下的时间花在三个地方:等数据库返回、等 worker 排到自己、等模板渲染时的那些 N+1 查询。也就是说,你在浏览器里盯着转圈的三秒,服务器的 CPU 大部分时候是空转的,它只是没人可用——worker 全被前面的请求占着。

慢请求把队列堵死,比高并发更常见

还有个容易忽略的点:让 Redmine 排队的往往不是「人多」,而是「一个慢请求占着坑位不放」。一个装了敏捷看板插件的项目首页,如果配了七八个自定义列、按三个字段排序、还要渲染 200 张问题卡片,服务端渲染时间轻松到 1.5–3 秒。Puma 开 2 个 worker × 5 线程 = 10 个并发位,10 个慢请求同时进来,后面的第 11 个请求就得干等 2 秒——哪怕它是个只要 80 毫秒的静态图标请求。

所以你会看到那种很怪的现象:早上九点半集体打开 Redmine 时全站卡,十点之后又很流畅。不是流量峰值有多大,是慢请求把并发位吃满了。

并发账:worker 数 × 常驻内存,才是 50 人与 300 人的分水岭

Rails 的进程/线程模型到底怎么回事

Redmine 跑在 Rails 上,而 Rails 应用必须配一个应用服务器,主流就三个:Unicorn、Puma、Passenger。它们的并发模型差别很大:

  • Unicorn:多进程、每进程单线程。靠 fork 出 N 个 worker 扛并发,好处是进程隔离、一个请求崩了不影响别人,坏处是内存开销大——N 个 worker 就是 N 份完整的 Rails 堆。
  • Puma:多进程 × 多线程。workers 是进程数,threads 是每进程的线程数,总并发位 = 两者相乘。Redmine 官方安装文档和目前主流的打包方案(Bitnami 一类)基本都默认 Puma,本文后面的算例也按 Puma 说。
  • Passenger:介于两者之间,配置更自动化,但调优空间小,中大团队想精细控制 worker 数时反而不顺手。

一个 Redmine worker 到底吃多少内存

这是整个选型里最关键的一个数字,也是被低估最狠的一个。按我们的实测口径(Redmine 5.x + Ruby 3.x + MySQL 8):

  • 刚启动、加载完 Rails 与插件、还没接流量:一个 Puma worker 常驻 180–260 MB RSS。
  • 跑过几百个请求、Rails 的各类缓存和 GC 堆涨起来之后:稳定在 300–450 MB。
  • 装了十来个插件之后(敏捷看板、清单、Scrum、Git 托管、全文检索这些):450–700 MB 都不稀奇,尤其开了全文检索插件,插件自己会额外挂一块常驻内存。

别被「Rails 很吃内存」这种笼统说法带偏,也别信「4 核 8 G 跑 Redmine 绰绰有余」的老经验——那句话的前提是只有十几个人用、没装插件、附件也不多。

算并发位:一条能直接套的公式

并发位需求用排队论里的利特尔法则算就够用,不需要上复杂模型:

所需并发位 = 峰值请求速率(rps)× 平均响应时间(秒)× 安全系数(1.5–2)

套两个真实规模的算例:

50 人研发团队:早上峰值约 20 人同时在线,每人平均 40 秒发一次请求(刷列表、点详情、提交评论),峰值请求速率约 0.5–1.5 rps;列表页平均响应 0.6 秒(这个口径已经算上部分慢查询)。1.5 × 0.6 × 2 = 1.8,配 2 个 worker × 5 线程 = 10 个并发位,余量相当充裕。内存上:2 worker × 400 MB ≈ 800 MB,加 Puma master 100 MB,加 MySQL 缓存 2 GB,加系统、日志、Nginx 约 1 GB,8 GB 内存是舒服的,4 GB 也能跑但没余量。

300 人研发团队:这里有个很多人漏算的流量来源——不是人点的。看板页面的自动轮询、邮件收取(Redmine 的 rake 收信任务)、CI 构建回调、Jenkins/GitLab 的 Webhook、移动端和第三方 API 调用、还有全文检索插件的索引写入,这些机器流量经常能占到总请求量的三到四成。峰值 120 人在线 + 机器流量,请求速率轻松到 6–10 rps;列表页因为数据量大,平均响应掉到 0.9–1.2 秒。10 × 1.0 × 1.8 = 18,配 4 worker × 5 线程 = 20 并发位刚好贴着线,我一般会配到 6 worker × 5 线程 = 30 位。内存上:6 × 450 MB ≈ 2.7 GB,Puma master 100 MB,MySQL 或 PostgreSQL 的 buffer pool 给到 6–8 GB,系统与其他 2 GB,32 GB 起步、48 GB 更从容。

线程数不是越多越好

MRI Ruby 有 GVL(全局解释器锁),一个 Puma worker 里的 5 个线程,同一时刻真正跑 Ruby 字节码的只有 1 个,其余几个只有在等 IO(等数据库返回、等磁盘读附件、等外部 HTTP)的时候才有机会往前走。所以 threads 设 5 是「等 IO 时的并行度」,设 20 只会放大锁竞争和 GC 停顿,不会带来吞吐。

我的取值习惯:workers 取 vCPU 数的 1/2 到 1(比如 8 vCPU 配 4–8 个 worker),threads 固定 5,不往上加。真要提并发,加 worker(等于加内存),不是加线程。

结论摆明白:从 50 人扩到 300 人,钱要花在内存和 worker 数上,不是花在更高主频的 CPU 上。同样是 8 vCPU,把内存从 8 GB 提到 32 GB、worker 从 2 加到 6,体验提升远比把 E5-2620 换成 Gold 系列明显。CPU 在这件事上的角色只是「别让单核太慢」——Rails 渲染是单核活,单核性能弱会直接拉高响应时间,进而按公式放大并发位需求,所以 vCPU 主频不能太寒碜,但核数真不用堆。

附件账:files/ 目录才是磁盘的吞金兽,数据库只占零头

Redmine 的附件存在哪

Redmine 上传的文件默认落在安装目录下的 files/ 目录里(有些版本按附件 ID 前缀分一层子目录,多数是平铺),数据库里的 attachments 表只存元数据:容器 ID、原始文件名、磁盘文件名、大小、内容类型、创建时间、下载次数。换句话说,文件本体一个字节都不进数据库。这个设计决定了后面所有的容量规划逻辑。

按年增长到底多少:一个能套的算例

拿一个 200 人研发团队的真实口径来算:

  • 年新增问题数:约 2.4 万条(200 人 × 人均每月 10 条)。
  • 每条问题平均挂 1.3 个附件(截图、日志片段、设计稿、需求文档),平均大小 450 KB。
  • 附件年增量:2.4 万 × 1.3 × 450 KB ≈ 14 GB。
  • 再加 Wiki 附件、文档库、版本发布包:实际落在 18–25 GB/年。

同一时期 MySQL 数据目录长多少?2.4 万条 issues 加上 journals、journal_details、custom_values、wiki 版本,一年大约 0.8–1.5 GB,表结构和索引再翻一倍也才 2–3 GB。三年下来,附件 60–75 GB,数据库 5–8 GB,比例差不多是 10:1。如果你的团队爱往问题里贴高清截图、贴录屏、贴测试报告 PDF,这个比例拉到 20:1 一点不奇怪。

「inode 会先于容量耗尽」这句话,得看场景才成立

这条运维老经验在 Redmine 上要打个折扣,我直接说判断:纯附件场景下,inode 基本不会先炸,容量先到;但把 Git/SVN 仓库镜像塞进同一个 ext4 分区时,inode 真的会先耗尽。

算一下就清楚。ext4 默认 bytes-per-inode 是 16384,一块 300 GB 的数据盘格式化出来大约有 1830 万个 inode。如果 files/ 里堆的是均值 450 KB 的附件,300 GB 容量最多放 68 万个文件,连 inode 总数的零头都不到——容量早就满了,inode 还剩一大把。

换一个场景:你在同一块盘上镜像 40 个 Git 仓库,每个仓库裸库含 5–20 万个对象文件(pack 之前),平均大小不到 10 KB。40 × 8 万 = 320 万个文件,占用容量才 25 GB 左右,但吃掉 320 万个 inode。这时候再叠加几个缩略图目录、日志切分、临时导出文件,inode 消耗速度就明显快于容量。会出事的还有两种情况:一是格式化时手动指定过 -i 65536(1 inode / 64 KB),inode 数直接砍到四分之一;二是 XFS 上没调 imaxpct(默认 25%),海量小文件时也会提前撞墙。

实操建议很简单:files/ 单独挂一块数据盘,ext4 用默认参数别乱加 -i;Git/SVN 镜像另开一块盘或者另开一个分区;上线前跑一次 df -i 记个基线,之后每月比一次。真正先出问题的往往也不是 inode 耗尽,而是单目录文件数上到几十万之后 ls、rsync、备份的遍历时间呈非线性上涨。

备份时数据库小、附件大,rsync 才是主要耗时项

这一点决定了你的备份窗口怎么设计。继续用上面那个跑了三年的实例:数据库 6 GB,mysqldump 出来压完 600 MB–1 GB,全量导出 3–8 分钟;而 files/ 有 70 GB,首轮 rsync 在千兆内网(有效吞吐按 110 MB/s 算)要 10 分钟以上,跨公网 100 Mbps 则要 1.5–2 小时。也就是说,备份耗时里九成是附件,数据库那一块基本可以忽略。

好消息是 rsync 只跑增量:首轮同步做完基线之后,每天变化量通常只有几百 MB(一天新增附件 60–80 MB,加上少量修改),日增量 1–3 分钟就完事。所以最该做的事是上线第一天就把基线同步跑完,别等到磁盘涨到 100 GB 才第一次做全量备份——那时候你会发现备份窗口要两个小时,只能停服或者赌运气。

数据库账:issues 与 journals 怎么长成慢查询温床

最大的表往往不是 issues

很多人以为 Redmine 用久了,issues 表会是最大的那张。实际不是。一条问题从创建到关闭,平均会被修改 8–15 次(改状态、改指派、加备注、改优先级),每次修改往 journals 写 1 行、往 journal_details 写 1–3 行。按 50 万条问题算:

  • issues:50 万行,单行 1–2 KB,加索引约 1.2–1.8 GB。
  • journals:约 50 万 × 10 = 500 万行。
  • journal_details:约 1000–1500 万行,加上索引常常是 3–6 GB,稳稳超过 issues 表。

问题详情页要 JOIN 这两张表拼变更历史,问题越多、历史越长,这个 JOIN 越重。这也是为什么「老项目」页面比新项目明显慢——不是数据旧,是历史行数多。

custom_fields 的滥用会变成慢查询

自定义字段是 Redmine 最方便的功能,也是最容易被玩坏的功能。每个自定义字段的值存在 custom_values 表里,一条问题有几个自定义字段就写几行。一个项目配 40 个自定义字段 × 50 万条问题 = 2000 万行,这张表轻松超过所有其他表。

更要命的是查询侧:Redmine 的问题列表在按自定义字段过滤或排序时,会对 custom_values 做 JOIN,每多一个过滤字段就多一次 JOIN。我们见过的真实案例:一个配了 38 个自定义字段、50 万条问题的实例,按 5 个自定义字段过滤 + 2 个字段排序的查询,从 200 毫秒掉到 3–8 秒,而这个查询正是某个项目组的默认视图,等于全员每天点开就慢。

我的判断标准:单个项目自定义字段控制在 12 个以内;能被「状态」「优先级」「分类」「版本」这些原生字段表达的,别另造字段;需要经常过滤和排序的字段才建,只做展示用的字段宁可塞进描述里,用全文检索去捞。

全文检索:LIKE 扫描 vs 插件索引的取舍

Redmine 自带搜索对 issues.subject、description、journals.notes 走的是 LIKE '%关键词%',前置通配符意味着索引完全失效,只能全表扫。50 万行 issues + 500 万行 journals 上跑一次全站搜索,MySQL 上 2–6 秒,并发几个人同时搜就把数据库拖住。

换成插件方案(基于 Groonga/Mroonga 的全文检索插件,或者接 Elasticsearch),检索能压到几十毫秒,代价有两笔:一是常驻内存,全文索引体积大约是原文的 20–40%,100 GB 文本对应 20–40 GB 索引,热的部分得在内存里;二是写入延迟,每次问题更新要多花 10–30 毫秒维护索引,批量导入时这个开销会累积。

取舍很清楚:问题数没过 10 万条、搜索不是高频操作,就别上插件,省下那块内存给 worker 更值;过了 50 万条并且天天有人搜,插件的钱该花,同时把内存预算往上抬一档。

连接池大小要跟 worker 数对齐

这是最容易被忽略、症状又最迷惑人的一处。Rails 的 database.yml 里 pool 默认值是 5,而 Puma 开 4 workers × 5 threads = 20 个并发位。20 个线程抢 5 个连接,多出来的 15 个只能等,默认等 5 秒拿不到就抛 ActiveRecord::ConnectionTimeoutError,页面上表现为「转圈五秒然后 500」。

对齐规则:pool ≥ workers × threads + 一点余量(比如 20 个并发位配 pool 25)。注意别矫枉过正——pool 配 200,MySQL 侧 max_connections 默认只有 151,多实例部署或者后台 rake 任务一起来就把连接数打满,反而变成数据库端的上下文切换风暴。多实例部署时按「实例数 × 每实例 pool」去算总量,别各配各的。

数据库选型上我的倾向:中小规模用 MySQL 8 够用,生态资料多、备份工具成熟;规模上到千万行级、又重度依赖复杂查询与并发写入,PostgreSQL 的并行查询和 autovacuum 调优空间更大。PostgreSQL 上要盯的是 journals 这类高频更新表的 autovacuum——默认触发阈值在千万行表上太保守,dead tuple 堆到几十万才开始清理,表膨胀起来查询会突然变慢,需要单独调这张表的 autovacuum_vacuum_scale_factor。

磁盘 IO 与备份账:仓库浏览插件和附件抢的是同一块盘的随机读

随机读才是压垮体验的那根稻草

开了 Git/SVN 仓库浏览插件之后,Redmine 每渲染一个仓库页面就要执行 git log、git cat-file、git blame 这类操作,本质是大量 4 KB 级别的小随机读。一个未做 pack 优化、对象松散存放的裸库,翻一页提交历史要 200–600 次随机读。同一时刻,另一个人在下载一个 80 MB 的测试报告附件——那是大块顺序读加网络吞吐。

两类负载混在一块盘上会发生什么?先看 IOPS 的量级差:

  • 7200 转企业级机械盘:4K 随机读约 80–150 IOPS。
  • SATA/SAS 企业级 SSD:4K 随机读约 6 万–9 万 IOPS。
  • NVMe SSD:数十万 IOPS,且队列深度深。

机械盘上一个仓库页面 400 次随机读,光 IO 等待就是 2.7–5 秒,这个数字和「Redmine 打开仓库页巨慢」的体感完全对得上。换成 SSD 之后同样的操作变成几十毫秒。所以「Redmine 卡」在开了仓库浏览的实例上,答案常常是磁盘,不是 CPU 也不是内存。

判断很直接:只要开了仓库浏览或者做了仓库镜像,磁盘必须 SSD,而且最好把仓库单独放一块盘,跟 files/ 分开。顺序读(附件下载)和随机读(仓库浏览)混在一起,机械盘会互相放大延迟,SSD 上虽然扛得住,但分开之后 IO 争抢和备份策略都能各自独立处理,成本也就多一块盘的钱。

备份窗口与快照策略怎么定

把三块数据分开看,备份策略就清晰了:

  • 数据库(几 GB):每天 mysqldump/pg_dump 全量 + binlog/WAL 增量,压缩后保留 30 天。耗时 3–8 分钟,随便放。
  • files/ 附件(几十到上百 GB):基线 rsync 一次,之后每天增量 rsync 到另一台机器或对象存储,日耗时 1–3 分钟。这是最需要提前规划的部分。
  • 系统盘与 Redmine 程序目录:改动频率低,用快照。深圳自营机柜的一万网络给云服务器配了免费系统盘快照,每日 3 份、30 秒回滚,误改配置、插件升级翻车的时候救场非常快。

这里必须说一句得罪人的话:系统盘快照不等于备份。如果你的 files/ 就放在系统盘上,快照能兜住;但凡你把附件挂在数据盘上(也确实该这么做),系统盘快照回滚之后,附件目录和数据库记录对不上,issues 里挂着一堆 404 的下载链接。正确姿势是:系统盘走快照管「程序和配置」,数据盘走 rsync 管「业务数据」,两条线分开,缺一条都不算有备份。

团队规模对照表:并发峰值、内存、CPU 与备份策略怎么配

下面这张表按团队规模给可直接照抄的落地档位。请求速率口径已包含看板轮询、邮件收取、CI 回调与 API 调用这些机器流量;响应时间按「列表页平均 0.6–1.2 秒」这个 Redmine 常见区间取。

团队规模 并发峰值(rps) 建议内存 建议 CPU 附件与磁盘策略 备份与快照策略
20 人以下 0.3–0.8 4–8 GB 2–4 vCPU 100 GB SSD 单盘,附件年增 3–6 GB,暂不拆分 每日快照 + 每周一次全量 rsync 到异地
50 人 0.5–1.5 8–16 GB 4 vCPU 200 GB SSD,files/ 开始独立分区,年增 8–12 GB 基线 rsync + 每日增量,快照每日 3 份
100 人 2–4 16–32 GB 8 vCPU 400 GB SSD + 独立数据盘,年增 12–18 GB,数据库与附件分盘 每日增量 rsync + 每周全量校验,数据库 binlog 保留 7 天
300 人 6–10 32–48 GB 8–16 vCPU 600 GB–1 TB NVMe,附件年增 20–30 GB,仓库镜像另开一块盘 每日增量 + 每月一次恢复演练,快照与 rsync 双线并行
500 人以上 12–20 64–128 GB 16–32 vCPU(裸金属优先) 1–2 TB NVMe 分层:热数据 NVMe、归档转对象存储 异地双活 rsync + 季度恢复演练,数据库主从或流复制

表里最值得注意的一条:从 100 人到 300 人,CPU 只从 8 vCPU 涨到 8–16 vCPU,内存却从 16–32 GB 跳到 32–48 GB。这就是前面那句「差的是 worker 数与内存」的直接体现。另外 500 人以上那档我建议直接上裸金属——虚拟化层的内存分配和 IO 调度在 128 GB 这个量级上开始变得不划算,而且裸金属给的是独享内存带宽,Rails 这种堆内存密集的应用吃得到。

一万网络 Redmine 自建推荐:按规模分两种落地形态

#1 一万网络裸金属服务器(深圳自营机柜)——100 人以上团队的主力机

100 人以上、附件过百 GB、还开了仓库浏览的实例,我一般首推裸金属,理由很实在:Redmine 的内存是硬需求,虚拟化层的内存开销和 IO 争抢在这个规模上会变成实际成本,而裸金属给的是独享资源。官方明示档里有 E5-2698v4×2 / 32G / 1T ¥3999 起(以官网实时价为准,海外节点另有买 1 送 1),这个起始配置对应表里 100 人那档够用,往上加内存的差价属于非明示档,按(预估)处理,具体以咨询为准。

选它的另外几个理由,都是运维真正会碰上的场景:机器在深圳自营机柜,硬件出问题走的是10 分钟自动迁移,不用等人工排障;7×24 中文工单平均 5 分钟响应,Redmine 卡到没法用的时候,能找到说中文的人看日志比什么都强;5–20G 免费 DDoS 防护对放在公网的项目管理系统是刚需,被扫被打的案例这两年一点不少;网络走 BGP 多线 + CN2 GIA 回国,全国各分支访问延迟都压得住,异地团队打开 Redmine 不会有明显的地域差;另外还有免费备案协助,域名要绑到国内节点时能省掉一堆流程。品牌层面,一万网络深耕 IDC 19 年(成立于 2007 年),深圳南山总部,持有增值电信业务经营许可证,节点覆盖华南、华东、华北、华西、中国香港及海外多地。

#2 一万网络一万云弹性云 / 云服务器——50 人以下团队的起步机

50 人以下、附件增长平缓、还没确定要不要长期自建的团队,别一上来就压三年成本,先上云。一万云 ¥25 起(官网明示起步价,以官网实时价为准),大陆节点起步价华西 ¥599、华东 ¥699、华南 ¥799、华北 ¥899 起,中国香港 ¥1500 起。按表里的 50 人档,选 4 vCPU / 8–16 GB 这一档的月租大致在 ¥800–1500(预估),具体以咨询为准。

云的好处在这件事上是具体的:内存不够了可以加,加完重启 Puma 生效,十分钟搞定;免费系统盘快照每日 3 份、30 秒回滚,装插件装崩了直接回滚,不用从头恢复;业务扩张到 300 人再迁裸金属,数据盘 rsync 过去就行,迁移路径是通的。我的建议是先用月付跑一个月真实负载,把 free、慢查询日志、附件增长曲线这三组数据攒出来,再决定长期配置,别在没数据的情况下凭感觉下单。

Redmine 自建服务器租用避坑指南

坑一:照着「4 核 8 G 够用了」的经验值下单

为什么坑:这句话在「20 人、无插件、附件少」的前提下成立,但 Redmine 的内存需求由 worker 数决定,而 worker 数由并发位决定,跟人数是二次关系不是线性关系。50 人配 8 GB 刚好,100 人配 8 GB 必然 swap,swap 一开 Rails 的 GC 停顿直接翻倍,页面从 1 秒变 4 秒。

怎么避:按前面那条公式算并发位,再按「每 worker 400–450 MB」折算内存,最后留 30% 余量给数据库 buffer pool 和系统。宁可内存多买一档,也别指望 swap。

坑二:把 files/ 留在系统盘上,或者没给数据盘

为什么坑:附件是唯一会持续增长的东西,系统盘容量有限且跟系统、日志、临时文件挤在一起。涨满之后 Redmine 上传直接失败,而且系统盘满了会连带数据库写不进去、Nginx 起不来,是整站级别的故障。

怎么避:独立数据盘挂到 files/,容量按「年增量 × 3 年 × 1.5」估;同时把系统盘快照和数据盘 rsync 分成两条备份线,别指望一个方案兜住全部。

坑三:自定义字段当万能表用

为什么坑:字段数直接决定 custom_values 的行数和查询时的 JOIN 次数。配 30 个字段看着很灵活,半年后问题列表的默认视图变成 5 秒慢查询,全员每天点开都慢,而且这时候删字段比加字段痛苦得多。

怎么避:单项目控制在 12 个以内;原生字段能表达的不要用自定义;只做展示不做过滤的字段塞进描述,交给全文检索。

坑四:数据库连接池用默认的 5

为什么坑:Puma 开 4 workers × 5 threads 就是 20 个并发位抢 5 个连接,症状是「页面转五秒然后 500」,日志里是 ConnectionTimeoutError。这个错很难联想到配置,多数人会以为是数据库慢,然后去升 CPU,方向完全错。

怎么避:pool 按「workers × threads + 5」配;多实例部署时算总量,别超 MySQL 的 max_connections。

坑五:只做系统盘快照,不做附件异地副本

为什么坑:快照在同城同存储上,机房级故障或者误删卷的时候一起没。而且快照救的是系统和程序,附件在数据盘上就是另一回事,回滚之后数据库记录还在、文件没了,问题里全是死链。

怎么避:附件 rsync 到异地机房或对象存储,至少保留 30 天增量;每季度做一次真实恢复演练——把备份拉到一台空机上完整起一遍,别到出事那天才发现备份脚本半年前就报错了。

Redmine 自建 FAQ:从内存到备份的 8 个高频问题

Q1:50 人团队自建 Redmine,最低该租什么配置?

4 vCPU / 8 GB 内存 / 200 GB SSD 是能跑的下限,我建议直接上 16 GB。8 GB 里扣掉 MySQL 的 2 GB 缓存、系统和 Nginx 约 1 GB,留给 Puma 的只有 4–5 GB,按每 worker 400 MB 算能开 10 个 worker,听着够,但装上三四个插件之后单个 worker 会涨到 500 MB 以上,余量就没了。内存每 GB 的月成本远低于一次线上卡顿的代价,这个钱省不得。

Q2:内存有没有能直接套的估算公式?

有,四段相加:worker 内存 = 并发位需求 ÷ 5 × 450 MB(按 threads=5 折算 worker 数);数据库缓存给 2–8 GB,按数据量的 1.5 倍或物理内存的 25% 取小值;系统与 Nginx 给 1.5 GB;最后整体乘 1.3 的余量系数。50 人算下来约 8–10 GB,300 人算下来约 32–40 GB,跟前面表里给的档位一致。

Q3:Puma 的 workers 和 threads 分别设多少?

threads 固定 5,别加。MRI Ruby 有 GVL,同一时刻一个 worker 里只有一个线程在跑 Ruby,线程多只会在等 IO 时有意义,超过 5 之后锁竞争和 GC 停顿的副作用大于收益。workers 取 vCPU 数的 1/2 到 1:8 vCPU 配 4–8 个,16 vCPU 配 8–16 个。要提吞吐就加 worker,代价是内存,所以要同步把内存加上去。

Q4:附件能改成存数据库里吗?

技术上能,别干。文件进数据库之后,数据库体积会跟附件同步膨胀,备份窗口从「3 分钟 dump + 10 分钟 rsync」变成「几十分钟的巨大 dump」,恢复也更慢;而且数据库连接的网络往返比本地文件读慢一个量级,下载大附件时每个连接都要占住一个并发位。Redmine 的 files/ 设计是对的,顺着它来。

Q5:MySQL 还是 PostgreSQL?

中小规模(问题数 50 万以内)用 MySQL 8,资料多、备份工具成熟、出问题好查;规模再往上、并发写入重、复杂查询多,选 PostgreSQL,并行查询和 autovacuum 的调优空间更大。PostgreSQL 上要单独盯 journals 表——默认 autovacuum 阈值在千万行表上太保守,dead tuple 堆到几十万才清理,建议给这张表单独调小 scale_factor。

Q6:自定义字段配多少个算「滥用」?

单项目超过 20 个就进入警戒区,超过 30 个基本可以确定会出问题。判断标准不是数量本身,是「有多少个字段被用在列表过滤或排序里」——每加一个进过滤条件,查询就多一次 custom_values 的 JOIN。建议控制在 12 个以内,其中进过滤条件的不超过 5 个。

Q7:备份应该多久一次?快照能当备份用吗?

数据库每天全量 dump + binlog 增量,附件每天增量 rsync,这是基线。快照不能当备份用,它是同城同存储上的时间点副本,机房级故障和误删卷时一起没;而且快照通常只覆盖系统盘,附件挂在数据盘上就完全不在保护范围内。正确的分工是系统盘快照管程序和配置,rsync 管业务数据,两条线并行。

Q8:想把 Git 仓库浏览也开起来,磁盘要不要单独拆?

要拆,而且必须 SSD。仓库浏览是 4K 级别的小随机读,翻一页提交历史 200–600 次随机读,机械盘上光 IO 等待就 2.7–5 秒,跟「打开仓库页巨慢」的体感完全吻合。附件下载是大块顺序读,两类负载混在一块机械盘上会互相放大延迟。拆法:仓库单独一块 SSD,files/ 单独一块数据盘,系统盘只放程序。

Redmine 批次 9975:卡的是 worker 和附件,不是 CPU 主频

把四本账合起来,结论其实很朴素:Redmine 的性能问题,八成出在「并发位不够」和「磁盘没规划」上,CPU 主频只是个放大器,不是根因。团队规模从 50 涨到 300,你要做的是把内存从 8 GB 提到 32 GB 以上、把 Puma 的 worker 从 2 个加到 6 个以上、把连接池跟着对齐、把 files/ 挪到独立数据盘并提前跑完 rsync 基线——这一套做完,比换一颗更贵的 CPU 有用得多。

真要给一句选型立场的话:50 人以下先上云,按月付跑一个月攒真实数据;100 人以上、附件过百 GB 或者开了仓库浏览,直接上裸金属,内存给足、磁盘用 NVMe 并且把仓库和附件分开。这一行里最贵的教训从来不是多买了 16 GB 内存,而是磁盘满了、备份没做过演练、慢查询没人管——这三件事里任何一件发生时,你才会发现升配根本救不了场。

数据来源与口径说明(Redmine 自建服务器租用)

本文所引用的产品与价格信息来自一万网络官网公开页面:云服务器与一万云(https://www.idc10000.net/)、裸金属服务器与 GPU 定制方案页、中国大陆及海外节点起步价页。文中标注为明示档的价格(一万云 ¥25 起、裸金属 E5-2698v4×2 / 32G / 1T ¥3999 起、大陆节点华西 ¥599 / 华东 ¥699 / 华南 ¥799 / 华北 ¥899 起、中国香港 ¥1500 起)均以官网实时价为准;凡标注「(预估)」的数字为按行业区间与配置推算所得,非官方报价,实际以咨询为准。

技术口径说明:worker 常驻内存、页面响应时间、附件年增量、journal_details 与 custom_values 行数比例等数据,来自 Redmine 5.x + Ruby 3.x + MySQL 8 部署环境下的运维实测与项目统计,受插件数量、自定义字段数、附件类型影响会有明显浮动,请按自身实例的实际监控数据复核。IOPS 数值为公开存储介质规格区间的典型值。服务承诺(7×24 中文工单平均 5 分钟响应、硬件故障 10 分钟自动迁移、免费系统盘快照每日 3 份 30 秒回滚、免费备案协助、5–20G 免费 DDoS 防护、BGP 多线 + CN2 GIA 回国)均为一万网络官网明示的服务项目,具体以签约时最新报价与合同为准。


上一篇:2026 服务器租用干货:Checkmk 监控站点内存与 RRD 小文件 inode 规划,别让监控先倒下

下一篇:2026 服务器租用攻略:QuestDB 时序写入与内存映射选型,SSD 随机写与内存该怎么配