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

別造輪子了,先來“抄”一下 RocketMQ 的文件編程藝術

開發 前端
學習 RocketMQ,我們學的不僅是 “術”(具體的實現技巧),更是 “道”(解決問題的思想和方法論)。希望通過本文的剖析,能為你打開一扇通往高性能存儲世界的大門,并在未來的系統設計中,能夠更加游刃有余地運用這些閃耀著智慧光芒的編程藝術。?

最近有朋友問我,如何從零開始設計一套高性能、高可靠、且支持快速查詢的文件存儲系統?

這是一個典型的后端面試高頻題,也是一個極具挑戰的真實工程難題。我的回答是:與其閉門造車,不如站在巨人的肩膀上——去“抄”一個頂級的開源實現。

他追問:“抄誰?”

我說:“當然是抄 RocketMQ!它在文件處理上的設計,堪稱 Java 領域的教科書,充滿了工程的智慧與藝術。無論是海量消息的順序寫入,還是高效的索引查詢,亦或是對內存和磁盤的極致運用,RocketMQ 的每一處細節都值得我們細細品味。下面,就讓我們一同深入這座寶庫,探索其背后的文件編程藝術。”

消息存儲格式看文件編程

commitlog 文件設計:學習文件編程的起點

我們知道,RocketMQ 的全量消息均存儲在 commitlog 文件中。由于每條消息的大小不一,我們面臨第一個挑戰:如何高效地組織這些消息,以便在讀取時能夠準確地區分每條消息的邊界?

在基于文件的編程模型中,首要任務是定義一套清晰的消息存儲格式。一個通用的實踐是將數據結構設計為 Header + Body 的形式。其中,Header 部分采用定長設計,存放元數據信息;Body 部分則存放實際的數據。在 RocketMQ 的存儲協議中,我們可以將記錄消息總長度的 4 字節視為 Header,其后的所有字段則構成 Body,包含了與消息相關的業務屬性,它們共同按照預定格式組裝。

圖片圖片

對于 Header + Body 這種協議,提取一條完整消息通常分為兩步:首先,讀取定長的 Header,從中解析出 Body 的長度(在 RocketMQ 中即為消息的總長度)。然后,根據這個長度,從消息的起始位置 讀取完整的消息數據,并按照預定義的格式解析出各個業務字段。

那問題又來了,如果確定一條消息的開頭呢?難不成從文件的開始處開始遍歷?

正如關系型數據庫會為每條記錄分配一個唯一的 ID,在文件編程模型中,我們也為每條消息引入了一個關鍵的身份標識:消息物理偏移量(Physical Offset),它精確地指明了消息在文件中的起始存儲位置。

圖片圖片

因此,通過 物理偏移量 + 消息大小(SIZE) 這一組合,我們便能輕而易舉地從海量數據中精確定位并提取出任何一條完整的消息。

此外,commitlog 的文件組織還揭示了另一個通用實踐:文件通常以一個“魔數”(Magic Number)開頭,用于快速校驗文件類型和完整性。同時,在文件末尾,可能會使用特殊填充(PAD)來處理空間。例如,當文件剩余空間不足以容納一條完整的消息時,系統不會將消息拆分存儲,而是用 PAD 填充剩余部分,以保證下一條消息能從新文件的起始位置寫入,維持了消息的原子性。

consumequeue 文件設計:索引的藝術

commitlog 文件基于物理偏移量查詢消息效率極高,但若要按 Topic 進行檢索,則顯得力不從心。為了解決這一痛點,RocketMQ 精心設計了 consumequeue文件作為消費隊列索引。

圖片圖片

consumequeue 的設計極具巧思。其核心在于,每個索引條目都采用固定長度設計:8 字節的 commitlog 物理偏移量、4 字節的消息長度和 8 字節的 Tag 哈希值。這里存儲的是 Tag 的哈希值而非原始字符串,正是為了確保每個條目定長。這種設計使得consumequeue 文件可以像數組一樣,通過下標(queueOffset)進行快速隨機訪問,極大地提升了索引查詢性能。

