Falco
(Falco)
1
我们刚刚发布了一个全新的容器镜像,将在您下次运行 ./launcher rebuild app 时使用。一如既往,只要您遵循我们的 Discourse 官方标准安装指南,则无需更改任何配置。不过,此次更新引入了一些新功能,将有助于某些部署环境。
Redis 6
我们在 Discourse 的多个地方大量使用 Redis,包括缓存、Sidekiq、MessageBus、分布式锁和速率限制等。总体而言,它一直是我们可靠的选择。
然而,在某些特定工作负载下,Redis 可能成为性能瓶颈。由于 Redis 的单线程特性,加上我们因使用 LUA 脚本而无法部署多个实例,这使得该瓶颈难以绕过。
幸运的是,Redis 6 增加了对 I/O 操作使用线程池的支持。在我们的测试中,它非常适合那些因 Redis 而受限的 Discourse 集群。
因此,如果您运行的机器拥有大量CPU 核心,且 监控指标 显示 Redis 难以处理当前负载,您现在可以通过 app.yml 的 params 部分选择启用写入操作的线程支持:
params:
redis_io_threads: "4" # 1 表示禁用,n>1 表示使用 n-1 个额外线程进行 I/O 写入
更小的镜像
在项目初期,我们选择发布较大的容器镜像,以便非技术人员更容易运行 Discourse,并处理所有必要的依赖项、版本控制和升级等问题。
不过,最近我们的压缩后镜像大小已超过 1GB,这确实有些过大。
为了缓解镜像体积不断增大的问题,我们将 Discourse 源代码从镜像内的完整副本改为仅包含最新代码版本的“浅克隆(shallow clone)”。
这一改动使压缩后的镜像体积减少了 25%,从而降低了所需的服务器存储空间,并在发布新镜像时加快了重建速度。同时,这也有助于控制镜像随时间增长的幅度。
我们在 tests-passed、beta 和 stable 分支上进行了测试,包括重建和 Web 更新,未破坏任何标准路径。不过,在 app.yml 钩子中执行更复杂的 git 操作的用户可能需要调整其自定义配置。
42 个赞
此类 Redis 升级后,浏览器体验会发生什么变化?是否会影响缓存的资源?升级后这些资源会被清空吗?
3 个赞
Falco
(Falco)
3
没有任何影响。
资源会保存到本地磁盘或对象存储中,并由 CDN 进行缓存。Redis 不会影响这些资源。
Redis 数据在升级期间会被保留。
10 个赞
Falco
(Falco)
5
是的。它来自 Redis 自身的配置文件,其中 1 表示单线程,如同旧版本一样。
8 个赞
pfaffman
(Jay Pfaffman)
6
我遇到了一个情况,我添加了以下内容:
after_redis:
- replace:
filename: "/etc/redis/redis.conf"
from: /^databases.*/
to: "databases 50"
但重建失败,原因是:
25:M 01 Dec 2020 20:21:08.830 # FATAL: Data file was created with a Redis server configured to handle
more than 16 databases. Exiting
是否有其他钩子可以在它尝试迁移或执行其他操作之前更新数据库数量?
嗯。现在在看似重建失败后,我在 Docker 日志中看到了以下内容:
chgrp: invalid group: ‘syslog’
2 个赞
pfaffman
(Jay Pfaffman)
8
多站点。多个实例共用一个 Redis。我本应使用更通用的 Redis 容器,但决定还是沿用您的方案。
2 个赞
Falco
(Falco)
9

多站点是否使用单个数据库和标准的 Redis 键名空间?据我所知,Redis 数据库只是一个薄层,而且我们有跨越其边界的命令,因此你不应该依赖这一点。
6 个赞
pfaffman
(Jay Pfaffman)
11
哦,那并不是多站点部署,而是在一台机器上运行多个实例,每个实例都需要独立的 Redis。我之所以将默认的 16 个数据库增加到 50 个,只是因为懒得严格管控哪些 Redis 数据库正在被使用。
所以,我是不是应该为每个实例运行一个独立的 Redis 容器呢?
2 个赞
pfaffman
(Jay Pfaffman)
13
哦,真糟糕。
好在我是在仅用于测试的服务器上发现的这个问题。
对于其他站点,我是该直接提供一个全新的 Redis 实例并丢弃已排队的任务,还是应该进行备份和恢复操作?
顺便提一下,过去一年多来,我并没有注意到任何交叉干扰的问题。
而且,确实有方法可以设置数据库编号。
编辑:好消息是,我可以进入容器,编辑 redis.conf 并重启它,之后它就能正常工作了。
如果您知道如何将一个站点从 DISCOURSE_REDIS_DB: 12(位于一个 Redis 容器)迁移到另一个 Redis 容器,我很想听听您的建议。或者,也许根本不必在意那些排队的任务?
3 个赞
Falco
(Falco)
14
没错。Discourse 应该能够合理地在 Redis 清空后继续运行。虽然会丢失一些数据,但都不是关键内容。
7 个赞
pfaffman
(Jay Pfaffman)
15
我原本也是这么想的,因为我不知道有任何方法可以让备份尝试恢复它(不过我还有很多不知道的地方)。看起来我可以像这样操作:https://stackoverflow.com/questions/23222616/copy-all-keys-from-one-db-to-another-in-redis,我刚刚在测试中尝试过,似乎成功了,但调整我的 playbook 以直接创建一个新的 Redis 容器并使用它会更简单。
谢谢。
现在需要决定是将这些 Redis 实例运行在数据库服务器上还是 Web 服务器上……
3 个赞
pfaffman
(Jay Pfaffman)
16
[quote=“sam, post:10, topic:171437, full:true”]
是的,多站点使用 1 个数据库
[/quote] 那么多站点配置中的 db_id: 2 指的是什么?
2 个赞
pfaffman
(Jay Pfaffman)
18
哈哈,是的,确实很令人困惑!
谢谢。我正在撰写一篇关于“在无外部反向代理的情况下使用 Let’s Encrypt 配置多站点”的主题,届时我也会顺便清理另一篇帖子。
4 个赞
RGJ
(Richard - Communiteq)
19
只需确保在操作后立即重启 Unicorn,这样它便会重新创建排定任务。
您会丢失所有已排队的任务,因此需要选择一个合适的时机来执行此操作。
6 个赞
Ed_S
(Ed S)
20
这是否仍按预期工作?是否有一个简单的单行命令可以查看压缩后镜像的大小?
1 个赞