diff --git a/x-pack/plugins/index_lifecycle_management/common/types/policies.ts b/x-pack/plugins/index_lifecycle_management/common/types/policies.ts index a0ee82cbbe385..f7c1b810ecbc5 100644 --- a/x-pack/plugins/index_lifecycle_management/common/types/policies.ts +++ b/x-pack/plugins/index_lifecycle_management/common/types/policies.ts @@ -42,9 +42,7 @@ export interface SerializedHotPhase extends SerializedPhase { max_age?: string; max_docs?: number; }; - forcemerge?: { - max_num_segments: number; - }; + forcemerge?: ForcemergeAction; set_priority?: { priority: number | null; }; @@ -57,9 +55,7 @@ export interface SerializedWarmPhase extends SerializedPhase { shrink?: { number_of_shards: number; }; - forcemerge?: { - max_num_segments: number; - }; + forcemerge?: ForcemergeAction; set_priority?: { priority: number | null; }; @@ -105,6 +101,12 @@ export interface AllocateAction { }; } +export interface ForcemergeAction { + max_num_segments: number; + // only accepted value for index_codec + index_codec?: 'best_compression'; +} + export interface Policy { name: string; phases: { @@ -150,6 +152,7 @@ export interface PhaseWithIndexPriority { export interface PhaseWithForcemergeAction { forceMergeEnabled: boolean; selectedForceMergeSegments: string; + bestCompressionEnabled: boolean; } export interface HotPhase diff --git a/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts b/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts index 8a0a5d9fbdfad..1cd81b55ea173 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/constants/policy.ts @@ -21,6 +21,7 @@ export const defaultNewHotPhase: HotPhase = { selectedMaxSizeStoredUnits: 'gb', forceMergeEnabled: false, selectedForceMergeSegments: '', + bestCompressionEnabled: false, phaseIndexPriority: '100', selectedMaxDocuments: '', }; @@ -29,6 +30,7 @@ export const defaultNewWarmPhase: WarmPhase = { phaseEnabled: false, forceMergeEnabled: false, selectedForceMergeSegments: '', + bestCompressionEnabled: false, selectedMinimumAge: '0', selectedMinimumAgeUnits: 'd', selectedNodeAttrs: '', diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/forcemerge.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/forcemerge.tsx index 50cc7fd8b3274..c079c7a19ce91 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/forcemerge.tsx +++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/components/forcemerge.tsx @@ -8,6 +8,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { EuiDescribedFormGroup, EuiFieldNumber, + EuiFormRow, EuiSpacer, EuiSwitch, EuiTextColor, @@ -19,10 +20,17 @@ import { ErrableFormRow } from './form_errors'; import { Phases, PhaseWithForcemergeAction } from '../../../../../common/types'; import { PhaseValidationErrors } from '../../../services/policies/policy_validation'; -const forcemergeLabel = i18n.translate('xpack.indexLifecycleMgmt.warmPhase.forceMergeDataLabel', { +const forcemergeLabel = i18n.translate('xpack.indexLifecycleMgmt.forcemerge.enableLabel', { defaultMessage: 'Force merge data', }); +const bestCompressionLabel = i18n.translate( + 'xpack.indexLifecycleMgmt.forcemerge.bestCompressionLabel', + { + defaultMessage: 'Compress stored fields', + } +); + interface Props { errors?: PhaseValidationErrors; phase: keyof Phases & string; @@ -30,6 +38,7 @@ interface Props { setPhaseData: (dataKey: keyof PhaseWithForcemergeAction, value: boolean | string) => void; isShowingErrors: boolean; } + export const Forcemerge: React.FunctionComponent = ({ errors, phaseData, @@ -42,7 +51,7 @@ export const Forcemerge: React.FunctionComponent = ({ title={

@@ -50,7 +59,7 @@ export const Forcemerge: React.FunctionComponent = ({ description={ {' '} @@ -73,23 +82,43 @@ export const Forcemerge: React.FunctionComponent = ({
{phaseData.forceMergeEnabled ? ( - - { - setPhaseData('selectedForceMergeSegments', e.target.value); - }} - min={1} - /> - + <> + + { + setPhaseData('selectedForceMergeSegments', e.target.value); + }} + min={1} + /> + + + } + > + { + setPhaseData('bestCompressionEnabled', e.target.checked); + }} + /> + + ) : null}
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/cold_phase.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/cold_phase.ts index 70f172de390e3..9f5f603fbc564 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/cold_phase.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/cold_phase.ts @@ -16,7 +16,7 @@ import { import { determineDataTierAllocationType } from '../../lib'; import { serializePhaseWithAllocation } from './shared'; -const coldPhaseInitialization: ColdPhase = { +export const coldPhaseInitialization: ColdPhase = { phaseEnabled: false, selectedMinimumAge: '0', selectedMinimumAgeUnits: 'd', diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/hot_phase.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/hot_phase.ts index 4ef4890b5ffe3..3bb9165c7d4f0 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/hot_phase.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/hot_phase.ts @@ -26,6 +26,7 @@ const hotPhaseInitialization: HotPhase = { selectedMaxSizeStoredUnits: 'gb', forceMergeEnabled: false, selectedForceMergeSegments: '', + bestCompressionEnabled: false, phaseIndexPriority: '', selectedMaxDocuments: '', }; @@ -64,6 +65,8 @@ export const hotPhaseFromES = (phaseSerialized?: SerializedHotPhase): HotPhase = const forcemerge = actions.forcemerge; phase.forceMergeEnabled = true; phase.selectedForceMergeSegments = forcemerge.max_num_segments.toString(); + // only accepted value for index_codec + phase.bestCompressionEnabled = forcemerge.index_codec === 'best_compression'; } if (actions.set_priority) { @@ -105,6 +108,10 @@ export const hotPhaseToES = ( esPhase.actions.forcemerge = { max_num_segments: parseInt(phase.selectedForceMergeSegments, 10), }; + if (phase.bestCompressionEnabled) { + // only accepted value for index_codec + esPhase.actions.forcemerge.index_codec = 'best_compression'; + } } else { delete esPhase.actions.forcemerge; } diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.test.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.test.ts index 222887069a0dc..71ae9b26e2903 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.test.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/policy_serialization.test.ts @@ -6,7 +6,7 @@ // Prefer importing entire lodash library, e.g. import { get } from "lodash" // eslint-disable-next-line no-restricted-imports import cloneDeep from 'lodash/cloneDeep'; -import { serializePolicy } from './policy_serialization'; +import { deserializePolicy, serializePolicy } from './policy_serialization'; import { defaultNewColdPhase, defaultNewDeletePhase, @@ -14,6 +14,7 @@ import { defaultNewWarmPhase, } from '../../constants'; import { DataTierAllocationType } from '../../../../common/types'; +import { coldPhaseInitialization } from './cold_phase'; describe('Policy serialization', () => { test('serialize a policy using "default" data allocation', () => { @@ -369,4 +370,203 @@ describe('Policy serialization', () => { serializePolicy(deserializedPolicy, originalPolicy); expect(originalPolicy).toEqual(originalClone); }); + + test('serialize a policy using "best_compression" codec for forcemerge', () => { + expect( + serializePolicy( + { + name: 'test', + phases: { + hot: { + ...defaultNewHotPhase, + forceMergeEnabled: true, + selectedForceMergeSegments: '1', + bestCompressionEnabled: true, + }, + warm: { + ...defaultNewWarmPhase, + phaseEnabled: true, + forceMergeEnabled: true, + selectedForceMergeSegments: '1', + bestCompressionEnabled: true, + }, + cold: { + ...defaultNewColdPhase, + }, + delete: { ...defaultNewDeletePhase }, + }, + }, + { + name: 'test', + phases: { + hot: { actions: {} }, + }, + } + ) + ).toEqual({ + name: 'test', + phases: { + hot: { + actions: { + rollover: { + max_age: '30d', + max_size: '50gb', + }, + forcemerge: { + max_num_segments: 1, + index_codec: 'best_compression', + }, + set_priority: { + priority: 100, + }, + }, + }, + warm: { + actions: { + forcemerge: { + max_num_segments: 1, + index_codec: 'best_compression', + }, + set_priority: { + priority: 50, + }, + }, + }, + }, + }); + }); + + test('de-serialize a policy using "best_compression" codec for forcemerge', () => { + expect( + deserializePolicy({ + modified_date: Date.now().toString(), + name: 'test', + version: 1, + policy: { + name: 'test', + phases: { + hot: { + actions: { + rollover: { + max_age: '30d', + max_size: '50gb', + }, + forcemerge: { + max_num_segments: 1, + index_codec: 'best_compression', + }, + set_priority: { + priority: 100, + }, + }, + }, + warm: { + actions: { + forcemerge: { + max_num_segments: 1, + index_codec: 'best_compression', + }, + set_priority: { + priority: 50, + }, + }, + }, + }, + }, + }) + ).toEqual({ + name: 'test', + phases: { + hot: { + ...defaultNewHotPhase, + forceMergeEnabled: true, + selectedForceMergeSegments: '1', + bestCompressionEnabled: true, + }, + warm: { + ...defaultNewWarmPhase, + warmPhaseOnRollover: false, + phaseEnabled: true, + forceMergeEnabled: true, + selectedForceMergeSegments: '1', + bestCompressionEnabled: true, + }, + cold: { + ...coldPhaseInitialization, + }, + delete: { ...defaultNewDeletePhase }, + }, + }); + }); + + test('delete "best_compression" codec for forcemerge if disabled in UI', () => { + expect( + serializePolicy( + { + name: 'test', + phases: { + hot: { + ...defaultNewHotPhase, + forceMergeEnabled: true, + selectedForceMergeSegments: '1', + bestCompressionEnabled: false, + }, + warm: { + ...defaultNewWarmPhase, + phaseEnabled: true, + forceMergeEnabled: true, + selectedForceMergeSegments: '1', + bestCompressionEnabled: false, + }, + cold: { + ...defaultNewColdPhase, + }, + delete: { ...defaultNewDeletePhase }, + }, + }, + { + name: 'test', + phases: { + hot: { actions: {} }, + warm: { + actions: { + forcemerge: { + max_num_segments: 1, + index_codec: 'best_compression', + }, + }, + }, + }, + } + ) + ).toEqual({ + name: 'test', + phases: { + hot: { + actions: { + rollover: { + max_age: '30d', + max_size: '50gb', + }, + forcemerge: { + max_num_segments: 1, + }, + set_priority: { + priority: 100, + }, + }, + }, + warm: { + actions: { + forcemerge: { + max_num_segments: 1, + }, + set_priority: { + priority: 50, + }, + }, + }, + }, + }); + }); }); diff --git a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/warm_phase.ts b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/warm_phase.ts index 6971f652f986b..436e5a222f86d 100644 --- a/x-pack/plugins/index_lifecycle_management/public/application/services/policies/warm_phase.ts +++ b/x-pack/plugins/index_lifecycle_management/public/application/services/policies/warm_phase.ts @@ -30,6 +30,7 @@ const warmPhaseInitialization: WarmPhase = { selectedPrimaryShardCount: '', forceMergeEnabled: false, selectedForceMergeSegments: '', + bestCompressionEnabled: false, phaseIndexPriority: '', dataTierAllocationType: 'default', }; @@ -76,6 +77,8 @@ export const warmPhaseFromES = (phaseSerialized?: SerializedWarmPhase): WarmPhas const forcemerge = actions.forcemerge; phase.forceMergeEnabled = true; phase.selectedForceMergeSegments = forcemerge.max_num_segments.toString(); + // only accepted value for index_codec + phase.bestCompressionEnabled = forcemerge.index_codec === 'best_compression'; } if (actions.shrink) { @@ -84,6 +87,12 @@ export const warmPhaseFromES = (phaseSerialized?: SerializedWarmPhase): WarmPhas ? actions.shrink.number_of_shards.toString() : ''; } + + if (actions.set_priority) { + phase.phaseIndexPriority = actions.set_priority.priority + ? actions.set_priority.priority.toString() + : ''; + } } return phase; }; @@ -136,6 +145,10 @@ export const warmPhaseToES = ( esPhase.actions.forcemerge = { max_num_segments: parseInt(phase.selectedForceMergeSegments, 10), }; + if (phase.bestCompressionEnabled) { + // only accepted value for index_codec + esPhase.actions.forcemerge.index_codec = 'best_compression'; + } } else { delete esPhase.actions.forcemerge; } diff --git a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts index 8234686a542a9..d9e0a6e218de5 100644 --- a/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts +++ b/x-pack/plugins/index_lifecycle_management/server/routes/api/policies/register_create_route.ts @@ -55,6 +55,7 @@ const allocateSchema = schema.maybe( const forcemergeSchema = schema.maybe( schema.object({ max_num_segments: schema.number(), + index_codec: schema.maybe(schema.literal('best_compression')), }) ); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index abf1f050b69cb..b1e3ad2edbc67 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -8052,8 +8052,6 @@ "xpack.indexLifecycleMgmt.editPolicy.validPolicyNameMessage": "ポリシー名の頭にアンダーラインを使用することはできず、括弧やスペースを含めることもできません。", "xpack.indexLifecycleMgmt.editPolicy.viewNodeDetailsButton": "この構成に関連付けられているインデックスのリストを表示", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.activateWarmPhaseSwitchLabel": "ウォームフェーズを有効にする", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.forceMergeDataExplanationText": "小さなファイルを結合して削除されたファイルを消去することで、シャードのセグメント数を減らします。", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.forceMergeDataText": "強制結合", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.indexPriorityExplanationText": "ノードの再起動後にインデックスを復元する優先順位を設定します。優先順位の高いインデックスは優先順位の低いインデックスよりも先に復元されます。", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkIndexExplanationText": "インデックス情報をプライマリシャードの少ない新規インデックスに縮小します。", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkText": "縮小", @@ -8167,11 +8165,9 @@ "xpack.indexLifecycleMgmt.removeIndexLifecycleActionButtonLabel": "ライフサイクルポリシーを削除", "xpack.indexLifecycleMgmt.retryIndexLifecycleAction.retriedLifecycleMessage": "ライフサイクルのステップを再試行します {indexNames}", "xpack.indexLifecycleMgmt.retryIndexLifecycleActionButtonLabel": "ライフサイクルのステップを再試行", - "xpack.indexLifecycleMgmt.warmPhase.forceMergeDataLabel": "データを強制結合", "xpack.indexLifecycleMgmt.warmPhase.moveToWarmPhaseOnRolloverLabel": "ロールオーバー時にウォームフェーズに変更", "xpack.indexLifecycleMgmt.warmPhase.numberOfPrimaryShardsLabel": "プライマリシャードの数", "xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasLabel": "レプリカの数", - "xpack.indexLifecycleMgmt.warmPhase.numberOfSegmentsLabel": "セグメントの数", "xpack.indexLifecycleMgmt.warmPhase.shrinkIndexLabel": "インデックスを縮小", "xpack.infra.alerting.alertFlyout.groupBy.placeholder": "なし(グループなし)", "xpack.infra.alerting.alertFlyout.groupByLabel": "グループ分けの条件", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 4a2cfabc20791..b0ab1f6180485 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -8056,8 +8056,6 @@ "xpack.indexLifecycleMgmt.editPolicy.validPolicyNameMessage": "策略名称不能以下划线开头,且不能包含问号或空格。", "xpack.indexLifecycleMgmt.editPolicy.viewNodeDetailsButton": "查看附加到此配置的节点列表", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.activateWarmPhaseSwitchLabel": "激活温阶段", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.forceMergeDataExplanationText": "通过合并较小文件并清除已删除文件,来减少分片中的段数目。", - "xpack.indexLifecycleMgmt.editPolicy.warmPhase.forceMergeDataText": "强制合并", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.indexPriorityExplanationText": "设置在节点重新启动后恢复索引的优先级。较高优先级的索引会在较低优先级的索引之前恢复。", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkIndexExplanationText": "将索引缩小成具有较少主分片的新索引。", "xpack.indexLifecycleMgmt.editPolicy.warmPhase.shrinkText": "缩小", @@ -8171,11 +8169,9 @@ "xpack.indexLifecycleMgmt.removeIndexLifecycleActionButtonLabel": "删除生命周期策略", "xpack.indexLifecycleMgmt.retryIndexLifecycleAction.retriedLifecycleMessage": "已为以下索引调用重试生命周期步骤:{indexNames}", "xpack.indexLifecycleMgmt.retryIndexLifecycleActionButtonLabel": "重试生命周期步骤", - "xpack.indexLifecycleMgmt.warmPhase.forceMergeDataLabel": "强制合并数据", "xpack.indexLifecycleMgmt.warmPhase.moveToWarmPhaseOnRolloverLabel": "滚动更新时移到温阶段", "xpack.indexLifecycleMgmt.warmPhase.numberOfPrimaryShardsLabel": "主分片数目", "xpack.indexLifecycleMgmt.warmPhase.numberOfReplicasLabel": "副本分片数目", - "xpack.indexLifecycleMgmt.warmPhase.numberOfSegmentsLabel": "段数目", "xpack.indexLifecycleMgmt.warmPhase.shrinkIndexLabel": "缩小索引", "xpack.infra.alerting.alertFlyout.groupBy.placeholder": "无内容(未分组)", "xpack.infra.alerting.alertFlyout.groupByLabel": "分组依据",