精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

從源碼角度看Spark on yarn client & cluster模式的本質區別

大數據 Spark
對于yarn-client和yarn-cluster的唯一區別在于,yarn-client的Driver運行在本地,而AppMaster運行在yarn的一個節點上,他們之間進行遠程通信,AppMaster只負責資源申請和釋放(當然還有DelegationToken的刷新),然后等待Driver的完成;而yarn-cluster的Driver則運行在AppMaster所在的container里,Driver和AppMaster是同一個進程的兩個不同線程,它們之間也會進行通信,AppMaster同樣等待Driver的完成,從而釋放資源。

首先區分下AppMaster和Driver,任何一個yarn上運行的任務都必須有一個AppMaster,而任何一個Spark任務都會有一個Driver,Driver就是運行SparkContext(它會構建TaskScheduler和DAGScheduler)的進程,當然在Driver上你也可以做很多非Spark的事情,這些事情只會在Driver上面執行,而由SparkContext上牽引出來的代碼則會由DAGScheduler分析,并形成Job和Stage交由TaskScheduler,再由TaskScheduler交由各Executor分布式執行。

所以Driver和AppMaster是兩個完全不同的東西,Driver是控制Spark計算和任務資源的,而AppMaster是控制yarn app運行和任務資源的,只不過在Spark on Yarn上,這兩者就出現了交叉,而在standalone模式下,資源則由Driver管理。在Spark on Yarn上,Driver會和AppMaster通信,資源的申請由AppMaster來完成,而任務的調度和執行則由Driver完成,Driver會通過與AppMaster通信來讓Executor的執行具體的任務。

client與cluster的區別

對于yarn-client和yarn-cluster的唯一區別在于,yarn-client的Driver運行在本地,而AppMaster運行在yarn的一個節點上,他們之間進行遠程通信,AppMaster只負責資源申請和釋放(當然還有DelegationToken的刷新),然后等待Driver的完成;而yarn-cluster的Driver則運行在AppMaster所在的container里,Driver和AppMaster是同一個進程的兩個不同線程,它們之間也會進行通信,AppMaster同樣等待Driver的完成,從而釋放資源。

Spark里AppMaster的實現:org.apache.spark.deploy.yarn.ApplicationMaster Yarn里MapReduce的AppMaster實現:org.apache.hadoop.mapreduce.v2.app.MRAppMaster

在yarn-client模式里,優先運行的是Driver(我們寫的應用代碼就是入口),然后在初始化SparkContext的時候,會作為client端向yarn申請AppMaster資源,當AppMaster運行后,它會向yarn注冊自己并申請Executor資源,之后由本地Driver與其通信控制任務運行,而AppMaster則時刻監控Driver的運行情況,如果Driver完成或意外退出,AppMaster會釋放資源并注銷自己。所以在該模式下,如果運行spark-submit的程序退出了,整個任務也就退出了

在yarn-cluster模式里,本地進程則僅僅只是一個client,它會優先向yarn申請AppMaster資源運行AppMaster,在運行AppMaster的時候通過反射啟動Driver(我們的應用代碼),在SparkContext初始化成功后,再向yarn注冊自己并申請Executor資源,此時Driver與AppMaster運行在同一個container里,是兩個不同的線程,當Driver運行完畢,AppMaster會釋放資源并注銷自己。所以在該模式下,本地進程僅僅是一個client,如果結束了該進程,整個Spark任務也不會退出,因為Driver是在遠程運行的

下面從源碼的角度看看SparkSubmit的代碼調用(基于Spark2.0.0):

代碼公共部分