由此可見,在高性能文件存儲設計中,為特定查詢場景構建高效的索引至關重要。而索引設計的關鍵原則之一,就是采用定長條目,從而實現類似數組的 O(1) 復雜度快速定位。

性能飛躍:內存映射與頁緩存

解決了數據存儲格式與唯一標識的問題后,下一個核心挑戰是如何提升I/O性能。在文件編程實踐中,為了便于管理和數據刪除(例如過期的消息),通常會采用固定大小的日志文件策略,將數據切分成多個大小相等的文件段。RocketMQ 的 commitlog文件夾中那些 1G 大小的文件正是這一思想的體現。

圖片圖片

采用定長文件的一個核心優勢在于,它極大地簡化了內存映射(Memory Mapping)的實現。通過內存映射技術,我們可以將磁盤文件直接映射到進程的虛擬地址空間,之后就可以像訪問內存一樣讀寫磁盤上的數據,從而繞過傳統 read/write 系統調用帶來的多次數據拷貝,顯著提升文件操作性能。

在 Java 中使用內存映射的示例代碼如下:

FileChannel fileChannel = new RandomAccessFile(this.file, "rw").getChannel();
MappedByteBuffer mappedByteBuffer = this.fileChannel.map(MapMode.READ_WRITE, 0, fileSize);

實現要點如下:

  • 首先需要通過 RandomAccessFile 構建一個文件讀寫通道 FileChannel。
  • 再通過 FileChannel 的 map 方法創建內存映射區域 MappedByteBuffer。

在 Linux 系統中,MappedByteBuffer 的背后正是強大的頁緩存(Page Cache)。Linux 會盡可能地利用空閑物理內存作為頁緩存,以緩存磁盤數據。當應用程序讀寫文件時,實際上是在與頁緩存交互。如果數據在緩存中(緩存命中),則無需磁盤 I/O;如果不在(緩存未命中),系統會觸發一個缺頁中斷,透明地將數據從磁盤加載到頁緩存中。整個過程由操作系統自動管理,對應用層開發者完全透明,極大地簡化了高性能應用的開發。

通過內存映射寫入的數據,首先會進入頁緩存,并不會立即刷寫到磁盤。持久化操作由操作系統根據其策略在后臺異步完成。這意味著,即使 Broker 進程異常崩潰,只要操作系統仍然運行,頁緩存中的數據就不會丟失,最終會被寫入磁盤,保證了一定程度的可靠性。然而,如果發生機器斷電或操作系統宕機等災難性故障,尚未從頁緩存刷入磁盤的數據將會永久丟失,這是內存映射技術需要權衡的風險。

磁盤性能提升:順序寫

要進一步壓榨磁盤性能,另一個關鍵的設計原則是使用順序寫替代隨機寫。與隨機寫相比,磁盤順序寫的性能要高出幾個數量級。這一原則在所有高性能存儲系統中都得到了廣泛應用。以大家熟悉的 MySQL InnoDB 存儲引擎為例:當執行一條更新語句時,數據首先在內存(Buffer Pool)中被修改。為了保證事務的持久性,InnoDB 并不會立即將修改后的數據頁(這會導致隨機 I/O)刷回磁盤,而是先將變更以 Redo Log 的形式順序追加到一個專用的日志文件中,并確保 Redo Log 被同步刷盤。數據文件本身的更新則可以在后臺異步、批量地進行。

圖片圖片

試想,如果沒有 Redo Log,每次更新都直接修改磁盤上的數據文件,那么更新不同表的數據就會導致磁頭在磁盤上大幅度來回尋道,產生大量的隨機 I/O,性能將慘不忍睹。通過引入 Redo Log,InnoDB 將多次離散的隨機寫操作,巧妙地轉換成了一次集中的順序寫操作,盡管多了一步寫日志的操作,但整體性能卻得到了質的飛躍。這個例子雄辯地證明了順序寫相比隨機寫的巨大優勢。

因此,在設計文件存儲模型時,一個黃金法則是:盡可能地將操作設計為順序追加(Append-Only),避免原地更新(In-Place Update)。

資源管理的智慧:引用計數器

