Skip to content

Commit daf5063

Browse files
ygcyaoiSecloud
authored andcommitted
fix(backend): redis集群列表展示优化 #8416
1 parent 172ef2b commit daf5063

File tree

3 files changed

+85
-6
lines changed

3 files changed

+85
-6
lines changed

dbm-ui/backend/db_services/dbbase/serializers.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from backend.configuration.constants import DBType
1818
from backend.db_dirty.models import DirtyMachine
1919
from backend.db_meta.enums import ClusterPhase, ClusterType
20+
from backend.db_meta.models import Cluster
2021
from backend.db_services.dbbase.constants import ResourceType
2122
from backend.db_services.dbbase.resources.serializers import ListClusterEntriesSLZ, ListResourceSLZ
2223
from backend.db_services.ipchooser.query.resource import ResourceQueryHelper
@@ -211,3 +212,25 @@ class QueryClusterCapSerializer(serializers.Serializer):
211212
class QueryClusterCapResponseSerializer(serializers.Serializer):
212213
class Meta:
213214
swagger_schema_fields = {"example": {"cluster1": {"used": 1, "total": 2, "in_use": 50}}}
215+
216+
217+
class UpdateClusterAliasSerializer(serializers.Serializer):
218+
bk_biz_id = serializers.IntegerField(help_text=_("业务ID"))
219+
cluster_id = serializers.IntegerField(help_text=_("集群ID"))
220+
new_alias = serializers.CharField(help_text=_("新集群别名"))
221+
222+
def validate(self, attrs):
223+
bk_biz_id = attrs.get("bk_biz_id")
224+
cluster_id = attrs.get("cluster_id")
225+
new_alias = attrs.get("new_alias")
226+
227+
try:
228+
cluster = Cluster.objects.get(bk_biz_id=bk_biz_id, id=cluster_id)
229+
except Cluster.DoesNotExist:
230+
raise serializers.ValidationError(_("Cluster with the given ID does not exist."))
231+
232+
# 验证新别名不能与原集群名相同
233+
if cluster.alias == new_alias:
234+
raise serializers.ValidationError(_("The new alias cannot be the same as the current alias."))
235+
236+
return attrs

dbm-ui/backend/db_services/dbbase/views.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from backend.db_services.dbbase.instances.yasg_slz import CheckInstancesResSLZ, CheckInstancesSLZ
3030
from backend.db_services.dbbase.resources import register
3131
from backend.db_services.dbbase.resources.query import ListRetrieveResource, ResourceList
32+
from backend.db_services.dbbase.resources.serializers import ClusterSLZ
3233
from backend.db_services.dbbase.serializers import (
3334
ClusterDbTypeSerializer,
3435
ClusterEntryFilterSerializer,
@@ -45,6 +46,7 @@
4546
QueryClusterCapSerializer,
4647
QueryClusterInstanceCountSerializer,
4748
ResourceAdministrationSerializer,
49+
UpdateClusterAliasSerializer,
4850
WebConsoleResponseSerializer,
4951
WebConsoleSerializer,
5052
)
@@ -407,3 +409,18 @@ def query_cluster_stat(self, request, *args, **kwargs):
407409
cluster_stat_map = {cluster_domain_map[domain]: cap for domain, cap in cluster_stat_map.items()}
408410

409411
return Response(cluster_stat_map)
412+
413+
@common_swagger_auto_schema(
414+
operation_summary=_("更新集群别名"),
415+
request_body=UpdateClusterAliasSerializer(),
416+
tags=[SWAGGER_TAG],
417+
)
418+
@action(methods=["POST"], detail=False, serializer_class=UpdateClusterAliasSerializer)
419+
def update_cluster_alias(self, request):
420+
validated_data = self.params_validate(self.get_serializer_class())
421+
"""更新集群别名"""
422+
cluster = Cluster.objects.get(bk_biz_id=validated_data["bk_biz_id"], id=validated_data["cluster_id"])
423+
cluster.alias = validated_data["new_alias"]
424+
cluster.save(update_fields=["alias"])
425+
serializer = ClusterSLZ(cluster)
426+
return Response(serializer.data)

