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

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はセグメントファイルの保存先としてディスクのみをサポートしており、セグメントの保存場所を設定できます。

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

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

### 詳細設定

一般設定で構成したファイル保存方法に応じて、異なる詳細設定が用意されています。

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

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

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

#### S3ストレージ

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

| 項目名               | 説明                                                         | 推奨値             |
| -------------------- | ------------------------------------------------------------ | ------------------ |
| URL Expire Time      | アップロード済みファイルへのアクセス用に生成されるURLの有効期間を指定します。有効期限切れ後はURLを使ったアクセスができなくなります。 | -                  |
| Minimum Part Size    | ファイルを複数パートに分割してS3にアップロードする際の最小パートサイズを指定します。小さいサイズはアップロード回数を増やしますが、不安定な接続環境で大きなファイルを扱う際に有効です。 | 5 MB               |
| Maximum Part Size    | S3へのマルチパートアップロード時の各パートの最大サイズ制限を定義します。大きなパートはアップロード回数を減らし高速化できますが、メモリ消費が増加します。 | 5 MB               |
| ACL                  | アップロードしたオブジェクトのアクセス制御リスト（ACL）を指定します。以下のオプションがあります：<br />`private`: オーナーのみフルアクセス<br />`public_read`: 全員が読み取り可能<br />`public_read_write`: 全員が読み書き可能<br />`authenticated_read`: 認証ユーザーのみ読み取り可能<br />`bucket_owner_read`: バケットオーナーが読み取り可能<br />`bucket_owner_full_control`: バケットオーナーがフルコントロール可能 | -                  |
| IPV6 Probe           | IPv6接続の有無をチェックするかどうかを指定します。ネットワークがIPv6をサポートしている場合、有効化すると互換性やパフォーマンス向上が期待されます。 | 有効               |
| Connect Timeout      | S3サーバーへの接続確立に許容される最大時間を指定します。これを超えるとタイムアウトとなり、サーバー応答の遅延を防ぎます。 | -                  |
| Pool Type            | S3接続管理に使用するコネクションプールの種類を指定します：<br />`random`: ランダム選択<br />`hash`: ハッシュ関数による選択。接続のパフォーマンスや信頼性に影響します。 | `random`           |
| Pool Size            | S3接続用コネクションプールのサイズを定義します。大きいほど同時接続数を増やせますが、リソース消費も増加します。 | 8                  |
| HTTP Pipelining      | レスポンスを待たずに送信できるHTTPリクエスト数を指定します。スループット向上に寄与しますが、複雑さが増す可能性があります。 | 100                |
| HTTP Headers         | S3リクエストに追加するカスタムHTTPヘッダーを指定できます。キー・バリュー形式で追加可能です。 | -                  |
| Max Retries          | エラー発生時のS3リクエスト再試行の最大回数を指定します。値を増やすと信頼性は向上しますが、遅延が発生する可能性があります。 | -                  |
| Request Timeout      | 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/)

:::
