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

10 億行數據集處理挑戰:從 15 分鐘到 5 秒

開發
Golang 在處理 10 億行數據集的挑戰中展現了高效的并發處理和優化的 I/O 操作能力,通過使用 Parquet 二進制格式,進一步提升了數據處理性能,并最終將處理時間從 15 分鐘優化到了 5 秒。

0 億行挑戰[2]在編程界引起了廣泛關注,其主要目的是測試不同編程語言處理并匯總包含 10 億行的海量數據集的速度,而以性能和并發能力著稱的 Go 是有力競爭者。目前性能最好的 Java 實現處理數據的時間僅為 1.535 秒,我們看看 Go 的表現如何。

本文將基于 Go 特有的功能進行優化。注:所有基準數據都是在多次運行后計算得出的。

硬件設置

在配備 M2 Pro 芯片的 16 英寸 MacBook Pro 上進行了所有測試,該芯片擁有 12 個 CPU 核和 36 GB 內存。不同環境運行的測試結果可能因硬件而異,但相對性能差異應該差不多。

什么是 "10 億行挑戰"?

挑戰很簡單:處理包含 10 億個任意溫度測量值的文本文件,并計算每個站點的匯總統計數據(最小值、平均值和最大值)。問題在于如何高效處理如此龐大的數據集。

數據集通過代碼倉庫中的createMeasurements.go 腳本生成。運行腳本后,將得到一個 12.8 GB 大的由分號分隔的文本文件(measurements.txt),包含兩列數據:站點名稱和測量值。

我們需要處理該文件,并輸出以下結果:

{Station1=12.3/25.6/38.9, Station2=10.0/22.5/35.0, ...}

我們看看如何實現這一目標。

Go 初始實現

1.單核版本

我們從基本的單線程實現開始。該版本逐行讀取文件,解析數據,并更新映射以跟蹤統計數據。

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

type Stats struct {
    Min   float64
    Max   float64
    Sum   float64
    Count int64
}

func processFile(filename string) {
    file, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    statsMap := make(map[string]*Stats)
    scanner := bufio.NewScanner(file)

    for scanner.Scan() {
        line := scanner.Text()
        parts := strings.Split(line, ";")
        if len(parts) != 2 {
            continue
        }

        station := parts[0]
        measurement, err := strconv.ParseFloat(parts[1], 64)
        if err != nil {
            continue
        }

        stat, exists := statsMap[station]
        if !exists {
            statsMap[station] = &Stats{
                Min:   measurement,
                Max:   measurement,
                Sum:   measurement,
                Count: 1,
            }
        } else {
            if measurement < stat.Min {
                stat.Min = measurement
            }
            if measurement > stat.Max {
                stat.Max = measurement
            }
            stat.Sum += measurement
            stat.Count++
        }
    }

    if err := scanner.Err(); err != nil {
        panic(err)
    }

    fmt.Print("{")
    for station, stat := range statsMap {
        mean := stat.Sum / float64(stat.Count)
        fmt.Printf("%s=%.1f/%.1f/%.1f, ", station, stat.Min, mean, stat.Max)
    }
    fmt.Print("\b\b} \n")
}

func main() {
    processFile("data/measurements.txt")
}

2.多核版本

為了充分利用多個 CPU 核,我們把文件分成若干塊,然后利用Goroutine 和Channel 并行處理。

package main

import (
    "bufio"
    "fmt"
    "os"
    "runtime"
    "strconv"
    "strings"
    "sync"
)

type Stats struct {
    Min   float64
    Max   float64
    Sum   float64
    Count int64
}

