国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

火山引擎在行為分析場景下的 ClickHouse JOIN 優(yōu)化

原創(chuàng) 精選
大數(shù)據(jù)
火山引擎增長分析 DataFinder 基于 ClickHouse 來進行行為日志的分析,ClickHouse 的主要版本是基于社區(qū)版改進開發(fā)的字節(jié)內(nèi)部版本。

1. 背景

火山引擎增長分析 DataFinder 基于 ClickHouse 來進行行為日志的分析,ClickHouse 的主要版本是基于社區(qū)版改進開發(fā)的字節(jié)內(nèi)部版本。主要的表結(jié)構(gòu):

圖片

事件表:存儲用戶行為數(shù)據(jù),以用戶 ID 分 shard 存儲。

--列出了主要的字段信息
CREATE TABLE tob_apps_all
(
`tea_app_id` UInt32, --應(yīng)用ID
`device_id` String DEFAULT '', --設(shè)備ID
`time` UInt64,--事件日志接受時間
`event` String,--事件名稱
`user_unique_id` String,--用戶ID
`event_date` Date , --事件日志日期,由time轉(zhuǎn)換而來
`hash_uid` UInt64 --用戶ID hash過后的id,用來join降低內(nèi)存消耗
)│
```

用戶表:存儲用戶的屬性數(shù)據(jù),以用戶 ID 分 shard 存儲。

--列出了主要的字段信息
CREATE TABLE users_unique_all
(
`tea_app_id` UInt32, --應(yīng)用ID
`user_unique_id` String DEFAULT '', -- 用戶ID
`device_id` String DEFAULT '', -- 用戶最近的設(shè)備ID
`hash_uid` UInt64,--用戶ID hash過后的id,用來join降低內(nèi)存消耗
`update_time` UInt64,--最近一次更新時間
`last_active_date` Date --用戶最后活躍日期
)

設(shè)備表:存儲設(shè)備相關(guān)的數(shù)據(jù),以設(shè)備 ID 分 shard 存儲。

--列出了主要的字段信息
CREATE TABLE devices_all
(
`tea_app_id` UInt32, --應(yīng)用ID
`device_id` String DEFAULT '', --設(shè)備ID
`update_time` UInt64, --最近一次更新時間
`last_active_date` Date --用戶最后活躍日期
)

業(yè)務(wù)對象表:存儲業(yè)務(wù)對象相關(guān)的數(shù)據(jù),每個 shard 存儲全量的數(shù)據(jù)。

--列出了主要的字段信息
CREATE TABLE rangers.items_all
(
`tea_app_id` UInt32,
`hash_item_id` Int64,
`item_name` String, --業(yè)務(wù)對象名稱。比如商品
`item_id` String, --業(yè)務(wù)對象ID。比如商品id 1000001
`last_active_date` Date
)

1.1 業(yè)務(wù)挑戰(zhàn)

圖片

隨著接入應(yīng)用以及應(yīng)用的 DAU 日益增加,ClickHouse 表的事件量增長迅速;并且基于行為數(shù)據(jù)需要分析的業(yè)務(wù)指標越來越復雜,需要 JOIN 的表增多;我們遇到有一些涉及到 JOIN 的復雜 SQL 執(zhí)行效率低,內(nèi)存和 CPU 資源占用高,導致分析接口響應(yīng)時延和錯誤率增加。

2. 關(guān)于 Clickhouse 的 JOIN

在介紹優(yōu)化之前,先介紹一下基本的 ClickHouse JOIN 的類型和實現(xiàn)方式。

2.1 分布式 JOIN

SELECT 
et.os_name,
ut.device_id AS user_device_id
FROM tob_apps_all AS et
ANY LEFT JOIN
(
SELECT
device_id,
hash_uid
FROM users_unique_all
WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411)
AND (event = 'app_launch')
AND (event_date = '2022-08-06')

基本執(zhí)行過程:

一個 Clickhouse 節(jié)點作為 Coordinator 節(jié)點,給每個節(jié)點分發(fā)子查詢,子查詢 sql(tob_apps_all 替換成本地表,users_unique_all 保持不變依然是分布式表)。

每個節(jié)點執(zhí)行 Coordinator 分發(fā)的 sql 時,發(fā)現(xiàn) users_unique_all 是分布式表,就會去所有節(jié)點上去查詢以下 SQL(一共有 N*N。N 為 shard 數(shù)量)。

  1. SELECT device_id, hash_uid FROMusers_uniqueWHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
  1. 每個節(jié)點從其他 N-1個節(jié)點拉取2中子查詢的全部數(shù)據(jù),全量存儲(內(nèi)存 or 文件),進行本地 JOIN。
  2. Coordinator 節(jié)點從每個節(jié)點拉取3中的結(jié)果集,然后做處理返回給 client。

存在的問題:

  1. 子查詢數(shù)量放大。
  2. 每個節(jié)點都全量存儲全量的數(shù)據(jù)。

2.2 分布式 Global JOIN

SELECT 
et.os_name,
ut.device_id AS user_device_id
FROM tob_apps_all AS et
GLOBAL ANY LEFT JOIN
(
SELECT
device_id,
hash_uid
FROM users_unique_all
WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411)
AND (event = 'app_launch')
AND (event_date = '2022-08-06')

基本執(zhí)行過程:

  1. 一個 Clickhouse 節(jié)點作為 Coordinator 節(jié)點,分發(fā)查詢。在每個節(jié)點上執(zhí)行sql(tob_apps_all 替換成本地表,右表子查詢替換成別名 ut)。
  2. Coordinator 節(jié)點去其他節(jié)點拉取 users_unique_all 的全部數(shù)據(jù),然后分發(fā)到全部節(jié)點(作為1中別名表 ut 的數(shù)據(jù))。
  3. 每個節(jié)點都會存儲全量的2中分發(fā)的數(shù)據(jù)(內(nèi)存or文件),進行本地 local join。
  4. Coordinator 節(jié)點從每個節(jié)點拉取3中的結(jié)果集,然后做處理返回給 client。

存在的問題:

  1. 每個節(jié)點都全量存儲數(shù)據(jù)。
  2. 如果右表較大,分發(fā)的數(shù)據(jù)較大,會占用網(wǎng)絡(luò)帶寬資源。

2.3 本地 JOIN

SQL 里面只有本地表的 JOIN,只會在當前節(jié)點執(zhí)行。

SELECT et.os_name,ut.device_id AS user_device_id
FROM tob_apps et any LEFT JOIN
(SELECT device_id,
hash_uid
FROM rangers.users_unique
WHERE tea_app_id = 268411
AND last_active_date>='2022-08-06') ut
ON et.hash_uid=ut.hash_uid
WHERE tea_app_id = 268411
AND event='app_launch'
AND event_date='2022-08-06'

2.3.1 Hash join

  • 右表全部數(shù)據(jù)加載到內(nèi)存,再在內(nèi)存構(gòu)建 hash table。key 為 joinkey。
  • 從左表分批讀取數(shù)據(jù),從右表 hash table匹配數(shù)據(jù)。
  • 優(yōu)點是:速度快 缺點是:右表數(shù)據(jù)量大的情況下占用內(nèi)存。

2.3.2 Merge join?

  • 對右表排序,內(nèi)部 block 切分,超出內(nèi)存部分 flush 到磁盤上,內(nèi)存大小通過參數(shù)設(shè)定。
  • 左表基于 block 排序,按照每個 block 依次與右表 merge。
  • 優(yōu)點是:能有效控制內(nèi)存 缺點是:大數(shù)據(jù)情況下速度會慢。

優(yōu)先使用 hash join 當內(nèi)存達到一定閾值后再使用 merge join,優(yōu)先滿足性能要求。

3. 解決方案

圖片

3.1 避免JOIN

3.1.1 數(shù)據(jù)預生成

數(shù)據(jù)預生成(由 Spark/Flink 或者 Clickhouse 物化視圖產(chǎn)出數(shù)據(jù)),形成大寬表,基于單表的查詢是 ClickHouse 最為擅長的場景。

我們有個指標,實現(xiàn)的 SQL 比較復雜(如下),每次實時查詢很耗時,我們單獨建了一個表 table,由 Spark 每日構(gòu)建出這個指標,查詢時直接基于 table 查詢。

SELECT event_date,count(distinct uc1) AS uv,sum(value) AS sum_value, ......
FROM
(SELECT event_date,hash_uid AS uc1,sum(et.float_params{ 'amount' }) AS value, count(1) AS cnt, value*cnt AS multiple
FROM tob_apps_all et GLOBAL ANY LEFT JOIN
(SELECT hash_uid AS join_key,int_profiles{ '$ab_time_34' }*1000 AS first_time
FROM users_unique_all
WHERE app_id = 10000000 AND last_active_date >= '2022-07-19' AND first_time is NOT null) upt
ON et.hash_uid=upt.join_key
WHERE (查詢條件)
GROUP BY uc1,event_date)
GROUP BY event_date;

數(shù)據(jù)量2300W,查詢時間由7秒->0.008秒。當然這種方式,需要維護額外的數(shù)據(jù)構(gòu)建任務(wù)。總的思路就是不要讓 ClickHouse 實時去 JOIN。

圖片

3.1.2 使用 IN 代替 JOIN

JOIN 需要基于內(nèi)存構(gòu)建 hash table 且需要存儲右表全部的數(shù)據(jù),然后再去匹配左表的數(shù)據(jù)。而 IN 查詢會對右表的全部數(shù)據(jù)構(gòu)建 hash set,但是不需要匹配左表的數(shù)據(jù),且不需要回寫數(shù)據(jù)到 block。

比如:

SELECT event_date, count()
FROM tob_apps_all et global any INNER JOIN
(SELECT hash_uid AS join_key
FROM users_unique_all
WHERE app_id = 10000000
AND last_active_date >= '2022-01-01') upt
ON et.hash_uid = upt.join_key
WHERE app_id = 10000000
AND event_date >= '2022-01-01'
AND event_date <= '2022-08-02'
GROUP BY event_date

可以改成如下形式:

SELECT event_date,
count()
FROM tob_apps_all
WHERE app_id = 10000000
AND event_date >= '2022-01-01'
AND event_date <= '2022-08-02'
AND hash_uid global IN
(SELECT hash_uid
FROM users_unique_all
WHERE (tea_app_id = 10000000)
AND (last_active_date >= '2022-01-01') )
GROUP BY event_date

如果需要從右表提取出屬性到外層進行計算,則不能使用 IN 來代替 JOIN。

相同的條件下,上面的測試 SQL,由 JOIN 時的16秒優(yōu)化到了 IN 查詢時的11秒。

圖片

?

3.2 更快的 JOIN

3.2.1 優(yōu)先本地 JOIN

數(shù)據(jù)預先相同規(guī)則分區(qū)

也就是 Colocate JOIN。優(yōu)先將需要關(guān)聯(lián)的表按照相同的規(guī)則進行分布,查詢時就不需要分布式的 JOIN。

SELECT 
et.os_name,
ut.device_id AS user_device_id
FROM tob_apps_all AS et
ANY LEFT JOIN
(
SELECT
device_id,
hash_uid
FROM users_unique_all
WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411)
AND (event = 'app_launch')
AND (event_date = '2022-08-06')
settings distributed_perfect_shard=1

比如事件表 tob_apps_all 和用戶表 users_unique_all 都是按照用戶 ID 來分 shard 存儲的,相同的用戶的兩個表的數(shù)據(jù)都在同一個 shard 上,因此這兩個表的 JOIN 就不需要分布式 JOIN 了。

distributed_perfect_shard 這個 settings key 是字節(jié)內(nèi)部 ClickHouse 支持的,設(shè)置過這個參數(shù),指定執(zhí)行計劃時就不會再執(zhí)行分布式 JOIN 了。

基本執(zhí)行過程:

  1. 一個 ClickHouse 節(jié)點作為 Coordinator 節(jié)點,分發(fā)查詢。在每個節(jié)點上執(zhí)行 sql(tob_apps_all、users_unique_all替換成本地表)。
  2. 每個節(jié)點都執(zhí)行1中分發(fā)的本地表 join 的 SQL(這一步不再分發(fā)右表全量的數(shù)據(jù))。
  3. 數(shù)據(jù)再回傳到 coordinator 節(jié)點,然后返回給 client。
數(shù)據(jù)冗余存儲

如果一個表的數(shù)據(jù)量比較小,可以不分 shard 存儲,每個 shard 都存儲全量的數(shù)據(jù),例如我們的業(yè)務(wù)對象表。查詢時,不需要分布式 JOIN,直接在本地進行 JOIN 即可。

SELECT count()
FROM tob_apps_all AS et
ANY LEFT JOIN
(
SELECT item_id
FROM items_all
WHERE (tea_app_id = 268411)
) AS it ON et.item_id = it.item_id
WHERE (tea_app_id = 268411)
AND (event = 'app_launch')
AND (event_date = '2022-08-06')
settings distributed_perfect_shard=1

例如這個 SQL,items_all 表每個 shard 都存儲同樣的數(shù)據(jù),這樣也可以避免分布式 JOIN 帶來的查詢放大和全表數(shù)據(jù)分發(fā)問題。

3.2.2 更少的數(shù)據(jù)

不論是分布式 JOIN 還是本地 JOIN,都需要盡量讓少的數(shù)據(jù)參與 JOIN,既能提升查詢速度也能減少資源消耗。

SQL 下推

ClickHouse 對 SQL 的下推做的不太好,有些復雜的 SQL 下推會失效。因此,我們手動對 SQL 做了下推,目前正在測試基于查詢優(yōu)化器來幫助實現(xiàn)下推優(yōu)化,以便讓 SQL 更加簡潔。

下推的 SQL:

SELECT 
et.os_name,
ut.device_id AS user_device_id
FROM tob_apps_all AS et
ANY LEFT JOIN
(
SELECT
device_id,
hash_uid
FROM users_unique_all
WHERE (tea_app_id = 268411)
AND (last_active_date >= '2022-08-06'
AND 用戶屬性條件 1 OR 用戶屬性條件 2)
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411)
AND (event = 'app_launch')
AND (event_date = '2022-08-06')
settings distributed_perfect_shard=1

對應(yīng)的不下推的 SQL:

SELECT 
et.os_name,
ut.device_id AS user_device_id
FROM tob_apps_all AS et
ANY LEFT JOIN
(
SELECT
device_id,
hash_uid
FROM rangers.users_unique_all
WHERE (tea_app_id = 268411)
AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
WHERE (tea_app_id = 268411)
AND (event = 'app_launch')
AND (event_date = '2022-08-06')
AND (ut.用戶屬性條件 1 OR ut.用戶屬性條件 2)
settings distributed_perfect_shard=1

可以看到,不下推的 SQL 更加簡潔,直接基于 JOIN 過后的寬表進行過濾。但是 ClickHouse 可能會將不滿足條件的 users_unique_all 數(shù)據(jù)也進行 JOIN。

我們使用中有一個復雜的 case,用戶表過濾條件不下推有1千萬+,SQL 執(zhí)行了3000秒依然執(zhí)行超時,而做了下推之后60秒內(nèi)就執(zhí)行成功了。

圖片

3.2.3 Clickhouse 引擎層優(yōu)化

一個 SQL 實際在 Clickhouse 如何執(zhí)行,對 SQL 的執(zhí)行時間和資源消耗至關(guān)重要。社區(qū)版的 Clickhouse 在執(zhí)行模型和 SQL 優(yōu)化器上還要改進的空間,尤其是復雜 SQL 以及多 JOIN 的場景下。

執(zhí)行模型優(yōu)化

社區(qū)版的 Clickhouse 目前還是一個兩階段執(zhí)行的執(zhí)行模型。第一階段,Coordinator 在收到查詢后,將請求發(fā)送給對應(yīng)的 Worker 節(jié)點。第二階段,Worker 節(jié)點完成計算,Coordinator 在收到各 Worker 節(jié)點的數(shù)據(jù)后進行匯聚和處理,并將處理后的結(jié)果返回。

圖片

有以下幾個問題:

  1. 第二階段的計算比較復雜時,Coordinator 的節(jié)點計算壓力大,容易成為瓶頸。
  2. 不支持 shuffle join,hash join 時右表為大表時構(gòu)建慢,容易 OOM。
  3. 對復雜查詢的支持不友好。

字節(jié)跳動 ClickHouse 團隊為了解決上述問題,改進了執(zhí)行模型,參考其他的分布式數(shù)據(jù)庫引擎(例如 Presto 等),將一個復雜的 Query 按數(shù)據(jù)交換情況切分成多個 Stage,各 Stage 之間則通過 Exchange 完成數(shù)據(jù)交換。根據(jù) Stage 依賴關(guān)系定義拓撲結(jié)構(gòu),產(chǎn)生 DAG 圖,并根據(jù) DAG 圖調(diào)度 Stage。例如兩表 JOIN,會先調(diào)度左右表讀取 Stage,之后再調(diào)度 JOIN 這個 Stage, JOIN 的 Stage 依賴于左右表的 Stage。

圖片

舉個例子

SELECT 
et.os_name,
ut.device_id AS user_device_id,
dt.hash_did AS device_hashid
FROM tob_apps_all AS et
GLOBAL ANY LEFT JOIN
(
SELECT
device_id,
hash_uid
FROM users_unique_all
WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS ut ON et.hash_uid = ut.hash_uid
GLOBAL ANY LEFT JOIN
(
SELECT
device_id,
hash_did
FROM devices_all
WHERE (tea_app_id = 268411) AND (last_active_date >= '2022-08-06')
) AS dt ON et.device_id = dt.device_id
WHERE (tea_app_id = 268411) AND (event = 'app_launch') AND (event_date = '2022-08-06')
LIMIT 10

Stage執(zhí)行模型基本過程(可能的):

  1. 讀取 tob_apps_all 數(shù)據(jù),按照 join key(hash_uid)進行 shuffle,數(shù)據(jù)分發(fā)到每個節(jié)點。這是一個Stage。
  2. 讀取 users_unique_all 數(shù)據(jù),按照 join key(hash_uid)進行 shuffle,數(shù)據(jù)分發(fā)到每個節(jié)點。這是一個 Stage。
  3. 上述兩個表的數(shù)據(jù),在每個節(jié)點上的數(shù)據(jù)進行本地JOIN,然后再按照 join key(device_id) 進行 shuffle。這是一個 Stage。
  4. 讀取 devices_all 數(shù)據(jù),按照 join key(device_id)進行 shuffle,這是一個Stage。
  5. 第3步、第4步的數(shù)據(jù),相同 join key(device_id) 的數(shù)據(jù)都在同一個節(jié)點上,然后進行本地JOIN,這是一個 Stage。
  6. 匯總數(shù)據(jù),返回 limit 10 的數(shù)據(jù)。這是一個 Stage。

統(tǒng)計效果如下:

圖片

查詢優(yōu)化器

有了上面的 stage 的執(zhí)行模型,可以靈活調(diào)整 SQL 的執(zhí)行順序,字節(jié)跳動 Clickhouse 團隊自研了查詢優(yōu)化器,根據(jù)優(yōu)化規(guī)則(基于規(guī)則和代價預估)對 SQL 的執(zhí)行計劃進行轉(zhuǎn)換,一個執(zhí)行計劃經(jīng)過優(yōu)化規(guī)則后會變成另外一個執(zhí)行計劃,能夠準確的選擇出一條效率最高的執(zhí)行路徑,然后構(gòu)建 Stage 的 DAG 圖,大幅度降低查詢時間。

下圖描述了整個查詢的執(zhí)行流程,從 SQL parse 到執(zhí)行期間所有內(nèi)容全部進行了重新實現(xiàn)(其中紫色模塊),構(gòu)建了一套完整的且規(guī)范的查詢優(yōu)化器。

圖片

還是上面的三表 JOIN 的例子,可能的一個執(zhí)行過程是:

  1. 查詢優(yōu)化器發(fā)現(xiàn) users_unique_all 表與 tob_apps_all 表的分 shard 規(guī)則一樣(基于用戶 ID ),所以就不會先對表按 join key 進行 shuffle,users_unique 與 tob_apps 直接基于本地表 JOIN,然后再按照 join key(device_id)進行 shuffle。這是一個 Stage。
  2. 查詢優(yōu)化器根據(jù)規(guī)則或者代價預估決定設(shè)備表 devices_all 是需要 broadcast join 還是 shuffle join。
  1. 如果 broadcast join:在一個節(jié)點查到全部的 device 數(shù)據(jù),然后分發(fā)到其他節(jié)點。這是一個 Stage。
  2. 如果 shuffle join:在每個節(jié)點對 device 數(shù)據(jù)按照 join key(device_id) 進行 shuffle。這是一個 Stage。
  1. 匯總數(shù)據(jù),返回 limit 10 的數(shù)據(jù)。這是一個 Stage。

效果:

可以看到,查詢優(yōu)化器能優(yōu)化典型的復雜的 SQL 的執(zhí)行效率,縮短執(zhí)行時間。

圖片

4. 總結(jié)

ClickHouse 最為擅長的領(lǐng)域是一個大寬表來進行查詢,多表 JOIN 時Clickhouse 性能表現(xiàn)不佳。作為業(yè)內(nèi)領(lǐng)先的用戶分析與運營平臺,火山引擎增長分析 DataFinder 基于海量數(shù)據(jù)做到了復雜指標能夠秒級查詢。本文介紹了我們是如何優(yōu)化 Clickhouse JOIN 查詢的。

主要有以下幾個方面:

  1. 減少參與 JOIN 的表以及數(shù)據(jù)量。
  2. 優(yōu)先使用本地 JOIN,避免分布式 JOIN 帶來的性能損耗。
  3. 優(yōu)化本地 JOIN,優(yōu)先使用內(nèi)存進行 JOIN。
  4. 優(yōu)化分布式 JOIN 的執(zhí)行邏輯,依托于字節(jié)跳動對 ClickHouse 的深度定制化。
責任編輯:未麗燕 來源: 字節(jié)跳動技術(shù)團隊
相關(guān)推薦

2022-12-07 08:31:45

ClickHouse并行計算數(shù)據(jù)

2021-04-14 14:31:37

私有云veStack系統(tǒng)

2021-09-16 10:47:09

數(shù)字化

2022-05-13 07:26:28

策略模式設(shè)計模式

2022-06-30 09:50:15

火山引擎ByteHouse

2021-08-31 16:17:50

數(shù)字化

2023-10-19 14:55:22

火山引擎擁塞控制算法

2025-05-20 08:35:00

2023-09-15 14:24:54

ByteHouseClickHouse開源

2021-09-16 14:30:02

數(shù)字化

2022-08-04 18:23:28

屏幕共享卡頓流暢度

2021-11-11 21:35:48

數(shù)字化
點贊
收藏

51CTO技術(shù)棧公眾號

国产拍揄自揄精品视频麻豆| 久久久国产午夜精品 | 中文字幕一区二区精品| aaa亚洲精品| 日韩一区二区三区电影| 成人深夜直播免费观看| 亚洲综合色在线观看| 精品久久免费| 色女人在线视频| 天天天综合网| 亚洲精选在线视频| 欧美激情videoshd| 久久久久久久少妇| 美女福利一区二区三区| 日本aⅴ精品一区二区三区 | 欧美成人a视频| 97久久天天综合色天天综合色hd| 成全视频全集| 国产精品男女| 久久久久国产精品人| 国产日韩欧美一区二区| 91在线直播| 欧美激情视频一区二区三区在线播放 | 日韩视频在线你懂得| 日本成在线观看| 久久99蜜桃| 亚洲一区免费在线观看| 性色av一区二区三区在线观看| 国产在线播放观看| 精品国产第一福利网站| 91极品美女在线| 97自拍视频| 久久亚洲黄色| 日韩欧美在线看| 国产精品亚洲综合| 成人ww免费完整版在线观看| 久久精品人人| 国产视频久久久| 国产主播自拍av| 久久99国产精品免费网站| 亚洲品质视频自拍网| 九色自拍视频在线观看| 免费观看久久久4p| 久久九九亚洲综合| av网站在线不卡| av不卡一区二区三区| 天天干天天色天天爽| 日本亚洲视频| 亚洲三级在线播放| 99久久精品免费看国产一区二区三区| 自拍视频在线播放| 一本色道久久综合亚洲aⅴ蜜桃| 免费国产在线精品一区二区三区| 91精品国产黑色瑜伽裤| 成人动漫精品一区二区| 欧美激情视频一区| 中文av一区二区三区| 国产精品99视频| 国产精品久久久久久亚洲影视| 狠狠狠综合7777久夜色撩人| 亚洲综合不卡| 自拍偷拍亚洲一区| 欧美大胆成人| 一区二区在线观看视频在线观看| 国内外成人免费视频| 国产一区二区三区四区三区四| 精品裸体舞一区二区三区| 男人天堂手机在线| 久久蜜桃av一区二区天堂| 国产精品一区二区久久久| 成人免费视屏| 精品久久久久久无| 天堂中文在线播放| 五月天亚洲精品| 黄色www在线观看| 三级精品视频| 精品国产99国产精品| 在线成人私人影院| 国产精品最新自拍| 欧美另类在线播放| 免费高清在线观看| 亚洲高清不卡av| 捆绑紧缚一区二区三区在线观看| 一区二区三区精品在线| 一区二区三区精品国产| 亚洲女娇小黑人粗硬| 日韩电影视频免费| 日本午夜在线视频| 99r精品视频| 精品乱码一区| 红杏aⅴ成人免费视频| 国产精品视频永久免费播放| 在线观看亚洲| 国产97色在线|日韩| 日韩在线影院| 性欧美暴力猛交69hd| 午夜久久影院| 欧美日韩国产成人在线| 日本不卡二三区| 久久不射电影网| 亚洲第一图区| 久久综合伊人77777| 日韩精品网站| 欧美激情精品久久久久久大尺度| 免费看成人哺乳视频网站| 精选一区二区三区四区五区| 欧美在线色图| 亚洲免费久久| 一级成人国产| 亚洲在线视频福利| 精品国产乱码久久久| 久久久999国产| 99热在线成人| 亚洲精品少妇一区二区| 热久久国产精品| 激情综合网五月激情| 97精品超碰一区二区三区| 最近中文字幕mv第三季歌词| 国产亚洲精品bt天堂精选| 丰满人妻一区二区三区53号| 视频一区二区中文字幕| 国产一区二区久久久| 久久久久久久久久久99999| 国产成人无吗| 国产精品偷伦免费视频观看的| 国产一区二区精品久久| 亚洲精品自在在线观看| 一区二区三区四区在线播放| 亚洲美女炮图| 成人免费视频网站| 在线国产一区| 国产日韩精品在线观看| 全球成人免费直播| 青青青在线观看视频| 国产成人亚洲精品青草天美| 亚洲国产欧美日韩| 亚洲一级二级三级| 99综合久久| 欧美国产中文字幕| 久草精品在线观看| 国产在线91| 欧美在线一级va免费观看| 福利在线一区| 性欧美18一19内谢| 欧美一级一区二区| 原纱央莉成人av片| 久久亚洲综合网| 一本大道综合伊人精品热热| 日韩高清在线免费观看| 亚洲熟妇av日韩熟妇在线| 国产欧美在线观看一区| 亚洲美女炮图| 日本一区二区三区视频在线观看 | 亚洲成人网在线| 亚洲经典三级| 色狠狠久久av五月综合| 久久精品国产在热久久| 国产精品av免费观看| 欧美一区二区不卡视频| 精品动漫3d一区二区三区免费| 情趣网站视频在线观看| 91精品在线一区二区| 国产精品186在线观看在线播放| 亚洲激情视频在线观看| 色综合视频一区二区三区44| 2019中文在线观看| 欧美破处大片在线视频| 日本成本人片免费观看| 午夜剧场成人观在线视频免费观看| 91视视频在线观看入口直接观看www| 超碰成人福利网| 欧美日韩成人在线播放| 91社区在线播放| 国产精品日本一区二区不卡视频| 国产aⅴ夜夜欢一区二区三区| 国产精品进线69影院| jzzjzzjzz亚洲成熟少妇| 日韩国产激情在线| 青青草成人在线观看| 台湾佬中文娱乐网欧美电影| 精品久久久无码人妻字幂| 中文字幕亚洲情99在线| 国产三级久久久| 久草精品在线| 国产视频福利在线| 久久精品视频在线观看| 99久久久国产精品免费蜜臀| 国产日本亚洲| 女人裸体免费网站| 国产精品久久久对白| 精品国产乱码久久久久久蜜臀| 国产盗摄一区二区三区| 日本一区二区三区电影免费观看| 2018高清国产日本一道国产| 亚洲综合视频1区| 精品久久人人做人人爱| 99国产精品久| 精品国产精品| 国产一二区在线观看| 亲子乱一区二区三区电影|