久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    Elasticsearch集群剖析架構分析

     心悅仰空 2022-02-10

      第一部分

      這篇文章是一系列文章的一部分,該文章涵蓋了流行的分布式搜索引擎Elasticsearch的基礎架構和原型示例。在本文中,我們將討論基礎存儲模型以及CRUD(創建,讀取,更新和刪除)操作在Elasticsearch中的工作方式。

      Elasticsearch是一種非常流行的分布式搜索引擎,已在GitHub,SalesforceIQ,Netflix等許多公司中用于全文搜索和分析應用程序。在Insight數據工程研究員計劃中,研究員已將Elasticsearch用于其各種不同功能,例如:

      全文搜索

      例如,查找與搜索詞最相關的Wikipedia文章。

      聚合分析

      例如,在廣告網絡上可視化搜索詞的出價直方圖。

      地理空間API

      例如,一個可以與最接近的駕駛員和騎手相匹配的乘車平臺。

      由于Elasticsearch在業界和我們的研究員中如此受歡迎,因此我決定仔細研究一下。在這篇文章中,我想分享我對它的存儲模型以及CRUD操作如何工作的了解。

      現在,當我想到分布式系統如何工作時,我想到下圖:

      Elasticsearch集群剖析架構分析

      表面上方的部分是API,下方部分是發生所有魔力的實際引擎。在這篇文章中,我們將專注于表面以下的部分。主要地,我們將看:

      它是主/從架構還是無主架構?什么是存儲模型?寫操作是如何進行的?讀操作如何進行?搜索結果如何確定相關性的?

      在深入探討這些概念之前,讓我們熟悉一些術語。

      Elasticsearch索引是用于組織數據(如數據庫)的邏輯命名空間。Elasticsearch索引具有一個或多個分片(默認為5)。分片是實際上存儲數據的Lucene索引,它本身就是搜索引擎。每個分片可以具有零個或多個副本(默認值為1)。Elasticsearch索引還具有“類型”(例如數據庫中的表),使您可以在索引中對數據進行邏輯分區。Elasticsearch索引中給定“類型”中的所有文檔都具有相同的屬性(例如表的架構)。

      Elasticsearch集群剖析架構分析

      圖a顯示了一個Elasticsearch集群,該集群由三個主要分組成,每個分都有一個副本。所有這些分片共同構成一個Elasticsearch索引,每個分片本身就是一個Lucene索引。圖b展示了Elasticsearch索引,分片,Lucene索引和文檔之間的邏輯關系。

      類比關系數據庫術語

      Elasticsearch索引?數據庫類型?表映射?模式

      注意:上面的類比僅用于等同目的,并不用于等同。我建議閱讀此博客,以幫助決定何時選擇索引或類型來存儲數據。

      現在,我們熟悉了Elasticsearch世界中的術語,讓我們看看節點可以具有的各種角色。

      節點類型

      Elasticsearch的一個實例是一個節點,一組節點組成一個集群。可以通過三種不同的方式配置Elasticsearch集群中的節點:

      主節點

      它控制Elasticsearch集群,并負責所有集群范圍的操作,例如創建/刪除索引,跟蹤哪些節點是集群的一部分以及為節點分配分片。主節點一次處理一個群集狀態,并將該狀態廣播到所有其他節點,這些節點響應主節點的確認。通過在elasticsearch.yml中將node.master屬性設置為true(默認值),可以將節點配置為有資格成為主節點。對于大型生產集群,建議使用專用的主節點來僅控制集群而不滿足任何用戶請求。

      數據節點

      它保存數據和倒排索引。默認情況下,每個節點都配置為一個數據節點,并且屬性node.data在elasticsearch.yml中設置為true。如果您想要一個專用的主節點,則將node.data屬性更改為false。

      客戶端節點:

      如果將node.master和node.data都設置為false,則該節點將配置為客戶端節點,并充當負載平衡器,將傳入的請求路由到群集中的其他節點。

      您作為客戶端連接的Elasticsearch集群中的節點稱為協調節點。協調節點將客戶端請求路由到集群中的適當分片。對于讀取請求,協調節點每次都會選擇一個不同的分片來處理請求,以平衡負載。

      在我們開始查看發送到協調節點的CRUD請求如何在集群中傳播并由引擎執行之前,讓我們了解一下Elasticsearch如何在內部存儲數據以在低延遲下為全文搜索提供結果。

      儲存模式

      Elasticsearch使用Apache Lucene,這是一種用Java編寫的全文搜索庫,由Doug Cutting(Apache Hadoop的創建者)開發,在內部使用了稱為倒排索引的數據結構,旨在提供低延遲搜索結果。文檔是Elasticsearch中數據的單位,并且通過對文檔中的單詞(Term)進行標記,創建所有唯一單詞的排序列表并將文檔列表與可以找到該單詞的列表相關聯來創建反向索引。

      它與書后部的索引非常相似,該索引包含書中所有唯一的單詞以及可在其中找到該單詞的頁面列表。當我們說一個文檔被索引時,我們指的是倒排索引。讓我們看看以下兩個文檔的倒排索引如何:

      Doc 1:Insight Data Engineering Fellows Program

      Doc 2:Insight Data Science Fellows Program

      Elasticsearch集群剖析架構分析

      如果我們要查找包含“ insight”一詞的文檔,我們可以掃描倒排索引(對單詞進行排序),找到“ insight”一詞,然后返回包含該單詞的文檔ID(在這種情況下為Doc)1和文件2。

      為了提高可搜索性(例如,對小寫和大寫單詞提供相同的結果),首先對文檔進行分析,然后將其編入索引。分析包括兩個部分:

      將句子標記為單個單詞將單詞標準化為標準格式

      默認情況下,Elasticsearch使用標準分析器,而標準分析器使用

      標準標記器可在單詞邊界上拆分單詞小寫標記過濾器將單詞轉換為小寫

      還有許多其他分析器可用。

      為了提供相關的搜索結果,還使用與索引相同的分析器來分析在文檔上進行的每個查詢。

      注意:標準分析器還使用停止令牌過濾器,但默認情況下處于禁用狀態。

      倒排索引的概念現在很清楚,讓我們回顧一下CRUD操作。我們將從寫開始。

      寫數據的分析

      創建(C)

      當您向協調節點發送請求以索引新文檔時,將發生以下一組操作:

      Elasticsearch集群中的所有節點都包含有關哪個分片位于哪個節點上的元數據。協調節點使用文檔ID(默認)將文檔路由到適當的分片。Elasticsearch使用murmur3作為哈希函數哈希哈希文檔ID,并根據索引中主要碎片的數量對mods進行哈希處理,以確定應在文檔中建立哪個碎片索引。

      分片=哈希(document_id)%(num_of_primary_shards)

      當節點從協調節點接收到請求時,該請求將被寫入事務日志,然后將文檔添加到內存緩沖區中。如果請求在主分片上成功,則將請求并行發送到副本分片。只有在所有主分片和副本分片上同步傳輸日志后,客戶端才會收到請求成功的確認。內存緩沖區會定期刷新(默認為1秒),并將內容寫入文件系統緩存中的新段。該細分受眾群尚未同步,但是該細分受眾群處于打開狀態,其內容可供搜索。每隔30分鐘或當Translog太大時,清空Translog,并同步文件系統緩存。在Elasticsearch中,此過程稱為沖洗。在刷新過程中,將清除內存緩沖區,并將內容寫入新的段。創建了一個新的提交點,其中的段已同步并刷新到磁盤。舊的日志被刪除,新的日志開始。

      下圖顯示了寫入請求和數據的流向。

      Elasticsearch集群剖析架構分析

      更新(U)和刪除(D)

      刪除和更新操作也是寫操作。但是,Elasticsearch中的文檔是不可變的,因此不能刪除或修改以表示任何更改。那么,如何刪除/更新文檔?

      磁盤上的每個段都有一個與其關聯的.del文件。發送刪除請求后,該文檔并沒有真正刪除,而是在.del文件中標記為已刪除。該文檔可能仍與搜索查詢匹配,但已從結果中過濾掉。合并細分后(我們將在后續帖子中介紹細分合并),. del文件中標記為已刪除的文檔不包括在新的合并細分中。

      現在,讓我們看看更新是如何工作的。創建新文檔后,Elasticsearch會為該文檔分配一個版本號。對文檔的每次更改都會產生一個新的版本號。執行更新時,舊版本在.del文件中標記為已刪除,而新版本在新段中建立索引。較舊的版本可能仍與搜索查詢匹配,但是,它已從結果中濾除。

      在對文檔建立索引/更新之后,我們想執行搜索請求。讓我們看看如何在Elasticsearch中執行搜索請求。

      讀數據的分析

      讀取操作包括兩部分:

      查詢階段提取階段

      讓我們看看每個階段如何運作。

      查詢階段

      在此階段,協調節點將搜索請求路由到索引中的所有分片(主分片或副本分片)。分片會獨立執行搜索,并創建一個按相關性得分排序的結果優先級隊列。所有分片將匹配文檔的文檔ID和相關分數返回給協調節點。協調節點創建一個新的優先級隊列,并對結果進行全局排序。可能有很多與結果匹配的文檔,但是,默認情況下,每個分片都會將前10個結果發送到協調節點,并且協調會從所有分片創建優先級隊列排序結果,并返回前10個匹配項。

      提取階段

      在協調節點對所有結果進行排序以生成文檔的全局排序列表之后,它隨后從所有分片中請求原始文檔。所有分片都會豐富文檔,然后將其返回到協調節點。

      下圖顯示了軟件讀取請求和數據的流向。

      Elasticsearch集群剖析架構分析

      如上所述,搜索結果按相關性排序。讓我們回顧一下相關性的定義。

      搜索相關性

      相關性由Elasticsearch給搜索結果中返回的每個文檔的分數確定。評分的默認算法是tf / idf(術語頻率/文檔反向頻率)。術語頻率衡量一個術語在文檔中出現的次數(較高的頻率==更高的相關性),反向文檔頻率衡量該術語在整個索引中出現的頻率占索引中文檔總數的百分比(較高的頻率)==減少相關性)。最終分數是tf-idf分數與其他因素的組合,例如術語接近度(針對短語查詢),術語相似度(針對模糊查詢)等。

      接下來是什么?

      這些CRUD操作得到一些內部數據結構和技術的支持,這對于理解Elasticsearch的工作方式非常重要。在后續文章中,我將在使用Elasticsearch時介紹一些概念和一些陷阱。

      Elasticsearch中的裂腦問題以及如何避免交易記錄Lucene段為什么在搜索過程中進行深度分頁很危險?計算搜索相關性時的困難和折衷并發控制為什么Elasticsearch接近實時?如何確保一致的讀寫?第二部分

      在本文中,我們將討論Elasticsearch如何處理三個C(共識,并發和一致性)以及分片(如跨記錄(Write Ahead Log,WAL))和Lucene段的內部概念。

      在上部分中,我們討論了Elasticsearch中的基礎存儲模型和CRUD操作。在本章中,我想分享一下Elasticsearch如何解決分布式系統的一些基本挑戰以及分片的一些內部概念。這些涉及Insight數據工程研究員在使用Elasticsearch構建數據平臺時成功解決和理解的一些操作方面。我主要講的是:

      共識-腦裂問題和法定人數的重要性并發一致性:確保一致的讀寫Translog(提前寫入日志-WAL)Lucene段共識-腦裂問題和法定人數的重要性

      共識是分布式系統的基本挑戰之一。它要求系統中的所有進程/節點都同意給定的數據值/狀態。有很多共識算法,例如Raft,Paxos等,都在數學上得到了證明,但是,由于Shay Banon(Elasticsearch的創建者)在此描述的原因,Elasticsearch已實現了自己的共識系統(zen discovery)。zen discovery模塊分為兩個部分:

      Ping:流程節點用于發現彼此單播:包含主機名列表的模塊,用于控制要ping的節點

      Elasticsearch是一個對等系統,其中所有節點都相互通信,并且有一個活動的主節點來更新和控制集群范圍的狀態和操作。作為ping進程的一部分,將對新的Elasticsearch集群進行選舉,在該過程中,從所有符合主條件的節點中選出一個節點作為主節點,其他節點加入該主節點。缺省ping_interval為1秒,而ping_timeout為3秒。當節點加入時,它們會使用默認的join_timeout(它是ping_timeout的20倍)向主服務器發送加入請求。如果主服務器發生故障,則群集中的節點將再次開始ping通,以開始另一個選舉。如果節點意外地認為主節點發生故障并通過其他節點發現主節點,則此ping過程也將有所幫助。

      注意:默認情況下,客戶端和數據節點不會參與選舉過程。可以通過在elasticsearch.yml配置文件中將

      Discovery.zen.master_election.filter_client和

      Discovery.zen.master_election.filter_data屬性設置為False來更改此設置。

      為了進行故障檢測,主節點對所有其他節點執行ping操作,以檢查它們是否還處于活動狀態,而所有節點對主節點執行ping操作,以報告它們仍處于活動狀態。

      如果使用默認設置,Elasticsearch會遇到裂腦的問題,在網絡分區的情況下,節點可以認為主節點已死,并將自己選舉為主節點,從而導致具有多個主節點的集群。這可能會導致數據丟失,并且可能無法正確合并數據。可以通過將以下屬性設置為合格的主節點法定數量來避免這種情況。

      discovery.zen.minimum_master_nodes=int(# of master eligible nodes/2)+1

      Elasticsearch集群剖析架構分析

      此屬性需要有效的主節點資格的法定人數參加選舉進程完成了新當選的主節點,并有新的主接受了主控權。這是確保群集穩定性的極其重要的屬性,并且如果群集大小發生更改,可以動態更新。圖a和b顯示了分別設置minimum_master_nodes屬性和未設置時在發生網絡分區時會發生的情況。

      注意:對于生產集群,建議有3個專用主節點,這些主節點不滿足任何客戶端請求,在任何給定時間中有1個處于活動狀態。

      當我們了解了Elasticsearch中的共識后,現在讓我們看看它如何處理并發。

      并發

      Elasticsearch是一個分布式系統,支持并發請求。當創建/更新/刪除請求命中主分片時,它也會并行發送到副本分片,但是,這些請求可能會亂序到達。在這種情況下,Elasticsearch使用樂觀并發控制來確保文檔的新版本不會被舊版本覆蓋。

      索引的每個文檔都有一個版本號,該版本號隨對該文檔進行的每次更改而增加。這些版本號用于確保按順序應用更改。為確保應用程序中的更新不會導致數據丟失,Elasticsearch的API允許您指定應將更改應用到的文檔的當前版本號。如果請求中指定的版本比分片中存在的版本舊,則請求將失敗,這意味著文檔已由另一個進程更新。失敗請求的處理方式可以在應用程序級別進行控制。還有其他可用的鎖定選項,您可以在此處閱讀有關它們的信息。

      當我們將并發請求發送到Elasticsearch時,下一個需要關注的問題是-如何使這些請求保持一致?現在,尚不清楚如何回答CAP三角形Elasticsearch落在哪一側,這是一個辯論,我們將不在本文中解決。

      Elasticsearch集群剖析架構分析

      但是,我們將介紹如何使用Elasticsearch實現一致的讀寫。

      一致性-確保一致的讀寫

      對于寫入,Elasticsearch支持與大多數其他數據庫不同的一致性級別,以允許進行初步檢查,以查看允許寫入的可用分片數量。可用的選項是定額,全部。默認情況下,它設置為仲裁,這意味著僅當大多數分片可用時才允許寫操作。在大多數分片可用的情況下,仍然可能會由于某種原因而導致對副本的寫入失敗,并且在這種情況下,據說該副本有故障,并且分片將在其他節點上重建。

      對于讀取,直到刷新間隔之后才能搜索新文檔。為確保搜索請求返回文檔最新版本的結果,可以將復制設置為同步(默認),該操作將在完成對主分片和副本分片的操作后返回寫請求。在這種情況下,來自任何分片的搜索請求都將返回文檔最新版本的結果。即使您的應用程序要求Replication=async以獲得更高的索引編制率,也可以將_preference參數設置為primary以用于搜索請求。這樣,就可以查詢搜索請求的主分片,并確保結果將來自文檔的最新版本。

      當我們了解Elasticsearch如何處理共識,并發性和一致性時,讓我們回顧一下分片內部的一些重要概念,這些概念會導致Elasticsearch作為分布式搜索引擎具有某些特征。

      跨日志

      自從關系數據庫開發以來,預寫日志(WAL)或事務日志(translog)的概念已出現在數據庫領域。事務日志可確保在發生故障時確保數據完整性,其基本原則是必須先記錄并提交預期的更改,然后再將對數據的實際更改提交到磁盤。

      當對新文檔建立索引或更新舊文檔時,Lucene索引將更改,并且這些更改將提交到磁盤以實現持久性。在每個寫請求之后執行該操作非常昂貴,因此,以一次將多個更改持久保存到磁盤的方式執行該操作。正如我們在之前的博客中所述,刷新操作(Lucene提交)默認情況下每30分鐘執行一次,或者當translog太大時(默認值為512MB)執行一次。在這種情況下,可能會丟失兩次Lucene提交之間的所有更改。為了避免出現此問題,Elasticsearch使用了一個Translog。所有索引/刪除/更新操作都會寫入轉日志,并且在每次索引/刪除/更新操作(默認情況下每5秒鐘)之后對轉日志進行同步,以確保更改是永久的。在主分片和副本分片上同步傳輸日志后,客戶端會收到寫入確認。

      如果兩次Lucene提交之間發生硬件故障或重新啟動,則重播事務日志以從上次Lucene提交之前丟失的所有更改中恢復,并將所有更改應用于索引。

      注意:建議重新啟動Elasticsearch實例之前顯式刷新事務日志,因為啟動的速度更快,因為要重播的事務日志將為空。POST / _all / _flush命令可用于刷新集群中的所有索引。

      通過translog刷新操作,文件系統緩存中的段將提交到磁盤,以使索引中的更改持久化。現在,我們來看看什么是Lucene細分市場。

      Lucene段

      Lucene索引由多個段組成,一個段本身就是一個功能齊全的反向索引。段是不可變的,這使得Lucene可以將新文檔遞增地添加到索引中,而無需從頭開始重建索引。對于每個搜索請求,將搜索索引中的所有段,并且每個段都消耗CPU周期,文件句柄和內存。這意味著段數越多,搜索性能將越低。

      為了解決此問題,Elasticsearch將較小的段合并到一個較大的段中(如下圖所示),將新合并的段提交到磁盤,并刪除舊的較小的段。

      Elasticsearch集群剖析架構分析

      這會在后臺自動發生,而不會中斷索引或搜索。由于段合并會消耗資源并影響搜索性能,因此Elasticsearch會限制合并過程,以使有足夠的資源可用于搜索。

      接下來是什么?

      對于搜索請求,將搜索Elasticsearch索引的給定分片中的所有Lucene段,但是,獲取所有匹配的文檔或排名結果深的文檔對您的Elasticsearch集群來說是危險的。在后續文章中,我們將了解原因,并復習以下主題,包括一些在Elasticsearch中進行的取舍,以在低延遲下提供相關的搜索結果。

      Elasticsearch的近實時方面為什么深度分頁搜索可能很危險?計算搜索相關性時需要權衡第三部分

      這篇文章是一系列文章的一部分,該文章涵蓋了流行的分布式搜索引擎Elasticsearch的基礎架構和原型示例。在這篇文章中,我們將討論Elasticsearch如何提供近乎實時的搜索,并考慮取舍取舍來計算搜索的相關性。

      在上部分中,我們討論了Elasticsearch如何解決分布式系統的一些基本挑戰。在本文中,我們將回顧Elasticsearch的各個方面,例如近乎實時的搜索和權衡取舍,它考慮了Insight數據工程研究員在構建數據平臺時所利用的搜索相關性。主要地,我們將看:

      近實時搜索為什么在分布式搜索中進行深度分頁可能很危險?計算搜索相關性時需要權衡近實時搜索

      盡管Elasticsearch中的更改無法立即看到,但它確實提供了接近實時的搜索引擎。如前一篇文章所述,將Lucene更改提交到磁盤是一項昂貴的操作。為了避免在繼續使文檔可供搜索的同時提交對磁盤的更改,在內存緩沖區和磁盤之間有一個文件系統緩存。內存緩沖區每秒刷新一次(默認情況下),并在文件系統緩存中創建一個具有反向索引的新段。此段已打開并可供搜索。

      文件系統緩存可以具有文件句柄,并且可以打開,讀取和關閉文件,但是它駐留在內存中。由于默認情況下刷新間隔為1秒,因此更改不會立即可見,因此幾乎是實時的。由于事務日志是未持久存儲在磁盤上的更改的持久記錄,因此它也有助于CRUD操作的近實時方面。對于每個請求,在查看相關段之前都會在事務日志中搜索任何最近的更改,因此,客戶端幾乎可以實時訪問所有更改。

      可以在每次“創建/更新/刪除”操作后顯式刷新索引,以使更改立即可見,但不建議這樣做,因為由于創建了太多小段,它會影響搜索性能。對于搜索請求,將搜索Elasticsearch索引的給定分片中的所有Lucene段,但是,獲取所有匹配的文檔或結果頁面中較深的文檔對于您的Elasticsearch集群是危險的。讓我們看看為什么。

      為什么在分布式搜索中進行深度分頁可能很危險?

      當您在具有大量匹配文檔的Elasticsearch中發出搜索請求時,默認情況下,返回的第一頁包含前10個結果。搜索API具有from和size參數,用于指定與搜索匹配的所有文檔的結果深度。例如,如果要查看與搜索匹配的等級50至60的文檔,則from=50和size=10。當每個分片接收搜索請求時,它會創建一個優先級隊列,其大小為+ size,以滿足搜索結果本身的要求,然后將結果返回給協調節點。

      Elasticsearch集群剖析架構分析

      如果要查看結果的范圍從50,000到500,010,則每個分片將創建一個優先級隊列,每個隊列具有500,010個結果,并且協調節點將必須對分片數進行排序* 50,010個結果在內存中。根據您擁有的硬件資源,可能無法達到這種級別的分頁,但是足以說明您應該對深層分頁非常小心,因為它很容易使您的集群崩潰。

      可以使用滾動API獲取所有與結果匹配的文檔,滾動API的作用更像是關系數據庫中的游標。滾動API禁用了排序功能,并且每個分片只要具有與搜索匹配的文檔,便會繼續發送結果。

      如果要獲取大量文檔,則對計分結果進行排序非常昂貴。而且由于Elasticsearch是分布式系統,因此計算文檔的搜索相關性得分非常昂貴。現在讓我們看一下在計算搜索相關性時要進行的許多權衡之一。

      計算搜索相關性時需要權衡

      Elasticsearch將tf-idf用于搜索相關性,并且由于其分布式性質,因此計算全局idf(反向文檔頻率)非常昂貴。相反,每個分片都會計算一個本地idf,以便為生成的文檔分配相關性得分,并僅返回該分片上文檔的結果。類似地,所有分片都返回使用本地idf計算的相關分數的結果文檔,并且協調節點對所有結果進行排序以返回最上面的結果。在大多數情況下,這很好,除非您的索引在關鍵字方面有所偏斜,或者單個分片上沒有足夠的數據來表示全局分布。

      例如,如果您要搜索單詞“ insight”,并且大多數包含“ insight”一詞的文檔都位于一個分片上,則與查詢匹配的文檔將不會在每個分片上公平地排名為本地idf值將有很大的不同,搜索結果可能不太相關。同樣,如果沒有足夠的數據,則某些搜索的本地idf值可能會發生很大變化,并且結果可能不如預期的那樣相關。在具有足夠數據的現實情況下,本地idf值趨于均勻,并且搜索結果具有相關性,因為文檔的評分較高。

      有兩種方法可以解決本地idf分數,但實際上不建議在生產系統中使用它們。

      一種方法是,您只能為索引分配一個分片,然后本地idf是全局IDf,但這不會為并行性/擴展留有余地,并且對于龐大的索引也不實用。另一種方法是在搜索請求中使用參數dfs_query_then_search(dfs=分布式頻率搜索),該參數首先計算所有分片的本地idf,然后將這些本地idf值組合起來以計算整個索引的全局IDf,然后將結果返回給使用全局idf計算的相關性得分。在生產中不建議這樣做,因為有足夠的數據可以確保頻率術語分布合理。

      在最近的幾篇文章中,我們回顧了Elasticsearch的一些基本原理,這些基本原理對于入門非常重要。在后續文章中,我將使用Apache Spark在Elasticsearch中為數據建立索引。

      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 久久精品国产亚洲AV高清热| 无码精品久久久久久人妻中字| 久久久久久亚洲精品| 99中文字幕国产精品| 丰满少妇人妻HD高清大乳| 日韩人妻精品无码一区二区三区 | 国产真人无码作爱视频免费| 内射一区二区三区四区| 亚洲国产五月综合网| 制服 丝袜 亚洲 中文 综合| 国产丝袜在线精品丝袜不卡| 狠狠久久亚洲欧美专区| 欧美韩中文精品有码视频在线 | a级黑人大硬长爽猛出猛进| 国产精成人品日日拍夜夜| 无遮挡免费高清羞羞视频| 肥臀浪妇太爽了快点再快点| 久草热久草热线频97精品| 性欧美VIDEOFREE高清大喷水 | 天天做天天爱夜夜爽导航 | 果冻传媒亚洲区二期| 精品视频在线观看免费观看| 精品亚洲麻豆1区2区3区| 国内老熟妇乱子伦视频| 岛国岛国免费v片在线观看| 国产精品点击进入在线影院高清 | 草裙社区精品视频播放| 亚洲精品国产综合久久久久紧| 国产农村妇女高潮大叫| 国产一区二区日韩在线| 成人小说亚洲一区二区三区| 日韩免费视频一一二区| 成人av午夜在线观看| 久久人人玩人妻潮喷内射人人 | 无码人妻丝袜在线视频| 一二三四在线视频观看社区| 久久精品免视看国产成人| 日韩精品中文字幕有码| 亚洲AV永久无码精品一区二区国产| 亚洲国产五月综合网| 麻豆国产AV剧情偷闻女邻居内裤|