ディスク使用量の調整
必要のない機能を無効にする
デフォルトでは、Elasticsearchはほとんどのフィールドにインデックスを作成し、ドキュメント値を追加するため、すぐに検索や集計が可能です。たとえば、foo
という名前の数値フィールドがあり、ヒストグラムを実行する必要があるが、フィルタリングする必要がない場合、このフィールドのインデックス作成をmappingsで安全に無効にできます。
Python
resp = client.indices.create(
index="index",
mappings={
"properties": {
"foo": {
"type": "integer",
"index": False
}
}
},
)
print(resp)
Ruby
response = client.indices.create(
index: 'index',
body: {
mappings: {
properties: {
foo: {
type: 'integer',
index: false
}
}
}
}
)
puts response
Js
const response = await client.indices.create({
index: "index",
mappings: {
properties: {
foo: {
type: "integer",
index: false,
},
},
},
});
console.log(response);
コンソール
PUT index
{
"mappings": {
"properties": {
"foo": {
"type": "integer",
"index": false
}
}
}
}
text
フィールドは、ドキュメントのスコアリングを容易にするためにインデックスに正規化係数を保存します。text
フィールドで一致機能のみが必要で、生成されたスコアには関心がない場合は、match_only_text
タイプを代わりに使用できます。このフィールドタイプは、スコアリングと位置情報を削除することで、かなりのスペースを節約します。
デフォルトの動的文字列マッピングを使用しない
デフォルトの動的文字列マッピングは、文字列フィールドをtext
とkeyword
の両方としてインデックスします。これらのうちの1つだけが必要な場合、これは無駄です。通常、id
フィールドはkeyword
としてのみインデックスされ、body
フィールドはtext
フィールドとしてのみインデックスされる必要があります。
これは、文字列フィールドに明示的なマッピングを設定するか、文字列フィールドをtext
またはkeyword
としてマッピングする動的テンプレートを設定することで無効にできます。
たとえば、文字列フィールドをkeyword
としてのみマッピングするために使用できるテンプレートは次のとおりです:
Python
resp = client.indices.create(
index="index",
mappings={
"dynamic_templates": [
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
},
)
print(resp)
Ruby
response = client.indices.create(
index: 'index',
body: {
mappings: {
dynamic_templates: [
{
strings: {
match_mapping_type: 'string',
mapping: {
type: 'keyword'
}
}
}
]
}
}
)
puts response
Js
const response = await client.indices.create({
index: "index",
mappings: {
dynamic_templates: [
{
strings: {
match_mapping_type: "string",
mapping: {
type: "keyword",
},
},
},
],
},
});
console.log(response);
コンソール
PUT index
{
"mappings": {
"dynamic_templates": [
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
シャードサイズに注意する
大きなシャードはデータの保存により効率的です。シャードのサイズを増やすには、インデックスを作成することでプライマリシャードの数を減らすか、より少ないインデックスを作成する(たとえば、Rollover APIを利用する)か、Shrink APIを使用して既存のインデックスを変更します。
大きなシャードサイズには、長い完全回復時間などの欠点があることを忘れないでください。
_sourceを無効にする
_source
フィールドは、ドキュメントの元のJSONボディを保存します。これにアクセスする必要がない場合は、無効にできます。ただし、更新、ハイライト、再インデックスなど、_source
にアクセスする必要があるAPIは機能しません。
best_compressionを使用する
_source
および保存されたフィールドは、無視できない量のディスクスペースを占有する可能性があります。best_compression
コーデックを使用することで、より積極的に圧縮できます。
強制マージ
Elasticsearchのインデックスは1つ以上のシャードに保存されます。各シャードはLuceneインデックスであり、1つ以上のセグメントで構成されています - 実際のディスク上のファイルです。大きなセグメントはデータの保存により効率的です。
force merge APIを使用して、シャードごとのセグメント数を減らすことができます。多くの場合、max_num_segments=1
を設定することで、セグメント数をシャードごとに1つに減らすことができます。
読み取り専用インデックス(つまり、インデックスがもはや書き込みを受け付けないことを意味します)を強制的にマージすることをお勧めします。 ドキュメントが更新または削除されると、古いバージョンはすぐには削除されず、代わりにソフト削除され、「墓石」としてマークされます。これらのソフト削除されたドキュメントは、通常のセグメントマージ中に自動的にクリーンアップされます。しかし、強制マージは非常に大きな(> 5GB)セグメントを生成する可能性があり、これは通常のマージの対象外です。そのため、ソフト削除されたドキュメントの数が急速に増加し、ディスク使用量が増加し、検索パフォーマンスが悪化する可能性があります。書き込みを受け付けるインデックスを定期的に強制マージすると、新しいドキュメントがインクリメンタルにバックアップできないため、スナップショットがより高価になる可能性があります。
インデックスを縮小する
shrink APIを使用すると、インデックス内のシャード数を減らすことができます。上記のforce merge APIと組み合わせることで、インデックスのシャード数とセグメント数を大幅に減少させることができます。
十分な最小の数値型を使用する
数値データに選択する型は、ディスク使用量に大きな影響を与える可能性があります。特に、整数は整数型(byte
、short
、integer
またはlong
)を使用して保存し、浮動小数点数は適切であればscaled_float
に保存するか、使用ケースに合った最小の型に保存する必要があります:float
をdouble
の代わりに使用したり、half_float
をfloat
の代わりに使用したりすることで、ストレージを節約できます。
インデックスソートを使用して類似のドキュメントを同じ場所に配置する
Elasticsearchが_source
を保存する際、全体の圧縮率を改善するために複数のドキュメントを一度に圧縮します。たとえば、ドキュメントが同じフィールド名を共有することは非常に一般的であり、特に低いカーディナリティやzipfian分布を持つフィールドでいくつかのフィールド値を共有することは非常に一般的です。
デフォルトでは、ドキュメントはインデックスに追加された順序で一緒に圧縮されます。インデックスソートを有効にすると、代わりにソートされた順序で圧縮されます。構造、フィールド、および値が類似しているドキュメントを一緒にソートすることで、圧縮率が改善されるはずです。
ドキュメント内のフィールドを同じ順序で配置する
複数のドキュメントがブロックに一緒に圧縮されるため、フィールドが常に同じ順序で出現する場合、_source
ドキュメント内で長い重複文字列を見つける可能性が高くなります。
履歴データを集約する
古いデータを保持することは後の分析に役立つ場合がありますが、ストレージコストのために避けられることがよくあります。ダウンサンプリングを使用して、元のデータのストレージコストの一部で履歴データを要約して保存できます。時系列データストリームのダウンサンプリングを参照してください。