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

強一致鎖:如何解決高并發(fā)下的庫存爭搶問題?

開發(fā) 前端
當(dāng)多線程并行對同一個公共變量讀寫時,由于沒有互斥,多線程的 set 會相互覆蓋或讀取時容易讀到其他線程剛寫一半的數(shù)據(jù),這就導(dǎo)致變量數(shù)據(jù)被損壞。

由于秒殺場景是庫存爭搶非常經(jīng)典的一個應(yīng)用場景,接下來我會結(jié)合秒殺需求,帶你看看如何實現(xiàn)高并發(fā)下的庫存爭搶,相信在這一過程中你會對鎖有更深入的認(rèn)識。

鎖爭搶的錯誤做法

在開始介紹庫存爭搶的具體方案之前,我們先來了解一個小知識——并發(fā)庫存鎖。還記得在我學(xué)計算機的時候,老師曾演示過一段代碼:

public class ThreadCounter {
private static int count = 0;


public static void main(String[] args) throws Exception {
        Runnable task = new Runnable() {
public void run() {
for (int i = 0; i < 1000; ++i) {
                    count += 1;
                }
            }
        };


        Thread t1 = new Thread(task);
        t1.start();


        Thread t2 = new Thread(task);
        t2.start();


        t1.join();
        t2.join();


        cout << "count = " << count << endl;
    }
}

從代碼來看,我們運行后結(jié)果預(yù)期是 2000,但是實際運行后并不是。為什么會這樣呢?當(dāng)多線程并行對同一個公共變量讀寫時,由于沒有互斥,多線程的 set 會相互覆蓋或讀取時容易讀到其他線程剛寫一半的數(shù)據(jù),這就導(dǎo)致變量數(shù)據(jù)被損壞。反過來說,我們要想保證一個變量在多線程并發(fā)情況下的準(zhǔn)確性,就需要這個變量在修改期間不會被其他線程更改或讀取。對于這個情況,我們一般都會用到鎖或原子操作來保護庫存變量:如果是簡單 int 類型數(shù)據(jù),可以使用原子操作保證數(shù)據(jù)準(zhǔn)確;如果是復(fù)雜的數(shù)據(jù)結(jié)構(gòu)或多步操作,可以加鎖來保證數(shù)據(jù)完整性。

考慮到我們之前的習(xí)慣會有一定慣性,為了讓你更好地理解爭搶,這里我再舉一個我們常會犯錯的例子。因為扣庫存的操作需要注意原子性,我們實踐的時候常常碰到后面這種方式:

redis> get prod_1475_stock_1
15
redis> set prod_1475_stock_1 14
OK

也就是先將變量從緩存中取出,對其做 -1 操作,再放回到緩存當(dāng)中,這是個錯誤做法。

圖片圖片

如上圖,原因是多個線程一起讀取的時候,多個線程同時讀到的是 5,set 回去時都是 6,實際每個線程都拿到了庫存,但是庫存的實際數(shù)值并沒有累計改變,這會導(dǎo)致庫存超賣。如果你需要用這種方式去做,一般建議加一個自旋互斥鎖,互斥其他線程做類似的操作。

原子操作

當(dāng)大量用戶并發(fā)修改某個變量時,使用互斥鎖雖然能保證數(shù)據(jù)修改的正確性,但性能非常低。假設(shè)有一萬個用戶爭搶一個鎖,排隊等待修改服務(wù)器中的變量,這樣的設(shè)計效率極差。鎖在獲取過程中需要自旋,反復(fù)嘗試才能搶到鎖,用戶越多,爭搶越激烈,系統(tǒng)資源的消耗就越大,可能導(dǎo)致系統(tǒng)不穩(wěn)定。

為了解決這個問題,我會選擇將庫存數(shù)據(jù)存放在高性能的內(nèi)存緩存服務(wù)(比如 Redis)中集中管理。這樣可以避免用戶爭搶鎖時影響到其他服務(wù),同時也能提高響應(yīng)速度。Redis 本身支持原子操作,并且通過它可以更好地應(yīng)對高并發(fā)場景。這也是目前互聯(lián)網(wǎng)行業(yè)普遍采用的庫存保護方案。

相比之下,不建議通過數(shù)據(jù)庫行鎖來保證庫存的修改。數(shù)據(jù)庫資源非常寶貴,如果使用行鎖管理庫存,不僅性能會很差,系統(tǒng)也容易變得不穩(wěn)定。