func worker(lines []string, wg *sync.WaitGroup, statsChan chan map[string]*Stats) {
    defer wg.Done()
    statsMap := make(map[string]*Stats)

    for _, line := range lines {
        parts := strings.Split(line, ";")
        if len(parts) != 2 {
            continue
        }

        station := parts[0]
        measurement, err := strconv.ParseFloat(parts[1], 64)
        if err != nil {
            continue
        }

        stat, exists := statsMap[station]
        if !exists {
            statsMap[station] = &Stats{
                Min:   measurement,
                Max:   measurement,
                Sum:   measurement,
                Count: 1,
            }
        } else {
            if measurement < stat.Min {
                stat.Min = measurement
            }
            if measurement > stat.Max {
                stat.Max = measurement
            }
            stat.Sum += measurement
            stat.Count++
        }
    }

    statsChan <- statsMap
}

func processFile(filename string) {
    file, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    numCPU := runtime.NumCPU()
    linesPerWorker := 1000000
    scanner := bufio.NewScanner(file)
    lines := make([]string, 0, linesPerWorker)

    var wg sync.WaitGroup
    statsChan := make(chan map[string]*Stats, numCPU)

    go func() {
        wg.Wait()
        close(statsChan)
    }()

    for scanner.Scan() {
        lines = append(lines, scanner.Text())
        if len(lines) >= linesPerWorker {
            wg.Add(1)
            go worker(lines, &wg, statsChan)
            lines = make([]string, 0, linesPerWorker)
        }
    }

    if len(lines) > 0 {
        wg.Add(1)
        go worker(lines, &wg, statsChan)
    }

    if err := scanner.Err(); err != nil {
        panic(err)
    }

    finalStats := make(map[string]*Stats)
    for partialStats := range statsChan {
        for station, stat := range partialStats {
            existingStat, exists := finalStats[station]
            if !exists {
                finalStats[station] = stat
            } else {
                if stat.Min < existingStat.Min {
                    existingStat.Min = stat.Min
                }
                if stat.Max > existingStat.Max {
                    existingStat.Max = stat.Max
                }
                existingStat.Sum += stat.Sum
                existingStat.Count += stat.Count
            }
        }
    }

    fmt.Print("{")
    for station, stat := range finalStats {
        mean := stat.Sum / float64(stat.Count)
        fmt.Printf("%s=%.1f/%.1f/%.1f, ", station, stat.Min, mean, stat.Max)
    }
    fmt.Print("\b\b} \n")
}

func main() {
    processFile("data/measurements.txt")
}

3.Go 實現結果

單核和多核版本的運行結果分別如下:

  • 單核版本:15 分 30 秒
  • 多核版本:6 分 45 秒

雖然多核版本有明顯改善,但處理數據仍然花了好幾分鐘。下面看看如何進一步優化。

利用 Go 的并發和緩沖 I/O 進行優化

為了提高性能,我們考慮利用緩沖 I/O,并優化 Goroutine。

package main

import (
    "bufio"
    "fmt"
    "os"
    "runtime"
    "strconv"
    "strings"
    "sync"
)

type Stats struct {
    Min   float64
    Max   float64
    Sum   float64
    Count int64
}

func worker(id int, jobs <-chan []string, results chan<- map[string]*Stats, wg *sync.WaitGroup) {
    defer wg.Done()
    for lines := range jobs {
        statsMap := make(map[string]*Stats)
        for _, line := range lines {
            parts := strings.Split(line, ";")
            if len(parts) != 2 {
                continue
            }

            station := parts[0]
            measurement, err := strconv.ParseFloat(parts[1], 64)
            if err != nil {
                continue
            }

            stat, exists := statsMap[station]
            if !exists {
                statsMap[station] = &Stats{
                    Min:   measurement,
                    Max:   measurement,
                    Sum:   measurement,
                    Count: 1,
                }
            } else {
                if measurement < stat.Min {
                    stat.Min = measurement
                }
                if measurement > stat.Max {
                    stat.Max = measurement
                }
                stat.Sum += measurement
                stat.Count++
            }
        }
        results <- statsMap
    }
}

