配置 Nextcloud 内存缓存

内存缓存把经常请求的对象保存在内存中,以便更快读取,能够显著改善 Nextcloud 服务器性能。这里涉及两类缓存:PHP 操作码缓存,通常称为 opcache;以及 Web 服务器的数据缓存,通常称为 memcache。

注意:如果没有安装并启用本地 memcache,Nextcloud 管理页面会显示警告。memcache 不是必需组件,不启用时可以忽略该警告。 如果只在 config.php 中启用分布式缓存 memcache.distributed,却没有启用本地缓存 memcache.local,警告仍会出现。

PHP opcache 保存编译后的 PHP 脚本,避免每次调用时重新编译。PHP 自 5.5 起就在核心中附带 Zend OPcache,无需额外安装。

数据缓存需要由部署者提供。Nextcloud 支持多个缓存后端,可以按部署需求选择:

  • APCu:要求 4.0.6 及以上,提供系统本地缓存。
  • Redis:要求 4.0.0 及以上,可用于本地缓存、分布式缓存和事务性文件锁。Valkey 与 KeyDB 预计也可作为兼容后端使用。原文说明,当前自动化和正式测试覆盖使用 redis PHP 扩展的 Redis Open Source,以及使用 Nextcloud KeyValueCache 的 Valkey;KeyDB 预期兼容,但未纳入正式测试。
  • Memcached:用于分布式缓存。

要使用数据缓存,需要安装并启用所选后端,再向 config.php 添加对应配置。所有配置项概览见配置参数。

根据部署类型选择缓存

本地缓存与分布式缓存可以同时使用。推荐 APCu 配合 Redis 或 Valkey。安装并启用所选数据缓存后,可以通过 PHP 版本及信息输出确认模块是否处于活动状态。各后端的具体设置见下文。

小型或私人家庭服务器

只使用 APCu:

'memcache.local' => '\OC\Memcache\APCu',

组织的单服务器部署

本地缓存使用 APCu,其他缓存功能使用 Redis:

'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => [
     'host' => 'localhost',
     'port' => 6379,
],

组织的集群部署

本地缓存使用 APCu,分布式缓存和锁缓存可以采用 Redis 集群:

'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis.cluster' => [
    'seeds' => [ // provide some/all of the cluster servers to bootstrap discovery, port required
       'cache-cluster:7000',
       'cache-cluster:7001',
    ],
 ],

或者使用 Memcached 集群提供分布式缓存,并按示例配置锁缓存:

'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Memcached',
'memcache.locking' => '\OC\Memcache\Memcached',
'memcached_servers' => [
    [ 'server1.example.com', 11211 ],
    [ 'server2.example.com', 11211 ],
 ],

注意:运行多个 Web 服务器时,如果启用了 memcache.distributed 或 memcache.locking,必须确保所有服务器指向同一个缓存服务器或集群,不能各自指向 localhost 或本机 Unix 套接字。

Redis 与 APCu 的内存缓存取舍

APCu 的本地缓存速度比 Redis 更快。如果内存充足,建议 APCu 负责内存缓存、Redis 负责文件锁。如果内存紧张,可以让 Redis 同时承担这两项功能。

APCu

多数 Linux 发行版都提供 APCu 数据缓存包。Red Hat、CentOS、Fedora 上安装 php-pecl-apcu;Debian、Ubuntu、Mint 上安装 php-apcu。

重启 Web 服务器后,在 config.php 加入:

'memcache.local' => '\OC\Memcache\APCu',

刷新 Nextcloud 管理页面,缓存警告应会消失。

根据实例规模、用户数和系统交互量,可能需要调整 php.ini 中的 apc.shm_size。默认 32M 通常不足以支持 Nextcloud,可以从 128M 开始。如果用户或应用较多,还需进一步增加。分配的内存必须在系统中实际可用,规划服务器 worker 数量时也要考虑这部分占用。

缓存频繁重置会不断经历清空和重新填充,可能造成意外的性能下降。管理检查会尝试发现缓存内存过小的问题,但仍应监控 APCu 状态,判断缓存是否已满、是否需要扩容。APCu 提供可辅助观察的脚本,Nextcloud 的 serverinfo 应用也能显示缓存状态。

通过 Nextcloud KeyValueCache 使用 Redis 或 Valkey

注意:KeyValueCache 在 Nextcloud 34.0.2 中加入。

KeyValueCache 是不依赖具体品牌的键值缓存后端,可连接 Valkey、Redis 等服务。这类系统适合分布式缓存,也适合作为事务性文件锁的键值存储,因为它们能够让所需缓存对象在需要期间保持可用。