為了減少鎖爭搶和提升系統(tǒng)效率,我們可以采取降低鎖粒度的方式,或者引入其他優(yōu)化方案。

圖片圖片

實際上,我們可以通過將熱門商品的庫存進行拆分,存儲到多個 key 中,從而顯著減少鎖的競爭。比如,假設(shè)當(dāng)前商品的庫存為 100 個,可以把庫存分成 10 個 key,每個 key 保存 10 個庫存,并將這些 key 分布在不同的 Redis 實例中。當(dāng)用戶下單時,可以隨機選擇一個 key 扣減庫存。如果某個 key 中的庫存不足,再記錄該 key 并隨機挑選剩余的 key 進行扣減,直到成功完成一次庫存的扣除。

不過,除了這種方法之外,我更推薦使用 Redis 的原子操作來處理庫存問題。原子操作的粒度更小,并且 Redis 本質(zhì)上是單線程運行,能夠提供全局唯一的決策。很多原子操作的底層實現(xiàn)甚至是通過硬件實現(xiàn)的,性能非常優(yōu)異,且不會產(chǎn)生鎖競爭問題。

以 Redis 的 INCR 和 DECR 操作為例,它們可以在不加鎖的情況下實現(xiàn)對庫存的精確修改,這樣能同時保證高性能和數(shù)據(jù)的一致性。

redis> decr prod_1475_stock_1
14

incr、decr 這類操作就是原子的,我們可以根據(jù)返回值是否大于 0 來判斷是否扣庫存成功。但是這里你要注意,如果當(dāng)前值已經(jīng)為負(fù)數(shù),我們需要考慮一下是否將之前扣除的補償回來。并且為了減少修改操作,我們可以在扣減之前做一次值檢測,整體操作如下:

//讀取當(dāng)前庫存,確認(rèn)是否大于零
//如大于零則繼續(xù)操作,小于等于拒絕后續(xù)
redis> get prod_1475_stock_1
1


//開始扣減庫存、如返回值大于或等于0那么代表扣減成功,小于0代表當(dāng)前已經(jīng)沒有庫存
//可以看到返回-2,這可以理解成同時兩個線程都在操作扣庫存,并且都沒拿到庫存
redis> decr prod_1475_stock_1
-2


//扣減失敗、補償多扣的庫存
//這里返回0是因為同時兩個線程都在做補償,最終恢復(fù)0庫存
redis> incr prod_1475_stock
0

這個庫存保護方案確實很有價值,但也有其局限性。庫存的準(zhǔn)確性依賴于業(yè)務(wù)是否能成功“返還”之前扣減的庫存。如果在服務(wù)運行過程中“返還”操作被中斷,人工修復(fù)將變得非常困難,因為無法確定當(dāng)前還有多少庫存正在處理中。通常,我們需要等到活動結(jié)束后再查看最終庫存。

為了完全保證庫存不丟失,通常會依賴事務(wù)和回滾機制,但 Redis 作為外置的庫存服務(wù),并不屬于數(shù)據(jù)庫的緩存范疇。這就要求我們在每個可能出現(xiàn)故障的業(yè)務(wù)環(huán)節(jié)中都能夠妥善處理庫存問題。因此,許多秒殺系統(tǒng)在出現(xiàn)故障時往往選擇不返還庫存,并不是因為不想,而是因為很多意外場景無法做到。

至于使用 SETNX 指令或數(shù)據(jù)庫的 CAS(比較并交換)機制來實現(xiàn)互斥鎖,盡管這能解決庫存問題,但這種鎖機制會引入自旋等待。在并發(fā)高的情況下,用戶服務(wù)需要反復(fù)嘗試才能獲取鎖,這樣會浪費系統(tǒng)資源,并對數(shù)據(jù)服務(wù)造成較大壓力。因此,這種方法并不推薦使用。

令牌庫存

除了這種用數(shù)值記錄庫存的方式外,還有一種比較科學(xué)的方式就是“發(fā)令牌”方式,通過這個方式可以避免出現(xiàn)之前因為搶庫存而讓庫存出現(xiàn)負(fù)數(shù)的情況。

圖片圖片