在基于 NIO 的文件編程中,我們頻繁地與 ByteBuffer 打交道。為了在不進行數據拷貝的前提下共享緩沖區內容,slice() 方法被廣泛使用。它能創建一個與原 ByteBuffer 共享同一塊內存區域,但擁有獨立 position、limit 和 mark 指針的新 ByteBuffer。

圖片圖片

上圖 selectMappedBuffer 方法的作用,正是從一個內存映射文件(如 commitlog)的指定位置“切割”出一段數據。這種零拷貝操作雖然高效,但也引入了復雜的資源管理問題:被主 MappedByteBuffer 切割(slice)出的多個子 ByteBuffer,它們的生命周期各不相同。我們必須確保在所有子 ByteBuffer 都使用完畢之前,主 MappedByteBuffer 不能被釋放,否則將導致懸空指針和程序崩潰。

RocketMQ 如何優雅地解決這個問題呢?答案是引入引用計數器(Reference Counting)。

其核心思想是:每次調用 slice() 派生出一個新的 ByteBuffer 時,就將主對象的引用計數加一;當任何一個派生對象使用完畢被釋放時,就將引用計數減一。只有當引用計數歸零時,才真正執行底層的資源釋放操作。

圖片圖片

結合 selectMappedBuffer 方法的實現,我們可以看到:

  1. 調用 hold() 方法來增加引用計數,這標志著 MappedByteBuffer 又被“借用”了一次。
  2. 返回的 SelectMappedBufferResult 對象中封裝了派生出的 ByteBuffer。當使用者調用其 release() 方法時,內部會調用 ReferenceResource 的 release(),使引用計數減一。

可靠與性能的權衡:同步與異步刷盤

內存映射機制極大地提升了寫入性能,但其“數據先到內存,后到磁盤”的特性也帶來了新的抉擇:當 Broker 接收到消息后,是應該在數據寫入頁緩存后就向客戶端返回成功,還是必須等到數據被持久化到磁盤后才返回?

這本質上是系統性能與數據可靠性之間的權衡。為此,RocketMQ 提供了兩種持久化策略:同步刷盤和異步刷盤。

所謂的 “刷盤”,在代碼層面其實就是調用 FileChannel 或 MappedByteBuffer 的 force() 方法,強制操作系統將頁緩存中對應的數據寫入物理磁盤。

圖片圖片

同步刷盤

同步刷盤策略要求 Broker 將消息寫入內存后,必須立即將其持久化到磁盤,然后才能向客戶端返回成功響應。

但這里有一個關鍵問題:同步刷盤是每條消息都單獨刷一次盤嗎?答案是否定的。

RocketMQ 的同步刷盤實現隱藏著一個重要的優化:組提交(Group Commit)。其入口位于 GroupCommitService 類中,從類名就能看出其設計思想。

圖片圖片

實現中有兩個關鍵點:

  • 組提交:一次刷盤操作會將當前所有待刷盤的消息(一個消息組)一次性寫入磁盤,而不是一條一條地刷。這極大地減少了磁盤 I/O 次數。
  • 同步轉異步:實現上采用 CountDownLatch 將同步調用轉換為異步處理模式。主線程提交一個刷盤請求后,會限時等待 (await) 后臺刷盤線程的結果,從而實現業務邏輯的解耦。

接下來繼續探討組提交的設計理念。

圖片圖片

判斷一條刷盤請求成功的條件:當前已刷盤指針大于該條消息對應的物理偏移量,這里使用了刷盤重試機制。然后喚醒主線程并返回刷盤結果。

所謂的組提交,其核心理念理念是調用刷盤時使用的是 MappedFileQueue.flush 方法,該方法并不是只將一條消息寫入磁盤,而是會將當期未刷盤的數據一次性刷寫到磁盤,既組提交,故即使在同步刷盤情況下,也并不是每一條消息都會被執行 flush 方法,為了更直觀的展現組提交的設計理念,給出如下流程圖:

圖片圖片

異步刷盤

同步刷盤提供了最高級別的數據可靠性,但犧牲了寫入性能。考慮到 RocketMQ 的消息首先寫入 PageCache,在非極端掉電情況下數據丟失的概率很小,因此,如果業務能容忍極低概率的數據丟失以換取更高的吞吐量,可以選擇異步刷盤。

