一周玩轉云原生技術之volcano【與云原生的故事】

      網友投稿 1491 2025-03-31

      本文的主要內容有:


      一 Volcano能干啥

      二 基本的名詞

      三 如何快速部署

      四 Volcano產生的背景

      五 場景下如何細分

      六 功能是有哪些

      一 Volcano能干啥

      現(xiàn)在 Volcano 已支持很多流行的計算框架,并源于華為云AI容器,能方便AI、大數(shù)據(jù)、基因、渲染等諸多行業(yè)通用計算框架接入,具體就是Spark、TensorFlow、PyTorch、Flink、Argo、MindSpore和PaddlePaddle,不僅包括了作業(yè)調度,還包含作業(yè)生命周期管理、多集群調度、命令行、數(shù)據(jù)管理、作業(yè)視圖及硬件加速等功能,它還支持不同架構的計算調度,譬如x86、Arm、鯤鵬等都是可以兼容。

      二 基本的名詞

      Queue

      一周玩轉云原生技術之volcano【與云原生的故事】

      隊列,Cluster級別的一種資源對象,可聲明資源配額,由多namespace共享,提供soft isolation

      Job

      一種批量計算作業(yè),支持定義作業(yè)所屬隊列,生命周期策略、所包含的任務模板以及持久卷等信息

      PodGroup

      任務組,與queue綁定,占用隊列的資源;與Volcano Job是1:1的關系,主要是供 schedule調度時使用的

      Command

      支持外部干預運行中的作業(yè),作用對象是Volcano Job

      三 如何快速部署

      部署Volcano的最簡單方法是用Helm這個工具,或可以通過克隆代碼來部署Volcano

      1、那我們用Volcano Helm Repo這個工具

      使用以下命令添加helm repo

      helm repo add volcano https://volcano-sh.github.io/charts

      然后使用以下命令安裝Volcano

      helm install volcano/volcano --namespace --name

      譬如

      helm install volcano/volcano --namespace volcano-trial --name volcano-trial

      2、克隆代碼

      1]、先決條件

      首先,把repo克隆到本地路徑上面來

      # mkdir -p $GOPATH/src/volcano.sh/ # cd $GOPATH/src/volcano.sh/ # git clone --recursive https://github.com/volcano-sh/volcano.git

      2]、Volcano Image

      DockerHub上提供了官方images,但可以使用以下命令在本地創(chuàng)建它們

      cd $GOPATH/src/volcano.sh/volcano make images ## Verify your images # docker images

      敲黑板:需要確保在kubernetes集群中正確加載images,例如,如果使用的是類型集群,請嘗試為每個images 用如下命令kind load docker-image :

      3]、Helm charts

      其次,是安裝helm這個工具

      helm install installer/helm/chart/volcano --namespace --name

      譬如:

      helm install installer/helm/chart/volcano --namespace volcano-trial --name volcano-trial

      若要驗證安裝,請運行下面命令

      #1. Verify the Running Pods # kubectl get pods --namespace #2. Verify the Services # kubectl get services --namespace

      四 Volcano產生的背景

      上圖是我們做的一個分析,我們將其分為三層,最下面是資源管理層,中間為領域的框架,包括AI的體系、HPC、Batch, WKflow的管理以及像現(xiàn)在的一些微服務及流量治理等。再往上是行業(yè)以及一些行業(yè)的應用。

      隨著一些行業(yè)的應用變得復雜,它對所需求的解決方案的要求也越來越高。舉個例子在10多年以前,在金融行業(yè)提供解決方案時,它的架構是非常簡單的,可能需要一個數(shù)據(jù)庫,一個ERP的中間件,就可以解決銀行大部分的業(yè)務。

      而現(xiàn)在,每天要收集大量的數(shù)據(jù),需要spark去做數(shù)據(jù)分析,甚至需要一些數(shù)據(jù)湖的產品去建立數(shù)據(jù)倉庫,然后去做分析,產生報表。同時它還會用 AI的一些系統(tǒng),來簡化業(yè)務流程等。

      所以,現(xiàn)在的一些行業(yè)應用與10年前比,變得很復雜,它可能會應用到下面這些領域框架里面的一個或多個,其實對于行業(yè)應用,它的需求是在多個領域框架作為一個融合,領域框架的訴求是下面的資源管理層能夠提供統(tǒng)一的資源管理。

      K8s現(xiàn)在越來越多的承載了統(tǒng)一的資源管理的角色,它可以為HPC這些行業(yè)領域框架提供服務,也可以作為大數(shù)據(jù)領域的資源管理層。Volcano主要是基于Kubernetes做的一個批處理系統(tǒng),希望上層的HPC、中間層大數(shù)據(jù)的應用以及最下面一層AI能夠在統(tǒng)一Kubernetes上面運行的更高效。

      六 場景下如何細分

      而在調度方面,Volcano 又對場景進行了細分以及歸類,并提供了相關的方案及算法;同時也為這些功能提供了調度框架,方便用戶對調度器進行擴展。那么對于分布式計算或者說并行計算來說,根據(jù)場景和作業(yè)屬性的不同,也可以對其進行細分;在 《并行計算導論》 中將并行計算簡單分成三類:

      簡單的并行

      指的是多個子任務(tasks)之間沒有通信也不需要同步,可以完全的并行的執(zhí)行。比較典型的例子應該就屬MapReduce了,它的兩個階段都屬于這種類型:mapper任務在執(zhí)行時并不會彼此通信同步運行狀態(tài);另一個常見的例子是蒙特·卡羅方法 ,各個子任務在計算隨機數(shù)時也無需彼此通信、同步。由于這種并行計算有比較廣泛的應用,例如 數(shù)據(jù)處理、VatR 等,針對不同的場景也產生了不同的調度框架,例如 Hadoop、DataSynapse 和 Symphony。敲黑板了哈,由于子任務之間無需信息和同步,當其中某幾個計算節(jié)點(workers)被驅逐后,雖然作業(yè)的執(zhí)行時間可能會變長,但整個作業(yè)仍可以順利完成;而當計算節(jié)點增加時,作業(yè)的執(zhí)行時間一般都會縮短。因此,這種作業(yè)也常常被稱作 Elastic Job。

      復雜的并行

      指的是多個子任務之間需要同步信息來執(zhí)行復雜的并行算法,單個子任務無法完成部分計算。最近比較有名的例子應該算是 Tensorflow 的 “ps-work模式” 和 ring all-reduce了,各個子任務之間需要大量的數(shù)據(jù)交換和信息同步,單獨的子任務無法獨立完成。正是由于作業(yè)的這種屬性,對作業(yè)調度平臺也提出了相應的調度要求,比如 gang-scheduling、作業(yè)拓撲等。又由于子任務之間需要彼此通信,所以作業(yè)在啟動后無法動態(tài)擴展子任務的,在沒有checkpoint的情況下,任一子任務失敗或驅逐,整個作業(yè)都需要重啟哦,這種作業(yè)也常常被稱作 Batch Job,傳統(tǒng)的HPC場景多屬于這種類型的并行作業(yè),針對這種場景的調度平臺為 Slurm/PBS/SGE/HTCondor 等。

      流水線并行

      指的是作業(yè)的多個子任務之間存在依賴關系,但不需要前置任務完全結束后再開始后續(xù)的任務。比如 Hadoop 里有相應的研究,在 Map 沒有完全結束的時候就部分開始 Reduce 階段,這樣從而提高任務的并行度,提高整體的運行性能。符合這種場景的應用相對來說比較少,一般都做為性能優(yōu)化;因此沒有針對這種場景的作業(yè)管理平臺。需要區(qū)分一下工作流與流水線并行,工作流一般指作業(yè)之間的依賴關系,而流水線并行一般指作業(yè)內部多個任務之間的依賴。由于工作流中的作業(yè)差異比較大,很難提前開始后續(xù)步驟。

      值得一提的是"二次調度"。由于簡單并行的作業(yè)一般會有大量的子任務,而且每個子任務所需要的資源相對一致,子任務之間也沒有通信和同步;使得資源的復用率相對比較高,所以二次調度在這種場景下能發(fā)揮比較大的作用;Hadoop的YARN,Symphony的EGO都屬于這種類型。但是在面對復雜并行的作業(yè)時,二次調度就顯得有也吃力;復雜并行作業(yè)一般并沒有太多的子任務,子任務之間還經常需要同時啟動,子任務之間的通信拓撲也可能不同 (e.g. ps/worker, mpi),而且作業(yè)與作業(yè)之間對資源的需求差異較大,因此導致了資源的復用率較低。

      雖然針對兩種不同并行作業(yè)類型有不同的作業(yè)、資源管理平臺,但是根本的目標都是為作業(yè)尋找最優(yōu)的資源;因此,Volcano一直以支持以多種類型的作業(yè)為目標進行設計。目前,Volcano可以同時支持 Spark、TensorFlow和MPI等多種類型的作業(yè)。

      七 功能是啥

      1 設計目標是啥

      1)首先提供統(tǒng)一接口,支持多種類型批 量計算任務,可以描述復雜類型 的作業(yè)

      Job API的定位是一個bach-system,支持多種類型的作業(yè),好比說大數(shù)據(jù)、AI、HPC,包含了多種作業(yè)類型。所以我們希望提供一個統(tǒng)一的接口去簡化用戶的使用,無論哪種類型、哪個場景的作業(yè),都可以通過統(tǒng)一的接口運行起來,這是我們設計的時候一個很重要的考慮點。

      2)靈活擴展性,滿足定制化需求

      其次就是靈活性,雖然說不同類型的作業(yè),通過一個作業(yè)能夠跑起來,但其實不同的場景,有不同定制化化需求,所以我們在設計這個Job API的時候,能提供定制化的需求,可以支持大部分的場景。

      2 Volcano多任務模板

      TaskSpec結構體里除包含最基本的信息外,還有一個policies, policy就定義了Task的生命周期。因為一個Job里會有多個 Task,就像下圖描述的如何用Vocano運行一個Tensorflow的Job,Task里面就有多個角色,不同的角色可以定義它自己的 port template,這樣的話我們就可以通過一個統(tǒng)一的Volcano Job支持不同的作業(yè)類型。

      3 Volcano作業(yè)插件機制

      作業(yè)內任務互相訪問的需求

      作業(yè)內任務索引

      ssh免密登錄

      其實有一些定制化的需求。好比說分布式訓練這種作業(yè),它在多個pod跑起來之后,它的pod和pod之間需要有網絡互訪,做數(shù)據(jù)同步。 對于像這種類型的需求,我們通過插件化的機制做成job plugin,讓用戶去通過這種方式去支撐它的場景。

      在這里面我們看到我們定義的接口叫PluginInterface,PluginInterface的定義當一個作業(yè)在增刪改查,或者Job在創(chuàng)建的時候,用戶可以去實現(xiàn)這個函數(shù),去做定制化的需求。以下三個作業(yè)的插件是我們默認已經支持的,簡單配置就可以使用:

      svc:

      不同類型的任務之間互訪

      env:

      任務索引,例如Tensorflow Worker index

      ssh:

      ssh秘鑰對創(chuàng)建及掛載,主要供MPI作業(yè)使用

      接下來我們看一下作業(yè)插件是怎么用的。它使用起來其實非常簡單,剛才說的那三個插件,只要在job spec里面的plugins字段,再加上插件的名字(如有需要還可以添加參數(shù),本課示例未添加)就可以運行起來了。

      下圖是一個Volcano跑Tensorflow的Job。

      除了剛才提到的統(tǒng)一job、定制化的需求,還有一個很重要的方面就是作業(yè)生命周期的管理。因為作業(yè)的狀態(tài)以及pod狀態(tài)是非常多的,上節(jié)課我們也提到大概有七八種pod的狀態(tài),這些pod在發(fā)生不同事件時,對于作業(yè)的狀態(tài)都會有影響。由于不同的場景需求是不一樣的,這就要求我們在支持生命周期管理時,提供豐富的用戶可配置機制的生命周期管理。

      除了作業(yè)生命周期管理之外,還有一個就是作業(yè)狀態(tài)的設計。上面我們提到我們在Volcano里增加了很多Pod的狀態(tài)。現(xiàn)在這里面提到的是作業(yè)的狀態(tài),作業(yè)的狀態(tài)有8種,Controller 維護 State 子類的實例,State定義接口,封裝與Controller 特定狀態(tài)相關的行為,每個子類實現(xiàn)一個與Controller 特定狀態(tài)相關的行為。

      八 常見的調度場景

      運行批處理作業(yè)(如Tensorflow/MPI)時,必須協(xié)調作業(yè)的所有任務才能一起啟動;否則,將不會啟動任何任務。如果有足夠的資源并行運行作業(yè)的所有任務,則該作業(yè)將正確執(zhí)行; 但是,在大多數(shù)情況下,尤其是在prem環(huán)境中,情況并非如此。在最壞的情況下,由于死鎖,所有作業(yè)都掛起。其中每個作業(yè)只成功啟動了部分任務,并等待其余任務啟動。

      當運行多個彈性作業(yè)(如流媒體)時,需要公平地為每個作業(yè)分配資源,以滿足多個作業(yè)競爭附加資源時的SLA/QoS要求。在最壞的情況下,單個作業(yè)可能會啟動大量的pod資源利用率低, 從而阻止其他作業(yè)由于資源不足而運行。為了避免分配過小(例如,為每個作業(yè)啟動一個Pod),彈性作業(yè)可以利用協(xié)同調度來定義應該啟動的Pod的最小可用數(shù)量。 超過指定的最小可用量的任何pod都將公平地與其他作業(yè)共享集群資源。

      隊列還廣泛用于共享彈性工作負載和批處理工作負載的資源。隊列的主要目的是:

      在不同的“租戶”或資源池之間共享資源

      為不同的“租戶”或資源池支持不同的調度策略或算法

      這些功能可以通過層次隊列進一步擴展,在層次隊列中,項目被賦予額外的優(yōu)先級,這將允許它們比隊列中的其他項目“跳轉”。在kube批處理中,隊列被實現(xiàn)為集群范圍的CRD。 這允許將在不同命名空間中創(chuàng)建的作業(yè)放置在共享隊列中。隊列資源根據(jù)其隊列配置(kube batch#590)按比例劃分。當前不支持分層隊列,但正在進行開發(fā)。

      集群應該能夠在不減慢任何操作的情況下處理隊列中的大量作業(yè)。其他的HPC系統(tǒng)可以處理成百上千個作業(yè)的隊列,并隨著時間的推移緩慢地處理它們。如何與庫伯內特斯達成這樣的行為是一個懸而未決的問題。支持跨越多個集群的隊列可能也很有用,在這種情況下,這是一個關于數(shù)據(jù)應該放在哪里以及etcd是否適合存儲隊列中的所有作業(yè)或pod的問題。

      在隊列中,每個作業(yè)在調度循環(huán)期間有幾乎相等的調度機會,這意味著擁有更多作業(yè)的用戶有更大的機會安排他們的作業(yè),這對其他用戶不公平。 例如,有一個隊列包含少量資源,有10個pod屬于UserA,1000個pod屬于UserB。在這種情況下,UserA的pod被綁定到節(jié)點的概率較小。

      為了平衡同一隊列中用戶之間的資源使用,需要更細粒度的策略。然后考慮到Kubernetes中的多用戶模型,使用名稱空間來區(qū)分不同的用戶, 每個命名空間都將配置一個權重,作為控制其資源使用優(yōu)先級的手段。

      對于批處理工作負載,通常不要求在某個時間點公平地分配資源,而是要求在長期內公平地分配資源。例如,如果有用戶提交大作業(yè),則允許用戶(或特定隊列)在一定時間內使用整個集群的一半, 這是可以接受的,但在下一輪調度(可能是作業(yè)完成后數(shù)小時)中,應懲罰此用戶(或隊列)而不是其他用戶(或隊列)。在 HTCondor 中可以看到如何實現(xiàn)這種行為的好例子。

      Pod優(yōu)先級/搶占在1.14版本中被中斷,它有助于確保高優(yōu)先級的pod在低優(yōu)先級的pod之前綁定。不過,在job/podgroup級別的優(yōu)先級上仍有一些工作要做,例如高優(yōu)先級job/podgroup應該嘗試以較低優(yōu)先級搶占整個job/podgroup,而不是從不同job/podgroup搶占幾個pod。

      通過公平分享來支持借貸模型,一些作業(yè)/隊列在空閑時會過度使用資源。但是,如果有任何進一步的資源請求,資源“所有者”將“收回”。 資源可以在隊列或作業(yè)之間共享:回收用于隊列之間的資源平衡,搶占用于作業(yè)之間的資源平衡。

      當一個請求大量資源的“巨大”作業(yè)提交給kubernetes時,當有許多小作業(yè)在管道中時,該作業(yè)可能會餓死,并最終根據(jù)當前的調度策略/算法被殺死。為了避免饑餓, 應該有條件地為作業(yè)保留資源,例如超時。當資源被保留時,它們可能會處于空閑和未使用狀態(tài)。為了提高資源利用率,調度程序將有條件地將“較小”作業(yè)回填到那些保留資源中。 保留和回填都是根據(jù)插件的反饋觸發(fā)的:volcano調度器提供了幾個回調接口,供開發(fā)人員或用戶決定哪些作業(yè)應該被填充或保留。

      九 Volcano 調度框架

      Volcano調度器通過作業(yè)級的調度和多種插件機制來支持多種作業(yè);Volcano的插件機制有效的支撐了針對不同場景算法的落地,從早期的gang-scheduling/co-scheduling,到后來各個級別的公平調度。下圖展示了Volcano調度器的總體架構:

      并且Cache 已經緩存了集群中Node和Pod信息,并根據(jù)PodGroup的信息重新構建 Job (PodGroup) 和 Task (Pod) 的關系。由于在分布式系統(tǒng)中很難保證信息的同步,因此調度器經常以某一時間點的集群快照進行調度;并保證每個調度周期的決定是一致的。在每個調度周期中,Volcano 通過以下幾個步驟派發(fā)作業(yè):

      在每個調度周期都會創(chuàng)建一個Session對象,用來存儲當前調度周期的所需的數(shù)據(jù),例如,Cache 的一個快照。當前的調度器中僅創(chuàng)建了一個Session,并由一個調度線程執(zhí)行;后續(xù)將會根據(jù)需要創(chuàng)建多個Session,并為每個Session分配一個線程進行調度;并由Cache來解決調度沖突。

      在每個調度周期中,會按順序執(zhí)行 OpenSession, 配置的多個動作(action)和CloseSession。在 OpenSession中用戶可以注冊自定義的插件,例如gang、 drf,這些插件為action提供了相應算法;多個action根據(jù)配置順序執(zhí)行,調用注冊的插件進行調度;最后,CloseSession負責清理中間數(shù)據(jù)。

      (1) action是第一級插件,定義了調度周期內需要的各個動作;默認提供 enqueue、allocate、 preempt和backfill四個action。以allocate為例,它定義了調度中資源分配過程:根據(jù) plugin 的 JobOrderFn 對作業(yè)進行排序,根據(jù)NodeOrderFn對節(jié)點進行排序,檢測節(jié)點上的資源是否滿足,滿足作業(yè)的分配要求(JobReady)后提交分配決定。由于action也是基于插件機制,因此用戶可以重新定義自己的分配動作,例如 基于圖的調度算法firmament。

      (2) plugin是第二級插件,定義了action需要的各個算法;以drf插件為例,為了根據(jù)dominant resource進行作業(yè)排序,drf插件實現(xiàn)了 JobOrderFn函數(shù)。JobOrderFn函數(shù)根據(jù) drf 計算每個作業(yè)的share值,share值較低代表當前作業(yè)分配的資源較少,因此會為其優(yōu)先分配資源;drf插件還實現(xiàn)了EventHandler回調函數(shù),當作業(yè)被分配或搶占資源后,調度器會通知drf插件來更新share值。

      Cache 不僅提供了集群的快照,同時還提供了調度器與kube-apiserver的交互接口,調度器與kube-apiserver之間的通信也都通過Cache來完成,例如 Bind。

      同時,為了支持上面這些場景,Volcano的調度器還增加了多個Pod狀態(tài)以提高調度的性能:

      Pending: 當Pod被創(chuàng)建后就處于Pending狀態(tài),等待調度器對其進行調度;調度的主要目的也是為這些Pending的Pod尋找最優(yōu)的資源

      Allocated: 當Pod被分配空閑資源,但是還沒有向kube-apiserver發(fā)送調度決策時,Pod處于Allocated狀態(tài)。 Allocated狀態(tài)僅存在于調度周期內部,用于記錄Pod和資源分配情況。當作業(yè)滿足啟動條件時 (e.g. 滿足minMember),會向kube-apiserver提交調度決策。如果本輪調度周期內無法提交調度決策,由狀態(tài)會回滾為Pending狀態(tài)。

      Pipelined: 該狀態(tài)與Allocated狀態(tài)相似,區(qū)別在于處于該狀態(tài)的Pod分配到的資源為正在被釋放的資源 (Releasing)。該狀態(tài)主要用于等待被搶占的資源釋放。該狀態(tài)是調度周期中的狀態(tài),不會更新到kube-apiserver以減少通信,節(jié)省kube-apiserver的qps。

      Binding: 當作業(yè)滿足啟動條件時,調度器會向kube-apiserver提交調度決策,在kube-apiserver返回最終狀態(tài)之前,Pod一直處于Binding狀態(tài)。該狀態(tài)也保存在調度器的Cache之中,因此跨調度周期有效。

      Bound: 當作業(yè)的調度決策在kube-apiserver確認后,該Pod即為Bound狀態(tài)。

      Releasing: Pod等待被刪除時即為Releasing狀態(tài)。

      Running, Failed, Succeeded, Unknown: 與Pod的現(xiàn)有含義一致。

      狀態(tài)之間根據(jù)不同的操作進行轉換,如圖這樣

      Pod的這些狀態(tài)為調度器提供了更多優(yōu)化的可能。比如說,當進行Pod驅逐時,驅逐在Binding和Bound狀態(tài)的Pod要比較驅逐Running狀態(tài)的Pod的代價要小 (思考:還有其它狀態(tài)的Pod可以驅逐嗎?);

      并且狀態(tài)都是記錄在Volcano調度內部,減少了與kube-apiserver的通信。但目前Volcano調度器僅使用了狀態(tài)的部分功能,比如現(xiàn)在的preemption/reclaim僅會驅逐Running狀態(tài)下的Pod;這主要是因為分布式系統(tǒng)中很難做到完全的狀態(tài)同步,在驅逐B(yǎng)inding和Bound狀態(tài)的Pod會有很多的狀態(tài)競爭;

      【與云原生的故事】有獎征文火熱進行 快來參加:https://bbs.huaweicloud.com/blogs/345260

      Java 云原生

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:怎么在表格中的方框里打勾(怎么在表格中的方框里打勾還不會顯示R)
      下一篇:自定義動漫(自定義動漫人物)
      相關文章
      在线观看亚洲视频| 久久久久久a亚洲欧洲aⅴ| 亚洲免费视频网址| 亚洲综合一区二区| 亚洲黄色免费网址| 亚洲系列国产精品制服丝袜第| 久久亚洲高清观看| 亚洲AV综合色区无码一区爱AV | 亚洲一区二区三区无码中文字幕| 亚洲AV无码乱码在线观看牲色| 亚洲成人影院在线观看| 亚洲人成人无码网www国产| 久久精品国产精品亚洲下载| 亚洲中文字幕日产乱码高清app| 久久影视国产亚洲| 亚洲综合日韩久久成人AV| 亚洲码国产精品高潮在线| 亚洲成av人在线视| 日韩亚洲AV无码一区二区不卡| 久久精品国产亚洲香蕉| 久久亚洲精品国产精品| 亚洲永久中文字幕在线| 精品久久久久久亚洲精品| 亚洲色欲啪啪久久WWW综合网| 亚洲乱码av中文一区二区| 亚洲国产成人AV网站| 亚洲国产午夜福利在线播放| 在线观看亚洲精品福利片| 亚洲精品无码久久一线| 亚洲天堂一区二区| 国产精品亚洲片在线va| 亚洲爆乳大丰满无码专区| 亚洲成A人片在线观看中文| 国产亚洲老熟女视频| 亚洲av日韩综合一区在线观看| 亚洲美女大bbbbbbbbb| 亚洲第一男人天堂| 日韩亚洲人成在线综合| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 亚洲AV成人一区二区三区AV| 亚洲综合一区二区国产精品|