Fess インデックスのバックアップとリストア

Windows 環境にて Fess で作成したインデックスのバックアップ～リストアの動作検証を行った記録です。

- 本記事では Fess ＋ Elasticsearch が稼働中のローカルストレージに対してバックアップを作成
- 記事中の curl コマンドは全て Windows 標準のコマンドプロンプトにて実行

# 環境
- Windows10 Pro 64bit
- Fess 13.9.3
- Elasticsearch 7.9.3

# スナップショット（バックアップ）

https://fess.codelibs.org/ja/13.9/config/index-backup.html
> Fess で扱うデータは elasticsearch のインデックスとして管理されています。 インデックスのバックアップ方法に関しては、elasticsearch がスナップショット機能として提供しています。 手順等の情報は スナップショット機能 を参照してください。

バックアップ＝スナップショット

## リポジトリディレクトリ作成・指定

スナップショット（バックアップ）を格納する `C:\elasticsearch-snapshot` を作成。
設定ファイルにも下記のように追記する。

```elasticsearch-7.9.3\config\elasticsearch.yml
path.repo: ["C:/elasticsearch-snapshot/"]
```

## リポジトリ確認（設定前）

```bash:command
C:\>curl -XGET "http://localhost:9200/_snapshot?pretty"
```

```json:response
{}
```
登録なし。

## リポジトリ作成

`_snapshot` API へ `elasticsearch-snapshot` リポジトリの作成をリクエストする。
（リポジトリ名称は任意）

```bash:command
C:\>curl -H "Content-Type: application/json" -XPUT "http://localhost:9200/_snapshot/elasticsearch-snapshot?pretty" -d "{"type": "fs","settings": {"location": "/elasticsearch-snapshot","compress": true}}"
```

```json:response
{
  "error" : {
    "root_cause" : [
      {
        "type" : "json_parse_exception",
        "reason" : "Unexpected character ('t' (code 116)): was expecting double-quote to start field name\n at [Source: (org.elasticsearch.common.bytes.AbstractBytesReference$MarkSupportingStreamInputWrapper); line: 1, column: 3]"
      }
    ],
    "type" : "json_parse_exception",
    "reason" : "Unexpected character ('t' (code 116)): was expecting double-quote to start field name\n at [Source: (org.elasticsearch.common.bytes.AbstractBytesReference$MarkSupportingStreamInputWrapper); line: 1, column: 3]"
  },
  "status" : 400
}
```

Windows 10 で標準使用できるようになった curl の癖が強いのかリクエストデータを直接指定するとエラーが発生する。
リクエストデータを外部 json ファイルで定義することで解決した。その際、コマンドは json ファイルがあるディレクトリで実行すること。

```json:snapshot.json
{
  "type": "fs",
  "settings": {
    "location": "/elasticsearch-snapshot",
    "compress": true
  }
}
```

```bash:command
C:\>curl -H "Content-Type: application/json" -XPUT "http://localhost:9200/_snapshot/elasticsearch-snapshot?pretty" -d @snapshot.json
```

```json:response
{
  "acknowledged" : true
}
```

## リポジトリ確認（設定後）

```bash:command
C:\>curl -XGET "http://localhost:9200/_snapshot?pretty"
```

```json:response
{
  "elasticsearch-snapshot" : {
    "type" : "fs",
    "settings" : {
      "compress" : "true",
      "location" : "/elasticsearch-snapshot"
    }
  }
}
```

## リポジトリ削除
削除する場合

```bash:command
C:\>curl -XDELETE "http://localhost:9200/_snapshot/elasticsearch-snapshot?pretty"
```

```json:response
{
  "acknowledged" : true
}
```

## スナップショット取得

```bash
C:\>curl -XPUT "http://localhost:9200/_snapshot/elasticsearch-snapshot/test_snapshot?wait_for_completion=true"
```

成功するとリポジトリに下記のようにファイルが生成されます。

```
C:\elasticsearch-snapshot
    ├── indices
    │    ├── hogehoge
    │    ├── fugafuga
    │    略
    │    └── piyopiyo
    ├── index.latest
    ├── index-0
    ├── meta-<uuid>.dat
    └── snap-<uuid>.dat
```

## スナップショット確認

