OpenWebUI调优

大量性能提升、流畅度优化

当我们的用户量增加到一定的程度时(比如当我的实时在线用户超过100人时),即便服务器的硬件配置再高,也会变得非常卡顿,这是因为OpenWebUI本身机制上有很多坑,接下来我们在GPT-5的帮助下逐步优化,整体流畅度可以提升10倍以上。

首先,OpenWebUI默认是单线程运行的,这也是导致卡顿的罪魁祸首,最大的问题根源,我们可以通过下面这个命令查看进程数:

# 1) 用宿主机的 ps 能力查看容器内进程
docker top open-webui -eo pid,comm,args | sed 's/\x00/ /g' | egrep -i "uvicorn|gunicorn|open-webui|python" || docker top open-webui

# 2) 粗略计数(看到几行 uvicorn/gunicorn 通常就是几个 worker)
docker top open-webui | egrep -i "uvicorn|gunicorn" | wc -l

对此,我们需要进行多进程配置,此时我们需要修改compose文件:

services:
  postgre:
    image: docker.1panel.live/library/postgres@sha256:4d89c904835259bc58876520e56267ca07a4ebd6a027f7814bbbf91b50d685be
    container_name: postgre
    restart: always
    environment:
      - POSTGRES_USER=st
      - POSTGRES_PASSWORD=STshentong
      - POSTGRES_DB=openwebui
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
    network_mode: host #端口5432

  open-webui:
    image: ghcr.nju.edu.cn/ovinc-cn/openwebui:latest
    container_name: open-webui
    volumes:
      - ./open-webui:/app/backend/data
    restart: always
    environment:
      - DATABASE_URL=postgresql://st:STshentong@localhost:5432/openwebui # 连接到 openwebui 数据库
      - UVICORN_WORKERS=6
      - WEBSOCKET_MANAGER=redis
      - ENABLE_WEBSOCKET_SUPPORT=True
      - WEBSOCKET_REDIS_URL=redis://localhost:6379
      - REDIS_URL=redis://localhost:6379
      - WEBUI_NAME=ChatST
      - AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST=1
      - AIOHTTP_CLIENT_TIMEOUT_OPENAI_MODEL_LIST=1
      - USER_AGENT=${USER_AGENT:-Mozilla/5.0 (compatible; OpenWebUI/1.0; +https://github.com/open-webui)}
      - WEBUI_SECRET_KEY=85fafa5e-0992-4d9b-a84c-6679646040f3
      - LICENSE_KEY=enterprise
      - ORGANIZATION_NAME=ST-STUDIO
      - CUSTOM_NAME=ChatST
    build:
      args:
        USER_AGENT: $USER_AGENT
    network_mode: host #端口8080
    ulimits:
      nofile:
        soft: 1048576
        hard: 1048576
    depends_on:
      - postgre
      - redis

  redis:
    image: docker.1panel.live/library/redis:latest
    container_name: redis
    restart: always
    network_mode: host #端口6379
    ulimits:
      nofile:
        soft: 1048576
        hard: 1048576

  tika:
    image: docker.1panel.live/apache/tika:latest-full
    container_name: tika
    network_mode: host #端口9998
    restart: always

注意,在这份compose文件中,相较于我们之前的版本有很多的修改项,首先我们将数据库的版本号固定了,采用SHA256的形式写死在文件中,这样可以避免PostgreSQL版本升级造成的变更;然后我们在环境变量中配置了进程数为6个,这可以大幅提升并发性能,大幅改善多用户场景卡顿问题(具体来说,进程数建议设置为服务器核心数或略少于核心数即可,比如我在8H的服务器上使用6进程);另外需要特别注意的是,要开启多进程必须要确保ws的管理器是redis,这里我们也在环境变量中显式指定了;然后我们还显式指定了ulimit文件描述符nofile限制为1048576,虽然默认值大概率就是这个,但是写死更好一些。

修改compose文件后需要重建一下发生修改的容器:

然后我们同样可以通过上面的指令去查看多workers配置是否生效。然后也可以验证一下我们的ulimit设置有没有生效:

这样我们在docker层面和项目本身的优化就差不多了,主要还是进程数的提升。接下来我们就要进行数据库层面的优化了。数据库层面将有很多的优化项,首先我们查询一下数据库的当前参数:

通过这个命令查看当前配置,然后我们可以一步到位修改参数(请注意下面这套参数是基于8GB的物理内存的服务器,如果内存大/小,需要按照比例进行修改):

修改后我们可以使用下面的指令验证一下关键项的修改是否到位:

也可以使用下面的指令查询有没有什么修改需要等待重启才能完成,若有,重启数据库容器即可:

然后这时有一个注意事项,当我们修改了这些参数后,系统盘的占用会快速增加,这主要是因为我们开启了大量的日志记录用于分析,他会写入大量的日志文件(前提是当前有大量用户正在使用),这时我们需要修改PostgreSQL的日志存储逻辑:

将日志存放在Postgre容器的数据卷内,也就是我们的数据盘中(前提是你的服务器分系统盘和数据盘),并且写了上限为200MB滚动记录。有了日志记录之后,我们就可以在业务跑一段时间之后来分析慢查询了,通过查看SQL查询最慢的几条记录来进行针对性的优化:

这个命令可以查出最慢的20条,如果需要进一步筛选也可:

然后我们将查询的结果发给AI让他帮我们撰写索引创建命令即可,创建了相应的索引后慢查询的速度会有显著提升;此外,我们还可以开启lz4压缩来减少大json的体积,先看是否支持lz4压缩,理论上Postgre 14以上的版本默认都支持:

然后开启lz4压缩:

将大字段存储策略确保为EXTENDED:

这里给出在我的生产环境中有效的提速索引创建命令:

让chat表维护更积极:

运营自检:

最后,因为我们对数据库启用了日志记录,时间久了可能会占用很多空间,因此对之前的清理脚本也进行了一些优化:

最后更新于