具體是使用 Redis 中的 list 保存多張令牌來代表庫存,一張令牌就是一個庫存,用戶搶庫存時拿到令牌的用戶可以繼續(xù)支付:

//放入三個庫存
redis> lpush prod_1475_stock_queue_1 stock_1
redis> lpush prod_1475_stock_queue_1 stock_2
redis> lpush prod_1475_stock_queue_1 stock_3


//取出一個,超過0.5秒沒有返回,那么搶庫存失敗
redis> brpop prod_1475_stock_queue_1 0.5

在庫存搶購失敗時,用戶只會收到 nil,這種實現(xiàn)方式確實能避免失敗后還要補償庫存的問題。不過,即便如此,如果我們的業(yè)務(wù)代碼在異常處理上不夠完善,依然可能發(fā)生庫存丟失的情況。同時,如果需要從隊列中取出令牌,使用 brpop 可以阻塞等待,而使用 rpop 則在壓測場景下性能表現(xiàn)更好,因為不需要等待。

然而,當(dāng)庫存數(shù)量非常龐大時,令牌方式可能并不適用。比如,如果有1萬個庫存,就需要插入1萬個令牌到 Redis 的 list 中;如果庫存有10萬,就得連續(xù)插入10萬個字符串,這會導(dǎo)致 Redis 在入庫期間發(fā)生大量卡頓。

到這里,庫存設(shè)計似乎已經(jīng)比較完善了,但如果產(chǎn)品團隊提出“一個商品可以一次搶多個庫存”的需求(比如一次秒殺兩袋大米),這個方案可能就無法滿足了。因為我們依賴于多個鎖來降低競爭,而一次性扣減多個庫存會讓這個設(shè)計變得復(fù)雜,鎖爭搶問題依舊存在。

多庫存秒殺

其實這種情況經(jīng)常出現(xiàn),這讓我們對之前的優(yōu)化有了更多的想法。對于一次秒殺多個庫存,我們的設(shè)計需要做一些調(diào)整。

圖片圖片

之前,我們?yōu)榱藴p少鎖競爭,將庫存拆分成了 10 個不同的 key 并隨機獲取。但如果到了庫存只剩下最后幾個商品的極端情況,用戶一次秒殺三件商品(如上例所示),可能需要嘗試所有的庫存 key。最終,在嘗試了 10 個 key 后,可能只成功扣減了兩個庫存。這個時候,我們就面臨選擇:是拒絕用戶的訂單,還是返還庫存?

這就取決于產(chǎn)品的設(shè)計思路了。同時,我們還需要增加一個檢測機制:如果庫存已經(jīng)售罄,就不要再去嘗試獲取 10 個庫存 key 了。畢竟,在沒庫存的情況下,每次請求都會刷 10 次 Redis,而這會對 Redis 服務(wù)帶來較大壓力。雖然 Redis 的 O(1) 操作理論上可以達(dá)到每秒 10 萬次操作(OPS),但一次請求刷 10 次,理想情況下?lián)屬弾齑娴慕涌谛阅艽蠹s為每秒 1 萬次請求(QPS)。實際壓測后,建議按照實測性能的 70% 來進行漏斗式限流。

你應(yīng)該注意到了,在“一個商品可以搶多個庫存”的場景下,庫存拆分方案并沒有減少鎖的爭搶次數(shù),反而增加了維護的復(fù)雜性。當(dāng)庫存越來越少時,系統(tǒng)性能會顯著下降,這樣的設(shè)計已經(jīng)不符合我們最初的目的(這種由業(yè)務(wù)需求引發(fā)的設(shè)計不適配問題在實際項目中非常常見,需要我們在設(shè)計之初更深入地理解產(chǎn)品需求)。

那么,應(yīng)該怎么優(yōu)化呢?我們可以考慮將原來拆分的 10 個 key 合并為 1 個,然后使用 rpop 來實現(xiàn)多個庫存的扣減操作。對于庫存不足的情況(例如,用戶想買 3 件但只剩 2 件庫存),需要產(chǎn)品側(cè)給出明確的建議,看是否繼續(xù)處理交易。同時,在每次操作開始時,可以使用 LLEN(O(1) 操作)檢查 list 中是否有足夠的庫存支持 rpop。

//取之前看一眼庫存是否空了,空了不繼續(xù)了(llen O(1))
redis> llen prod_1475_stock_queue
3


