Skip to content

Commit 79130f5

Browse files
authored
Introduce StorageTier for IOPS/Throughput configurability (#181)
* Introduce StorageTier for IOPS/Throughput configurability * Refactor according to review * Make storage field pointer * Use top level storageTier field for simplicity
1 parent dac4b95 commit 79130f5

File tree

9 files changed

+153
-13
lines changed

9 files changed

+153
-13
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
out
44
gen
55
vendor/
6-
bin/
6+
bin/
7+
cover.out

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ CRD_REF_DOCS ?= $(LOCALBIN)/crd-ref-docs
1212
GCI ?= $(LOCALBIN)/gci
1313

1414
CONTROLLER_TOOLS_VERSION ?= v0.18.0
15-
CRD_REF_DOCS_VERSION ?= v0.1.0
15+
CRD_REF_DOCS_VERSION ?= v0.2.0
1616
CHART_DIR ?= charts/qdrant-kubernetes-api
1717
CRDS_DIR ?= crds
1818

@@ -102,4 +102,4 @@ GOBIN=$(LOCALBIN) go install $${package} ;\
102102
mv $(1) $(1)-$(3) ;\
103103
} ;\
104104
ln -sf $(1)-$(3) $(1)
105-
endef
105+
endef

api/v1/qdrantcluster_types.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ const (
5555
ByCountAndSize RebalanceStrategy = "by_count_and_size"
5656
)
5757