func processFile(filename string) {
    file, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    defer file.Close()

    numCPU := runtime.NumCPU()
    jobs := make(chan []string, numCPU)
    results := make(chan map[string]*Stats, numCPU)

    var wg sync.WaitGroup
    for i := 0; i < numCPU; i++ {
        wg.Add(1)
        go worker(i, jobs, results, &wg)
    }

    go func() {
        wg.Wait()
        close(results)
    }()

    scanner := bufio.NewScanner(file)
    bufferSize := 1000000
    lines := make([]string, 0, bufferSize)

    for scanner.Scan() {
        lines = append(lines, scanner.Text())
        if len(lines) >= bufferSize {
            jobs <- lines
            lines = make([]string, 0, bufferSize)
        }
    }

    if len(lines) > 0 {
        jobs <- lines
    }
    close(jobs)

    if err := scanner.Err(); err != nil {
        panic(err)
    }

    finalStats := make(map[string]*Stats)
    for partialStats := range results {
        for station, stat := range partialStats {
            existingStat, exists := finalStats[station]
            if !exists {
                finalStats[station] = stat
            } else {
                if stat.Min < existingStat.Min {
                    existingStat.Min = stat.Min
                }
                if stat.Max > existingStat.Max {
                    existingStat.Max = stat.Max
                }
                existingStat.Sum += stat.Sum
                existingStat.Count += stat.Count
            }
        }
    }

    fmt.Print("{")
    for station, stat := range finalStats {
        mean := stat.Sum / float64(stat.Count)
        fmt.Printf("%s=%.1f/%.1f/%.1f, ", station, stat.Min, mean, stat.Max)
    }
    fmt.Print("\b\b} \n")
}

func main() {
    processFile("data/measurements.txt")
}

優化 Go 實現結果

優化后,處理時間大大縮短:

多核優化版:3 分 50 秒

確實獲得了實質性改進,但仍然無法與最快的 Java 實現相媲美。

利用高效數據格式

由于文本文件不是處理大型數據集的最有效方式,我們考慮將數據轉換為 Parquet 等二進制格式來提高效率。

1.轉換為 Parquet

可以用 Apache Arrow 等工具將文本文件轉換為 Parquet 文件。為簡單起見,假設數據已轉換為measurements.parquet。

2.用 Go 處理 Parquet 文件

我們用parquet-go 庫來讀取 Parquet 文件。

package main

import (
    "fmt"
    "log"
    "sort"

    "github.com/xitongsys/parquet-go/reader"
    "github.com/xitongsys/parquet-go/source/local"
)

type Measurement struct {
    StationName string  `parquet:"name=station_name, type=BYTE_ARRAY, convertedtype=UTF8, encoding=PLAIN_DICTIONARY"`
    Measurement float64 `parquet:"name=measurement, type=DOUBLE"`
}

type Stats struct {
    Min   float64
    Max   float64
    Sum   float64
    Count int64
}

func processParquetFile(filename string) {
    fr, err := local.NewLocalFileReader(filename)
    if err != nil {
        log.Fatal(err)
    }
    defer fr.Close()

    pr, err := reader.NewParquetReader(fr, new(Measurement), 4)
    if err != nil {
        log.Fatal(err)
    }
    defer pr.ReadStop()

    num := int(pr.GetNumRows())
    statsMap := make(map[string]*Stats)

    for i := 0; i < num; i += 1000000 {
        readNum := 1000000
        if i+readNum > num {
            readNum = num - i
        }

        measurements := make([]Measurement, readNum)
        if err = pr.Read(&measurements); err != nil {
            log.Fatal(err)
        }

        for _, m := range measurements {
            stat, exists := statsMap[m.StationName]
            if !exists {
                statsMap[m.StationName] = &Stats{
                    Min:   m.Measurement,
                    Max:   m.Measurement,
                    Sum:   m.Measurement,
                    Count: 1,
                }
            } else {
                if m.Measurement < stat.Min {
                    stat.Min = m.Measurement
                }
                if m.Measurement > stat.Max {
                    stat.Max = m.Measurement
                }
                stat.Sum += m.Measurement
                stat.Count++
            }
        }
    }

    stationNames := make([]string, 0, len(statsMap))
    for station := range statsMap {
        stationNames = append(stationNames, station)
    }
    sort.Strings(stationNames)

    fmt.Print("{")
    for _, station := range stationNames {
        stat := statsMap[station]
        mean := stat.Sum / float64(stat.Count)
        fmt.Printf("%s=%.1f/%.1f/%.1f, ", station, stat.Min, mean, stat.Max)
    }
    fmt.Print("\b\b} \n")
}

