Skip to content

Commit

Permalink
feat(frontend): Redis新增RedisCluster和主从架构 #3931
Browse files Browse the repository at this point in the history
  • Loading branch information
3octaves authored and zhangzhw8 committed May 10, 2024
1 parent c1ce025 commit 4ab03ae
Show file tree
Hide file tree
Showing 72 changed files with 7,920 additions and 427 deletions.
29 changes: 21 additions & 8 deletions dbm-ui/frontend/src/common/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ export enum ClusterTypes {
TENDBSINGLE = 'tendbsingle',
TENDBHA = 'tendbha',
TENDBCLUSTER = 'tendbcluster',
TWEMPROXY_REDIS_INSTANCE = 'TwemproxyRedisInstance',
PREDIXY_TENDISPLUS_CLUSTER = 'PredixyTendisplusCluster',
TWEMPROXY_TENDIS_SSD_INSTANCE = 'TwemproxyTendisSSDInstance',
TWEMPROXY_REDIS_INSTANCE = 'TwemproxyRedisInstance', // Redis 分片集群 cache
PREDIXY_TENDISPLUS_CLUSTER = 'PredixyTendisplusCluster', // Redis 分片集群 plus
TWEMPROXY_TENDIS_SSD_INSTANCE = 'TwemproxyTendisSSDInstance', // Redis 分片集群 SSD
ES = 'es',
KAFKA = 'kafka',
HDFS = 'hdfs',
PULSAE = 'pulsar',
INFLUXDB = 'influxdb',
REDIS = 'redis',
PREDIXY_REDIS_CLUSTER = 'PredixyRedisCluster',
PREDIXY_REDIS_CLUSTER = 'PredixyRedisCluster', // Redis 分片集群 原生
TWEMPROXY_TENDISPLUS_INSTANCE = 'TwemproxyTendisplusInstance',
REDIS_INSTANCE = 'RedisInstance',
REDIS_INSTANCE = 'RedisInstance', // Redis 主从集群
TENDIS_SSD_INSTANCE = 'TendisSSDInstance',
TENDIS_PLUS_INSTANCE = 'TendisplusInstance',
REDIS_CLUSTER = 'RedisCluster',
Expand Down Expand Up @@ -321,8 +321,12 @@ export enum TicketTypes {
SQLSERVER_RESET = 'SQLSERVER_RESET', // sqlserver 集群重置
SQLSERVER_BACKUP_DBS = 'SQLSERVER_BACKUP_DBS', // sqlserver 数据库备份
TENDBCLUSTER_MIGRATE_CLUSTER = 'TENDBCLUSTER_MIGRATE_CLUSTER', // spider 迁移主从
TENDBCLUSTER_RESTORE_LOCAL_SLAVE = "TENDBCLUSTER_RESTORE_LOCAL_SLAVE", // spider 重建从库-原地重建
TENDBCLUSTER_RESTORE_SLAVE = "TENDBCLUSTER_RESTORE_SLAVE" // spider 重建从库-新机重建
TENDBCLUSTER_RESTORE_LOCAL_SLAVE = 'TENDBCLUSTER_RESTORE_LOCAL_SLAVE', // spider 重建从库-原地重建
TENDBCLUSTER_RESTORE_SLAVE = 'TENDBCLUSTER_RESTORE_SLAVE', // spider 重建从库-新机重建
REDIS_INS_APPLY = 'REDIS_INS_APPLY', // redis 主从集群部署
REDIS_INSTANCE_PROXY_OPEN = 'REDIS_INSTANCE_PROXY_OPEN', // redis 主从集群启用
REDIS_INSTANCE_PROXY_CLOSE = 'REDIS_INSTANCE_PROXY_CLOSE', // redis 主从集群禁用
REDIS_INSTANCE_DESTROY = 'REDIS_INSTANCE_DESTROY', // redis 主从集群删除
}
export type TicketTypesStrings = keyof typeof TicketTypes;

Expand Down Expand Up @@ -361,6 +365,12 @@ export const redisType = {
type: ClusterTypes.TWEMPROXY_REDIS_INSTANCE,
dbType: DBTypes.REDIS,
},
[TicketTypes.REDIS_INS_APPLY]: {
id: TicketTypes.REDIS_INS_APPLY,
name: t('主从部署'),
type: ClusterTypes.REDIS_INSTANCE,
dbType: DBTypes.REDIS,
},
};