58+
// StorageTier specifies the performance profile for the disk to use.
59+
// +kubebuilder:validation:Enum=budget;balanced;performance
60+
type StorageTier string
61+
62+
//goland:noinspection GoUnusedConst
63+
const (
64+
StorageTierBudget StorageTier = "budget"
65+
StorageTierBalanced StorageTier = "balanced"
66+
StorageTierPerformance StorageTier = "performance"
67+
)
68+
5869
// QdrantClusterSpec defines the desired state of QdrantCluster
5970
// +kubebuilder:pruning:PreserveUnknownFields
6071
type QdrantClusterSpec struct {
@@ -117,6 +128,10 @@ type QdrantClusterSpec struct {
117128
// StorageClassNames specifies the storage class names for db and snapshots.
118129
// +optional
119130
StorageClassNames *StorageClassNames `json:"storageClassNames,omitempty"`
131+
// StorageTier specifies the performance tier to use for the disk
132+
// +kubebuilder:validation:Enum=budget;balanced;performance
133+
// +optional
134+
StorageTier *StorageTier `json:"storageTier,omitempty"`
120135
// TopologySpreadConstraints specifies the topology spread constraints for the cluster.
121136
// +optional
122137
TopologySpreadConstraints *[]corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`

api/v1/qdrantcluster_types_test.go

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,92 @@
11
package v1
22

33
import (
4+
"fmt"
45
"testing"
56

6-
"github.com/stretchr/testify/require"
7+
"github.com/stretchr/testify/assert"
78
)
89

910
func TestValidate(t *testing.T) {
10-
r := Resources{}
11-
err := r.Validate("test")
12-
require.Error(t, err)
13-
require.ErrorContains(t, err, "test.CPU error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'")
11+
testCases := []struct {
12+
name string
13+
spec QdrantClusterSpec
14+
expectedError error
15+
}{
16+
{
17+
name: "Storage size is not specified",
18+
spec: QdrantClusterSpec{
19+
Resources: Resources{
20+
CPU: "100m",
21+
Memory: "128Mi",
22+
},
23+
},
24+
expectedError: fmt.Errorf("Spec.Resources.Storage error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'"),
25+
},
26+
{
27+
name: "Invalid storage size",
28+
spec: QdrantClusterSpec{
29+
Resources: Resources{
30+
CPU: "100m",
31+
Memory: "128Mi",
32+
Storage: "foo",
33+
},
34+
},
35+
expectedError: fmt.Errorf("Spec.Resources.Storage error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'"),
36+
},
37+
{
38+
name: "CPU amount is not specified",
39+
spec: QdrantClusterSpec{
40+
Resources: Resources{
41+
Memory: "128Mi",
42+
Storage: "2Gi",
43+
},
44+
},
45+
expectedError: fmt.Errorf("Spec.Resources.CPU error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'"),
46+
},
1447

15-
spec := QdrantClusterSpec{}
16-
err = spec.Validate()
17-
require.Error(t, err)
18-
require.ErrorContains(t, err, "Spec.Resources.CPU error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'")
48+
{
49+
name: "Invalid CPU amount",
50+
spec: QdrantClusterSpec{
51+
Resources: Resources{
52+
CPU: "foo",
53+
Memory: "128Mi",
54+
Storage: "2Gi",
55+
},
56+
},
57+
expectedError: fmt.Errorf("Spec.Resources.CPU error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'"),
58+
},
59+
{
60+
name: "Memory amount is not specified",
61+
spec: QdrantClusterSpec{
62+
Resources: Resources{
63+
CPU: "100m",
64+
Storage: "2Gi",
65+
},
66+
},
67+
expectedError: fmt.Errorf("Spec.Resources.Memory error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'"),
68+
},
69+
{
70+
name: "Invalid Memory amount",
71+
spec: QdrantClusterSpec{
72+
Resources: Resources{
73+
CPU: "100m",
74+
Memory: "foo",
75+
Storage: "2Gi",
76+
},
77+
},
78+
expectedError: fmt.Errorf("Spec.Resources.Memory error: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'"),
79+
},
80+
}
81+
82+
for _, tt := range testCases {
83+
t.Run(tt.name, func(t *testing.T) {
84+
err := tt.spec.Validate()
85+
if tt.expectedError == nil {
86+
assert.NoError(t, err)
87+
} else {
88+
assert.EqualError(t, err, tt.expectedError.Error())
89+
}
90+
})
91+
}
1992
}

api/v1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/qdrant-kubernetes-api/templates/region-crds/qdrant.io_qdrantclusters.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,19 @@ spec:
870870
volume.
871871
type: string
872872
type: object
873+
storageTier:
874+
allOf:
875+
- enum:
876+
- budget
877+
- balanced
878+
- performance
879+
- enum:
880+
- budget
881+
- balanced
882+
- performance
883+
description: StorageTier specifies the performance tier to use for
884+
the disk
885+
type: string
873886
suspend:
874887
default: false
875888
description: |-

crds/qdrant.io_qdrantclusters.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,19 @@ spec:
869869
volume.
870870
type: string
871871
type: object
872+
storageTier:
873+
allOf:
874+
- enum:
875+
- budget
876+
- balanced
877+
- performance
878+
- enum:
879+
- budget
880+
- balanced
881+
- performance
882+
description: StorageTier specifies the performance tier to use for
883+
the disk
884+
type: string
872885
suspend:
873886
default: false
874887
description: |-

docs/api.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@ _Appears in:_
796796
| `gpu` _[GPU](#gpu)_ | GPU specifies GPU configuration for the cluster. If this field is not set, no GPU will be used. | | |
797797
| `statefulSet` _[KubernetesStatefulSet](#kubernetesstatefulset)_ | StatefulSet specifies the configuration of the Qdrant Kubernetes StatefulSet. | | |
798798
| `storageClassNames` _[StorageClassNames](#storageclassnames)_ | StorageClassNames specifies the storage class names for db and snapshots. | | |
799+
| `storageTier` _[StorageTier](#storagetier)_ | StorageTier specifies the performance tier to use for the disk | | Enum: [budget balanced performance] <br /> |
799800
| `topologySpreadConstraints` _[TopologySpreadConstraint](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#topologyspreadconstraint-v1-core)_ | TopologySpreadConstraints specifies the topology spread constraints for the cluster. | | |
800801
| `podDisruptionBudget` _[PodDisruptionBudgetSpec](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#poddisruptionbudgetspec-v1-policy)_ | PodDisruptionBudget specifies the pod disruption budget for the cluster. | | |
801802
| `restartAllPodsConcurrently` _boolean_ | RestartAllPodsConcurrently specifies whether to restart all pods concurrently (also called one-shot-restart).<br />If enabled, all the pods in the cluster will be restarted concurrently in situations where multiple pods<br />need to be restarted, like when RestartedAtAnnotationKey is added/updated or the Qdrant version needs to be upgraded.<br />This helps sharded but not replicated clusters to reduce downtime to a possible minimum during restart.<br />If unset, the operator is going to restart nodes concurrently if none of the collections if replicated. | | |
@@ -1361,6 +1362,25 @@ _Appears in:_
13611362
| `async_scorer` _boolean_ | AsyncScorer enables io_uring when rescoring | | |
13621363

13631364

1365+
#### StorageTier
1366+
1367+
_Underlying type:_ _string_
1368+
1369+
StorageTier specifies the performance profile for the disk to use.
1370+
1371+
_Validation:_
1372+
- Enum: [budget balanced performance]
1373+
1374+
_Appears in:_
1375+
- [QdrantClusterSpec](#qdrantclusterspec)
1376+
1377+
| Field | Description |
1378+
| --- | --- |
1379+
| `budget` | |
1380+
| `balanced` | |
1381+
| `performance` | |
1382+
1383+
13641384
#### TraefikConfig
13651385

13661386

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ require (
1414
k8s.io/apiextensions-apiserver v0.33.3
1515
k8s.io/apimachinery v0.33.3
1616
k8s.io/client-go v0.33.3
17+
k8s.io/utils v0.0.0-20241210054802-24370beab758
1718
sigs.k8s.io/controller-runtime v0.21.0
1819
)
1920

@@ -67,7 +68,6 @@ require (
6768
gopkg.in/yaml.v3 v3.0.1 // indirect
6869
k8s.io/klog/v2 v2.130.1 // indirect
6970
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
70-
k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect
7171
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
7272
sigs.k8s.io/randfill v1.0.0 // indirect
7373
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect

0 commit comments

Comments
 (0)