dbm-ui/backend/db_services/redis/resources/redis_cluster/query.py

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ def _filter_cluster_hook(
105105
offset: int,
106106
**kwargs,
107107
) -> ResourceList:
108+
# 提前预取storage的tuple
109+
storage_queryset = storage_queryset.prefetch_related(
110+
"machine", "nosqlstoragesetdtl_set", "as_receiver", "as_ejector"
111+
)
108112
# 预取remote的spec
109113
redis_spec_map = {spec.spec_id: spec for spec in Spec.objects.filter(spec_cluster_type=SpecClusterType.Redis)}
110114
return super()._filter_cluster_hook(
@@ -132,9 +136,44 @@ def _to_cluster_representation(
132136
**kwargs,
133137
) -> Dict[str, Any]:
134138
"""集群序列化"""
135-
redis_master = [m.simple_desc for m in cluster.storages if m.instance_role == InstanceRole.REDIS_MASTER]
136-
redis_slave = [m.simple_desc for m in cluster.storages if m.instance_role == InstanceRole.REDIS_SLAVE]
137-
machine_list = list(set([inst["bk_host_id"] for inst in [*redis_master, *redis_slave]]))
139+
# 创建一个字典来存储 ejector_id 到cluster.storages下标的映射
140+
ejector_id__storage_map = {storage_instance.id: storage_instance for storage_instance in cluster.storages}
141+
142+
remote_infos = {InstanceRole.REDIS_MASTER.value: [], InstanceRole.REDIS_SLAVE.value: []}
143+
for inst in cluster.storages:
144+
try:
145+
seg_range = (
146+
inst.nosqlstoragesetdtl_set.all()[0].seg_range
147+
if inst.cluster_type != ClusterType.RedisInstance.value
148+
else "-1"
149+
)
150+
except IndexError:
151+
# 异常处理 因nosqlstoragesetdtl的分片数据只有redis为master才有seg_range值 以下处理是slave找出对应master seg_range并赋予值 供主从对应排序处理
152+
master = ejector_id__storage_map.get(inst.as_receiver.all()[0].ejector_id)
153+
seg_range = master.nosqlstoragesetdtl_set.all()[0].seg_range if master is not None else "-1"
154+
except Exception:
155+
# 如果无法找到seg_range,则默认为-1。有可能实例处于restoring状态(比如集群容量变更时)
156+
seg_range = "-1"
157+
158+
remote_infos[inst.instance_role].append({**inst.simple_desc, "seg_range": seg_range})
159+
160+
remote_infos[InstanceRole.REDIS_MASTER.value].sort(
161+
key=lambda x: int(x.get("seg_range", "-1").split("-")[0]) if x.get("seg_range", "-1").split("-")[0] else -1
162+
)
163+
remote_infos[InstanceRole.REDIS_SLAVE.value].sort(
164+
key=lambda x: int(x.get("seg_range", "-1").split("-")[0]) if x.get("seg_range", "-1").split("-")[0] else -1
165+
)
166+
machine_list = list(
167+
set(
168+
[
169+
inst["bk_host_id"]
170+
for inst in [
171+
*remote_infos[InstanceRole.REDIS_MASTER.value],
172+
*remote_infos[InstanceRole.REDIS_SLAVE.value],
173+
]
174+
]
175+
)
176+
)
138177
machine_pair_cnt = len(machine_list) / 2
139178

140179
# 补充集群的规格和容量信息
@@ -163,9 +202,9 @@ def _to_cluster_representation(
163202
"cluster_capacity": cluster_capacity,
164203
"dns_to_clb": dns_to_clb,
165204
"proxy": [m.simple_desc for m in cluster.proxies],
166-
"redis_master": redis_master,
167-
"redis_slave": redis_slave,
168-
"cluster_shard_num": len(redis_master),
205+
"redis_master": remote_infos[InstanceRole.REDIS_MASTER.value],
206+
"redis_slave": remote_infos[InstanceRole.REDIS_SLAVE.value],
207+
"cluster_shard_num": len(remote_infos[InstanceRole.REDIS_MASTER.value]),
169208
"machine_pair_cnt": machine_pair_cnt,
170209
"module_names": module_names,
171210
}

0 commit comments

Comments
 (0)