異步刷盤模式下,Broker 將消息寫入 PageCache 后會立即向客戶端返回成功,然后由一個后臺線程(FlushRealTimeService)定時將臟頁數據刷入磁盤,默認間隔為 500ms。

你可能會猜測這是用 ScheduledExecutorService 之類的定時任務實現的,但 RocketMQ 的實現更為精妙。它同樣利用了帶超時時間的 CountDownLatch.await()。這種方式的好處在于:

  • 在沒有新消息寫入時,線程會安靜地等待 500ms,避免了空輪詢帶來的 CPU 消耗。
  • 一旦有新消息寫入(wakeup() 被調用),線程會立即被喚醒執行刷盤,而無需等待 500ms 周期結束,保證了刷盤的及時性。

保障數據一致性:文件恢復機制

圖片圖片

在 RocketMQ 的架構中,commitlog 是主數據文件,而 consumequeue 和 indexFile 等索引文件是根據 commitlog 的內容異步構建的。既然是異步構建,就必然存在數據不一致的風險窗口。例如,Broker 在將數據轉發到 consumequeue 之前異常關閉,重啟后如何保證數據的一致性?

在探討恢復機制前,我們先設想幾個典型的異常場景:

  • 消息已同步刷盤到 commitlog,但在轉發到 consumequeue 之前,機器斷電。
  • 一次批量刷盤操作(例如 100MB 數據)在執行到一半(例如 50MB)時,機器斷電,導致 commitlog 文件末尾存在一條不完整的消息。
  • commitlog 刷盤成功,但在更新 checkpoint 文件(記錄各文件刷盤點)之前,進程退出。

在 RocketMQ 中,文件恢復分為正常停止和異常停止兩種場景。

兩種場景定位恢復起點的邏輯略有不同,但一旦定位到起始恢復文件,后續的文件校正思路是統一的:

  • 首先嘗試恢復 consumequeue:遍歷 consumequeue 文件,根據其定長格式(8字節偏移量 + 4字節長度 + 8字節Tag哈希碼),找到最后一條完整條目所指向的 commitlog 物理偏移量,記為 maxPhysicalOfConsumequeue。
  • 然后嘗試恢復 commitlog:遍歷 commitlog 文件,校驗魔數,并根據消息存儲格式找到最后一條完整的、校驗合格的消息,記錄其物理偏移量 physicalOffset。
  • 對比與校正:

如果 commitlog 的有效偏移量小于 consumequeue 中記錄的最大偏移量,說明 consumequeue 中存在無效的“超前”索引,需要被截斷。

如果 commitlog 的有效偏移量大于 consumequeue 中記錄的最大偏移量,說明有部分消息還未建立索引,需要從 commitlog 中重新讀取這部分消息,并重建 consumequeue 和其他索引文件。

那么,如何高效地定位到可能需要恢復的文件呢?

正常退出定位文件

在 RocketMQ 啟動時候會創建一個名為 abort 的文件,并在正常關閉時將其刪除。因此,通過檢查 abort 文件是否存在,即可判斷上次是否為異常退出。

圖片圖片

對于正常退出場景,恢復策略相對樂觀:

  • ConsumeQueue 的恢復從每個主題的第一個文件開始。
  • commitlog 的恢復從倒數第三個文件開始向后檢查。因為正常退出時,大部分文件都已完整寫入并刷盤。

異常退出定位文件

異常退出時,不確定性大大增加,恢復策略必須更加嚴謹。此時,checkpoint 文件就派上了用場。該文件記錄了 commitlog、consumequeue 等文件的最后一次刷盤時間戳。

圖片圖片

  • physicMsgTimestamp:commitlog 文件最后的刷盤的時間點
  • logicsMsgTimestamp: consumequeue 文件最后的刷盤時間點
  • indexMsgTimestamp: indexfile 文件最后的刷盤時間點

checkpoint 文件的更新總是在 commitlog 刷盤成功之后進行。

圖片圖片

