エンジニアリング

"タイプ"廃止へ。"タイプレス"が登場!

Elasticではバージョン5.0よりElasticsearchのタイプ廃止に向けて取り組んできました。そして7.0より、タイプは完全に廃止されます。タイプはこれまで単インデックス内でマルチテナンシーを実現する目的で設けられていましたが、Luceneとの互換性がありませんでした。このため、メリットを上回る数々の問題を生じさせている事実が明らかになっていました。 いくつかの回避策(たとえばタイプごとに固有のフィールドを使用するとか、内部では1つのタイプに対し1つのインデックスしか持たせないなど)も長く議論されてきましたが、最終的にタイプへのサポート自体を廃止するという結論に至りました。ユーザーが移行作業をスムーズに行えるよう、この変更は4つのメジャーバージョンで段階的に提供されます。

  • 5.0は、複数のタイプにわたって同じ名前を共有するフィールド同士に対し、強制的に互換性マッピングを持たせます。
  • 6.0では複数のタイプを備える新規のインデックスを作成できなくなり、_default_マッピングが廃止されます。
  • 7.0はタイプを受け入れるAPIを廃止し、新たにタイプレスAPIを導入するほか、_default_マッピングをサポート対象外とします。
  • 8.0はタイプに対応するAPIを削除します。

タイプレスAPI

URLパス、リクエストbody、またはレスポンスbodyでタイプを受け入れるすべてのAPIが、新たに"タイプレス"カウンターパートを取得します。この挙動はindex creationやindex、GET APIなどの非常に一般的なAPIで生じます。具体的な説明は長くなるので割愛しますが、7.0クラスターとのやり取りは下のようになります。

PUT index
{
  "mappings": {
    "properties": { // Note how there is no top-level key with the type name
      "@timestamp": {
        "type": "date"
      }
    }
  }
}
PUT index/_doc/1 // _doc becomes the new endpoint for document index, get and delete requests
{
  "@timestamp":"2019-02-20"
}
POST index/_bulk
{"index": {"_id":"2"}} // no _type in the URL or in document metadata
{"@timestamp":"2019-03-01"}
{"update": {"_id":"1"}}
{"@timestamp":"2019-02-21"}
GET index/_doc/2
GET index/_search // unchanged, the `GET index/{type}/_search` endpoint is deprecated however
{
  "query": {
    "range": {
      "@timestamp": {
        "gte":"2019-01-01"
      }
    }
  }
}
GET index/_explain/1 // note how the type does not appear in the URL anymore, this would have been "GET index/{type}/1/_explain" in 6.x
{
  "query": {
    "range": {
      "@timestamp": {
        "gte":"2019-01-01"
      }
    }
  }
}

対応にあたって必要となる作業

一部の変更は破損を招く内容となるため、7.0へのアップグレードの前にお使いのクラスターを変更していただく作業が必要です。その他の変更は、8.0へのアップグレードに際してのみ実施する必要があり、かつ7.0へのアップグレード完了後に実施しなければなりません。

アップグレード前の手順

6.8にアップグレードしておく

ダウンタイムを設けず連続的にアップグレードすることを検討されている場合、はじめにバージョン6.8にアップグレードする必要があります。6.8は6.x台のリリースで唯一include_type_nameパラメーターといった機能をサポートするバージョンで、こうした一連の機能は7.0にスムーズにアップグレードする上で必要となります。

_default_マッピングの使用をやめる

_default_マッピングは7.0以降でサポートされません。6.xの既存のインデックスに_default_マッピングがある場合、新しいインデックスでは_default_マッピングがリジェクトされるだけなので問題にはなりません。

この場合、実際のタイプを_default_マッピングに含めるのではなく、インデックステンプレートとアプリケーションコードを更新してこれらのマッピングを実際のタイプに追加する必要があります。タイプの名称を重視しない場合に推奨されるやり方として、_docを使用する方法があり、将来のタイプレスAPIへの移行をより容易にします。

インデックス作成とテンプレート、およびマッピングAPIにinclude_type_name=trueをパスする

タイプレスAPIに移行すると、従来リクエストbodyがタイプを要求していたAPIは、期待値と異なるフォーマットを受け取ることになります。

  • create index
  • put mapping
  • put template

一方、レスポンスでタイプを返していたAPIの場合は、これまでと異なるレスポンスフォーマットを持つことになります。

  • get index
  • get mapping
  • get field mapping
  • get template

この変更による問題を回避するには、お使いのアプリケーションからこれらのAPIコールにinclude_type_name=trueをパスする必要があります。include_type_name=trueは6.xでは無処理(no operation)ですが、7.xではAPIに6.xと同じ挙動を命じます。一例として、このパラメーターを使ったインデックス作成コールを見てみましょう。6.8と7.xで同じように動作します。

PUT index?include_type_name=true
{
  "mappings": {
    "my_type": {
      "properties": { // Note how there is no top-level key with the type name
        "@timestamp": {
          "type": "date"
        }
      }
    }
  }
}

アップグレード後の手順

推奨の手順に沿って事前アップグレードを完了すると、あらゆる面で正常な動作を保つことができます。しかし、この段階でまだタイプを受け入れるAPIを使用している場合は、"サポート終了"の警告が発生します。この警告を回避するには、タイプレスAPIに移行する必要があります。

インデックス作成、テンプレートとマッピングAPIではURLパラメーターからinclude_type_name=trueを削除し、リクエストbodyやレスポンスフォーマットの期待値にタイプを含めないよう修正する必要があります。リクエストbodyやレスポンスにマッピングが含まれているとき、通常は次のようなセクションがあります。

{
  "my_type": { // this key is no longer accepted in mappings as of 7.0
    "properties": ...
  }
}

今後タイプ名を含めないようアップデートする必要があります。その修正後は次のようになります。

{
  "properties": ...
}

インデックスやGET、アップデートなどその他のAPIの場合、URL中のタイプ名を_docに置き換える必要があります。この手順は、インデックスのタイプ名にかかわらず有効です。たとえばmy_typeというタイプ名のインデックス向けにインデックスコールを実施していた場合、置き換え前のインデックスコールは次のような感じです。

PUT index/my_type/1
{
  "@timestamp":"2019-02-20"
}

置き換え後はこのようになります。

PUT index/_doc/1
{
  "@timestamp":"2019-02-20"
}

その他のリソース

タイプの削除やタイプレスAPIへの移行についてより詳しい情報に関心をお持ちの方は、タイプの廃止に関するドキュメントをご一読いただくことをおすすめいたします。このドキュメントは、変更の実装や対応に関する準備についてさらに豊富な情報を提供しています。

ぜひ7.0.0をダウンロードして、新しいタイプレスAPIをお試しください。お気づきの点がありましたら、フィードバックをディスカッションページにお寄せください。お待ちしています。