//取出庫存3個,實際搶到倆
redis> rpop prod_1475_stock_queue 3
"stock_1"
"stock_2"


//產(chǎn)品說數(shù)量不夠,不允許繼續(xù)交易,將庫存返還  
redis> lpush prod_1475_stock_queue stock_1
redis> lpush prod_1475_stock_queue stock_2

通過這個設(shè)計,我們已經(jīng)大大降低了下單系統(tǒng)鎖爭搶壓力。要知道,Redis 是一個性能很好的緩存服務(wù),其 O(1) 類復(fù)雜度的指令在使用長鏈接的情況下多線程壓測,5.0 版本的 Redis 就能夠跑到 10w OPS,而 6.0 版本的網(wǎng)絡(luò)性能會更好。這種利用 Redis 原子操作減少鎖沖突的方式,對各個語言來說是通用且簡單的。不過你要注意,不要把 Redis 服務(wù)和復(fù)雜業(yè)務(wù)邏輯混用,否則會影響我們的庫存接口效率。

自旋互斥超時鎖

如果我們在庫存爭搶時需要操作多個決策 key 才能夠完成爭搶,那么原子這種方式是不適合的。因為原子操作的粒度過小,無法做到事務(wù)性地維持多個數(shù)據(jù)的 ACID。這種多步操作,適合用自旋互斥鎖的方式去實現(xiàn),但流量大的時候不推薦這個方式,因為它的核心在于如果我們要保證用戶的體驗,我們需要邏輯代碼多次循環(huán)搶鎖,直到拿到鎖為止,如下:

//業(yè)務(wù)邏輯需要循環(huán)搶鎖,如循環(huán)10次,每次sleep 10ms,10次失敗后返回失敗給用戶
//獲取鎖后設(shè)置超時時間,防止進程崩潰后沒有釋放鎖導(dǎo)致問題
//如果獲取鎖失敗會返回nil
redis> set prod_1475_stock_lock EX 60 NX
OK


//搶鎖成功,扣減庫存
redis> rpop prod_1475_stock_queue 1
"stock_1"


//扣減數(shù)字庫存,用于展示
redis> decr prod_1475_stock_1
3


// 釋放鎖
redis> del prod_1475_stock_lock

圖片圖片

這種方式的缺點在于,在搶鎖階段如果排隊搶的線程越多,等待時間就越長,并且由于多線程一起循環(huán) check 的緣故,在高并發(fā)期間 Redis 的壓力會非常大,如果有 100 人下單,那么有 100 個線程每隔 10ms 就會 check 一次,此時 Redis 的操作次數(shù)就是:

100線程×(1000ms÷10ms)次=10000ops

CAS 樂觀鎖:鎖操作后置

另外一個推薦的方式是使用 CAS(Compare and Swap)樂觀鎖。與自旋互斥鎖相比,在并發(fā)搶庫存的線程較少時,CAS 樂觀鎖效率更高。傳統(tǒng)的鎖機制是通過先獲取鎖,再對數(shù)據(jù)進行操作,這個過程中搶鎖本身會消耗性能,哪怕沒有其他線程參與爭搶,搶鎖的開銷依然存在。

而 CAS 樂觀鎖 的核心在于記錄或監(jiān)控當(dāng)前的庫存信息或版本號,在此基礎(chǔ)上進行預(yù)操作。當(dāng)線程準(zhǔn)備修改數(shù)據(jù)時,系統(tǒng)會先檢查當(dāng)前的庫存版本號是否和預(yù)期的一致。如果一致,則修改成功;否則,重新讀取最新的數(shù)據(jù)并重試。這種方式可以避免鎖競爭帶來的性能損耗,在并發(fā)較低的場景下更具優(yōu)勢。

圖片圖片

如上圖,在操作期間如果發(fā)現(xiàn)監(jiān)控的數(shù)值有變化,那么就回滾之前操作;如果期間沒有變化,就提交事務(wù)的完成操作,操作期間的所有動作都是事務(wù)的。

//開啟事務(wù)
redis> multi
OK


// watch 修改值
// 在exec期間如果出現(xiàn)其他線程修改,那么會自動失敗回滾執(zhí)行discard
redis> watch prod_1475_stock_queue prod_1475_stock_1