func main() {
    processParquetFile("data/measurements.parquet")
}

3.Parquet 處理結果

通過以 Parquet 格式處理數據,取得了顯著的性能提升:

Parquet 處理時間:5 秒

Go 的性能更進一步接近了最快的 Java 實現。

結論

Go 在 10 億行挑戰中表現出色。通過利用 Go 的并發模型和優化 I/O 操作,大大縮短了處理時間。通過將數據集轉換為二進制格式(如 Parquet)可進一步提高性能。

主要收獲:

  • Go 高效的并發機制使其適合處理大型數據集。
  • 優化 I/O 和使用緩沖讀取可大幅提高性能。
  • 利用 Parquet 等高效數據格式可大大縮短處理時間。

最終想法:

盡管 Go 可能無法取代速度最快的 Java 實現,但在高效處理大數據方面展示了令人印象深刻的能力。工具的選擇和優化可以縮小性能差距,使 Go 成為數據密集型任務的可行選擇。

參考資料

  • [1]Go One Billion Row Challenge — From 15 Minutes to 5 Seconds:https://medium.com/@code-geass/go-one-billion-row-challenge-from-15-minutes-to-5-seconds-a1206611e230
  • [2]10 億行挑戰:https://1brc.dev
責任編輯:趙寧寧 來源: DeepNoMind
相關推薦

2024-11-08 09:34:54

2021-07-19 15:33:27

編程Rust開發

2019-01-30 09:34:56

ElasticSearLogstashKibana

2022-05-02 17:43:23

Java編程語言

2021-03-03 11:36:57

Java 8Java 15Java

2023-06-19 14:09:43

2022-09-26 09:41:25

MySQL數據庫

2015-11-23 17:34:33

秒借

2025-03-27 00:14:10

2021-08-26 10:13:22

5G 5G網絡5G商用

2020-01-21 19:26:28

5G網絡數據

2015-04-09 14:26:07

2021-05-19 09:26:03

代碼開源IBM

2019-11-26 10:50:47

代碼編程語言重構

2015-08-17 10:42:13

2014-12-01 11:15:40

2017-06-03 23:30:32

視覺問答深度學習數據集

2017-12-25 11:15:06

JavaArray數組

2015-12-28 15:55:57

戴爾云計算

2021-12-31 18:20:44

數據云端數據遷移
點贊
收藏

51CTO技術棧公眾號