這意味著 checkpoint 中記錄的刷盤點是“絕對可靠”的,早于該時間點的數據一定已經落盤。基于此,異常退出時的恢復策略是:

  • ConsumeQueue 是按照 topic 進行恢復的,從第一文件開始恢復。
  • commitlog 的恢復從最后一個文件開始,逐個向前掃描。讀取每個文件的第一條消息的存儲時間,與 checkpoint 中記錄的 physicMsgTimestamp 進行比較。一旦找到一個文件的起始時間小于等于 checkpoint 的時間戳,那么就從這個文件開始執行恢復流程。

文件恢復的入口位于 DefaultMessageStore#recover 方法,讀者可根據上述理念,自行探索源碼,定會事半功倍。

終極性能優化:Java 零拷貝

在高性能網絡文件服務中,“零拷貝”(Zero-Copy)是一個高頻詞匯。這里我們不贅述其底層原理,而是直接看 RocketMQ 在消息消費場景下,如何結合 Netty 實現零拷貝,將磁盤文件高效地發送到網絡。

圖片圖片

零拷貝的關鍵實現要點:

  • 當需要發送消息時,RocketMQ 首先通過內存映射從 commitlog 文件中獲取一個代表消息數據的 ByteBuf。重要的是,這個 ByteBuf 僅僅是一個引用,數據本身仍在頁緩存中,并未被加載到 Java 堆內存。
  • 然后,將這個 ByteBuf 包裝成一個 Netty 的 FileRegion 對象,并最終調用其 transferTo 方法。該方法的底層實現委托給了 FileChannel.transferTo()。

在 ManyMessageTransfer 類中可以看到具體的 transferTo 實現:

圖片圖片

FileChannel.transferTo() 在 Linux 系統上會觸發 sendfile() 系統調用。這個系統調用可以直接在內核空間中,將數據從文件句柄(頁緩存)拷貝到套接字緩沖區,避免了數據在內核態和用戶態之間的來回拷貝,實現了真正的零拷貝,極大地提升了數據傳輸效率。

本文從文件編程的視角,跟隨 RocketMQ 的設計學習了諸多優秀的工程技巧。希望這些內容能對你有所啟發

結語

學習 RocketMQ,我們學的不僅是 “術”(具體的實現技巧),更是 “道”(解決問題的思想和方法論)。希望通過本文的剖析,能為你打開一扇通往高性能存儲世界的大門,并在未來的系統設計中,能夠更加游刃有余地運用這些閃耀著智慧光芒的編程藝術。

責任編輯:武曉燕 來源: JAVA日知錄
相關推薦

2015-08-06 10:14:15

造輪子facebook

2020-09-08 08:45:39

jupyter插件代碼

2022-04-27 20:02:22

Dubbo注冊中心開發

2023-02-14 12:40:44

ChatGPTAI聊天

2023-02-06 17:27:48

2022-12-07 10:34:45

AST前端編譯

2018-09-03 14:05:08

編程語言Python編程技巧

2021-02-26 13:59:41

RocketMQProducer底層

2022-05-13 09:16:49

Python代碼

2021-10-09 18:26:59

二叉樹多叉樹搜索

2012-01-13 16:00:05

愛國者馮軍蘋果

2024-04-07 09:34:59

集群RemoteTransform

2020-06-11 18:06:03

電腦電路板元件

2021-10-28 19:10:51

RustPythonjs

2021-04-09 10:26:43

Python編程技術

2021-11-08 22:38:44

電腦科技C盤

2022-06-29 10:04:01

PiniaVuex

2024-05-14 08:11:56

ReactuseState造輪子

2021-03-15 09:44:39

Broker源碼RocketMQ

2023-02-23 19:39:06

華為汽車業務
點贊
收藏

51CTO技術棧公眾號