//事務(wù)內(nèi)對數(shù)據(jù)進行操作
redis> rpop prod_1475_stock_queue 1
QUEUED


//操作步驟2
redis> decr prod_1475_stock_1
QUEUED


//執(zhí)行之前所有操作步驟
//multi 期間 watch有數(shù)值有變化則會回滾
redis> exec
3

以看到,通過這個方式我們可以批量地快速實現(xiàn)庫存扣減,并且能大幅減少鎖爭搶時間。它的好處我們剛才說過,就是爭搶線程少時效率特別好,但爭搶線程多時會需要大量重試,不過即便如此,CAS 樂觀鎖也會比用自旋鎖實現(xiàn)的性能要好。當(dāng)采用這個方式的時候,我建議內(nèi)部的操作步驟盡量少一些。同時要注意,如果 Redis 是 Cluster 模式,使用 multi 時必須在一個 slot 內(nèi)才能保證原子性。

Redis Lua 方式實現(xiàn) Redis 鎖

與“事務(wù) + 樂觀鎖”類似的另一種實現(xiàn)方式是使用 Redis 的 Lua 腳本 來進行多步驟的庫存操作。由于 Lua 腳本在 Redis 內(nèi)部的執(zhí)行是連續(xù)且原子的,因此所有操作不會被其他操作打斷,避免了鎖爭搶的問題。

此外,Lua 腳本可以根據(jù)不同情況靈活處理不同的操作,業(yè)務(wù)只需調(diào)用指定的 Lua 腳本并傳遞相關(guān)參數(shù),就可以實現(xiàn)高性能的庫存扣減。這樣做不僅提高了操作的原子性,也顯著減少了由于多次請求等待所帶來的 RTT(往返時間),提升了整體系統(tǒng)的響應(yīng)速度和并發(fā)處理能力。

為了方便演示怎么執(zhí)行 Lua 腳本,我使用了 PHP 實現(xiàn):

<?php
$script = <<<EOF
// 獲取當(dāng)前庫存?zhèn)€數(shù)
local stock=tonumber(redis.call('GET',KEYS[1])); 
//沒找到返回-1
if stock==nil 
then
return -1; 
end 
//找到了扣減庫存?zhèn)€數(shù)
local result=stock-ARGV[1]; 
//如扣減后少于指定個數(shù),那么返回0
if result<0 
then
return 0; 
else
    //如果扣減后仍舊大于0,那么將結(jié)果放回Redis內(nèi),并返回1
    redis.call('SET',KEYS[1],result); 
return 1; 
end
EOF;


$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
$result = $redis->eval($script, array("prod_stock", 3), 1);
echo $result;

通過這個方式,我們可以遠(yuǎn)程注入各種連貫帶邏輯的操作,并且可以實現(xiàn)一些補庫存的操作。

總結(jié)

圖片 圖片

責(zé)任編輯:武曉燕 來源: 二進制跳動
相關(guān)推薦

2024-02-02 11:24:00

I/O高并發(fā)場景

2025-05-28 02:25:00

高并發(fā)緩存穿透雪崩

2025-03-10 09:20:00

庫存異常Redis架構(gòu)

2021-04-18 15:01:56

緩存系統(tǒng)數(shù)據(jù)

2025-11-14 01:20:00

2024-01-10 08:01:55

高并發(fā)場景悲觀鎖

2019-08-07 10:25:41

數(shù)據(jù)庫緩存技術(shù)

2025-06-12 02:15:00

Kafka消費者高并發(fā)

2019-05-27 09:00:00

蘇寧智慧零售平臺數(shù)據(jù)庫

2022-06-12 06:45:26

高并發(fā)防重

2023-09-03 22:44:28

I/O高并發(fā)

2017-03-24 16:54:52

PhxSQL微信開源MySQL

2013-01-30 10:12:24

NginxNginx優(yōu)化高并發(fā)

2014-08-08 13:30:44

Nginx

2022-10-19 12:22:53

并發(fā)扣款一致性

2021-12-26 18:24:51

MySQL InnoDB引擎

2023-10-13 08:11:22

2021-01-15 05:12:14

Java并發(fā)樂觀鎖

2019-08-30 12:46:10

并發(fā)扣款查詢SQL

2020-08-05 08:46:10

NFS網(wǎng)絡(luò)文件系統(tǒng)
點贊
收藏

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

