# ファイル転送サーバー側設定の構成

EMQXでは、MQTTファイル転送機能はデフォルトで有効になっていません。この機能を利用する場合は、設定ファイルで有効化する必要があります。

本ページでは主に、EMQXでファイル転送機能を有効化し、サーバー側でのファイル転送に関する各種機能を設定する方法を紹介します。これには、セグメントの保存やマージされたファイルのローカルディスクおよびS3バケットへのエクスポート、さらにファイル転送処理を最適化するためのMQTT転送設定の構成が含まれます。以下のセクションで、設定ファイルを通じた詳細な設定方法を説明します。

- [ファイル転送の有効化](#enable-file-transfer)
- [セグメント保存の設定](#configure-segment-storage)
- [ファイルエクスポートの設定](#configure-file-export)
- [MQTT転送設定の構成](#configure-mqtt-transfer-settings)

また、Dashboardからもファイル転送機能の有効化および設定が可能です。詳細は[Dashboardによるファイル転送の有効化と設定](#enable-and-configure-file-transfer-via-dashboard)を参照してください。

さらに、REST APIを利用したエクスポート済みファイルの管理方法についても紹介します。詳細は[エクスポート済みファイルの管理](#manage-exported-files)をご覧ください。

## ファイル転送の有効化

EMQXではファイル転送機能はデフォルトで無効になっており、設定ファイルで有効化する必要があります。

```bash
file_transfer {
  enable = true
}
```

この設定により、EMQXはデフォルトでセグメントファイルを `data/file_transfer/segments` ディレクトリに保存し、ローカルディスクへのエクスポートを有効化して、マージされたファイルを `data/transfers/exports` ディレクトリに出力します。

ファイル転送機能をさらに細かく設定する場合は、以下の設定例を参照してください。

## セグメント保存の設定

EMQXはクライアントからファイルのセグメントをアップロードさせ、すべてのセグメント受信後に完全なファイルとしてマージします。これをサポートするために、EMQXはセグメントファイルを一時的に保存し管理する必要があります。

現状、EMQXはセグメントファイルの保存先としてディスクのみをサポートしており、セグメントの保存場所を設定可能です。

ファイルアップロード完了後はセグメントは自動的にクリーンアップされます。アップロードがタイムアウト期間内に完了しなかったファイルについては、セグメントの有効期間やクリーンアップのスケジュールを設定し、ディスク容量の無駄な占有を防止できます。

```bash
file_transfer {
  # ファイル転送機能の有効化
  enable = true

  # セグメント保存の設定
  storage.local.segments = {
    # セグメント保存ディレクトリ。I/O性能の高いディスクに設定することが望ましい。
    root = "./data/file_transfer/segments"

    # 有効期限切れセグメントの定期クリーンアップ設定
    gc {
      # クリーンアップ間隔
      interval = "1h"

      # セグメント保存の最大有効期間。この期間を過ぎるとマージされていなくてもセグメントは削除される。
      # クライアントが指定する有効期間はこの値を超えてはならない。
      maximum_segments_ttl = "24h"
    }
  }
}
```

想定されるファイルサイズ、同時転送数、利用可能なディスク容量に応じて適切な設定を行ってください。

## ファイルエクスポートの設定

すべてのセグメント転送完了後、EMQXはセグメントをマージして完全なファイルを生成し、ローカルディスクまたはS3バケットにエクスポートしてアプリケーションと連携できます。

:::tip

ファイルエクスポートを設定しない場合はデフォルトでローカルディスクへのエクスポートとなります。EMQXは両方のエクスポート方法を同時に設定することはできず、いずれか一方のみ利用可能です。

:::

### ローカルディスクへのファイルエクスポート

以下の設定例は、マージされた完全ファイルをローカルディスクに保存する方法です。エクスポートファイルの保存場所や有効期間を設定できます。

```bash
file_transfer {
  # ファイル転送機能の有効化
  enable = true

  # セグメント保存の設定
  # ...

  # ローカルディスクへのファイルエクスポートを有効化
  storage.local.exporter.local {
    # エクスポートファイル保存ディレクトリ。I/O性能の高いディスクに設定することが望ましい。
    root = "./data/transfers/exports"
  }
}
```

### S3バケットへのファイルエクスポート

以下の設定例は、マージされた完全ファイルをS3バケットに保存する方法です。

```bash
file_transfer {
  # ファイル転送機能の有効化
  enable = true

  # セグメント保存の設定
  # ...

  storage.local.exporter.s3 {

    host = "s3.us-east-1.amazonaws.com"
    port = 443

    # S3アクセス用認証情報
    access_key_id = "AKIA27EZDDM9XLINWXFE"
    secret_access_key = "******"

    # エクスポートファイル保存バケット
    bucket = "my-bucket"

    # 共有URLの有効期限
    # EMQXはクライアントがS3から直接ファイルをダウンロードできる一時的な共有URLを生成します。
    # このパラメータはEMQX APIが返すファイルダウンロードURLの有効期限を指定します。
    # 有効期限切れ後はURLは無効となりますが、実際のファイルはS3に残ります。
    #url_expire_time = "1h"

    # S3とのHTTP(S)接続に関する設定。安全なファイルアップロードや接続プール管理に利用されます。
    transport_options {
      ssl.enable = true
      connect_timeout = 15s
    }
  }
}
```

## MQTT転送設定の構成

ファイル転送処理を最適化し、クライアントの待機時間を抑えるために、各種ファイル転送操作に対してタイムアウトを設定できます。以下のMQTT設定を構成可能です。

```bash
file_transfer {
    enable = true
    init_timeout = "10s"
    store_segment_timeout = "10s"
    assemble_timeout = "60s"
}
```

- `init_timeout`：初期化操作のタイムアウト時間
- `store_segment_timeout`：ファイルセグメント保存のタイムアウト時間
- `assemble_timeout`：ファイル組み立てのタイムアウト時間

これらの操作が指定したタイムアウトを超えた場合、MQTTクライアントは `RC_UNSPECIFIED_ERROR` コード付きのPUBACKパケットを受信します。

## Dashboardによるファイル転送の有効化と設定

このセクションでは、Dashboard上でファイル転送機能を有効化し、各種機能を設定する方法を示します。

EMQX Dashboardにアクセスし、**管理** -> **ファイル転送**をクリックします。ファイル転送ページで、**有効化**トグルスイッチをクリックしてファイル転送機能を有効化できます。[一般設定](#general-settings)および[詳細設定](#advanced-settings)を参照して機能を設定し、設定完了後に**変更を保存**をクリックしてください。

<img src="./assets/file-transfer-enable.png" alt="ファイル転送の有効化" style="zoom:67%;" />

### 一般設定

以下の一般設定を構成できます。

- **初期化タイムアウト**：`init` コマンドの実行がタイムアウトするまでの最大許容時間。例えばシステムが過負荷で `init` コマンドを処理できない場合、この時間を超えるとタイムアウトとなり、エラーコード（0x80）付きのPUBACKメッセージが送信されます。デフォルト値は `10s` です。
- **セグメントルートディレクトリ**：アップロードされたファイルの一時セグメントを保存するディレクトリパス。絶対パスで指定し、I/O性能の高いディスクに配置することが推奨されます。これにより、特に負荷が高い場合のファイルセグメント処理が効率化されます。
- **ファイル保存方法**：ファイルのエクスポート方法を選択します。`ローカルストレージ` または `S3ストレージ` が選択可能です。`S3ストレージ` を選択した場合は追加設定が必要です：
  - **ホスト**：S3サービスのエンドポイント。例：`s3.us-east-1.amazonaws.com`
  - **ポート**：S3サービス接続に使用するポート。例：`443`（HTTPSの安全な接続）
  - **アクセスキーID** と **シークレットアクセスキー**：S3バケットへのアクセスに必要な認証情報。安全に管理してください。
  - **バケット**：ファイルを保存するS3バケット名。例：`my-bucket`
  - **TLSの有効化**：安全なファイル転送のためTLS（Transport Layer Security）を使用するかどうか。詳細は[外部リソースアクセスのTLS](../network/overview.md#tls-for-external-resource-access)を参照してください。
- **ファイルルートディレクトリ**：ファイル保存のルートディレクトリを絶対パスで指定します。`ローカルストレージ`をファイル保存方法に選択した場合に、組み立て済みファイルの保存先として使用されます。

### 詳細設定

一般設定で構成したファイル保存方法に応じて、異なる詳細設定を行えます。

#### ローカルストレージ

ファイルをローカルストレージにエクスポートする場合、以下の詳細設定を構成できます。

| フィールド名             | 説明                                                         | 推奨値           |
| ------------------------ | ------------------------------------------------------------ | ---------------- |
| セグメント保存タイムアウト | `segment` コマンドでファイルセグメントを保存する最大許容時間。これを超えると（例：システム過負荷時）エラーコード（0x80）付きPUBACKメッセージが送信され、タイムアウトとなる。 | 5分              |
| 組み立てタイムアウト       | `fin` コマンドでファイル組み立て処理を完了する最大許容時間。タイムアウト時はエラーコード（0x80）付きPUBACKメッセージが送信される。システムリソース不足による遅延時に重要。 | 5分              |
| ストレージGC間隔          | ファイル保存システムのガベージコレクション（不要データ削除）を実行する間隔。 | 1時間            |
| 最大セグメントTTL         | 保存されたセグメントの最大有効期間。これを超えたセグメントは自動的に削除される。マージ済みか否かや転送時に指定されたTTLに関わらず適用される。 | 24時間           |
| 最小セグメントTTL         | セグメントの最小有効期間。マージ済みであっても、転送時に短いTTLが指定されていても、この期間までは削除されない。後処理や冗長性確保のために最低限の保持期間を保証。 | 5分              |

#### S3ストレージ

ファイルをS3ストレージにエクスポートする場合、[ローカルストレージ](#ローカルストレージ)と同様の設定のほか、以下の詳細設定も構成できます。

| フィールド名           | 説明                                                         | 推奨値           |
| ---------------------- | ------------------------------------------------------------ | ---------------- |
| URL有効期限           | S3にアップロードされたファイルにアクセスするために生成されるURLの有効期間。期限切れ後はURLからアクセスできなくなる。 | -                |
| 最小パートサイズ       | マルチパートアップロード時の各パートの最小サイズ。小さいとアップロード回数が増えるが、不安定な環境で大きなファイルを扱う際に有効。 | 5 MB             |
| 最大パートサイズ       | マルチパートアップロード時の各パートの最大サイズ。大きいとアップロード回数は減るが、メモリ消費が増える。 | 5 MB             |
| ACL                    | アップロードオブジェクトのアクセス制御リスト。以下のオプションがある：<br />`private`：所有者のみフルアクセス<br />`public_read`：全員が読み取り可能<br />`public_read_write`：全員が読み書き可能<br />`authenticated_read`：認証ユーザーのみ読み取り可能<br />`bucket_owner_read`：バケット所有者が読み取り可能<br />`bucket_owner_full_control`：バケット所有者がフルコントロール可能 | -                |
| IPV6プローブ           | IPv6接続の確認を行うかどうか。ネットワークがIPv6対応の場合、有効化すると互換性やパフォーマンス向上が期待できる。 | 有効             |
| 接続タイムアウト       | S3サーバーへの接続確立にかける最大時間。これを超えるとタイムアウトとなり、応答遅延を防止する。 | -                |
| プールタイプ           | S3接続の管理に用いるコネクションプールの種類。<br />`random`：ランダム選択<br />`hash`：ハッシュ関数による選択。接続の性能や信頼性に影響。 | `random`         |
| プールサイズ           | S3接続用コネクションプールのサイズ。大きいほど同時接続数は増えるがリソース消費も増加。 | 8                |
| HTTPパイプライニング   | 応答を待たずに送信するHTTPリクエスト数。スループット向上に寄与するが複雑さも増す。 | 100              |
| HTTPヘッダー           | S3リクエストに追加するカスタムHTTPヘッダー。キー・バリュー形式で指定可能。**追加**ボタンで設定。 | -                |
| 最大リトライ回数       | エラー発生時のS3リクエスト再試行の最大回数。増やすと信頼性向上だが遅延も増加。 | -                |
| リクエストタイムアウト | S3リクエストの最大許容時間。超過するとタイムアウトとなる。 | -                |

## エクスポート済みファイルの管理

エクスポート済みファイルの一覧表示や詳細情報の閲覧、移動、削除、ダウンロードなどの管理操作が可能です。これらの管理はREST APIまたは手動で行えます。将来的にはDashboard上での管理インターフェースも追加予定です。

### REST APIによるエクスポート済みファイル管理

EMQXはエクスポート済みファイル管理用のREST APIを提供しており、[MQTTファイル転送管理API](https://docs.emqx.com/en/enterprise/v5.3/admin/api-docs.html#tag/File-Transfer)を利用してファイルの閲覧やダウンロードが可能です。

### ローカルディスクエクスポートファイルの手動管理

ディスク上のエクスポート済みファイルを直接管理する場合（ファイル移動やFTP/HTTPサービスによるダウンロードなど）、以下のファイル保存場所のルールを参照してください。

ファイル名の衝突や単一ディレクトリ内のファイル数過多を避けるため、EMQXはバケットストレージ方式でエクスポートファイルを保存します。仕組みは以下の通りです。

- まず、ファイルIDとクライアントIDのsha256ハッシュ値を計算（例：`ABCDEFG012345...`）
- 6階層のディレクトリ構造で保存：
  1. ハッシュの最初の2バイトを1階層目のディレクトリ名に
  2. 次の2バイトを2階層目のディレクトリ名に
  3. 残りのハッシュを3階層目のディレクトリ名に
  4. エスケープ済みクライアントID
  5. エスケープ済みファイルID
  6. メタデータのファイル名を最下層に

例：エクスポートファイルは `AB/CD/EFGH.../{clientid}/{file_id}/{filename}` のようなディレクトリ構造に保存されます。

### S3バケットエクスポートファイルの手動管理

S3バケットの場合は、S3クライアントツールやS3のREST APIを利用してファイルの削除やダウンロードなどの管理が可能です。ファイル保存場所のルールは以下の通りです。

ローカルエクスポーターのバケットストレージ方式とは異なり、S3エクスポーターでエクスポートされたファイルはよりシンプルな3階層構造で保存されます。

1. エスケープ済みクライアントID
2. エスケープ済みファイルID
3. ファイル名

例：エクスポートファイルは `{clientid}/{file_id}/{filename}` のようなディレクトリ構造に保存されます。

::: tip

S3クライアントツールやREST APIの利用方法については以下を参照してください。

- [Amazon S3](https://aws.amazon.com/s3/?nc1=h_ls) および [ユーザーガイド](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html)
- [MinIO オブジェクトストレージシステム](https://min.io/)

:::
