跳转到主要内容

架构

Immich 采用传统的客户端-服务器设计,并配备专用数据库用于数据持久化。前端客户端通过 HTTP 使用 REST API 与后端服务进行通信。以下是架构的高层次图。

高层次图

Immich架构

图示显示了客户端通过 REST 与服务器的 API 进行通信。服务器通过存储库接口与下游系统(如 Redis、Postgres、机器学习、文件系统)通信。图中未显示的是服务器被拆分为两个独立的容器 immich-serverimmich-microservices。微服务容器不处理 API 请求或安排定时任务,主要处理来自 Redis 的作业请求。

客户端

Immich 有三个主要客户端:

  1. 移动应用 - Android,iOS
  2. 网页应用 - 响应式网站
  3. CLI - 命令行工具用于批量上传
信息

所有三个客户端都使用 OpenAPI 自动生成 REST 客户端以便轻松集成。有关该过程的更多信息,请参阅 OpenAPI

移动应用

移动应用是使用 Flutter 基于 Dart 编写的。以下是架构概览:

Mobile App
Mobile App
Services
Services
Repositories
Repositories
Providers
Providers
Pages
Pages
Widgets
Widgets
User
User
platform
system
platform...
on-device
database
on-device...
server
server
OpenAPI
OpenAPI
UI part
UI part
non-UI part
non-UI part
Models
Models
Entities
Entities

图示展示了目标架构,但当前代码库未完全遵循此架构。新代码和贡献应遵循此架构。 目前,它使用 Isar 数据库 作为本地数据库,并使用 Riverpod 进行状态管理(provider)。 数据类分为两种:实体类和模型类。实体类存储在设备上的数据库中,而模型类是临时的,仅保存在内存中。 存储库内部应是唯一采用其他数据类(例如 OpenAPI DTO)的地方。然而,其接口不应使用外部数据类!

网页客户端

网页应用是一个 TypeScript 项目,使用 SvelteKitTailwindcss

命令行工具 (CLI)

Immich CLI 是一个 npm 包,用户可以通过命令行控制他们的 Immich 实例。它使用 API 执行各种任务,特别是上传资源。有关更多信息,请参阅 CLI 文档

服务器

Immich 后端分为若干服务,作为单个 Docker 容器运行。

  1. immich-server - 处理并响应 REST API 请求,执行后台作业(生成缩略图,提取元数据,转码等)
  2. immich-machine-learning - 执行机器学习模型
  3. postgres - 持久化数据存储
  4. redis - 背景作业队列管理

Immich 服务器

Immich 服务器是基于 Node.jsTypeScript 项目。它使用 Nest.js 框架,Express 服务器,以及查询构建工具 Kysely。服务器代码库也大致遵循 六边形架构。具体来说,我们旨在将技术特定实现(src/repositories)与核心业务逻辑(src/services)分离。

API 端点

传入的 HTTP 请求映射到控制器(src/controllers)。控制器是 HTTP 端点的集合。每个控制器通常为其相关资源类型实现以下 CRUD 操作:

  • POST /<type> - 创建
  • GET /<type> - 读取(所有)
  • GET /<type>/:id - 读取(按ID)
  • PUT /<type>/:id - 更新(按ID)
  • DELETE /<type>/:id - 删除(按ID)

域传输对象 (DTO)

服务器使用 域传输对象 作为每个端点的输入(查询、参数和主体)和输出(响应)的公共接口。DTO 翻译为 OpenAPI 架构,控制每个客户端使用的生成代码。

后台作业

Immich 使用一个 工作者 来运行后台作业。这些作业包括:

  • 生成缩略图
  • 提取元数据
  • 视频转码
  • 智能搜索
  • 人脸识别
  • 存储模板迁移
  • 辅助文件(见 XMP 辅助文件
  • 背景作业(文件删除、用户删除)
信息

此列表与 管理 > 作业 页上提供的作业功能密切匹配,该页面提供一些远程队列管理功能。

机器学习

机器学习服务是用 Python 编写的,并使用 FastAPI 进行 HTTP 通信。

所有与机器学习相关的操作都已外包到此服务 immich-machine-learning。Python 是人工智能和机器学习的自然选择,同时它还需要一些特定的硬件要求。将其作为单独的容器运行,可以在单独的机器上运行该容器,或轻松完全禁用它。

每个对机器学习服务的请求都包含模型任务相关的元数据、模型名称等。这些设置与其他系统配置一起存储在 Postgres 中。对于每个请求,微服务容器会抓取这些设置以将它们附加到请求中。

在内部,机器学习服务在处理文本或图像负载之前,下载、加载并配置指定的模型以响应请求。已加载的模型会被缓存并在请求间重用。线程池用于在不同线程中处理每个请求,以避免阻塞异步事件循环。

所有模型都采用 ONNX 格式。此格式拥有广泛的行业支持,这意味着大多数其他模型格式都可以导出到该格式,并且许多硬件 API 支持该格式。它的运行速度也非常快。

机器学习模型通常非常大,需要相当多的内存。我们一直在寻找改进和优化该容器的具体方法。

Postgres

Immich 使用 Postgres 持久化数据,包括有关访问和授权的信息、用户、相册、资源、共享设置等。

信息

有关如何修改数据库以创建索引、修改表、添加新列等的更多信息,请参阅 数据库迁移

Redis

Immich 使用 Redis 通过 BullMQ 管理作业队列。有些作业会触发后续作业。例如,智能搜索和人脸识别依赖于缩略图生成,并在生成后自动运行。