<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Elasticsearch學習筆記-說明篇

          共 7577字,需瀏覽 16分鐘

           ·

          2021-07-31 03:20

          Elasticsearch是一款分布式、RESTful 風格的搜索和數(shù)據(jù)分析引擎,已經(jīng)被越來越多的企業(yè)廣泛使用。


          隨著ES的穩(wěn)步發(fā)展,ES現(xiàn)如今支持的功能也越來越強大。最近這幾天正好有時間好好學習一下ES,在這里整理幾篇相關(guān)文章。一來為自己整理一下學習筆記,二來希望這幾篇筆記能夠幫助到剛?cè)腴T學習ES的讀者。


          ES的學習筆記主要分為以下三篇:

          • 說明篇:簡單介紹一下Elasticsearch,搜索技術(shù)的基本知識以及ES相關(guān)架構(gòu)設計。

          • 安裝篇:利用ES壓縮包或docker-compose安裝ES使用環(huán)境,幾種比較常用的分詞器,及kibana安裝。

          • 使用篇:利用kibana和Java中的RestClientHighLevel實現(xiàn)一些基礎和高級的查詢。例如:索引創(chuàng)建,刪除,數(shù)據(jù)查詢聚合等相關(guān)操作。


          初步設想是讀者可以根據(jù)這三篇學習筆記自己能夠上手使用ES,包含簡單的使用,查詢,聚合等。未來自己在不斷學習的過程中也會隨時整理一些相關(guān)內(nèi)容,希望大家多多關(guān)注。


          好了其它的不多說,下面開始這篇筆記的正文,說明篇。


          Elasticsearch簡介


          Elasticsearch(以下簡稱ES)是一個分布式,可擴展,近實時的高性能搜索和數(shù)據(jù)分析引擎。所以ES不僅能夠存儲,檢索數(shù)據(jù),還能對數(shù)據(jù)進行統(tǒng)計分析。


          ES是基于Java編寫,底層使用Lucene做索引與搜索。通過對Lucene的封裝,屏蔽了Lucene的復雜性。并且ES支持簡單的RESTful API,無論你使用哪種開發(fā)語言,都能讓使用變得更簡單。


          ES的特點和優(yōu)勢:

          • 分布式實時文件存儲:ES可以將被索引文檔中的每一個字段存入索引,以便字段可以被檢索到。

          • 實時分析的分布式搜索引擎:ES的索引被拆分成多個分片,每個分片可以有0或多個副本。而集群中的每個數(shù)據(jù)節(jié)點都可以承載一個或多個分片,并且協(xié)調(diào)處理各種操作,負載均衡和路由則會自動完成。

          • 高可拓展性:ES不僅可以運行在單臺PC機上,也可以擴展到上百臺服務器,處理PB級別的結(jié)構(gòu)化或非結(jié)構(gòu)化數(shù)據(jù)。

          • 可插拔插件支持:ES支持多種插件,例如:分詞插件,同步插件,可視化插件等,這些都可以選擇性安裝。


          Lucene簡介


          提到ES就不得不說下Lucene。Lucene是一個免費,開源,高性能,純Java編寫的全文檢索引擎工具包。


          值得一提的是,Lucene僅僅是一個工具包,并不是一個完整的全文搜索引擎。Lucene的初衷是為了給開發(fā)者提供一個好用的工具包,主要提供倒排索引的查詢結(jié)構(gòu)。


          搜索技術(shù)基本知識


          提到搜索,需要提及一下數(shù)據(jù)搜索方式,而數(shù)據(jù)主要分為結(jié)構(gòu)化數(shù)據(jù)和非結(jié)構(gòu)化數(shù)據(jù)兩種。

          • 結(jié)構(gòu)化數(shù)據(jù):一般會存儲在關(guān)系型數(shù)據(jù)庫中,較常用的就是MySQL,Oracle等,數(shù)據(jù)有固定的數(shù)據(jù)格式和有限個數(shù)的字段。

          • 非結(jié)構(gòu)化數(shù)據(jù):一般會存儲在MongoDB這類文檔型數(shù)據(jù)庫中,因為非結(jié)構(gòu)化數(shù)據(jù)長度不定且無固定數(shù)據(jù)格式。而這類數(shù)據(jù)存儲在關(guān)系型數(shù)據(jù)庫中較為困難。


          為此,在搜索方面也分為結(jié)構(gòu)化數(shù)據(jù)搜索和非結(jié)構(gòu)化數(shù)據(jù)搜索。

          • 結(jié)構(gòu)化數(shù)據(jù)搜索:由于結(jié)構(gòu)化數(shù)據(jù)可以存儲在關(guān)系型數(shù)據(jù)庫中,所以一般來說,結(jié)構(gòu)化數(shù)據(jù)搜索就借助關(guān)系型數(shù)據(jù)庫,因為關(guān)系型數(shù)據(jù)庫支持索引,索引查找起來會比較方便。常用方式就是借助like關(guān)鍵字,進行左匹配(like xxx%),右匹配(like %xxx),模糊匹配(like %xxx%)。

          • 非結(jié)構(gòu)化數(shù)據(jù)搜索:搜索主要有順序掃描和全文檢索兩種方法。因為順序掃描效率非常低下,所以全文檢索技術(shù)應運而生,而搜索引擎主要的目的就是在做這樣的事情。


          下面簡單介紹一下搜索引擎的工作原理。


          搜索引擎工作分為兩個階段,即數(shù)據(jù)準備階段,和搜索階段

          • 數(shù)據(jù)準備階段:通過網(wǎng)頁數(shù)據(jù)爬取(一般使用網(wǎng)絡爬蟲)將網(wǎng)頁信息存儲在網(wǎng)頁庫中,再通過一些常見的預處理方式(例如:去除噪聲內(nèi)容,關(guān)鍵詞處理,分詞,網(wǎng)頁鏈接計算等)將數(shù)據(jù)進行轉(zhuǎn)化。轉(zhuǎn)化之后,再將數(shù)據(jù)進行正向索引,倒排索引階段處理,最終建立索引庫,將數(shù)據(jù)保存。

          • 搜索階段:搜索階段是指由用戶主動發(fā)起的請求。通過用戶輸入的關(guān)鍵字進行預處理(主要包含去重,去空格,刪除標點,拼寫錯誤檢查等)后,進行相關(guān)分詞。分詞后,搜索引擎向索引庫發(fā)起搜索請求,索引庫會將包含該分詞結(jié)果的網(wǎng)頁信息進行整理排序,最終返回給用戶。


          倒排索引


          倒排索引的名詞在ES中比較常見,都知道ES是基于倒排索引來進行數(shù)據(jù)搜索的,那么什么是倒排索引呢?


          一般來說,在建立索引的過程中均涉及正排索引和倒排索引兩種,下面簡單介紹一下:

          • 正排索引:顧名思義,正排索引就是將網(wǎng)頁或文章映射關(guān)系作為Key、以分詞后的列表為Value。(例如:一篇網(wǎng)頁中包含中文詞1,中文詞2,和中文詞3,那么正排索引的結(jié)果就是中文網(wǎng)頁1 -> 中文詞1 中文詞2 中文詞3)這就是最常見的正排索引。但是往往我們在實際搜索網(wǎng)頁或文章時恰恰與此結(jié)構(gòu)相反,所以倒排索引應運而生。

          • 倒排索引:在正排索引基礎上進行轉(zhuǎn)化,轉(zhuǎn)化為以分詞結(jié)果為Key,以網(wǎng)頁或文章列表為Value的格式。(例如:上述所說一篇網(wǎng)頁包含中文詞1,中文詞2,中文詞3,那么倒排索引的結(jié)構(gòu)就如下所示:

            中文詞1 -> 中文網(wǎng)頁1

            中文詞2?-> 中文網(wǎng)頁1

            中文詞3 -> 中文網(wǎng)頁1)


          按照上述的文字說明,大家不難發(fā)現(xiàn)。有了倒排索引,能夠大大提高文章或網(wǎng)頁的檢索效率。因為用戶可以直接通過關(guān)鍵詞定位到相關(guān)網(wǎng)頁或文章,這就是倒排索引。


          當然真正的倒排索引,不會只存儲網(wǎng)頁或文章內(nèi)容,還會存儲更多信息。例如詞匯出現(xiàn)位置,頻率等,這些都會在搜索時用到。除此之外,倒排索引還有詞條(Term),詞典(Term Dictionary),倒排表(Post List)三個名詞。

          • 詞條:是索引中最小的存儲和查詢單元。一般是指分詞后的一個詞組。

          • 詞典:也叫字典,顧名思義是詞條的集合,是出現(xiàn)所有詞條的字符串集合。

          • 倒排表:記錄詞條出現(xiàn)在哪些文檔或網(wǎng)頁中,記錄出現(xiàn)的位置和頻率等相關(guān)信息,而倒排表中的每條記錄稱為一個倒排項。

          詞典和倒排表是實現(xiàn)快速檢索的基礎。此外,詞典和倒排表是分開存儲的,詞典存儲在內(nèi)存中,而倒排表存儲在磁盤上。


          分詞器


          分詞器的目的就是將單詞或詞組進行拆分。一般來說,英文具有天然的優(yōu)勢,因為每個英文單詞都是通過空格進行分詞的,然而對于中文來說,分詞可能就不會像英文這么簡單了。例如:對于“中國人”這個詞進行分詞,不同分詞器可能分詞的結(jié)果就不相同,有的分詞器可能會拆分成,中國,人。有的分詞器可能會拆分成,中國,中國人,國人等等。


          所以對于中文分詞器來說,每種分詞器的分詞效果可能是不同的,但是無法說哪種分詞器效果最好,只能說哪種分詞器更適合自身的業(yè)務需求。而ES本身自帶的分詞器,對中文并不友好,只能將中文逐個拆分,在很多時候造成索引浪費。為此很多分詞器插件就出現(xiàn)了,這些插件不僅對中文分詞非常友好,而且支持很多復雜語境。下面簡單介紹幾種分詞器。

          • IK分詞器:IK分詞器是一個開源的,基于java語言開發(fā)的輕量級的中文分詞工具包。支持文本細粒度拆分(ik_max_word)和粗粒度拆分(ik_smart)。應該是如今比較好用的中文分詞器之一。git項目地址(https://github.com/medcl/elasticsearch-analysis-ik)。

          • Ansj中文分詞器:基于n-Gram+CRF+HMM算法實現(xiàn),用Java實現(xiàn)。分詞速度可以達到大約200萬字/s,準確率達96%以上。適用于對分詞效果要求較高的項目。目前支持ToAnalysis(精準分詞),DicAnalysis(用戶自定義詞典優(yōu)先策略分詞),NlpAnalysis(帶有新詞發(fā)現(xiàn)功能的分詞),IndexAnalysis(面向索引的分詞),BaseAnalysis(最小顆粒度分詞)幾種。git項目地址(https://github.com/NLPchina/elasticsearch-analysis-ansj)。

          • Jcseg中文分詞器:基于MMSEG算法的一個輕量級中文分詞器,Java實現(xiàn)。目前支持簡易模式,復雜模式,檢測模式,最多模式,分隔符模式,NLP模式,n-gram模式。除此之外還支持多種分詞功能特性。詳情可參考git項目地址(https://github.com/lionsoul2014/jcseg)。


          總的來說,分詞器的目的就是能夠讓ES更好的對中文進行分詞,所以在使用上讀者只需選擇一種最適合自身業(yè)務的分詞器即可。


          ES架構(gòu)設計及核心概念


          ES核心概念


          ES中有很多核心概念,想要真正學好,用好ES,首先要了解其核心概念。ES的核心概念主要有:Node,Cluster,Shards,Replicas,Index,Type,Document,Settings,Mapping和Analyzer。其對應含義分別如下:

          • Node:節(jié)點。是組成ES集群的基本數(shù)據(jù)單元,集群中每個運行中的ES服務器都可以稱之為節(jié)點,

          • Cluster:集群。ES的集群是由具有相同cluster.name的一個或者多個ES節(jié)點組成的。每個節(jié)點協(xié)同工作,共享相同數(shù)據(jù)。同一個集群,節(jié)點名字不能重復,但是集群名稱一定要相同,否則無法加入同一集群。

            在ES集群中,節(jié)點狀態(tài)有GreenYellowRed三種,含義如下:

            1. Green:綠色。表示節(jié)點運行狀態(tài)健康,所有的主分片和副本分片都可以正常工作,集群100%可用。

            2. Yellow:黃色。表示節(jié)點運行狀態(tài)預警,所有的主分片都可以正常工作,但是至少有一個副本分片是不能正常工作的。此時集群仍然可用,但是高可用性在此狀態(tài)下被弱化。

            3. Red:紅色。表示集群無法正常使用。集群中至少有一個分片的主分片和它的全部副本分片都不能正常工作。如果出現(xiàn)此狀態(tài)則需要關(guān)注問題原因,及時修復,否則集群雖然還能正常查詢,但是不能正常工作的分片無法返回和存儲數(shù)據(jù),導致數(shù)據(jù)丟失。

          • Shards:分片。當索引數(shù)據(jù)量太大時,由于單個節(jié)點的內(nèi)存,磁盤空間等受限,節(jié)點需要將索引上的數(shù)據(jù)進行水平拆分。那么拆分出來的每個數(shù)據(jù)部分就稱之為一個分片。一般來說,每個分片都會放在不同服務器上,使集群能夠快速響應客戶端請求。

            分片又分為主分片副本分片,其中主分片是必須有的,副本分片可以沒有,默認情況下ES為一個索引創(chuàng)建5個主分片,并且為每個主分片創(chuàng)建一個副本分片。注意:副本分片一般來說不承擔查詢的任務。

          • Replicas:備份。也可以稱之為副本。副本的含義就是上面提到的主分片的備份。ES中的副本是精確復制模式,即每個副本都包含主分片上的所有數(shù)據(jù)。當在索引中寫入數(shù)據(jù)時,首先會在主分片上寫入數(shù)據(jù),然后數(shù)據(jù)會從主分片分發(fā)到備份分片上進行寫入。當主分片不可用時,ES會在備份分片中選舉出一個分片作為主分片。實現(xiàn)高可用。當然副本也是一把雙刃劍,過多的副本數(shù)量會增加數(shù)據(jù)同步的開銷。設置適合的副本數(shù)量即可。

          • Index:索引。ES中索引由一個或多個分片組成。使用時需要通過索引名稱在集群內(nèi)進行唯一標識。

          • Type:類別。指的是索引內(nèi)的邏輯分區(qū)。通過Type的名字在索引內(nèi)唯一標識查詢數(shù)據(jù),如果沒有Type則認為是整個索引內(nèi)查詢。需要注意的是,ES在7.x之后已經(jīng)不再推薦使用Type屬性,未來的8.x版本可能會徹底廢棄掉Type屬性。

          • Document:文檔。索引中每一條數(shù)據(jù)稱作一個文檔,可以理解為關(guān)系型數(shù)據(jù)庫中的一條記錄。一條文檔可以通過_id和Type屬性(7.x之后版本忽略)進行唯一標識。

          • Settings:配置信息。即對集群中索引的定義信息,例如索引的分片數(shù),副本數(shù)等。

          • Mapping:表示索引中字段(Field)的存儲類型,分詞方式等配置,有點類似于關(guān)系型數(shù)據(jù)庫中的表結(jié)構(gòu)信息。

            在ES中,Mapping如果沒有特殊需求,是可以動態(tài)識別字段類型的,不需要手動創(chuàng)建Mapping。如果需要定義特殊屬性時,例如:是否分詞,使用其它分詞器等,就需要手動設置Mapping。

          • Analyzer:字段分詞方式定義。ES默認的標準Analyzer包含一個標準的Tokenizer和三個Filter,即Standard Token Filter,Lower Case Token Filter和Stop Token Filter。


          ES架構(gòu)設計


          ES的設計架構(gòu)大致如下所示:


          16f57a264c3678a52ddabba062198f13.webp


          由上圖可以知道,ES架構(gòu)自底向上分為五層,分別為:核心層,數(shù)據(jù)處理層,發(fā)現(xiàn)與腳本層,協(xié)議層,應用層。下面分別闡述相關(guān)內(nèi)容。

          • 核心層:從圖中可以發(fā)現(xiàn),ES的核心層就是Lucene,基于Lucene實現(xiàn)的。

          • 數(shù)據(jù)處理層:主要是對數(shù)據(jù)的處理,常見的索引模塊(對索引的新增,刪除,更新等處理)、搜索模塊(對數(shù)據(jù)常規(guī)查詢,聚合等操作),映射模塊(對數(shù)據(jù)字段映射等處理)

          • 發(fā)現(xiàn)與腳本層:主要包含Discovery模塊(對節(jié)點自動發(fā)現(xiàn)功能)。Script腳本模塊,可以對數(shù)據(jù)進行腳本加工處理,目前ES支持Python和JavaScript等多種語言。第三方插件模塊,例如上文提到的IK分詞插件,SQL插件等,這些第三方插件都是在這個模塊中處理的。

          • 協(xié)議層:指ES的數(shù)據(jù)交互協(xié)議。目前ES支持Thrift,Memcache,HTTP三種,默認協(xié)議是HTTP。而JMX協(xié)議是指ES對Java的管理框架,用來管理ES應用。

          • 應用層:指ES支持的API模式,ES的特色就是RESTful風格的API。


          ES數(shù)據(jù)寫入過程


          最后,我們來說一下ES數(shù)據(jù)的寫入過程。


          首先ES的數(shù)據(jù)寫入操作是在內(nèi)存中執(zhí)行的,數(shù)據(jù)會被分配到特定的分片和副本上,但最終數(shù)據(jù)需要存儲到磁盤上進行持久化。


          分段存儲


          索引數(shù)據(jù)在磁盤上是以分段形式存儲的。

          段其實是Lucene中的概念,在索引中,索引文件被拆分成多個子文件,每個子文件就稱作段,每個段就是一個倒排索引的小單元。

          段具有不可變性,即只要段寫入磁盤后就不可以修改。


          使用分段存儲的好處

          • 避免數(shù)據(jù)量過大導致索引過大,查詢數(shù)據(jù)緩慢。如果全部索引都寫在一個文件中,隨著數(shù)據(jù)量增大,文件也會隨之增大,大大降低了數(shù)據(jù)索引的速度。

          • 避免在讀寫操作時使用鎖,提升讀寫性能。提高并發(fā)。設想一下,采用分段存儲的方式,能夠保證用戶沒有緩存到磁盤上的段內(nèi)容不被讀取,此時只能寫入,而一旦段寫入磁盤后,就變?yōu)橹蛔x,不再允許使用,保證讀寫并發(fā)時數(shù)據(jù)不會出現(xiàn)錯誤,同時提高并發(fā)。


          段存儲過程


          當分段被寫入磁盤后,就會生成一個提交點,提交點意味著一個用來記錄所有段信息記錄的文件已經(jīng)生成。由于段具有不可變性,所以一旦段生成提交點,就意味著只具有讀權(quán)限,而無法再寫入了。


          當分段在內(nèi)存中時,此時段具有只寫權(quán)限,數(shù)據(jù)不斷寫入,此時由于段還沒有生成提交點,所以還不具有讀權(quán)限,所以此時用戶索引是不會獲取到內(nèi)存中段記錄的。


          不得不說,ES這點設計真是精妙,即減少了鎖的使用,還能大大提高并發(fā)。當然凡事都具有兩面性,由于段的特殊性,所以在更新,刪除索引數(shù)據(jù)時顯得就不這么方便,下面會詳細說明。


          段數(shù)據(jù)新增


          數(shù)據(jù)新增是最簡單的,因為數(shù)據(jù)是最新的,所以只需要在當前索引新增一個段文件即可,無需考慮其它操作。


          段數(shù)據(jù)刪除


          當刪除數(shù)據(jù)時,由于段具有不可修改的特性,ES不會把文檔從舊的段中刪除,而是會創(chuàng)建一個.del的文件,在.del文件中會記錄被刪除文檔的段信息。被標記刪除的文檔仍然可以被查詢匹配到,但在數(shù)據(jù)返回前會根據(jù).del文件中的內(nèi)容進行過濾,將其從結(jié)果集中移除。


          段數(shù)據(jù)更新


          當更新數(shù)據(jù)時,由于段具有不可更新特性,所以數(shù)據(jù)更新無法對段進行操作。所以更新操作就變成兩部操作結(jié)合,即先刪除,再新增。同數(shù)據(jù)刪除相同,ES會將舊的文檔在.del文件中標記刪除,然后將新版本文檔緩存到新的段中,這樣雖然舊文檔和新文檔都能被查詢匹配到,但是在數(shù)據(jù)返回前舊文檔就會被.del文件中標記刪除的內(nèi)容過濾掉,從結(jié)果集中移除。


          綜上所述,分段存儲雖然可以不需要鎖提升ES的讀寫性能,但是相對來說帶來的代價就是存儲空間的浪費,尤其在更新,刪除數(shù)據(jù)比較頻繁的情況下。此外,在查詢出全部數(shù)據(jù)后,主節(jié)點還需要根據(jù).del文件中的內(nèi)容排除被標記刪除的舊數(shù)據(jù),隨之帶來的是對查詢的負擔。


          延遲寫策略


          首先,在ES中索引寫入磁盤的過程是異步的,因此,為了提升寫的性能,ES并不是每新增一條記錄就增加一個段到磁盤上,而是采用延遲寫策略。


          大體上延遲寫策略分為以下幾步:

          1. 新數(shù)據(jù)寫入時,將其寫入JVM內(nèi)存中。

          2. 當達到默認時間或內(nèi)存數(shù)據(jù)達到一定數(shù)量時觸發(fā)刷新(Refresh)操作。

          3. 刷新操作將內(nèi)存中數(shù)據(jù)生成到一個新的分段上并寫入文件緩存系統(tǒng)。

          4. 最后刷新到磁盤中,生成提交點。

          從上面幾步來看,不難理解,當數(shù)據(jù)新增時,由于新增數(shù)據(jù)都是先存入JVM內(nèi)存中,并不生成段,所以此時用戶在查詢數(shù)據(jù)時,這些記錄是無法被查詢匹配到的,只有當經(jīng)歷了步驟3之后,生成新的分段并寫入文件緩存系統(tǒng)后,這些記錄才能被查詢匹配到。這也是ES能做到近實時查詢的原因,默認情況下每個分片自動刷新時間是1s,這也是為什么有的時候,寫入記錄后前端并不是能夠馬上查詢到,需要等待1s后才能匹配的原因。(相信很多讀者在初期使用ES的時候都遇到過這樣的問題。)


          當然延遲寫策略一定程度上提升了ES寫的效率,但是面臨的問題也隨之而來,那就是數(shù)據(jù)丟失,設想當你的數(shù)據(jù)剛剛寫入JVM內(nèi)存后,還沒有寫入文件緩存系統(tǒng)并刷新到磁盤的時候,機器斷電了。那么這部分數(shù)據(jù)很有可能面臨丟失的風險,為此,ES提供了事務日志機制(Translog),事務日志用于記錄所有還沒有緩存到磁盤上的數(shù)據(jù)。所以在添加了事務日志機制后,每當有新數(shù)據(jù)寫入JVM內(nèi)存時,同時會追加到事務日志中一條記錄,當內(nèi)存中記錄都刷新到磁盤后,這份事務日志也會隨之清空。這樣即使機器或機房突然斷電,有了事務日志,記錄也不會丟失。


          段合并


          最后來說說段合并,因為ES默認1s刷新一次,所以短時間內(nèi)ES會生成大量的段文件,而段數(shù)量太多,帶來的就是對資源的損耗,內(nèi)存,CPU等都會受其影響,而且段越多,查詢數(shù)據(jù)時需要索引的段文件就越多,大大降低了ES的搜索性能。


          所以ES引入了段合并機制,段合并是在后臺定期進行的,這些都是由ES控制將較小的段合并為大的段,大的段再合并為更大的段。值得一提的是,在段合并的過程中,已經(jīng)刪除的文檔將會從段中刪除,這也是上文提到的如果頻繁更新,刪除數(shù)據(jù),短時間內(nèi)會造成磁盤資源浪費的原因。段合并的過程計算量較大,并且對磁盤I/O消耗也較大,所以ES會對其進行資源限制,并不會影響查詢操作。


          以上就是Elasticsearch學習筆記第一篇-說明篇的全部內(nèi)容,希望能對大家有所幫助。歡迎大家繼續(xù)關(guān)注后續(xù)兩篇學習筆記,共勉。


          瀏覽 17
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  伊人二区 | 停停色导航 | 手机看片在线播放联合毛片 | 国产黄色一级毛片 | 日韩人妻丰满无码区A片 |