aa在线免费观看| 欧美大片免费看| 国产亚洲视频一区| av免费在线视| 国产女同性恋一区二区| 91在线观看免费观看| 91视频免费网址| 婷婷亚洲综合| 亚洲欧美一区二区精品久久久| 成人av毛片在线观看| 涩涩涩在线视频| 亚洲欧洲美洲综合色网| 免费精品视频一区二区三区| 国产视频在线观看视频| 免费亚洲婷婷| 欧美俄罗斯乱妇| 91成人精品一区二区| 亚洲精选av| 欧美日韩精品综合在线| 99热成人精品热久久66| 欧洲黄色一区| 中文字幕在线观看一区| 欧洲一区二区在线观看| 亚洲精品综合网| 久久99久久99小草精品免视看| 97国产一区二区精品久久呦| 欧美成人精品欧美一级| 99热精品久久| 一区二区三区四区视频| av网站有哪些| jizz国产精品| 日韩小视频在线观看专区| 99久久激情视频| 色多多在线观看| 亚洲一区二区三区四区在线| 最新av在线免费观看| 爱久久·www| 久久久五月婷婷| 精品国产乱码久久久久软件 | 亚洲综合好骚| 欧美日韩福利电影| 亚洲成人生活片| 欧美激情黄色片| 日韩综合视频在线观看| 精品成人无码一区二区三区| 久久91精品| 亚洲精品之草原avav久久| 国产视频久久久久久| 成人在线视频中文字幕| 精品国产凹凸成av人网站| 久草福利在线观看| 日韩中文字幕一区二区高清99| 91麻豆精品国产91久久久久久久久 | 在线视频免费在线观看一区二区| 久久久久久国产精品美女| 欧美在线视频第一页| 亚洲草久电影| 欧美成人免费全部| 国产亚洲精品成人| 亚洲性感美女99在线| 久久久亚洲国产| 日本在线小视频| 在线亚洲国产精品网站| 欧美在线一区二区视频| 国语对白永久免费| 蜜桃av综合| 国产精品美乳在线观看| 伊人色综合久久久| 韩国三级中文字幕hd久久精品| 成人在线中文字幕| 精品国产av一区二区| 粉嫩高潮美女一区二区三区| 国产精品一级久久久| 婷婷在线观看视频| 国产日韩欧美亚洲| 中文精品视频一区二区在线观看| av中文字幕在线观看| 亚洲亚洲精品在线观看| 亚洲中文字幕无码不卡电影| 久久xxx视频| 91精品福利在线一区二区三区| 熟女人妻一区二区三区免费看| 婷婷成人综合| 久久精品欧美视频| 日本网站在线播放| 免费在线观看成人av| 国产精品一区二区三区久久久| 国产v片在线观看| www激情久久| 宅男av一区二区三区| 精品一性一色一乱农村| 欧美性色黄大片| 妖精视频在线观看| 国产亚洲一区二区三区不卡| 久久成人综合视频| 久久免费激情视频| 国产一区二区在线视频| 久久久久久久久久码影片| 国产二区视频在线观看| 亚洲一线二线三线久久久| 久久久久久久久久久免费视频| 国产一区二区| 亚洲人成毛片在线播放| 欧美成人手机视频| 日韩电影在线观看电影| 国产欧美日韩在线播放| 日韩伦理在线电影| 欧美午夜精品久久久久久浪潮| 久国产精品视频| 国产探花在线精品| 欧美黑人性生活视频| 中文字幕在线2018| 91丨porny丨最新| www.一区二区.com| 国内欧美日韩| 亚洲人成电影网站色xx| 麻豆一区二区三区精品视频| 精品一区二区三区日韩| 国产成人aa精品一区在线播放| 亚洲国产精品成人av| 亚洲影院理伦片| 中文字幕第一区二区| 欧美成人一区二区| 中文字幕在线免费看线人| 在线精品国产| 国产精品久久久久久久久久新婚| 女人18毛片一区二区三区| **欧美大码日韩| 91香蕉视频污版| 性人久久久久| 7m精品福利视频导航| 亚洲男人第一天堂| 亚洲欧美日韩中文播放 | www.av欧美| 激情欧美一区| 国产精品大全| 狂野欧美性猛交xxxxx视频| 美女爽到高潮91| 欧美网站一区二区| 国产艳俗歌舞表演hd| 禁久久精品乱码| 91嫩草视频在线观看| 免费不卡视频| 91精品国产综合久久香蕉麻豆| 国产不卡在线观看视频| 日韩福利电影在线| 欧美性色黄大片人与善| 黑人精品一区| 一区二区三区www| 中文字幕在线日本| 久久日韩粉嫩一区二区三区| 久久久999视频| 香蕉视频一区二区三区| 68精品久久久久久欧美| 无码精品一区二区三区在线| 亚洲成在线观看| 亚洲av人人澡人人爽人人夜夜| 欧美日韩国产高清| 国产在线精品一区二区中文| 51漫画成人app入口| 亚洲国产欧美在线成人app | 青青草免费在线| 色伊人久久综合中文字幕| 波多野结衣 在线| 久久午夜视频| 亚洲午夜精品久久久久久浪潮| 免费成人黄色网| 免费成人高清视频| www三级免费| 午夜伊人狠狠久久| a级片在线观看| 激情综合色播五月| 久久久天堂国产精品| 精品精品国产毛片在线看| 欧美一区二区大胆人体摄影专业网站| 黄色在线免费观看大全| 欧美三日本三级三级在线播放| 国产欧美小视频| 国产一区二区免费在线| 久久久久久免费看| 中文字幕中文字幕精品| 国产欧美日韩精品专区| 4438x成人网全国最大| 精品成人在线观看| 亚洲无码精品一区二区三区| 日韩一区日韩二区| 水蜜桃av无码| 精品综合久久久久久8888| 日韩a级在线观看| 精品久久久久中文字幕小说| 91在线观看免费观看| 日韩av一卡| 久久久国产一区| 天天干天天草天天射| 欧美久久久久久久久中文字幕| 日韩久久久久久久久| 国产精品国产自产拍在线| 国产精品一区二区在线免费观看| 日韩高清不卡一区二区三区| 欧美性猛交内射兽交老熟妇| 国产一区网站| 国产精品18毛片一区二区| 日产精品一区| 午夜精品久久久久久99热| 日本在线观看www| 亚洲第一区中文99精品| 在线视频免费观看一区| 亚洲成人激情自拍| 精品国产视频一区二区三区| 久久久久久一级片| 男人女人拔萝卜视频| 免费一级欧美片在线观看| 国产在线精品91| 欧美影视一区| 亚洲永久一区二区三区在线| 欧洲亚洲视频| av一本久道久久波多野结衣| 欧美成人毛片| 国产精品久久久久久久久影视 | 精品久久久久一区二区| 狠狠色丁香九九婷婷综合五月| 毛片av免费在线观看| 国产精品vip| 福利在线小视频| 久久精品不卡| 亚洲第一综合| 国产一区二区三区四区五区| 好看的日韩精品视频在线| 亚洲码欧美码一区二区三区| 91亚洲人电影| 91麻豆精品| 国产欧美精品在线| 欧美亚洲二区| 国产欧美亚洲视频| 久久天天久久| 国产日韩欧美在线看| 国产成人精品一区二区三区视频 | 久久精品夜夜夜夜夜久久| 二区三区在线| 国产一区二区三区网站| 黄色小视频在线免费观看| 亚洲欧美视频在线| 三级在线播放| 亚洲男女自偷自拍图片另类| 欧美777四色影视在线| 国产视频精品va久久久久久| 天天操天天干天天爱| 亚洲激情在线观看| 色婷婷av一区二区三区之红樱桃 | 国模私拍在线观看| av在线免费不卡| 亚洲中文字幕一区| 91麻豆福利精品推荐| 亚洲天堂久久新| 国产三级欧美三级日产三级99| 黄色av免费播放| 国产精品视频在线看| 激情无码人妻又粗又大| 亚洲丝袜另类动漫二区| 一区二区三区四区五区| 亚洲国产一区二区三区| 成人毛片18女人毛片| 色偷偷久久人人79超碰人人澡| 欧美成人精品网站| 欧美日韩另类国产亚洲欧美一级| 国产又粗又黄又爽的视频| 91精品国产综合久久精品性色| 99久久久国产精品无码网爆| 精品少妇一区二区三区视频免付费| 性生活三级视频| 亚洲国产精品国自产拍av秋霞 | 久久奇米777| 香蕉久久久久久久| 一区二区视频在线| 日韩 欧美 综合| 在线精品视频一区二区| 国产精品久久久久久无人区| 日韩欧美高清在线| 婷婷亚洲一区二区三区| 在线视频亚洲欧美| 金瓶狂野欧美性猛交xxxx| 欧美性在线视频| 亚洲欧美专区| 精品伊人久久大线蕉色首页| 超碰成人久久| 国产女教师bbwbbwbbw| 久久高清国产| 色哟哟在线观看视频| 久久综合九色综合久久久精品综合| 欧美乱大交做爰xxxⅹ小说| 亚洲一线二线三线久久久| 黄色网址中文字幕| 欧美一二三四区在线| 国产在线网站| 欧美激情亚洲国产| 久久人人视频| 欧美12av| 国产精品久久| 国产野外作爱视频播放| 成人激情综合网站| 亚洲图片第一页| 在线免费观看亚洲| av一二三不卡影片| 国产mv免费观看入口亚洲| 欧美人与性囗牲恔配| 日本欧美韩国| 亚洲国语精品自产拍在线观看| 美丽的姑娘在线观看免费动漫| 久久精品国产一区二区电影| 成人免费影院| 成人情视频高清免费观看电影| 日韩精品久久| 国产xxxxx视频| 成人av在线网站| 一区二区成人免费视频| 欧美亚洲动漫制服丝袜| 天堂中文在线看| 欧美日韩国产成人| 亚洲色图图片| 欧美一区二区三区婷婷月色| 免费观看黄网站| 国产欧美一区视频| 欧美在线观看不卡| 精品国产免费人成在线观看| 麻豆传媒在线观看| 国产精品成人观看视频国产奇米| 麻豆一区二区麻豆免费观看| 久久久久久久香蕉| 激情文学综合插| 天美传媒免费在线观看| 日本道色综合久久| 飘雪影院手机免费高清版在线观看 | 免费看成人哺乳视频网站| 日韩国产一级片| 国产suv一区二区三区88区| 国产精品成人69xxx免费视频| 在线观看国产91| 川上优的av在线一区二区| 日韩免费黄色av| 怕怕欧美视频免费大全| 免费毛片小视频| 久久久久久久久久看片| 国产成人综合欧美精品久久| 亚洲国产精品高清久久久| aa级大片免费在线观看| 国产区日韩欧美| 中文亚洲字幕| 日韩av在线看免费观看| 色婷婷亚洲综合| 国产露出视频在线观看| 国产精品视频网站| 大色综合视频网站在线播放| 久久国产精品国产精品| 亚洲欧洲www| 国产女同91疯狂高潮互磨| 色综合久久精品亚洲国产| 哺乳一区二区三区中文视频 | 蜜桃久久久久久| av最新在线观看| 精品国产自在久精品国产| 999精品网| 欧美亚洲精品日韩| 麻豆精品一区二区av白丝在线| 97在线观看视频免费| 日韩欧美色综合| 伊人久久综合一区二区| 日韩在线第一区| 国产乱码精品一区二区三区av| 国产一级中文字幕| 亚洲精品日韩丝袜精品| 国产69精品久久久久按摩| 日本黄色a视频| 成人手机电影网| 69xxxx国产| 久久这里有精品| 开心激情综合| 欧美丰满熟妇xxxxx| 中文字幕日韩av资源站| 国内爆初菊对白视频| 欧美综合国产精品久久丁香| 色999日韩| 日韩综合第一页| 欧美午夜一区二区三区| 青春草免费在线视频| 欧美三级电影在线播放| 国产在线精品一区二区夜色| 国产女同在线观看| 色先锋资源久久综合5566| 国产成人aa在线观看网站站| 午夜欧美福利视频| 一区二区三区精品| 嫩草在线播放| 99re在线观看| 日韩成人免费看| 国产一级大片在线观看| 中文字幕一区二区三区电影| 久久激情av| 亚洲在线观看网站| 色综合一个色综合亚洲| 黄页网站在线|