与后文介绍的 phpredis 后端不同,KeyValueCache 不需要 PHP 扩展,而是使用 Nextcloud 附带的 predis 库。只需安装并运行兼容 Valkey 或 Redis 的服务器,再在 config.php 中配置即可。

注意:如果缓存服务与 Nextcloud 不在同一台机器上,相比基于 php-redis 的后端,网络开销可能影响性能。此时可优先考虑 php-redis 后端。

Debian、Ubuntu、Mint 上可安装 valkey-server 或 redis-server;CentOS、Fedora 上可安装 valkey 或 redis。部分发行版不会自动启动服务,需要通过服务管理器启动,并设置为开机运行的守护进程。

可使用 ps ax 查看进程:

ps ax | grep valkey
22203 ? Ssl    0:00 /usr/bin/valkey-server 127.0.0.1:6379

在 config.php 添加相应条目后,刷新 Nextcloud 管理页面。

config.php 中的 KeyValueCache 配置

为了获得良好性能,使用 KeyValueCache 提供文件锁:

'memcache.locking' => '\OC\Memcache\KeyValueCache',

同时也应将它用于分布式服务器缓存:

'memcache.distributed' => '\OC\Memcache\KeyValueCache',

技术上还可以把它用于本地缓存,但不推荐:

'memcache.local' => '\OC\Memcache\KeyValueCache',

警告:多服务器环境中,使用键值存储服务器作为本地缓存可能引发问题。即使只有一台服务器,APCu 通常也更快。

只要在上述任一位置使用 keyvalue 缓存,就还需要在 config.php 中配置 memcache.kvstore。它支持三种拓扑:单服务器 server、Sentinel 管理的复制组 sentinel,以及服务器集群 seeds。三者只能选择一种。

单服务器可使用下面的选项,其中只有 server 必填:

'memcache.locking' => '\OC\Memcache\KeyValueCache',
'memcache.distributed' => '\OC\Memcache\KeyValueCache',
'memcache_customprefix' => 'mynextcloudprefix',
'memcache.kvstore' => [
   'server' => [
      'host' => 'cache-host.example.com',
      'port' => 6379,
      // Protocol used to connect. One of 'tcp', 'tls' or 'unix'.
      // When omitted it is derived from the host (a leading '/' means 'unix').
      'protocol' => 'tcp',
   ],
   'user'         => 'nextcloud', // only sent when the server uses ACLs
   'password'     => 'password',
   'dbindex'      => 0,
   'timeout'      => 1.5,
   'read_timeout' => 1.5,
   'persistent'   => false, // keep the connection open across requests
],

相同的可选参数也适用于下文的 Sentinel 和集群拓扑,并会应用到每个节点。

使用 Sentinel 管理复制组时,需要提供受监控服务的名称,并为每个 Sentinel 节点提供一个 seed。每个 seed 的格式与前面的 server 条目相同:

'memcache.kvstore' => [
   'sentinel' => [
      'service' => 'mymaster',
      'seeds' => [
         ['host' => 'sentinel1.example.com', 'port' => 26379],
         ['host' => 'sentinel2.example.com', 'port' => 26379],
         ['host' => 'sentinel3.example.com', 'port' => 26379],
      ],
   ],
],

使用集群时,提供部分或全部节点作为发现集群的入口:

'memcache.kvstore' => [
   'seeds' => [
      ['host' => 'cache-cluster.example.com', 'port' => 7000],
      ['host' => 'cache-cluster.example.com', 'port' => 7001],
   ],
],

注意:通过 dbindex 选择编号数据库只适用于单服务器或 Sentinel 部署。集群始终使用数据库 0;Valkey 9 新增的编号数据库支持仍有待上游实现。

通过 TLS 连接

要通过 TLS 加密的 TCP 连接,将服务器或各 seed 的 protocol 设为 tls,并提供 SSL 上下文参数:

'memcache.kvstore' => [
   'server' => [
      'host' => 'cache-host.example.com',
      'port' => 6379,
      'protocol' => 'tls',
   ],
   'ssl_context' => [
      'local_cert' => '/certs/cache.crt',
      'local_pk' => '/certs/cache.key',
      'cafile' => '/certs/ca.crt',
   ],
],

通过 Unix 套接字连接

如果缓存服务与 Nextcloud 位于同一台系统,推荐通过 Unix 套接字连接。将套接字路径作为 host 传入即可;以斜杠开头的 host 会自动识别为 Unix 套接字,不需要 protocol 或 port:

'memcache.kvstore' => [
   'server' => [
      'host' => '/run/valkey/valkey.sock',
   ],
],

同时更新缓存服务器配置,例如 /etc/valkey/valkey.conf,取消 Unix 套接字选项的注释,并确保路径与 Nextcloud 配置一致。

还需设置正确权限,使 Web 服务器可读写套接字。通常应将 Web 服务器用户加入 valkey 或 redis 用户组:

usermod -a -G valkey www-data

再相应修改服务配置中的 unixsocketperm:

unixsocketperm 770

修改后可能需要重启 Web 服务器与缓存服务器。

通过 phpredis PHP 扩展使用 Redis

Redis 适合分布式缓存和事务性文件锁,因为它能够使缓存对象在需要期间保持可用。

Nextcloud 使用 PhpRedis PHP 扩展与兼容 Redis 的键值存储通信。正式测试覆盖 Redis Open Source;Valkey 和 KeyDB 预计也可作为兼容后端使用。

Redis PHP 模块要求 2.2.6 及以上。如果发行版没有提供受支持版本,或完全没有 Redis 包,可以参考后文的 Memcached。

Debian、Ubuntu、Mint 上安装 redis-server 或同类后端包,以及 php-redis。具体包名取决于发行版和后端。

CentOS、Fedora 上安装 redis 或对应后端包,以及 php-pecl-redis。服务不会自动启动,需要通过服务管理器启动并配置开机运行。

可以用 ps ax 查看 Redis 守护进程:

ps ax | grep redis
22203 ? Ssl    0:00 /usr/bin/redis-server 127.0.0.1:6379

重启 Web 服务器,在 config.php 添加相应条目,然后刷新 Nextcloud 管理页面。

config.php 中的 Redis 配置

使用 Redis 提供文件锁:

'memcache.locking' => '\OC\Memcache\Redis',

同时将其用于分布式服务器缓存:

'memcache.distributed' => '\OC\Memcache\Redis',

也可以按以下方式配置本地缓存,但不推荐:

'memcache.local' => '\OC\Memcache\Redis',

警告:多服务器环境中使用 Redis 作为本地缓存可能造成问题;即使是单服务器,APCu 通常也更快。

只要上述任一缓存功能使用 Redis,就必须同时在 config.php 中配置 redis 或 redis.cluster。

单 Redis 服务器配置如下。除 host 与 port 外,其余选项均可选;这两个字段的具体用法见后文:

'memcache.locking' => '\OC\Memcache\Redis',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.local' =>'\OC\Memcache\Redis' ,
'memcache_customprefix' => 'mynextcloudprefix',
'redis' => [
   // 'host'      => see connection parameters below
   // 'port'      => see connection parameters below
  'user'          => 'nextcloud',
  'password'      => 'password',
  'dbindex'       => 0,
  'timeout'       => 1.5,
  'read_timeout'  => 1.5,
],

Redis 集群配置如下,只有 seeds 必填:

'memcache.locking' => '\OC\Memcache\Redis',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.local' =>'\OC\Memcache\Redis' ,
'memcache_customprefix' => 'mynextcloudprefix',
'redis.cluster' => [
   'seeds' => [ // provide some/all of the cluster servers to bootstrap discovery, port required
      'cache-cluster:7000',
      'cache-cluster:7001',
      'cache-cluster:7002',
      'cache-cluster:7003',
      'cache-cluster:7004',
      'cache-cluster:7005'
   ],
   'failover_mode'   => \RedisCluster::FAILOVER_ERROR,
   'timeout'         => 0.0,
   'read_timeout'    => 0.0,
   'user'            => 'nextcloud',
   'password'        => 'password',
   'dbindex'         => 0,
],

注意:服务器 URL 必须包含端口,但不必列出所有服务器。例如,如果所有服务器都通过同一个 DNS 名称进行负载均衡,只需提供这个名称。

通过 TCP 连接单个 Redis 服务器

远程或本地 TCP 连接示例:

'redis' => [
   'host' => 'redis-host.example.com',
   'port' => 6379,
],

通过 TLS 连接单个 Redis 服务器

使用 TLS 加密的 TCP 连接时,添加:

'redis' => [
   'host' => 'tls://127.0.0.1',
   'port' => 6379,
   'ssl_context' => [
      'local_cert' => '/certs/redis.crt',
      'local_pk' => '/certs/redis.key',
      'cafile' => '/certs/ca.crt',
      'verify_peer_name' => false,
   ],
],

