機(jī)器學(xué)習(xí)平臺(tái)在Kubernetes上的實(shí)踐
背景
過去音樂算法的模型訓(xùn)練任務(wù),是在物理機(jī)上進(jìn)行開發(fā)、調(diào)試以及定時(shí)調(diào)度。每個(gè)算法團(tuán)隊(duì)使用屬于自己的獨(dú)立物理機(jī),這種現(xiàn)狀會(huì)造成一些問題。比如物理機(jī)的分布零散,缺乏統(tǒng)一的管理,主要依賴于doc文檔的表格記錄機(jī)器的使用與歸屬;各業(yè)務(wù)間機(jī)器資源的調(diào)配,有時(shí)需要機(jī)器在不同機(jī)房的搬遷,耗時(shí)耗力。另外,由于存在多人共用、開發(fā)與調(diào)度任務(wù)共用等情況,會(huì)造成環(huán)境的相互影響,以及資源的爭(zhēng)奪。針對(duì)當(dāng)前的情況,總結(jié)問題如下:
- 資源利用率低:部分機(jī)器資源利用率偏低;無法根據(jù)各個(gè)業(yè)務(wù)的不同階段,在全局內(nèi)快速、動(dòng)態(tài)的實(shí)現(xiàn)擴(kuò)縮容,以達(dá)到資源的合理配置,提升資源整體利用率;
- 環(huán)境相互影響:存在多人共用、測(cè)試與調(diào)度混用同一開發(fā)機(jī),未做任何的隔離,造成可能的環(huán)境、共享資源的相互影響與爭(zhēng)奪;
- 監(jiān)控報(bào)警缺失:物理機(jī)模式,任務(wù)監(jiān)控報(bào)警功能缺失,導(dǎo)致任務(wù)無法運(yùn)維,或者效率低。
資源沒有全局統(tǒng)一的合理調(diào)配,會(huì)出現(xiàn)負(fù)載不均衡,資源不能最大化的利用。
Kubernetes的嘗試
在快速的擴(kuò)縮容、環(huán)境隔離、資源監(jiān)控等方面,Kubernetes及其相關(guān)擴(kuò)展,可以很好的解決問題?,F(xiàn)將物理機(jī)集中起來,并構(gòu)建成一個(gè)Kubernetes集群。通過分析算法同事以往的工作方式,機(jī)器學(xué)習(xí)平臺(tái)(GoblinLab)決定嘗試基于Kubernetes提供在線的開發(fā)調(diào)試容器環(huán)境以及任務(wù)的容器化調(diào)度兩種方案,其分別針對(duì)任務(wù)開發(fā)和任務(wù)調(diào)度兩種場(chǎng)景。
任務(wù)開發(fā)
為最大化的減少算法同事由物理機(jī)遷移到容器化環(huán)境的學(xué)習(xí)成本,GoblinLab系統(tǒng)中基本將Kubernetes的容器當(dāng)做云主機(jī)使用。容器的鏡像以各版本Tensoflow鏡像為基礎(chǔ)(底層是Ubuntu),集成了大數(shù)據(jù)開發(fā)環(huán)境(Hadoop、Hive、Spark等Client),安裝了常用的軟件。另外,為了方便使用,容器環(huán)境提供了Jupyter Lab、SSH登錄、Code Server(VSCode)三種使用方式。
在GoblinLab中新建容器化開發(fā)環(huán)境比較簡(jiǎn)單,只需選擇鏡像,填寫所需的資源,以及需要掛載的外部存儲(chǔ)即可(任務(wù)開發(fā)的環(huán)境下文簡(jiǎn)稱開發(fā)實(shí)例)。
新建環(huán)境配置后,點(diǎn)擊啟動(dòng)實(shí)例,容器初始化時(shí),會(huì)自動(dòng)啟動(dòng)Jupyter lab、SSH以及CodeServer。
Jupyter Lab:
Code Server:
SSH登錄:
算法可以選擇以上任意一種方式進(jìn)行任務(wù)的開發(fā),或者調(diào)試。由于提供了Code Server(VSCode),所以可以獲得更好的體驗(yàn)。
任務(wù)開發(fā)所用的容器化環(huán)境,在底層Kubernetes上是通過StatefulSet類型實(shí)現(xiàn),對(duì)應(yīng)資源編排文件如下(已精簡(jiǎn)細(xì)節(jié)):
- kind: StatefulSet
- apiVersion: apps/v1
- metadata:
- name: ${name}
- namespace: "${namespace}"
- spec:
- replicas: 1
- selector:
- matchLabels:
- statefulset: ${name}
- system/app: ${name}
- template:
- spec:
- <#if (gpu > 0)>
- tolerations:
- - effect: NoSchedule
- key: nvidia.com/gpu
- value: "true"
- </#if>
- <#if usePrivateRepository == "true">
- imagePullSecrets:
- - name: registrykey-myhub
- </#if>
- volumes:
- - name: localtime
- hostPath:
- path: /etc/localtime
- <#if MountPVCs?? && (MountPVCs?size > 0)>
- <#list MountPVCs?keys as key>
- - name: "${key}"
- persistentVolumeClaim:
- claimName: "${key}"
- </#list>
- containers:
- - name: notebook
- image: ${image}
- imagePullPolicy: IfNotPresent
- volumeMounts:
- - name: localtime
- mountPath: /etc/localtime
- <#if readMountPVCs?? && (readMountPVCs?size > 0)>
- <#list readMountPVCs?keys as key>
- - name: "${key}"
- mountPath: "${readMountPVCs[key]}"
- readOnly: true
- </#list>
- </#if>
- <#if writeMountPVCs?? && (writeMountPVCs?size > 0)>
- <#list writeMountPVCs?keys as key>
- - name: "${key}"
- mountPath: "${writeMountPVCs[key]}"
- </#list>
- </#if>
- env:
- - name: NOTEBOOK_TAG
- value: "${name}"
- - name: HADOOP_USER
- value: "${hadoopUser}"
- - name: PASSWORD
- value: "${password}"
- resources:
- requests:
- cpu: ${cpu}
- memory: ${memory}Gi
- <#if (gpu > 0)>
- nvidia.com/gpu: ${gpu}
- </#if>
- limits:
- cpu: ${cpu}
- memory: ${memory}Gi
- <#if (gpu > 0)>
- nvidia.com/gpu: ${gpu}
- </#if>
目前GolbinLab已提供基于Tensoflow各版本的CPU與GPU通用鏡像11個(gè),以及多個(gè)定制化鏡像。
任務(wù)調(diào)度
算法同事在使用容器化環(huán)境之前,任務(wù)的開發(fā)調(diào)度都是在GPU物理機(jī)器上完成,調(diào)度一般都是通過定時(shí)器或crontab命令調(diào)度任務(wù),任務(wù)無失敗、超時(shí)等報(bào)警,以及也沒有重試等機(jī)制,基本無相關(guān)的任務(wù)運(yùn)維工具。
在介紹容器中開發(fā)的任務(wù)如何上線調(diào)度之前,先簡(jiǎn)要介紹一下GoblinLab的系統(tǒng)架構(gòu)。
上圖為GoblinLab簡(jiǎn)化的系統(tǒng)架構(gòu),其中主要分為四層,由上到下分別為:
- Application-應(yīng)用層:提供直接面向用戶的機(jī)器學(xué)習(xí)開發(fā)平臺(tái)(GoblinLab)
- Middle-中間層: 中間層,主要是接入了統(tǒng)一的調(diào)度、報(bào)警、以及配置等服務(wù)
- Wizard-執(zhí)行服務(wù): 其提供統(tǒng)一的執(zhí)行服務(wù),提供包含Kubernetes、Spark、Jar等各類任務(wù)的提交執(zhí)行。插件式,支持快速擴(kuò)展
- Infrastructure-基礎(chǔ)設(shè)施: 底層的基礎(chǔ)設(shè)施,主要包含Kubernetes集群、Spark集群以及普通服務(wù)器等
GolbinLab為了保障調(diào)度任務(wù)的穩(wěn)定性,將任務(wù)的開發(fā)與調(diào)度拆分,改變之前算法直接在物理機(jī)上開發(fā)完任務(wù)后,通過定時(shí)器或者crontab調(diào)度任務(wù)的方式。如上圖所示,在開發(fā)完成后,任務(wù)的調(diào)度是通過任務(wù)流中的容器化任務(wù)調(diào)度組件實(shí)現(xiàn),用戶需填組件的相關(guān)參數(shù)(代碼所在PVC及路徑,配置鏡像等),再通過任務(wù)流的調(diào)度功能實(shí)現(xiàn)任務(wù)調(diào)度。與任務(wù)開發(fā)不同,每個(gè)調(diào)度任務(wù)執(zhí)行在獨(dú)立的容器中,保證任務(wù)間相互隔離,同時(shí)通過后續(xù)介紹的資源隔離方案,可以優(yōu)先保障線上調(diào)度任務(wù)所需資源。
任務(wù)調(diào)度執(zhí)行的一般流程如下:
任務(wù)調(diào)度執(zhí)行時(shí)在Kubernetes上資源編排文件(已精簡(jiǎn)細(xì)節(jié)):
- apiVersion: batch/v1
- kind: Job
- metadata:
- name: ${name}
- namespace: ${namespace}
- spec:
- template:
- spec:
- containers:
- - name: jupyter-job
- image: ${image}
- env:
- - name: ENV_TEST
- value: ${envTest}
- command: ["/bin/bash", "-ic", "cd ${workDir} && \
- ${execCommand} /root/${entryPath} ${runArgs}"]
- volumeMounts:
- - mountPath: "/root"
- name: "root-dir"
- resources:
- requests:
- cpu: ${cpu}
- memory: ${memory}Gi
- <#if (gpu > 0)>
- nvidia.com/gpu: ${gpu}
- </#if>
- limits:
- cpu: ${cpu}
- memory: ${memory}Gi
- <#if (gpu > 0)>
- nvidia.com/gpu: ${gpu}
- </#if>
- volumes:
- - name: "root-dir"
- persistentVolumeClaim:
- claimName: "${pvc}"
- backoffLimit: 0
權(quán)限控制
容器化開發(fā)環(huán)境配置啟動(dòng)后,用戶可以通過SSH登錄、CodeServer或JupyterLab等其中一種方式使用。為了避免容器化開發(fā)環(huán)境被其他人使用,GoblinLab給每種方式都設(shè)置了統(tǒng)一的密鑰,而密鑰在每次啟動(dòng)時(shí)隨機(jī)生成。
1、隨機(jī)生成密碼
2、設(shè)置賬號(hào)密碼(SSH登錄密碼)
- echo "root:${password}" | chpasswd
3、設(shè)置Code Server密碼 (VSCode)
- #設(shè)置環(huán)境變量PASSWORD即可
- env:
- - name: PASSWORD
- value: "${password}"
4、設(shè)置Jupyter Lab密碼
- jupyter notebook --generate-config,~/.jupyter 目錄下生成jupyter_notebook_config.py,并添加代碼
- import os
- from IPython.lib import passwd
- c = c # pylint:disable=undefined-variable
- c.NotebookApp.ip = '0.0.0.0' # https://github.com/jupyter/notebook/issues/3946 c.NotebookApp.port = int(os.getenv('PORT', 8888)) c.NotebookApp.open_browser = False
- sets a password if PASSWORD is set in the environment
- if 'PASSWORD' in os.environ:
- password = os.environ['PASSWORD']
- if password:
- c.NotebookApp.password = passwd(password)
- else:
- c.NotebookApp.password = ''
- c.NotebookApp.token = ''
- del os.environ['PASSWORD']
數(shù)據(jù)持久化
在Kubernetes容器中,如無特殊配置,容器中的數(shù)據(jù)是沒有進(jìn)行持久化,這意味著隨著容器的刪除或者重啟,數(shù)據(jù)就會(huì)丟失。對(duì)應(yīng)的解決方法比較簡(jiǎn)單,只需給需要持久化的目錄,掛載外部存儲(chǔ)即可。在GoblinLab中,會(huì)給每個(gè)用戶自動(dòng)創(chuàng)建一個(gè)默認(rèn)的外部存儲(chǔ)PVC,并掛載到容器的/root目錄。另外,用戶也可以自定義外部存儲(chǔ)的掛載。
除了自動(dòng)創(chuàng)建的PVC外,用戶也可以自己創(chuàng)建PVC,并支持將創(chuàng)建的PVC只讀或者讀寫分享給其他人。
另外,在Goblinlab上也可以對(duì)PVC里的數(shù)據(jù)進(jìn)行管理。
服務(wù)暴露
Kubernetes集群中創(chuàng)建的服務(wù),在集群外無法直接訪問,GoblinLab使用Nginx Ingress + Gateway訪問,將集群內(nèi)的服務(wù)暴露到外部。
容器化開發(fā)環(huán)境的Service資源編排文件如下(已精簡(jiǎn)細(xì)節(jié)):
- apiVersion: v1
- kind: Service
- metadata:
- name: ${name}
- namespace: ${namespace}
- spec:
- clusterIP: None
- ports:
- - name: port-notebook
- port: 8888
- protocol: TCP
- targetPort: 8888
- - name: port-sshd
- port: 22
- protocol: TCP
- targetPort: 22
- - name: port-vscode
- port: 8080
- protocol: TCP
- targetPort: 8080
- - name: port-tensofboard
- port: 6006
- protocol: TCP
- targetPort: 6006
- <#if ports?? && (ports?size > 0)>
- <#list ports as port>
- - name: port-${port}
- port: ${port}
- targetPort: ${port}
- </#list>
- </#if>
- selector:
- statefulset: ${name}
- type: ClusterIP
每當(dāng)用戶啟動(dòng)一個(gè)容器化開發(fā)環(huán)境,GoblinLab將通過接口自動(dòng)修改Nginx Ingress配置,將服務(wù)暴露出來,以供用戶使用,Ingress轉(zhuǎn)發(fā)配置如下:
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: tcp-services
- namespace: kube-system
- data:
- "20000": ns/notebook-test:8888
- "20001": ns/notebook-test:8080
- "20002": ns/notebook-test:22
資源管控
為提高資源的利用率,GoblinLab底層Kubernetes中的資源,基本都是以共享的方式使用,并進(jìn)行一定比例的超售。但是當(dāng)多個(gè)團(tuán)隊(duì)共享一個(gè)資源總量固定的集群時(shí),為了確保每個(gè)團(tuán)隊(duì)公平的共享資源,此時(shí)需要對(duì)資源進(jìn)行管理和控制。在Kubernetes中,資源配額就是解決此問題的工具。目前GoblinLab需要管控的資源主要為CPU、內(nèi)存、GPU以及存儲(chǔ)等。平臺(tái)在考慮各個(gè)團(tuán)隊(duì)的實(shí)際需求后,將資源劃分為多個(gè)隊(duì)列(Kubernetes中的概念為namespace),提供給各個(gè)團(tuán)隊(duì)使用。
- apiVersion: v1
- kind: ResourceQuota
- metadata:
- name: skiff-quota
- namespace: test
- spec:
- hard:
- limits.cpu: "2"
- limits.memory: 5Gi
- requests.cpu: "2"
- requests.memory: 5Gi
- requests.nvidia.com/gpu: "1"
- requests.storage: 10Gi
在集群中,最常見的資源為CPU與內(nèi)存,由于可以超售(overcommit),所以存在limits與requests兩個(gè)配額限制。除此以外,其他資源為擴(kuò)展類型,由于不允許overcommit,所以只有requests配額限制。參數(shù)說明:
- limits.cpu:Across all pods in a non-terminal state, the sum of CPU limits cannot exceed this value.
- limits.memory: Across all pods in a non-terminal state, the sum of memory limits cannot exceed this value.
- requests.cpu:Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value.
- requests.memory:Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value.
- http://requests.nvidia.com/gpu:Across all pods in a non-terminal state, the sum of gpu requests cannot exceed this value.
- requests.storage:Across all persistent volume claims, the sum of storage requests cannot exceed this value.
可以進(jìn)行配額控制的資源不僅有CPU、內(nèi)存、存儲(chǔ)、GPU,其他類型參見官方文檔:https://kubernetes.io/docs/con ... otas/
資源隔離
GoblinLab的資源隔離,指的是在同一Kubernetes集群中,資源在調(diào)度層面的相對(duì)隔離,其中包含GPU機(jī)器資源的隔離、線上與測(cè)試任務(wù)的隔離。
GPU機(jī)器資源的隔離
在Kubernetes集群中,相對(duì)于CPU機(jī)器,GPU機(jī)器資源較為珍貴,因此為了提供GPU的利用率,禁止CPU任務(wù)調(diào)度在GPU機(jī)器上。
GPU節(jié)點(diǎn)設(shè)置污點(diǎn)(Taint):禁止一般任務(wù)調(diào)度在GPU節(jié)點(diǎn)
- key: nvidia.com/gpu
- value: true
- effect: NoSchedule
Taint的effect可選配置:
- NoSchedule:Pod不會(huì)被調(diào)度到標(biāo)記為taints節(jié)點(diǎn)。
- PreferNoSchedule:NoSchedule的軟策略版本。盡量避免將Pod調(diào)度到存在其不能容忍taint的節(jié)點(diǎn)上。
- NoExecute:該選項(xiàng)意味著一旦Taint生效,如該節(jié)點(diǎn)內(nèi)正在運(yùn)行的Pod沒有對(duì)應(yīng)Tolerate設(shè)置,會(huì)直接被逐出。
GPU任務(wù)設(shè)置容忍(Toleration):讓GPU任務(wù)可以調(diào)度在GPU節(jié)點(diǎn)
- <#if (gpu > 0)>
- tolerations:
- - effect: NoSchedule
- key: nvidia.com/gpu
- value: "true"
- </#if>
線上與測(cè)試任務(wù)隔離
線上與測(cè)試任務(wù)(GolbinLab中線上任務(wù)與測(cè)試任務(wù)為業(yè)務(wù)層面的定義,指的是周期調(diào)度任務(wù)和開發(fā)測(cè)試任務(wù))使用同一Kubernetes集群,但為了保障線上任務(wù)的資源,會(huì)特殊設(shè)置一些機(jī)器節(jié)點(diǎn)為線上任務(wù)的專有資源池。線上任務(wù)執(zhí)行時(shí)優(yōu)先調(diào)度在線上節(jié)點(diǎn)上,線上資源池?zé)o資源時(shí),也可調(diào)度于非線上節(jié)點(diǎn)。
線上資源池節(jié)點(diǎn)設(shè)置污點(diǎn)(Taint):禁止一般任務(wù)調(diào)度在線上資源池
- key: node.netease.com/node-pool
- value: online
- effect: NoSchedule
線上任務(wù)添加容忍(Toleration):允許線上任務(wù)調(diào)度于線上資源池,但不是必須調(diào)度于線上資源池中
- tolerations:
- - effect: NoSchedule
- key: node.netease.com/node-pool
- value: "online"
- operator: Equal
線上資源池中機(jī)器節(jié)點(diǎn)設(shè)置標(biāo)簽 + 線上任務(wù)設(shè)置節(jié)點(diǎn)親和性(nodeAffinity):優(yōu)先將線上任務(wù)調(diào)度在線上資源池中,但如果線上資源池中無已資源,此時(shí)也可以調(diào)度在其他節(jié)點(diǎn)上
線上資源池中節(jié)點(diǎn)設(shè)置標(biāo)簽:為了方便,標(biāo)簽與污點(diǎn)同名:
- node.netease.com/node-pool: online
線上任務(wù)設(shè)置節(jié)點(diǎn)親和性(nodeAffinity):線上任務(wù)優(yōu)先調(diào)度在線上資源池中
- affinity:
- nodeAffinity:
- preferredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: node.netease.com/node-pool
- operator: In
- values:
- - online
目前Node affinity有以下幾種策略,官方文檔affinity-and-anti-affinity:
- requiredDuringSchedulingIgnoredDuringExecution表示Pod必須部署到滿足條件的節(jié)點(diǎn)上,如果沒有滿足條件的節(jié)點(diǎn),就不停重試。其中IgnoreDuringExecution表示Pod部署之后運(yùn)行的時(shí)候,如果節(jié)點(diǎn)標(biāo)簽發(fā)生了變化,不再滿足Pod指定的條件,Pod也會(huì)繼續(xù)運(yùn)行。
- requiredDuringSchedulingRequiredDuringExecution表示Pod必須部署到滿足條件的節(jié)點(diǎn)上,如果沒有滿足條件的節(jié)點(diǎn),就不停重試。其中RequiredDuringExecution表示Pod部署之后運(yùn)行的時(shí)候,如果節(jié)點(diǎn)標(biāo)簽發(fā)生了變化,不再滿足Pod指定的條件,則重新選擇符合要求的節(jié)點(diǎn)。
- preferredDuringSchedulingIgnoredDuringExecution表示優(yōu)先部署到滿足條件的節(jié)點(diǎn)上,如果沒有滿足條件的節(jié)點(diǎn),就忽略這些條件,按照正常邏輯部署。
- preferredDuringSchedulingRequiredDuringExecution表示優(yōu)先部署到滿足條件的節(jié)點(diǎn)上,如果沒有滿足條件的節(jié)點(diǎn),就忽略這些條件,按照正常邏輯部署。其中RequiredDuringExecution表示如果后面節(jié)點(diǎn)標(biāo)簽發(fā)生了變化,滿足了條件,則重新調(diào)度到滿足條件的節(jié)點(diǎn)。
策略生效后效果如下圖所示, 線上任務(wù)優(yōu)先執(zhí)行與線上資源池節(jié)點(diǎn)中,但當(dāng)線上資源池沒有空閑資源后,線上任務(wù)Job5也可以去使用普通節(jié)點(diǎn)的資源。
階段性結(jié)果
截止今日,音樂機(jī)器學(xué)習(xí)平臺(tái)(GoblinLab)在容器化方面的嘗試,已開展了一段時(shí)間,并且已經(jīng)有了階段性的成果。
集群建設(shè)
經(jīng)過近一段時(shí)間的嘗試,目前音樂數(shù)據(jù)平臺(tái)的Kubernetes,隨著承載的業(yè)務(wù)越來越多,以及基于Kubernetes的大數(shù)據(jù)計(jì)算平臺(tái)(Flink等)的落地,后續(xù)將有大量的CPU資源加入, 其穩(wěn)定性將會(huì)成為比較大的挑戰(zhàn)。
用戶使用
- 任務(wù)遷移:目前協(xié)助算法同事已完成80%任務(wù)遷移
任務(wù)開發(fā)
- 用戶情況 : 已有60%算法同學(xué)使用開發(fā)實(shí)例的容器化環(huán)境;其中用戶來源包含音樂推薦算法、社交視頻推薦算法、搜索算法、音視頻、數(shù)據(jù)應(yīng)用、實(shí)時(shí)計(jì)算算法等團(tuán)隊(duì)
- 開發(fā)實(shí)例:平臺(tái)鼓勵(lì)組內(nèi)共用開發(fā)實(shí)例,限制了每人最多創(chuàng)建3個(gè)開發(fā)實(shí)例
- 任務(wù)調(diào)度: 覆蓋云音樂音樂推薦、社交視頻推薦算法、搜索算法、音視頻、數(shù)據(jù)應(yīng)用、實(shí)時(shí)計(jì)算算法等多個(gè)團(tuán)隊(duì)
容器化的好處
對(duì)于算法同事,由物理機(jī)遷移到機(jī)器學(xué)習(xí)平臺(tái)提供容器化的環(huán)境,能夠帶來的好處是:
- 更多資源:由于整理資源利用率的提高,將有機(jī)會(huì)獲取到比之前單獨(dú)使用物理機(jī)更多的資源;另外資源擴(kuò)縮容的周期由之前的以天為單位減少到秒級(jí)別即可完成
- 更好體驗(yàn):通過打通大數(shù)據(jù)、Git環(huán)境,提供多樣化的使用方式(SSH和在線IDE),由機(jī)器學(xué)習(xí)平臺(tái)統(tǒng)一維護(hù)環(huán)境鏡像,避免了每個(gè)團(tuán)隊(duì)需自己搭建、運(yùn)維環(huán)境的苦惱
- 更完善的任務(wù)調(diào)度:GoblinLab的調(diào)度,提供了更完善的報(bào)警、重試、依賴檢查等功能,并且能夠與之前已有PS、Ironbaby任務(wù)的整合,實(shí)現(xiàn)在一個(gè)任務(wù)流的統(tǒng)一調(diào)度
- 更好的隔離:環(huán)境隔離是容器化的天然優(yōu)勢(shì)。另外資源在調(diào)度層面的隔離,可以更好的保障線上任務(wù)
- 統(tǒng)一的入口:統(tǒng)一了開發(fā)的入口后,可以有更大的操作空間。例如將通用的服務(wù)抽象后由平臺(tái)直接提供(依賴檢查、調(diào)度、報(bào)警監(jiān)控等等)、數(shù)據(jù)的共享、鏡像的更新以及后面持續(xù)的支持服務(wù)等
后續(xù)規(guī)劃
目前音樂機(jī)器學(xué)習(xí)平臺(tái)已能提供完整的容器化開發(fā)基礎(chǔ)能力,為進(jìn)一步提高集群的資源利用率、提升運(yùn)維效率,后續(xù)計(jì)劃從資源調(diào)度策略優(yōu)化(搶占等)、更豐富的資源監(jiān)控等方面入手,進(jìn)一步優(yōu)化。
作者:網(wǎng)易云音樂數(shù)據(jù)智能部數(shù)據(jù)平臺(tái)組王軍正