SparkSubmit#main =>

  1. val appArgs = new SparkSubmitArguments(args) 
  2. appArgs.action match { 
  3.   // normal spark-submit 
  4.   case SparkSubmitAction.SUBMIT => submit(appArgs) 
  5.   // use --kill specified 
  6.   case SparkSubmitAction.KILL => kill(appArgs) 
  7.   // use --status specified 
  8.   case SparkSubmitAction.REQUEST_STATUS => requestStatus(appArgs) 

SparkSubmit的main方法是在用戶使用spark-submit腳本提交Spark app的時候調用的,可以看到正常情況下,它會調用SparkSubmit#submit方法

SparkSubmit#submit =>

  1. val (childArgs, childClasspath, sysProps, childMainClass) = prepareSubmitEnvironment(args) 
  2. // 此處省略掉代理賬戶,異常處理,提交失敗的重提交邏輯,只看主干代碼 
  3. runMain(childArgs, childClasspath, sysProps, childMainClass, args.verbose) 

在submit方法內部,會先進行提交環境相關的處理,調用的是SparkSubmit#prepareSubmitEnvironment方法,之后利用拿到的mainClass等信息,再調用SparkSubmit#runMain方法來執行對于主函數

SparkSubmit#prepareSubmitEnvironment =>

主干相關的代碼如下:

  1. // yarn client mode 
  2. if (deployMode == CLIENT) { 
  3.   // client 模式下,運行的是 --class 后指定的mainClass,也即我們的代碼 
  4.   childMainClass = args.mainClass 
  5.   if (isUserJar(args.primaryResource)) { 
  6.     childClasspath += args.primaryResource 
  7.   } 
  8.   if (args.jars != null) { childClasspath ++= args.jars.split(",") } 
  9.   if (args.childArgs != null) { childArgs ++= args.childArgs } 
  10.  
  11. // yarn cluster mode 
  12. val isYarnCluster = clusterManager == YARN && deployMode == CLUSTER 
  13. if (isYarnCluster) { 
  14.   // cluster 模式下,運行的是Client類 
  15.   childMainClass = "org.apache.spark.deploy.yarn.Client" 
  16.   if (args.isPython) { 
  17.     childArgs += ("--primary-py-file", args.primaryResource) 
  18.     childArgs += ("--class""org.apache.spark.deploy.PythonRunner"
  19.   } else if (args.isR) { 
  20.     val mainFile = new Path(args.primaryResource).getName 
  21.     childArgs += ("--primary-r-file", mainFile) 
  22.     childArgs += ("--class""org.apache.spark.deploy.RRunner"
  23.   } else { 
  24.     if (args.primaryResource != SparkLauncher.NO_RESOURCE) { 
  25.       childArgs += ("--jar", args.primaryResource) 
  26.     } 
  27.     // 這里 --class 指定的是AppMaster里啟動的Driver,也即我們的代碼 
  28.     childArgs += ("--class", args.mainClass) 
  29.   } 
  30.   if (args.childArgs != null) { 
  31.     args.childArgs.foreach { arg => childArgs += ("--arg", arg) } 
  32.   } 

在 prepareSubmitEnvironment 里,主要負責解析用戶參數,設置環境變量env,處理python/R等依賴,然后針對不同的部署模式,匹配不同的運行主類,比如: yarn-client>args.mainClass,yarn-cluster>o.a.s.deploy.yarn.Client

SparkSubmit#runMain =>

骨干代碼如下

  1. try { 
  2.   mainClass = Utils.classForName(childMainClass) 
  3. } catch { 
  4.   // ... 
  5. val mainMethod = mainClass.getMethod("main", new Array[String](0).getClass) 
  6. try { 
  7.   // childArgs就是用戶自己傳給Spark應用代碼的參數 
  8.   mainMethod.invoke(null, childArgs.toArray) 
  9. } catch { 
  10.   // ... 

在runMain方法里,會設置ClassLoader,根據用戶代碼優先的設置(spark.driver.userClassPathFirst)來加載對應的類,然后反射調用prepareSubmitEnvironment方法返回的主類,并調用其main方法

從所反射的不同主類,我們來看看具體調用方式的不同:

對于yarn-cluster

o.a.s.deploy.yarn.Client#main =>

  1. val sparkConf = new SparkConf  
  2. val args = new ClientArguments(argStrings) 
  3. new Client(args, sparkConf).run() 

在Client伴生對象里構建了Client類的對象,然后調用了Client#run方法

o.a.s.deploy.yarn.Client#run =>

  1. this.appId = submitApplication() 
  2. // report application ... 

run方法核心的就是提交任務到yarn,其調用了Client#submitApplication方法,拿到提交完的appID后,監控app的狀態

o.a.s.deploy.yarn.Client#submitApplication =>

  1. try { 
  2.   // 獲取提交用戶的Credentials,用于后面獲取delegationToken 
  3.   setupCredentials() 
  4.   yarnClient.init(yarnConf) 
  5.   yarnClient.start() 
  6.  
  7.   // Get a new application from our RM 
  8.   val newApp = yarnClient.createApplication() 
  9.   val newAppResponse = newApp.getNewApplicationResponse() 
  10.   // 拿到appID 
  11.   appId = newAppResponse.getApplicationId() 
  12.   // 報告狀態 
  13.   reportLauncherState(SparkAppHandle.State.SUBMITTED) 
  14.   launcherBackend.setAppId(appId.toString) 
  15.  
  16.   // Verify whether the cluster has enough resources for our AM 
  17.   verifyClusterResources(newAppResponse) 
  18.  
  19.   // 創建AppMaster運行的context,為其準備運行環境,java options,以及需要運行的java命令,AppMaster通過該命令在yarn節點上啟動 
  20.   val containerContext = createContainerLaunchContext(newAppResponse) 
  21.   val appContext = createApplicationSubmissionContext(newApp, containerContext) 
  22.  
  23.   // Finally, submit and monitor the application 
  24.   logInfo(s"Submitting application $appId to ResourceManager"
  25.   yarnClient.submitApplication(appContext) 
  26.   appId 
  27. } catch { 
  28.   case e: Throwable => 
  29.     if (appId != null) { 
  30.       cleanupStagingDir(appId) 
  31.     } 
  32.     throw e 

在 submitApplication 里完成了app的申請,AppMaster context的創建,***完成了任務的提交,對于cluster模式而言,任務提交后本地進程就只是一個client而已,Driver就運行在與AppMaster同一container里,對于client模式而言,執行 submitApplication 方法時,Driver已經在本地運行,這一步就只是提交任務到yarn而已

o.a.s.deploy.yarn.Client#createContainerLaunchContext

  1. val appStagingDirPath = new Path(appStagingBaseDir, getAppStagingDir(appId)) 
  2. // 非pySpark時,pySparkArchives為Nil 
  3. val launchEnv = setupLaunchEnv(appStagingDirPath, pySparkArchives) 
  4. // 這一步會進行delegationtoken的獲取,存于Credentials,在AppMasterContainer構建完的***將其存入到context里 
  5. val localResources = prepareLocalResources(appStagingDirPath, pySparkArchives) 
  6.  
  7. val amContainer = Records.newRecord(classOf[ContainerLaunchContext]) 
  8. // 設置AppMaster container運行的資源和環境 
  9. amContainer.setLocalResources(localResources.asJava) 
  10. amContainer.setEnvironment(launchEnv.asJava) 
  11. // 設置JVM參數 
  12. val javaOpts = ListBuffer[String]() 
  13. javaOpts += "-Djava.io.tmpdir=" + tmpDir 
  14. // other java opts setting... 
  15.  
  16. // 對于cluster模式,通過 --class 指定AppMaster運行我們的Driver端,對于client模式則純作為資源申請和分配的工具 
  17. val userClass = 
  18.   if (isClusterMode) { 
  19.     Seq("--class", YarnSparkHadoopUtil.escapeForShell(args.userClass)) 
  20.   } else { 
  21.     Nil 
  22.   } 
  23. // 設置AppMaster運行的主類 
  24. val amClass = 
  25.   if (isClusterMode) { 
  26.     Utils.classForName("org.apache.spark.deploy.yarn.ApplicationMaster").getName 
  27.   } else { 
  28.     // ExecutorLauncher只是ApplicationMaster的一個warpper 
  29.     Utils.classForName("org.apache.spark.deploy.yarn.ExecutorLauncher").getName 
  30.   } 
  31.  
  32. val amArgs = 
  33.   Seq(amClass) ++ userClass ++ userJar ++ primaryPyFile ++ primaryRFile ++ 
  34.     userArgs ++ Seq( 
  35.       "--properties-file", buildPath(YarnSparkHadoopUtil.expandEnvironment(Environment.PWD), 
  36.         LOCALIZED_CONF_DIR, SPARK_CONF_FILE)) 
  37.  
  38. // Command for the ApplicationMaster 
  39. val commands = prefixEnv ++ Seq( 
  40.     YarnSparkHadoopUtil.expandEnvironment(Environment.JAVA_HOME) + "/bin/java""-server" 
  41.   ) ++ 
  42.   javaOpts ++ amArgs ++ 
  43.   Seq( 
  44.     "1>", ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stdout"
  45.     "2>", ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stderr"
  46.  
  47. val printableCommands = commands.map(s => if (s == null"null" else s).toList 
  48. // 設置需運行的命令 
  49. amContainer.setCommands(printableCommands.asJava) 
  50.  
  51. val securityManager = new SecurityManager(sparkConf) 
  52. // 設置應用權限 
  53. amContainer.setApplicationACLs( 
  54.       YarnSparkHadoopUtil.getApplicationAclsForYarn(securityManager).asJava) 
  55. // 設置delegationToken 
  56. setupSecurityToken(amContainer) 

對于yarn-client

args.mainClass =>

在我們的Spark代碼里,需要創建一個SparkContext來執行Spark任務,而在其構造器里創建TaskScheduler的時候,對于client模式就會向yarn申請資源提交任務,如下

  1. // 調用createTaskScheduler方法,對于yarn模式,master=="yarn" 
  2. val (sched, ts) = SparkContext.createTaskScheduler(this, master, deployMode) 
  3. _schedulerBackend = sched 
  4. _taskScheduler = ts 
  5. // 創建DAGScheduler 
  6. _dagScheduler = new DAGScheduler(this) 

SparkContext#createTaskScheduler =>

這里會根據master匹配不同模式,比如local/standalone/yarn,在yarn模式下會利用ServiceLoader裝載YarnClusterManager,然后由它創建TaskScheduler和SchedulerBackend,如下:

  1. // 當為yarn模式的時候 
  2. case masterUrl => 
  3.   // 利用當前loader裝載YarnClusterManager,masterUrl為"yarn" 
  4.   val cm = getClusterManager(masterUrl) match { 
  5.     case Some(clusterMgr) => clusterMgr 
  6.     case None => throw new SparkException("Could not parse Master URL: '" + master + "'"
  7.   } 
  8.   try { 
  9.     // 創建TaskScheduler,這里masterUrl并沒有用到 
  10.     val scheduler = cm.createTaskScheduler(sc, masterUrl) 
  11.     // 創建SchedulerBackend,對于client模式,這一步會向yarn申請AppMaster,提交任務 
  12.     val backend = cm.createSchedulerBackend(sc, masterUrl, scheduler) 
  13.     cm.initialize(scheduler, backend) 
  14.     (backend, scheduler) 
  15.   } catch { 
  16.     case se: SparkException => throw se 
  17.     case NonFatal(e) => 
  18.       throw new SparkException("External scheduler cannot be instantiated", e) 
  19.   } 

YarnClusterManager#createSchedulerBackend

  1. sc.deployMode match { 
  2.   case "cluster" => 
  3.     new YarnClusterSchedulerBackend(scheduler.asInstanceOf[TaskSchedulerImpl], sc) 
  4.   case "client" => 
  5.     new YarnClientSchedulerBackend(scheduler.asInstanceOf[TaskSchedulerImpl], sc) 
  6.   case  _ => 
  7.     throw new SparkException(s"Unknown deploy mode '${sc.deployMode}' for Yarn"

可以看到yarn下的SchedulerBackend實現對于client和cluster模式是不同的,yarn-client模式為YarnClientSchedulerBackend,yarn-cluster模式為 YarnClusterSchedulerBackend,之所以不同,是因為在client模式下,YarnClientSchedulerBackend 相當于 yarn application 的client,它會調用o.a.s.deploy.yarn.Client#submitApplication 來準備環境,申請資源并提交yarn任務,如下:

  1. val driverHost = conf.get("spark.driver.host"
  2. val driverPort = conf.get("spark.driver.port"
  3. val hostport = driverHost + ":" + driverPort 
  4. sc.ui.foreach { ui => conf.set("spark.driver.appUIAddress", ui.appUIAddress) } 
  5.  
  6. val argsArrayBuf = new ArrayBuffer[String]() 
  7. argsArrayBuf += ("--arg", hostport) 
  8.  
  9. val args = new ClientArguments(argsArrayBuf.toArray) 
  10. totalExpectedExecutors = YarnSparkHadoopUtil.getInitialTargetExecutorNumber(conf) 
  11. // 創建o.a.s.deploy.yarn.Client對象 
  12. client = new Client(args, conf) 
  13. // 調用submitApplication準備環境,申請資源,提交任務,并把appID保存下來 
  14. // 對于submitApplication,前文有詳細的分析,這里與前面是一致的 
  15. bindToYarn(client.submitApplication(), None) 

而在 YarnClusterSchedulerBackend 里,由于 AppMaster 已經運行起來了,所以它并不需要再做申請資源等等工作,只需要保存appID和attemptID并啟動SchedulerBackend即可.

責任編輯:武曉燕 來源: oschina博客
相關推薦

2021-02-06 23:21:35

SaaS開發低代碼

2021-03-10 08:20:54

設計模式OkHttp

2021-07-02 06:54:45

GoJavachannel

2011-05-25 13:10:40

SQL ServerOracle

2019-04-28 16:10:50

設計Redux前端

2017-05-27 09:58:42

BGP動態靜態

2018-02-06 14:32:03

云服務器本質區別

2023-03-13 07:43:51

PHP類型轉換

2021-08-26 11:21:34

技術代碼計算

2014-04-16 13:47:43

SparkYarn

2015-05-05 11:04:31

CoreOS自動化運維

2020-02-04 09:53:05

數據安全數據泄漏信息安全

2010-09-27 11:24:37

SQL聚簇索引

2010-07-16 09:00:20

開源RedOffice紅旗2000

2012-04-29 10:37:28

APP

2009-07-12 13:55:29

2022-03-08 11:29:06

Linux進程系統

2010-09-27 15:17:48

JVM client模式server模式

2013-12-11 21:48:38

OpenStack

2022-07-15 13:01:13

Kotlin編程語言Java
點贊
收藏

51CTO技術棧公眾號

精品中文字幕一区二区小辣椒| 亚洲精品亚洲人成在线观看| 亚洲精品国产一区二区精华液 | 99精品视频99| 精品久久久久久久久久久下田| 7777精品伊人久久久大香线蕉的| 免费看日b视频| 欧美亚洲日本| 九九九久久久精品| 性欧美亚洲xxxx乳在线观看| 精品人体无码一区二区三区| 一级毛片精品毛片| 欧美网站大全在线观看| 波多野结衣av一区二区全免费观看| 天堂在线中文网| 久久超碰97中文字幕| 国产综合在线视频| 黑人狂躁日本娇小| 亚瑟一区二区三区四区| 欧美精品日韩精品| 日韩欧美国产免费| www久久日com| 国产欧美精品一区| 国产精品三区www17con| 亚洲天堂999| 久久亚洲视频| 久久免费在线观看| 爱爱视频免费在线观看| 精品理论电影| 亚洲电影在线观看| 日本一二三区在线| 精品久久在线| 欧美午夜丰满在线18影院| 国产手机视频在线观看| 在线视频婷婷| 国产日韩欧美综合一区| 国产欧美在线一区二区| 国产成人综合精品在线| 91看片就是不一样| 超碰在线公开| 亚洲成人综合网站| 亚洲高潮无码久久| 欧美成人性生活视频| 97精品国产97久久久久久久久久久久 | 亚洲美女毛片| 色综合久综合久久综合久鬼88 | av男人的天堂在线| 久久久久久影视| 国产亚洲福利社区| 亚洲精品字幕在线观看| 国产精品中文字幕一区二区三区| 国产精品免费观看在线| 黄色污污网站在线观看| 久久国产精品99国产| 97在线视频免费观看| 精品无码人妻一区二区三区品| 久久久五月天| www.xxxx欧美| 久久国产精品国语对白| 亚洲国产日韩欧美在线| 日韩在线观看网址| 国产极品美女在线| 亚洲欧美综合| 久久久综合av| 国产无套丰满白嫩对白| 先锋亚洲精品| 国产精品777| 在线观看国产一区二区三区| 麻豆久久一区二区| 亚洲一区二区三区视频| www.污视频| 成人激情小说乱人伦| 激情欧美一区二区三区中文字幕| 亚洲AV第二区国产精品| 久久蜜臀中文字幕| 色女人综合av| 八戒八戒神马在线电影| 亚洲午夜久久久| 欧美色图色综合| 日本在线中文字幕一区二区三区| 欧美日韩日日骚| 337p日本欧洲亚洲大胆张筱雨 | 精品国产欧美一区二区| 亚洲av人人澡人人爽人人夜夜| 久久精品色综合| 亚洲午夜久久久影院| 久久成人小视频| 好看的亚洲午夜视频在线| 97av在线视频免费播放| 波多野结衣一二区| 国产尤物一区二区在线| 国产精品一区二区a| 欧美zzoo| 最新久久zyz资源站| 全黄性性激高免费视频| 欧美日韩亚洲国产| 日韩一卡二卡三卡四卡| 人妻精品久久久久中文字幕| 色喇叭免费久久综合网| 欧美日本啪啪无遮挡网站| 六月丁香婷婷综合| 麻豆传媒一区二区三区| 俄罗斯精品一区二区| 国产午夜在线观看| 一卡二卡三卡日韩欧美| 欧美精品成人网| 亚洲成人五区| 中文字幕日韩欧美| 日本五十路女优| 蜜桃视频第一区免费观看| 国产精品午夜av在线| 瑟瑟视频在线| 黑人极品videos精品欧美裸| 在线免费看v片| 九九免费精品视频在线观看| 欧美精品生活片| 久久久久精彩视频| 成人一区二区三区视频在线观看| 亚洲一区bb| 韩国成人漫画| 欧美精品一区二区蜜臀亚洲| 亚洲精品卡一卡二| 日本欧美一区二区在线观看| 国内精品视频在线播放| 中文字幕中文字幕在线十八区 | 日韩码欧中文字| av免费在线播放网站| 99久久人爽人人添人人澡| 日韩在线精品一区| 日本久久综合网| 91丨porny丨蝌蚪视频| 真人抽搐一进一出视频| 国产 日韩 欧美| 菠萝蜜影院一区二区免费| 狠狠人妻久久久久久| 成人国产亚洲欧美成人综合网 | 中中文字幕av在线| 在线观看91精品国产麻豆| 日本xxxxxxxxx18| 亚洲欧美高清| 久久久久欧美| а√在线天堂官网| 欧美精品一区二区三区很污很色的| 免费高清在线观看电视| 久久91精品国产91久久小草| 亚洲国产高清国产精品| 日本肉肉一区| 一本色道久久综合亚洲精品小说| 免费看毛片网站| 久久嫩草精品久久久精品一| 久久久久狠狠高潮亚洲精品| 久久99国产精品久久99大师 | 日韩精品一区二区三区国语自制| 国产精品一区二区在线观看网站| 在线观看福利一区| 99久久这里有精品| 久久精品夜夜夜夜夜久久| 91亚洲国产成人精品一区| 国产精品国产成人国产三级| 国产一伦一伦一伦| 欧美第一精品| 亚洲永久在线观看| 国产经典三级在线| 亚洲高清一二三区| www五月天com| 国产精品天天摸av网| 久久久精品高清| 国产精品v一区二区三区 | 国内精品视频在线观看| 国产成人亚洲综合| 自拍视频在线网| 在线播放/欧美激情| 麻豆chinese极品少妇| 不卡区在线中文字幕| 久久成人免费观看| 日本一区二区高清不卡| 91欧美精品午夜性色福利在线| 一二三四区在线观看| 精品少妇一区二区三区| 欧美一二三区视频| 国产精品久久久久久久久久免费看 | 精品一区二区久久| 大胆欧美熟妇xx| 天堂一区二区三区四区| 国产欧美日韩精品在线观看| 麻豆传媒在线完整视频| 亚洲国内精品视频| 国产主播第一页| 一区二区三区在线播放| 欧美在线一级片| 奇米影视一区二区三区小说| 一区二区三区四区久久| 欧美一级二级三级视频| 成人国产在线视频| 交100部在线观看| 色妞欧美日韩在线| 神马久久精品| 6080午夜不卡| www.国产毛片| 亚洲精品日韩一| 美女脱光内衣内裤| 国内精品在线播放| 国产免费成人在线| 亚洲九九在线| 日韩精品一线二线三线| 亚洲不卡视频| 国产日本欧美一区二区三区在线| 97蜜桃久久| 久久网福利资源网站| 欧洲视频在线免费观看| 欧美一二区视频| 成人黄色免费网| 午夜精品一区二区三区电影天堂 | 日韩美女视频中文字幕| 五月婷婷视频在线观看| 国产亚洲福利一区| 手机看片一区二区三区| 91麻豆精品久久久久蜜臀| 国产农村妇女aaaaa视频| 一区二区三区在线视频观看| 青青青手机在线视频| 久久综合给合久久狠狠狠97色69| 又黄又爽又色的视频| 麻豆成人免费电影| 日韩精品一区中文字幕| 亚洲免费高清| 日韩亚洲欧美一区二区| 99久久激情| 亚洲精品国产精品国自产| 亚欧洲精品视频在线观看| 成人h在线播放| 电影一区中文字幕| 国产日本欧美视频| 国外成人福利视频| 国产精品91在线观看| 在线人成日本视频| 97免费视频在线播放| 成人av影院在线观看| 欧美精品日韩三级| 污污视频在线| 欧美巨乳在线观看| 日韩123区| 久久99亚洲热视| 18视频在线观看| 久久这里只有精品视频首页| 免费a级人成a大片在线观看| 伊人久久综合97精品| 九一国产在线| 国产一区二区三区丝袜| 国产露出视频在线观看| 亚洲性生活视频| 国产精品视频二区三区| 亚洲天堂一区二区三区| 国产一级片在线播放| 影音先锋欧美精品| 98在线视频| 久久精品电影网站| 羞羞网站在线看| 久久久久久久久久久免费 | 色综合久久久久久久久| 中文字幕黄色片| 欧美性生活久久| 一级全黄裸体免费视频| 欧美精品少妇一区二区三区| 97caocao| 精品国产伦一区二区三区免费 | 97超碰国产精品| 在线免费高清一区二区三区| 青青青免费在线| 麻豆精品网站| 一级黄色录像在线观看| 国产一二三精品| 欧美日韩人妻精品一区在线| 91视频xxxx| 美女av免费看| 亚洲欧洲综合另类| 国产午夜精品无码一区二区| 欧美日韩人人澡狠狠躁视频| 久久久久久亚洲av无码专区| 欧美日韩精品一区视频| 国产xxxx在线观看| 日韩久久午夜影院| eeuss影院www在线播放| 久久精品视频在线| 狠狠操一区二区三区| 国产狼人综合免费视频| 成人福利免费在线观看| 日韩久久精品一区二区三区| 五月天久久网站| 欧美在线一区视频| 日韩avvvv在线播放| 久久无码人妻一区二区三区| 久久综合九色综合97_久久久| 美国一级黄色录像| 亚洲一区二区四区蜜桃| 国产精品久久久久久久久夜色| 91精品国产色综合久久不卡蜜臀| 日本韩国在线观看| 日韩中文字幕精品| 韩日毛片在线观看| 亚洲自拍小视频| 国产欧美日韩一区二区三区四区| 国产又黄又爽免费视频| 亚洲综合另类| 中文字幕一二三| 国产欧美日产一区| 日韩欧美中文字幕一区二区| 欧美日韩亚洲综合| 婷婷婷国产在线视频| 久久综合久中文字幕青草| 欧美xxx性| 国模一区二区三区私拍视频| 亚洲综合中文| 欧美男女交配视频| ww亚洲ww在线观看国产| 日韩一级片大全| 在线看国产日韩| 天堂在线中文字幕| 欧美国产日韩中文字幕在线| 久久精品资源| 日韩黄色影视| 国产日韩1区| 天天躁日日躁狠狠躁av麻豆男男| 国产精品精品国产色婷婷| 无码人妻av免费一区二区三区 | 亚洲永久网站| 人妻换人妻a片爽麻豆| 亚洲日本乱码在线观看| 男操女视频网站| 亚洲欧美福利视频| 2001个疯子在线观看| 91九色偷拍| 亚洲精品一区二区妖精| 久久久久国产一区| 国产欧美视频一区二区| 国产一级淫片a视频免费观看| 亚洲第一精品久久忘忧草社区| caopon在线免费视频| 成人免费直播live| 色婷婷综合网| 亚洲色图 在线视频| 欧美国产精品v| 中文字幕+乱码+中文乱码www| 国产亚洲综合久久| 巨胸喷奶水www久久久免费动漫| 欧美午夜免费| 日韩av一二三| 999精品久久久| 在线播放国产精品二区一二区四区 | 国产极品尤物在线| 99re在线精品| 在线观看日本视频| 亚洲色图欧美制服丝袜另类第一页| 欧美成人性网| 亚洲一卡二卡三卡四卡无卡网站在线看| 奇米影视一区二区三区| 最新av电影网站| 日韩免费视频一区二区| xxx在线免费观看| 欧美大香线蕉线伊人久久| 天堂资源在线中文精品| 国产7777777| 3751色影院一区二区三区| 1区2区3区在线视频| 国产亚洲精品自在久久| 老鸭窝亚洲一区二区三区| 自拍偷拍你懂的| 欧美一级免费观看| www.色在线| 亚洲国产精品毛片| 国产高清不卡一区| 日本在线免费观看| 国产亚洲精品久久久优势| 日本午夜免费一区二区| 欧美国产视频一区| 2021久久国产精品不只是精品| 中文字幕一区二区三区人妻四季| 久久亚洲精品中文字幕冲田杏梨| 91在线一区| 日日碰狠狠丁香久燥| 亚洲欧洲无码一区二区三区| 懂色av蜜臀av粉嫩av分享吧| 欧美精品第一页在线播放| 亚洲国产最新| 女人天堂av手机在线| 中文字幕乱码日本亚洲一区二区| 国产视频在线观看免费| 欧美精品激情在线| 成人影视亚洲图片在线| 亚洲无在线观看| 欧美视频在线看| 午夜小视频在线| 麻豆91av| 久久99久久久久久久久久久| 久久综合激情网| 亚洲男人天堂手机在线| 日本综合久久| 日本福利视频网站| 国产欧美va欧美不卡在线| 国产999久久久|