国产999精品久久| 久久精品亚洲人成影院 | 欧美日韩dvd在线观看| 这里只有精品66| 免费观看国产视频| 三级在线观看一区二区 | 草草视频在线观看| 欧美激情在线观看视频免费| 亚洲a在线播放| 在线观看黄网站| 亚洲国产精品成人| 亚洲国产97在线精品一区| 黄色一级二级三级| 免费男女羞羞的视频网站在线观看| 久久在线观看免费| 亚洲综合在线做性| 亚洲精品国产精品乱码视色| 黑人一区二区| 最近2019中文字幕第三页视频| 免费看91视频| 欧美黄页免费| 色8久久人人97超碰香蕉987| 日韩一级免费看| 高清福利在线观看| www.99精品| 2019国产精品视频| 中文天堂在线资源| 亚洲国产日本| 久久91精品国产91久久久| 国产无遮挡在线观看| 日韩丝袜视频| 精品国产sm最大网站| 日韩av影视大全| 97成人超碰| 色综合天天综合在线视频| 久久久久久久久久久综合| 欧美日韩国产综合视频 | 熟女少妇内射日韩亚洲| 欧美wwwsss9999| 精品福利一区二区三区免费视频| 欧美一级视频在线| 农村妇女一区二区| 欧美熟乱第一页| 国模杨依粉嫩蝴蝶150p| 色戒汤唯在线| 图片区小说区区亚洲影院| 亚洲天堂第一区| 国产在线二区| 国产视频一区不卡| 欧美日韩精品久久| 蜜桃视频在线播放| 久久影院电视剧免费观看| 精品国产一区二区三| 人妻精品无码一区二区| 成人黄色av电影| 国产免费一区二区三区| 欧美 日韩 中文字幕| 国产成人精品三级| 99久久无色码| 俄罗斯嫩小性bbwbbw| 丁香六月久久综合狠狠色| 91入口在线观看| 亚洲第一色网站| 成人av一区二区三区| 国产综合 伊人色| 天堂在线视频网站| 91片黄在线观看| 欧美在线播放一区二区| 久久精品国产亚洲a∨麻豆| 国产婷婷一区二区| 翔田千里亚洲一二三区| 男人资源在线播放| 亚洲免费观看高清完整| 69精品丰满人妻无码视频a片| 免费看电影在线| 精品久久久一区| 日本va中文字幕| 88xx成人网| 制服丝袜av成人在线看| 色诱av手机版| 精品在线91| www.日韩不卡电影av| 欧美成人精品欧美一级| 亚洲人成久久| 国产精品成人一区| 国产av无码专区亚洲av| 99精品欧美一区二区蜜桃免费| 欧美高清一区二区| 免费在线观看av网站| 亚洲在线观看免费| 日日碰狠狠躁久久躁婷婷| 日韩精品一区二区三区av| 欧美一级黄色大片| 中文字幕av网址| 偷拍欧美精品| 欧美自拍视频在线| 91在线视频国产| av动漫一区二区| 亚洲一区二区三区午夜| 亚洲小说区图片| 色系网站成人免费| 精品人妻人人做人人爽夜夜爽| 中国av一区| 久99久在线视频| 最近日韩免费视频| 成人精品免费视频| 中文字幕一区二区三区5566| 九九色在线视频| 欧美亚洲日本国产| 黄色性视频网站| 天天做综合网| 日本一区二区在线播放| 亚洲爱爱综合网| 国产精品午夜在线| 俄罗斯av网站| 日韩在线网址| 中文综合在线观看| wwwwww国产| 国产精品影视在线观看| 色噜噜狠狠一区二区三区| 操喷在线视频| 欧美一区二区三区喷汁尤物| 在线小视频你懂的| 亚洲精品乱码久久久久久蜜桃麻豆| 国产精品三级久久久久久电影| 天堂中文在线观看视频| 一区二区三区四区视频精品免费| 亚洲一级片免费| 亚洲福利网站| 97成人精品视频在线观看| 国产成人三级在线播放| 国产精品美女www爽爽爽| 中文字幕乱码人妻综合二区三区| 粉嫩一区二区三区四区公司1| 久久亚洲精品一区二区| 亚洲资源在线播放| 国产欧美精品一区二区三区四区 | 制服国产精品| 少妇精品视频一区二区免费看| 亚洲二区在线播放视频| 五月天丁香激情| 精品亚洲欧美一区| 新呦u视频一区二区| 全球最大av网站久久| 亚洲天堂av综合网| 中文字幕精品无| 国产无遮挡一区二区三区毛片日本| 欧美国产激情视频| 青草久久视频| 欧美一性一乱一交一视频| 婷婷丁香花五月天| 黄色一区二区三区| 亚洲欧美在线不卡| 一本一道久久综合狠狠老精东影业| 99久久久久国产精品免费| 欧美另类tv| 欧美成人国产一区二区| 久久久久久久久99| 成人av电影在线网| 亚欧无线一线二线三线区别| 日日狠狠久久偷偷综合色| 欧美伊久线香蕉线新在线| 青青草在线免费观看| 色欧美88888久久久久久影院| 亚洲自拍偷拍一区二区| 天堂久久一区二区三区| 天堂资源在线亚洲视频| 日本国产亚洲| 欧美大尺度激情区在线播放| www.久久成人| 天天影视网天天综合色在线播放| 国产亚洲色婷婷久久99精品91| 国产欧美一区二区色老头| 欧美大陆一区二区| 成人国产一区| 欧美高清在线观看| 亚洲色图另类小说| 欧美午夜精品理论片a级按摩| 一级片黄色录像| 国产精品1024久久| 欧洲黄色一级视频| 成人激情免费视频| 亚洲综合视频1区| 蜜桃视频在线网站| 少妇高潮久久77777| 精品人妻无码一区二区色欲产成人 | 欧美日韩一级在线观看| caoporn国产一区二区| 国产熟女高潮视频| 中文精品久久| 久久伊人一区二区| 4438五月综合| 欧美一级大片视频| 黄av在线免费观看| 日韩精品中文字幕视频在线| 亚洲熟女乱色一区二区三区久久久 | 天堂在线中文网官网| 中文字幕欧美日韩在线| 韩国av免费在线观看| 欧美在线不卡一区| 国产性生活网站| 中文一区二区在线观看| 最新版天堂资源在线| 蜜桃av一区二区在线观看| 成人精品视频在线播放| 日韩一区二区三区免费播放| 国产视频在线观看一区| 国产亚洲高清一区| 国产精品xxx视频| sm捆绑调教国产免费网站在线观看| 中文字幕日韩精品有码视频| 偷拍自拍在线| 精品免费日韩av| 97超视频在线观看| 色婷婷精品久久二区二区蜜臂av | 97超碰在线播放| 精品亚洲美女网站| 97在线视频免费播放| 麻豆传媒视频在线观看免费| 亚洲美女激情视频| 成人小说亚洲一区二区三区 | 久久久久xxxx| 天堂蜜桃91精品| 国产在线精品91| 欧美久久一区| a级网站在线观看| 欧美在线观看视频一区| 欧美lavv| 亚洲+变态+欧美+另类+精品| 国产91亚洲精品一区二区三区| 人人精品久久| 国产美女搞久久| 欧美与亚洲与日本直播| 5566成人精品视频免费| 999福利在线视频| 欧美精品精品精品精品免费| a天堂中文在线官网在线| 日韩亚洲欧美中文高清在线| a√资源在线| 正在播放亚洲1区| 成人免费视频| 中文字幕免费国产精品| 成人性爱视频在线观看| 亚洲图片在线综合| 国产精品免费观看| 在线亚洲午夜片av大片| av黄色在线观看| 日韩在线视频免费观看| 日本美女高清在线观看免费| 在线亚洲欧美视频| 免费的黄网站在线观看| 久久精品一偷一偷国产| 成人日批视频| 欧美俄罗斯性视频| 国产精品蜜臀| 8x拔播拔播x8国产精品| 午夜影院在线观看国产主播| 日本久久亚洲电影| 性欧美hd调教| 国产日本欧美在线观看| 不卡的国产精品| 99国产超薄肉色丝袜交足的后果| caoporn成人| 久久亚裔精品欧美| 极品美女一区二区三区| 亚洲一区3d动漫同人无遮挡| 亚洲精品99| 日韩黄色短视频| 视频一区二区三区中文字幕| 538任你躁在线精品免费| 久久99久久久欧美国产| 日本网站在线看| av一区二区不卡| 夜夜春很很躁夜夜躁| 中文字幕色av一区二区三区| 妺妺窝人体色www在线下载| 精品女同一区二区三区在线播放| 蜜臀尤物一区二区三区直播| 555www色欧美视频| 色wwwwww| 这里只有精品久久| a毛片不卡免费看片| 国产精品27p| 高清一区二区三区av| 国产在线精品一区| 久久国产精品亚洲人一区二区三区| 国产免费一区二区三区四在线播放| 99国内精品| 午夜免费看视频| 成人av动漫在线| 日韩精品电影一区二区三区| 一二三区精品福利视频| 中文人妻av久久人妻18| 欧美一区二区三区在线视频| 视频福利在线| 久久夜精品va视频免费观看| 狼人综合视频| 91在线免费网站| 国产精品入口久久| 丁香六月激情婷婷| 精品一区二区三区免费| 北岛玲一区二区| 亚洲丝袜自拍清纯另类| 欧美一区二区激情视频| 欧美一二三区精品| 国产高清视频在线观看| 久久久久久久国产精品视频| 国产a亚洲精品| 久久久亚洲综合网站| 综合av在线| 在线观看免费成人av| 播五月开心婷婷综合| 一本一本久久a久久| 色综合久久天天综合网| 免费观看黄色一级视频| 美女啪啪无遮挡免费久久网站| 你懂得影院夜精品a| 九九九九精品九九九九| 欧美私人啪啪vps| 免费成人黄色大片| 国产色91在线| 国产精品乱子伦| 亚洲精品suv精品一区二区| www久久日com| 国产在线a不卡| 日本道不卡免费一区| 久久国产亚洲精品无码| 懂色一区二区三区免费观看 | porn视频在线观看| 欧洲成人免费aa| 精品福利网址导航| 激情五月婷婷六月| 国产精品77777| 国产精品99久久久久久成人| 欧美日韩成人综合天天影院| 国产爆初菊在线观看免费视频网站 | 久久 天天综合| 欧美xxxx精品| 欧美日韩大陆在线| 一级日本在线| 国产色婷婷国产综合在线理论片a| 欧美精品一区二区三区中文字幕| 丰满少妇被猛烈进入高清播放| 波多野结衣精品在线| 国产无码精品在线播放| 亚洲高清一二三区| cao在线视频| 精品久久久久久亚洲| 一本色道久久综合| 欧美丰满少妇人妻精品| 欧美性xxxx| 免费福利在线视频| 国产成一区二区| 成人免费电影网址| 日本人69视频| 亚洲精品国产视频| 亚洲精品视频专区| 97在线视频精品| 狠狠色狠狠色综合婷婷tag| 欧美性猛交久久久乱大交小说| 日本一区二区三区国色天香| 在线免费观看一区二区| 久久精品国产成人精品| 日韩精品视频一区二区三区| 国内精品视频一区二区三区| 91美女福利视频| 国产情侣小视频| 久久精品一区中文字幕| silk一区二区三区精品视频| 99蜜桃臀久久久欧美精品网站| 国产女人aaa级久久久级| 91麻豆视频在线观看| 九九热最新视频//这里只有精品| 成人h动漫免费观看网站| 国产精品333| 国产精品视频在线看| 国内精品偷拍视频| 欧美一级电影免费在线观看| jizzjizz欧美69巨大| 亚洲AV无码久久精品国产一区| 亚洲国产欧美在线人成| 免费一级毛片在线观看| 92看片淫黄大片欧美看国产片| 亚洲黄色一区| 青青草自拍偷拍| 亚洲国产精品人人爽夜夜爽| 亚洲综合在线电影| 路边理发店露脸熟妇泻火| 91麻豆精品在线观看| 97超碰人人草| 欧洲亚洲免费视频| 一区二区三区四区在线观看国产日韩| 一级黄色电影片| 欧美三级欧美一级| 国产蜜臀在线| 一区不卡字幕| 91麻豆产精品久久久久久| 国产毛片毛片毛片毛片| 欧美中文字幕在线播放| 欧美一区国产在线|