久久6精品影院| 91麻豆精品国产91久久久资源速度| 久久久久久久免费| 做爰视频毛片视频| 欧美96在线丨欧| 日韩精品久久久久| 加勒比av中文字幕| 91禁在线看| 欧美国产禁国产网站cc| 99久久无色码| 波多野结衣黄色网址| 欧美福利一区| 伊人伊成久久人综合网小说 | 亚洲天堂精品一区| 日韩综合一区二区三区| 一本一本久久a久久精品综合麻豆| 椎名由奈jux491在线播放| 日本黄色不卡视频| 毛片一区二区三区| 2018中文字幕一区二区三区| 成年人一级黄色片| 国产一区二区亚洲| 精品久久久久久久久久久久久久久| 欧在线一二三四区| 搞黄网站在线看| ●精品国产综合乱码久久久久| 国产在线精品一区二区三区| 国产精品玖玖玖| 日韩和欧美一区二区三区| 久久久亚洲网站| 91精品一区二区三区蜜桃| 欧美猛男做受videos| 亚洲国产精品系列| 在线成人精品视频| 人人玩人人添人人澡欧美| 欧美性生交大片免费| 97免费视频观看| 国产视频中文字幕在线观看| 国产精品女人毛片| 日本午夜精品一区二区| 天堂成人在线视频| 成人午夜激情在线| www.成人av.com| a天堂视频在线| 韩国av一区二区| 成人性教育视频在线观看| 涩涩视频在线观看| 日本亚洲天堂网| 国产精品久久一| www.com亚洲| 石原莉奈在线亚洲三区| 日韩免费观看高清| 精品免费囯产一区二区三区| 欧美网站在线| 久久久亚洲国产天美传媒修理工| 久草免费在线视频观看| 国模 一区 二区 三区| 久久99热精品这里久久精品| 久草综合在线视频| 欧美日韩久久| 亚州欧美日韩中文视频| 亚洲一区欧美在线| 免费在线亚洲| 国产精品久久久久久久久久久久| 在线观看日批视频| 青青草91视频| 91综合免费在线| 亚洲成人一级片| 96av麻豆蜜桃一区二区| 免费一区二区三区| 成人在线观看免费| 1区2区3区精品视频| 乱子伦一区二区| 1234区中文字幕在线观看| 欧美日韩综合视频| 色哟哟精品视频| 国产精品视频一区二区三区综合 | 男生女生差差差的视频在线观看| 久久网站热最新地址| 日韩在线第一区| bt在线麻豆视频| 亚洲成人在线网站| 91n.com在线观看| 国产精品一区免费在线 | 欧美日韩精品一本二本三本| 性欧美长视频免费观看不卡| 精品久久久久久久久久久久久久久久| 日日夜夜免费精品视频| 91在线色戒在线| 四虎在线视频免费观看| 国产精品嫩草影院com| www插插插无码免费视频网站| 中文字幕影音在线| 欧美浪妇xxxx高跟鞋交| 成人性生活免费看| 国产精品久久久久久麻豆一区软件| 欧美国产一区二区三区| 亚洲精品无码久久久久| 福利一区二区在线| 日韩经典在线视频| 麻豆蜜桃在线| 欧美三电影在线| 日韩精品一区二区三区高清免费| 精品国产美女| 海角国产乱辈乱精品视频| 国产无遮挡又黄又爽又色视频| 国产一区二区成人久久免费影院| 久久久久久久久久久久久9999| 国产在线观看a视频| 欧美性猛交xxxx富婆| 6080国产精品| 午夜精品福利影院| 欧美噜噜久久久xxx| 中文字幕久久熟女蜜桃| 成人精品视频一区二区三区尤物| 日韩一区二区三区高清| 麻豆网站免费在线观看| 日韩一级免费观看| 国产黄色片在线| 丝袜诱惑亚洲看片| 精品一区二区不卡| 免费在线看污片| 欧美精品乱码久久久久久按摩| 久久久无码人妻精品一区| 红桃视频国产精品| 91在线观看免费观看| 天堂а√在线资源在线| 日韩欧美aⅴ综合网站发布| 在线精品视频播放| 欧美久久久久| 91色视频在线观看| 天堂中文а√在线| 欧美日韩一本到| 日本性高潮视频| 久久综合影视| 日韩av一区二区三区在线观看| 黄视频网站在线观看| 亚洲成人aaa| 精品少妇theporn| 国产激情精品久久久第一区二区| 国产精品美女在线播放| 免费成人黄色网| 精品国产美女在线| 在线中文字幕网站| 亚洲欧美一区二区在线观看| 57pao国产成永久免费视频| 久久国产亚洲精品| 国产欧美一区二区三区在线看| 都市激情在线视频| 欧美亚洲国产一区二区三区va| av中文字幕免费观看| 午夜亚洲视频| 天堂精品一区二区三区| 国产激情欧美| 久久久999成人| 国产青青草视频| 一区二区三区加勒比av| 国产a√精品区二区三区四区| 欧美精品网站| 国产久一道中文一区| 成人免费网站观看| 日韩经典一区二区三区| 国产精品久久久久久人| 久久免费视频一区| 亚洲 激情 在线| 亚洲午夜精品一区二区国产| 成人字幕网zmw| 污污在线观看| 精品无人国产偷自产在线| 国产伦精品一区二区三区视频我| 国产欧美日韩不卡免费| 午夜一区二区视频| 黑丝一区二区| 免费久久99精品国产自| 成人免费在线观看视频| 成人97在线观看视频| 少妇精品视频一区二区| 欧美亚洲国产怡红院影院| 无码人妻精品一区二区三区夜夜嗨| 国产成人8x视频一区二区| 无码播放一区二区三区| 日韩国产综合| 成人免费视频视频在| 欧美电影免费观看高清完整| 日韩视频第一页| 性xxxx视频播放免费| 欧美丝袜第三区| 国产中文字幕免费| 国产人成亚洲第一网站在线播放 | 免费无码国产精品| 亚洲欧美日韩国产另类专区| 欧美肉大捧一进一出免费视频| 久久三级福利| av一区二区三区免费观看| 精品一区在线| 99久久国产免费免费| 日韩免费小视频| 色综合久久88色综合天天看泰| 毛片在线播放网站| 日韩亚洲欧美在线| 亚洲免费视频二区| 午夜精品123| 国产传媒免费在线观看| 久久影音资源网| 香蕉久久久久久av成人| 日本不卡视频在线| 日本熟妇人妻xxxx| 99热在线成人| 日本10禁啪啪无遮挡免费一区二区| 精品中文字幕一区二区三区| 国产精品国产三级国产aⅴ浪潮| 欧美人体视频xxxxx| 色噜噜狠狠狠综合曰曰曰| 日韩精品视频在线观看一区二区三区| 91精品国产综合久久久蜜臀粉嫩| 在线观看日本网站| 亚洲v日本v欧美v久久精品| 黄色一级大片在线免费观看| 久久精品日韩一区二区三区| xxxx黄色片| 国产精品99久久久| 天天干天天色天天干| 日本欧美一区二区| 国产超级av在线| 亚洲激情欧美| 日本aa在线观看| 欧美国产日本| 二级片在线观看| 99久久99久久精品国产片桃花| 欧洲成人一区二区| 亚洲婷婷影院| 久久精品国产精品国产精品污 | 人狥杂交一区欧美二区| 欧美激情videos| 欧美性受ⅹ╳╳╳黑人a性爽| 久久久成人av| 菠萝蜜视频国产在线播放| 久久精品国产亚洲精品| 免费在线你懂的| 最近中文字幕mv在线一区二区三区四区 | 久久午夜无码鲁丝片| 一区二区三区色| 九九热精品在线观看| 怡红院av一区二区三区| 538任你躁在线精品视频网站| ●精品国产综合乱码久久久久| 91无套直看片红桃在线观看| 欧美国产在线观看| 日本精品久久久久中文| 国产精品国产a| 精品无码一区二区三区蜜臀| 国产精品国产馆在线真实露脸| 天天鲁一鲁摸一摸爽一爽| 亚洲婷婷综合色高清在线| 91视频综合网| 亚洲福利电影网| 久久国产视频播放| 日本韩国欧美在线| 中文字幕一二三四| 欧美肥妇毛茸茸| 亚洲第一成人av| 精品爽片免费看久久| 国产乱子伦三级在线播放| 在线视频中文亚洲| 中文字幕中文字幕在线中高清免费版| 欧美床上激情在线观看| av影片在线| 国产精品成人国产乱一区| 99久久综合国产精品二区| 成人精品在线视频| 97成人在线| 欧美视频观看一区| 国产韩日影视精品| 欧美一级片免费播放| 久久亚洲综合| 亚洲天堂一区二区在线观看| 波多野结衣一区二区三区| 公侵犯人妻一区二区三区| 国产精品久久久久婷婷二区次| 九九热视频精品| 欧美小视频在线| 国产又粗又黄又爽的视频| 精品免费国产一区二区三区四区| 日本午夜在线| 色婷婷成人综合| 欧美极品videos大乳护士| 欧美最猛性xxxx| 欧美区一区二区| 欧美日韩国产精品一区二区| 欧美激情欧美| www国产精品内射老熟女| 免费成人你懂的| 午夜剧场免费看| 国产精品久久久久一区二区三区 | 一区二区视频欧美| 成年人在线观看视频免费| 国产高清不卡一区二区| 久久精品—区二区三区舞蹈| 玉米视频成人免费看| 欧美亚洲另类小说| 精品国产91乱码一区二区三区 | 日韩综合网站| 男的插女的下面视频| 免费xxxx性欧美18vr| 国产女主播在线播放| 国产欧美一区二区三区沐欲| 18精品爽视频在线观看| 日本高清视频一区二区| 亚洲精品97久久中文字幕无码| 中文字幕9999| av资源一区| 2019国产精品视频| 精品久久综合| 日韩欧美在线播放视频| 国产91在线观看| 来吧亚洲综合网| 欧美在线视频全部完| 天天干在线观看| 欧美激情精品在线| 国产乱码精品一区二区三区亚洲人| 日韩免费一区二区三区| 亚洲深夜影院| 久久性爱视频网站| 一区二区三区四区高清精品免费观看| 亚洲精品一区二区二区| 精品亚洲一区二区三区在线播放 | 99热国内精品| 日本激情视频在线播放| 久久久噜噜噜久久中文字幕色伊伊 | 小日子的在线观看免费第8集| 国产精品免费视频网站| 亚洲成人av网址| 国产亚洲激情视频在线| 日韩免费va| 蜜桃麻豆91| 久久久国产精品一区二区中文| 少妇被狂c下部羞羞漫画| 一区二区三区欧美激情| 精品国自产在线观看| 久久成人av网站| 久久视频免费| 7777在线视频| 丁香亚洲综合激情啪啪综合| 欧美日韩精品在线观看视频 | 欧美黄色aaaa| 潘金莲一级淫片aaaaa| 亚洲一区在线观看视频| 丰满肥臀噗嗤啊x99av| 久久久久久伊人| 欧美男人操女人视频| 凹凸国产熟女精品视频| 2019国产精品| 男操女视频网站| 色777狠狠综合秋免鲁丝| 91精品视频一区二区| 麻豆映画在线观看| 成人性生交大片免费看视频在线| 国产一级理论片| 亚洲韩国日本中文字幕| 亚洲国产成人二区| 五月天亚洲综合情| 蜜桃久久久久久久| 九九热最新地址| 亚洲第一免费网站| 都市激情亚洲综合| 亚洲欧洲另类精品久久综合| 国产一区二区久久| 日韩女优在线观看| 亚洲亚裔videos黑人hd| 91麻豆精品国产综合久久久 | 久久久美女艺术照精彩视频福利播放| 亚洲欧美日韩激情| 色狠狠av一区二区三区香蕉蜜桃| 久久婷婷五月综合色丁香| 超碰97在线看| 91亚洲精品久久久蜜桃| 中文字幕在线天堂| 久热精品在线视频| 欧美一级二级三级视频| 999精品视频在线| 亚洲综合图片区| 男女网站在线观看| 91亚洲一区精品| 久久精品道一区二区三区| 丝袜美腿小色网| 日韩激情在线视频| 国产精品亚洲四区在线观看 | 亚洲福利影院| 亚洲国产欧洲综合997久久| 国产成人免费视| 日韩欧美国产另类| 欧美高清在线视频观看不卡| 精品一区欧美| 国产伦精品一区二区三区88av| 日本道免费精品一区二区三区| h片在线免费观看| 日本在线播放不卡| 国产不卡一区视频| 中文字幕欧美在线观看| 久久免费视频在线观看|