/**
Expand Down Expand Up @@ -508,7 +518,10 @@ export enum UserPersonalSettings {
MONGODB_SHARED_CLUSTER_SETTINGS = 'MONGODB_SHARED_CLUSTER_SETTINGS',
SQLSERVER_SINGLE_TABLE_SETTINGS = 'SQLSERVER_SINGLE_TABLE_SETTINGS',
SQLSERVER_HA_TABLE_SETTINGS = 'SQLSERVER_HA_TABLE_SETTINGS',
RESOURCE_POOL_SELECTOR_SETTINGS = 'RESOURCE_POOL_SELECTOR_SETTINGS'
RESOURCE_POOL_SELECTOR_SETTINGS = 'RESOURCE_POOL_SELECTOR_SETTINGS',
REDIS_HA_TABLE_SETTINGS = 'REDIS_HA_TABLE_SETTINGS',
REDIS_INSTANCE_SETTINGS = 'REDIS_INSTANCE_SETTINGS',
REDIS_HA_INSTANCE_SETTINGS = 'REDIS_HA_INSTANCE_SETTINGS',
}

/**
Expand Down
59 changes: 36 additions & 23 deletions dbm-ui/frontend/src/components/apply-items/BackendSpec.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
v-bkloading="{ loading: isLoading }"
class="custom-edit-table"
:columns="columns"
:data="renderSpecs"
:data="specs"
@row-click="handleRowClick">
<template #empty>
<p
Expand Down Expand Up @@ -66,6 +66,8 @@
import { ClusterTypes } from '@common/const';
import TextOverflowLayout from '@components/text-overflow-layout/Index.vue';
interface ModelValue {
spec_id: number,
capacity: number | string,
Expand All @@ -84,10 +86,11 @@
const { t } = useI18n();
const specRef = ref();
const specs = shallowRef<ClusterSpecModel[]>([]);
const renderSpecs = shallowRef<ClusterSpecModel[]>([]);
const isLoading = ref(false);
const countMap = shallowRef({} as Record<number, number>)
const isTendisCache = computed(() => props.clusterType === ClusterTypes.TWEMPROXY_REDIS_INSTANCE);
const targetCapacityTitle = computed(() => (isTendisCache.value ? t('集群容量需求(内存容量)') : t('集群容量需求(磁盘容量)')));
Expand All @@ -97,20 +100,33 @@
{
field: 'spec_name',
label: t('资源规格'),
width: 300,
showOverflowTooltip: false,
render: ({ data, index }: { data: ClusterSpecModel, index: number }) => (
<bk-radio
v-model={modelValue.value.spec_id}
label={data.spec_id}
kye={index}
class="spec-radio">
<div
class="text-overflow"
v-overflow-tips>
{data.spec_name}
</div>
</bk-radio>
),
<TextOverflowLayout>
{{
default: () => (
<bk-radio
v-model={modelValue.value.spec_id}
label={data.spec_id}
key={index}
class="spec-radio">
{data.spec_name}
</bk-radio>
),
append: () => (
(countMap.value[data.spec_id] || 0) < data.machine_pair && (
<bk-tag
class='ml-6'
size="small"
theme="danger">
{t('资源不足')}
</bk-tag>
)
)
}}
</TextOverflowLayout>
),
},
{
field: 'machine_pair',
Expand All @@ -130,6 +146,7 @@
{
field: 'count',
label: t('可用主机数'),
render: ({ data }: { data: ClusterSpecModel }) => countMap.value[data.spec_id] || 0
},
];
Expand Down Expand Up @@ -173,7 +190,6 @@
const resetSlider = () => {
specs.value = [];
renderSpecs.value = [];
};
const fetchFilterClusterSpec = () => {
Expand All @@ -192,14 +208,13 @@
})
.then((res) => {
specs.value = res;
renderSpecs.value = res;
})
.catch(() => {
specs.value = [];
renderSpecs.value = [];
})
.finally(() => {
isLoading.value = false;
countMap.value = {}
});
};
Expand Down Expand Up @@ -241,10 +256,7 @@
bk_cloud_id: Number(props.cloudId),
spec_ids: specs.value.map(item => item.spec_id),
}).then((data) => {
renderSpecs.value = specs.value.map(item => ({
...item,
count: data[item.spec_id] ?? 0,
}));
countMap.value = data
});
}, 100);
Expand Down Expand Up @@ -276,15 +288,16 @@
:deep(.spec-radio) {
max-width: 100%;
overflow: hidden;
display: flex;
.bk-radio-input {
flex-shrink: 0;
width: 16px;
}
.bk-radio-label {
flex: 1;
overflow: hidden;
font-size: 12px;
}
}
Expand Down
2 changes: 1 addition & 1 deletion dbm-ui/frontend/src/components/apply-items/RegionItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@
getValue() {
return {
cityCode: state.cityCode,
cityName: state.cityCode,
cityName: state.cityName || '',
};
},
});
Expand Down
58 changes: 53 additions & 5 deletions dbm-ui/frontend/src/components/instance-selector/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@
} from '@services/source/instances';
import { getMongoInstancesList, getMongoTopoList } from '@services/source/mongodb';
import { queryClusters as getMysqlClusterList , queryClusters as queryMysqlCluster } from '@services/source/mysqlCluster';
import { getRedisClusterList } from '@services/source/redis';
import { getRedisClusterList , getRedisMachineList } from '@services/source/redis';
import { getRedisHostList } from '@services/source/redisToolbox';
import { getSpiderInstanceList, getSpiderMachineList } from '@services/source/spider';
import { getTendbhaInstanceList } from '@services/source/tendbha';
Expand All @@ -198,6 +198,7 @@
import MongoClusterContent from './components/mongo/Index.vue';
import MysqlContent from './components/mysql/Index.vue';
import RedisContent from './components/redis/Index.vue';
import RenderRedisHost from './components/redis-host/Index.vue';
import TendbClusterContent from './components/tendb-cluster/Index.vue';
import TendbClusterHostContent from './components/tendb-cluster-host/Index.vue';

Expand Down Expand Up @@ -233,7 +234,7 @@
manualConfig?: {
checkType: 'ip' | 'instance',
checkKey: keyof IValue,
activePanelId?: string
activePanelId?: string,
checkInstances?: (params: any) => Promise<any[] | ListBase<any[]>>,
},
previewConfig?: {
Expand All @@ -250,7 +251,7 @@
type RedisHostModel = ServiceReturnType<typeof getRedisHostList>['results'][number]

interface Props {
clusterTypes: (ClusterTypes | 'TendbClusterHost')[],
clusterTypes: (ClusterTypes | 'TendbClusterHost' | 'RedisHost')[],
tabListConfig?: Record<string, PanelListType>,
selected?: InstanceSelectorValues<T>,
}
Expand Down Expand Up @@ -526,6 +527,55 @@
content: ManualInputHostContent,
},
],
RedisHost: [
{
id: 'RedisHost',
name: t('主库主机'),
topoConfig: {
getTopoList: getRedisClusterList,
countFunc: (clusterItem: { redis_master: { ip: string }[]}) => {
const ipList = clusterItem.redis_master.map(hostItem => hostItem.ip)
return new Set(ipList).size
}
},
tableConfig: {
getTableList: getRedisMachineList,
firsrColumn: {
label: t('主库主机'),
field: 'ip',
role: 'redis_master',
},
columnsChecked: ['ip', 'cloud_area', 'alive', 'host_name', 'os_name']
},
previewConfig: {
displayKey: 'ip',
},
content: RenderRedisHost,
},
{
id: 'manualInput',
name: t('手动输入'),
tableConfig: {
getTableList: getRedisMachineList,
firsrColumn: {
label: t('主库主机'),
field: 'ip',
role: 'redis_master',
},
columnsChecked: ['ip', 'cloud_area', 'alive', 'host_name', 'os_name']
},
manualConfig: {
checkInstances: getRedisMachineList,
checkType: 'ip',
checkKey: 'ip',
activePanelId: 'RedisHost',
},
previewConfig: {
displayKey: 'ip',
},
content: ManualInputHostContent,
},
],
};

const panelTabActive = ref<string>('');
Expand Down Expand Up @@ -654,7 +704,5 @@
padding: 8px 16px 8px;
}
}


}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,28 @@
import type { SearchAttrs } from '@hooks';
export type SearchSelectList = {
id: string,
name: string,
id: string;
name: string;
children?: {
id: string | number,
name: string,
}[]
}[]
id: string | number;
name: string;
}[];
}[];
interface Props {
searchAttrs: SearchAttrs,
validateSearchValues: ValidateValuesFunc,
type?: string,
searchAttrs: SearchAttrs;
validateSearchValues: ValidateValuesFunc;
type?: string;
isHost?: boolean;
}
interface Emits {
(e: 'searchValueChange', value: ISearchValue[]): void,
(e: 'searchValueChange', value: ISearchValue[]): void;
}
const props = withDefaults(defineProps<Props>(), {
type: '',
isHost: false,
});
const emits = defineEmits<Emits>();
Expand All @@ -45,13 +47,13 @@
const { t } = useI18n();
const isHideStatus = computed(() => props.type && props.type === 'redis');
const isHideStatus = computed(() => (props.type && props.type === 'redis') || props.isHost);
const searchSelectData = computed(() => {
const basicSelct = [
{
name: t('IP 或 IP:Port'),
id: 'instance',
name: props.isHost ? 'IP' : t('IP 或 IP:Port'),
id: props.isHost ? 'ip' : 'instance',
multiple: true,
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
<RenderManualHost
:active-panel-id="manualConfig.activePanelId"
:firsr-column="firsrColumn"
:get-table-list="getTableList"
is-manul
:last-values="lastValues"
:manual-table-data="inputState.tableData"
Expand Down Expand Up @@ -115,6 +116,7 @@
tableSetting: TableSetting,
firsrColumn?: TableConfigType['firsrColumn'],
statusFilter?: TableConfigType['statusFilter'],
getTableList: NonNullable<TableConfigType['getTableList']>;
}

interface Emits {
Expand Down
Loading

0 comments on commit 4ab03ae

Please sign in to comment.