```bash:command
C:\>curl -XGET "http://localhost:9200/_snapshot/elasticsearch-snapshot/test_snapshot?pretty"
```

```json:response
{
  "snapshots" : [
    {
      "snapshot" : "test_snapshot",
      "uuid" : "hogehoge",
      "version_id" : 7090399,
      "version" : "7.9.3",
      "indices" : [
        ".fess_config.scheduled_job",
        ".fess_config.job_log",
        ".fess_config.failure_url",
        ".crawler.queue",
        ".fess_config.duplicate_host",
        ".fess_config.access_token",
        ".fess_config.label_type",
        ………
      ],
      "data_streams" : [ ],
      "include_global_state" : true,
      "state" : "SUCCESS",
      "start_time" : "2021-01-27T03:20:03.048Z",
      "start_time_in_millis" : 1611717603048,
      "end_time" : "2021-01-27T03:20:04.453Z",
      "end_time_in_millis" : 1611717604453,
      "duration_in_millis" : 1405,
      "failures" : [ ],
      "shards" : {
        "total" : 88,
        "failed" : 0,
        "successful" : 88
      }
    }
  ]
}
```

## スナップショット削除
削除する場合

```bash:command
C:\>curl -XDELETE "http://localhost:9200/_snapshot/elasticsearch-snapshot/test_snapshot?pretty"
```

```json:response
{
  "acknowledged" : true
}
```

成功するとリポジトリ内が下記のようになる。

```
C:\elasticsearch-snapshot
    ├── indices
    ├── index.latest
    └── index-1
```
`indices` フォルダ内の各インデックスファイルも削除されている。`index-0` から `index-1` にカウントアップした？

# リストア

**インデックス削除前**
![search1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/1dcfdcfc-9d0e-8c28-4595-4813743ac43f.png)

**インデックス削除後**
下記の方法にて検索用インデックスを削除
https://qiita.com/naente_dev/items/9535c0f10518e1d4a7d3#%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E5%89%8A%E9%99%A4
![search2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/51a3a752-36d5-7e4a-5771-9052014ef1e1.png)

## リストア実施

```bash:command
C:\>curl -H "Content-Type: application/json" -XPOST "http://localhost:9200/_snapshot/elasticsearch-snapshot/test_snapshot/_restore?pretty"
```

```json:response
{
  "error" : {
    "root_cause" : [
      {
        "type" : "snapshot_restore_exception",
        "reason" : "[elasticsearch-snapshot:test_snapshot/hogehoge] cannot restore index [.fess_config.related_content] because an open index with same name already exists in the cluster. Either close or delete the existing index or restore the index under a different name by providing a rename pattern and replacement name"
      }
    ],
    "type" : "snapshot_restore_exception",
    "reason" : "[elasticsearch-snapshot:test_snapshot/hogehoge] cannot restore index [.fess_config.related_content] because an open index with same name already exists in the cluster. Either close or delete the existing index or restore the index under a different name by providing a rename pattern and replacement name"
  },
  "status" : 500
}
```
一部のインデックスが使用中の為、リストア出来ないと怒られた（たぶん）

```bash:command
C:\>curl -XDELETE "http://localhost:9200/*?pretty"
```
```json:response
{
  "acknowledged" : true
}
```
全てのインデックスを完全に削除する。
※「削除したインデックス」＝「スナップショットから復元できるインデックス」であることの確認が**【取れていません】**ので実行する場合は自己責任でお願いします。

```bash:command
C:\>curl -H "Content-Type: application/json" -XPOST "http://localhost:9200/_snapshot/elasticsearch-snapshot/test_snapshot/_restore?pretty"
```
```json:response
{
  "accepted" : true
}
```
再度、リストアコマンドを実行すると正常に完了した。


**リストア後**
![search3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243093/ccced79a-2f13-49ac-cb0b-9ae1cd791907.png)
復元を確認。

# 参考
https://suzuki.tdiary.net/20141113.html
https://note.com/wi_curation/n/nd8338fc8af60
https://orebibou.com/ja/home/201806/20180606_001/
https://kohei.life/elasticsearch-backup/
https://www.bluecore.net/archives/6769
https://qiita.com/shouta-dev/items/c2d2eb6cf61bb1fa8e1b