通过 TLS 连接 Redis 集群

集群的 TLS 配置如下:

'redis.cluster' => [
   'seeds' => [ // provide some/all of the cluster servers to bootstrap discovery, port required
      'cache-cluster:7000',
      'cache-cluster:7001',
   ],
   'ssl_context' => [
      'local_cert' => '/certs/redis.crt',
      'local_pk' => '/certs/redis.key',
      'cafile' => '/certs/ca.crt',
      'verify_peer_name' => false,
   ],
],

通过 Unix 套接字连接单个 Redis 服务器

如果 Redis 与 Nextcloud 位于同一台系统,推荐使用 Unix 套接字。config.php 示例:

'redis' => [
   'host'     => '/run/redis/redis-server.sock',
   'port'     => 0,
],

只有 host 和 port 必填,其余可选。相应更新 /etc/redis/redis.conf,取消 Unix 套接字选项的注释,并确保套接字和端口设置与 Nextcloud 配置匹配。

为 redis.sock 设置正确权限,让 Web 服务器能够读写。通常需要将 Web 服务器用户加入 redis 组:

usermod -a -G redis www-data

然后修改 redis.conf 的 unixsocketperm:

unixsocketperm 770

可能还需要重启 Apache 和 Redis:

systemctl restart apache2
systemctl restart redis-server

Redis 有很多可配置项,更多内容请参阅其官方文档。

使用 Redis 会话处理器

如果已经用 Redis 提供锁或缓存,也可以考虑用它管理会话。与标准文件会话处理器不同,Redis 能在多个 Nextcloud 应用服务器之间集中管理会话。

但是,使用 Redis 会话处理器时,必须启用会话锁。原文撰写时,Redis 会话处理器默认不启用会话锁。这可能让 Talk 等频繁写入会话的 Nextcloud 应用出现会话损坏。此外,即使启用了会话锁,应用无法获得锁时,Redis 会话处理器当前也不会返回错误。

原文建议在 php.ini 中加入以下设置,以防止使用 Redis 会话处理器时发生会话损坏:

redis.session.locking_enabled=1
redis.session.lock_retries=-1
redis.session.lock_wait_time=10000

更多配置说明见 PhpRedis GitHub 项目。

Memcached

Memcached 是成熟可靠的分布式共享缓存,在 Nextcloud 中表现良好,但有一个重要例外:它不适合事务性文件锁。Memcached 不保存锁,而且缓存数据随时可能消失;这种用途应选择 Redis。

注意:必须安装名为 memcached 的 PHP 模块,而不是 memcache。Nextcloud 只支持 memcached 模块。

Debian、Ubuntu、Mint 上安装 memcached 与 php-memcached,安装程序会自动启动服务并配置开机运行。

Red Hat、CentOS、Fedora 上安装 memcached 与 php-pecl-memcached。服务不会自动启动,需要使用服务管理器启动并设置开机运行。

可通过 ps ax 查看守护进程:

ps ax | grep memcached
19563 ? Sl 0:02 /usr/bin/memcached -m 64 -p 11211 -u memcache -l
127.0.0.1

重启 Web 服务器,在 config.php 添加配置,然后刷新 Nextcloud 管理页面。

config.php 中的 Memcached 配置

下面使用 APCu 作为本地缓存,Memcached 作为分布式缓存,并列出共享缓存池中所有服务器及其端口:

'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Memcached',
'memcache.locking' => '\OC\Memcache\Memcached',
'memcached_servers' => [
     [ 'server0.example.com', 11211 ],
     [ 'server1.example.com', 11211 ],
     [ 'server2.example.com', 11211 ],
 ],

缓存目录的位置

缓存目录默认为 data/$user/cache,其中 $user 是当前用户。可以通过 config.php 中的 cache_path 指定其他位置,详见配置参数。

Redis 或 Memcached 的缓存键前缀

默认情况下,Nextcloud 根据实例 ID、版本等信息生成一个近似唯一的缓存键前缀,以降低多个实例共享缓存时发生冲突的可能性。要明确避免冲突,可以设置自定义前缀:

'memcache_customprefix' => 'mynextcloudprefix',

这也便于在 Redis 中设置 ACL,限制特定用户能访问的键,例如在共用缓存时隔离不同 Nextcloud 实例,因此可能关系到部署的安全边界。

原文来源:Memory caching。本文依据留存原文译为中文,代码示例按原文保留。

© Copyright 2016–2026 Nextcloud GmbH and Nextcloud contributors. 原文许可:License。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容