最新日韩欧美在线综合网_成人在线视_自拍偷拍第八页_欧美又大又粗又硬又色A片_亚洲精品国产成人片_一级片手机在线

中國專業(yè)IT外包服務(wù)

用心服務(wù)每一天
IT之道-艾銻知道

您當(dāng)前位置: 主頁 > 資訊動態(tài) > 艾銻分享 >

聊聊Kafka事務(wù)流由基礎(chǔ)到實踐-項目外包


2020-06-11 21:01 作者:admin

聊聊Kafka事務(wù)流由基礎(chǔ)到實踐-項目外包

 
項目外包開發(fā),技術(shù)成熟,報價透明,營銷推廣運(yùn)營平臺.IT解決方案與服務(wù)提供商,完善的開發(fā)流程,軟件開發(fā)公司多年開發(fā)經(jīng)驗
 
事件源,最終一致性,微服務(wù),CQRS等等,這些越多越多的概念被現(xiàn)代開發(fā)者所熟悉。從細(xì)粒度的服務(wù)組裝到復(fù)雜的以業(yè)務(wù)為中心的應(yīng)用架構(gòu),這其中最重要的一塊就是以中間件為基礎(chǔ)的業(yè)務(wù)脫藕。
 
事件源,最終一致性,微服務(wù),CQRS等等,這些越多越多的概念被現(xiàn)代開發(fā)者所熟悉。從細(xì)粒度的服務(wù)組裝到復(fù)雜的以業(yè)務(wù)為中心的應(yīng)用架構(gòu),這其中最重要的一塊就是以中間件為基礎(chǔ)的業(yè)務(wù)脫藕。本文我們介紹中間件基礎(chǔ)構(gòu)建塊——事務(wù)流。其主導(dǎo)者是Apache Kafka,事實上的事務(wù)流平臺標(biāo)準(zhǔn),還會介紹Kafka的一個Web界面工具Kafdrop。
 
概述
事務(wù)流平臺屬于更廣泛的面向消息的中間件(MoM)類,與傳統(tǒng)的消息隊列和主題類似,但是由于日志結(jié)構(gòu)的不變性,它提供了更強(qiáng)大的時間保證和大幅度性能提高。簡而言之,由于事務(wù)流的寫操作只限于順序追加,所以更加高效。
傳統(tǒng)消息隊列(MQ)中的消息往往是任意排序的,并且通常彼此獨(dú)立,而流中的事務(wù)(或記錄)往往是按時間順序或因果關(guān)系排序的。而且,事務(wù)流會保留其記錄,而MQ一旦讀取了一條消息,就會丟棄它。因此,事務(wù)流往往更適合事件驅(qū)動的體系結(jié)構(gòu),包括事件源,最終一致性和CQRS等(當(dāng)然,也包括FIFO消息隊列,但是FIFO隊列和成熟的事務(wù)流平臺之間的差異非常大,而不僅限于訂購)。
事務(wù)流平臺是MoM領(lǐng)域中相對較新的范例。與數(shù)百種MQ風(fēng)格的消息代理相比較,只有少數(shù)幾種主流可用。與已建立的標(biāo)準(zhǔn)(例如AMQP,MQTT,XMPP和JMS)相比,事務(wù)流空間中還沒有與之等效的標(biāo)準(zhǔn)。
事務(wù)流平臺是當(dāng)前持續(xù)研究和實驗的活躍領(lǐng)域。但是,事務(wù)流平臺不僅僅是一個商用產(chǎn)品,或者復(fù)雜的學(xué)術(shù)問題。它可以廣泛應(yīng)用于消息傳遞和事務(wù)場景,可用于例行性替換消息隊列的傳統(tǒng)使用場景。
架構(gòu)概述
下圖簡要概述了Kafka組件體系結(jié)構(gòu)。此處限于篇幅,我們不詳細(xì)介紹Kafka內(nèi)部工作原理。
 
kafka組成
Kafka是一個分布式系統(tǒng),包含如下幾個關(guān)鍵組件:
Broker(代理)節(jié)點:負(fù)責(zé)批量I/O操作和集群內(nèi)的持續(xù)持久化。代理附加日志文件,這些文件中包含由集群托管的主題分區(qū)。可以在多個代理之間復(fù)制分區(qū),以實現(xiàn)水平可伸縮性和增加的持久性,這些復(fù)制的分區(qū)被稱為副本。有一個代理節(jié)點為控制節(jié)點(控制者),其他副本受其管理(追隨者)。一個代理節(jié)點會被選舉為集群控制器,負(fù)責(zé)分區(qū)狀態(tài)的內(nèi)部管理,還負(fù)責(zé)仲裁給定分區(qū)的領(lǐng)導(dǎo)者跟隨者角色。
ZooKeeper節(jié)點:在后臺Kafka需要一種方法來管理集群中總體控制器狀態(tài)。如果控制器出于某種原因退出,則有一個協(xié)議可以從剩余的代理集中選出另一個控制器。ZooKeeper很大程度上實現(xiàn)了控制器選舉,心跳等的實際機(jī)制。ZooKeeper還充當(dāng)各種配置存儲庫,維護(hù)集群元數(shù)據(jù),領(lǐng)導(dǎo)者和跟隨者狀態(tài),配額,用戶信息,ACL和其他內(nèi)部管理項目。由于底層的選舉和共識協(xié)議,ZooKeeper節(jié)點的數(shù)量必須為奇數(shù)。
生產(chǎn)者:負(fù)責(zé)將消息發(fā)布到Kafka主題的客戶端應(yīng)用程序。由于Kafka具有日志結(jié)構(gòu)的性質(zhì),并且能夠在多消費(fèi)者生態(tài)系統(tǒng)之間共享主題,因此只有生產(chǎn)者才能修改底層日志文件中的數(shù)據(jù)。實際I/O由代理節(jié)點代表生產(chǎn)者客戶端執(zhí)行。可以將任意數(shù)量生產(chǎn)者消息發(fā)布到同一Kafka主題,并選擇用于保存記錄的分區(qū)。
消費(fèi)者:從主題讀取消息的客戶端應(yīng)用程序。任意數(shù)量的消費(fèi)者都可以從同一主題中閱讀內(nèi)容;但是,根據(jù)消費(fèi)者的配置和分組,存在一些規(guī)則來管理消費(fèi)者之間的記錄分配。
分區(qū),記錄、偏移量和主題
分區(qū)是記錄的完全有序序列,每一個分區(qū)對應(yīng)一個append日志,這是Kafka的基礎(chǔ)。每一條記錄具有一個ID:64位整數(shù)偏移量和毫秒級的時間簽。它可能會存在一個鍵和一個值。兩者都是字節(jié)數(shù)組,并且都是可選的。術(shù)語"完全排序"僅表示對于任何給定的生產(chǎn)者,記錄將按照應(yīng)用程序發(fā)出的順序進(jìn)行寫入。如果記錄P在Q之前發(fā)布,則P將在分區(qū)中的Q之前。(假設(shè)P和Q共享一個分區(qū)。)此外,所有消費(fèi)者將以相同的順序讀取它們。對于每個可能的消費(fèi)者,將始終在Q之前讀取P。在大多數(shù)用例中,這種訂購保證至關(guān)重要。通常,已發(fā)布的記錄將與某些現(xiàn)實事務(wù)相對應(yīng),并且保留這??些事務(wù)的時間表通常是必不可少的。
記錄的偏移量是分區(qū)中一條記錄的唯一標(biāo)識分。偏移量是稀疏地址空間中嚴(yán)格單調(diào)遞增的整數(shù),每個記錄偏移量始終高于其上一個記錄偏移量,并且相鄰偏移量之間可能存在可變的間隙。如果啟用了壓縮或作為事務(wù)的結(jié)果,則必然會存在間隙,所以偏移量也有可能不是連續(xù)的。
應(yīng)用程序不應(yīng)嘗試從字面上解釋偏移量,也不應(yīng)該猜測下一個偏移量是多少。但是,可以根據(jù)偏移量推斷任何記錄的相對順序,按記錄的偏移量對記錄進(jìn)行排序。
下圖顯示了內(nèi)部分區(qū)的結(jié)構(gòu):
 
第一個偏移量(也稱為low-water mark,低水位標(biāo)記)是要顯示給消費(fèi)者的第一個消息。由于Kafka的保留期限制,因此不一定是第一個發(fā)布的消息。可以根據(jù)時間和/或分區(qū)大小來修剪記錄。當(dāng)有這種情況發(fā)生時,低水位線似乎會后移,早于低水位線的記錄將被截斷。
主題是分區(qū)的邏輯組成。一個主題可以具有一個或多個分區(qū),而一個分區(qū)只能有一個主題或者一個主題的部分。主題是Kafka的基礎(chǔ),允許并行和負(fù)載平衡。前面我們說過分區(qū)顯示總順序。由于主題內(nèi)的分區(qū)是相互獨(dú)立的,因此稱該主題具有部分順序。簡而言之,這意味著某些記錄可以互相排序,而相對于某些其他記錄則不可排序。總順序和部分順序的概念雖然聽起來有些學(xué)術(shù)化,但在構(gòu)建性能事務(wù)流管道中非常重要。它使我們能夠在可能的地方并行處理記錄,同時在必須的地方保持順序。稍后,我們將探討記錄順序,消費(fèi)者并行性和主題大小的概念。
實例:消息發(fā)布
實踐是檢驗真理的唯一標(biāo)準(zhǔn),我將理論付諸實踐,通過實例說明概念。我們將啟動一對Docker容器,一個用Kafka容器,另一個為Kafdrop容器。我們使用Docker Compose方式啟用容器。
在選定目錄中創(chuàng)建一個docker-compose.yaml文件,內(nèi)容如下:
為了方便起見,我們用obsidiandynamics/kafka鏡像,它會將Kafka和ZooKeeper巧妙地打包在一個鏡像中。然后通過docker-compose up啟動容器。啟動成功后,可以通過瀏覽器中訪問localhost:9000,就能看到Kafdrop登陸界面。
 
實例中是一個單代理集群,還沒有任何主題。我們可以使用Kafka的命令行工具創(chuàng)建一個主題并發(fā)布一些消息。我們可以使用docker exec工具對kafka容器進(jìn)行操作方便地調(diào)用內(nèi)置的CLI工具:
docker exec -it kafka-kafdrop_kafka_1 bash
上面的命令將讓我么進(jìn)入容器的shell命令行界面。工具位于/opt/kafka/bin目錄中,cd進(jìn)入該目錄:
創(chuàng)建一個名為streams-intro的主題,其中包含3個分區(qū):
切換回Kafdrop界面,現(xiàn)在我們就能在列表中看到新主創(chuàng)建的主題。
 
接著,我們可以使用kafka-console-producer工具發(fā)布消息:
注意:kafka-topics使用--bootstrap-server參數(shù)來配置Kafka代理列表,而kafka-console-producer則使用--broker-list。
記錄由換行符分隔。鍵和值部分由冒號分隔,如key.separator屬性所指示。本例下,我們可以輸入下內(nèi)容:
完成后,按CTRL + D鍵完成消息發(fā)布。然后切換回Kafdrop,然后單擊streams-intro主題。將看到該主題的概述以及基礎(chǔ)分區(qū)的詳細(xì)分類:
 
我們創(chuàng)建了一個包含三個分區(qū)的主題。然后,我們使用兩個唯一的鍵foo和bar發(fā)布了五條記錄。Kafka使用鍵將記錄映射到分區(qū),這樣具有相同鍵的所有記錄將始終出現(xiàn)在同一分區(qū)上。很方便,也很重要,它可以使發(fā)布者指定準(zhǔn)確的記錄順序。稍后,我們將更詳細(xì)地討論鍵哈希和分區(qū)分配。
查看分區(qū)表,分區(qū)#0的第一個和最后一個偏移分別為0和2。分區(qū)#2的值為零和3個,而分區(qū)#1的顯示為空白。在Kafdrop網(wǎng)絡(luò)用戶界面中單擊#0,會將會轉(zhuǎn)到主題查看器:
 
可以看到在bar鍵下發(fā)布的兩條記錄。注意,它們與foo記錄完全無關(guān)。
消費(fèi)者和消費(fèi)組
上面我們實例講了,聽過生產(chǎn)者發(fā)布消息,將記錄發(fā)送到流中。這些記錄被組織成井井有條的分區(qū)。Kafka的發(fā)布-訂閱拓?fù)渥裱`活的多到多模型,所以,可以有任意數(shù)量的生產(chǎn)者和消費(fèi)者同時與流進(jìn)行交互。根據(jù)實際的解決方案,流拓?fù)湟部梢砸粚Χ啵鄬σ弧O旅嫖覀冎v,如何消費(fèi)這些記錄。
消費(fèi)者是通過客戶端庫連接到Kafka集群的進(jìn)程或線程。消費(fèi)者通常(但不一定)是一個整體消費(fèi)組的成員。該組由group.id屬性指定。消費(fèi)組實際上是Kafka中的負(fù)載平衡機(jī)制,負(fù)責(zé)在組內(nèi)的各個消費(fèi)者實例之間大致平均地進(jìn)行分區(qū)分配。當(dāng)組中的第一個消費(fèi)者訂閱該主題時,它將收到該主題中的所有分區(qū)。當(dāng)?shù)诙€消費(fèi)者隨后加入時,它將獲得大約一半的分區(qū),從而減輕了第一個使用者的負(fù)擔(dān)。當(dāng)消費(fèi)者離開時(通過斷開連接或超時),該過程將反向進(jìn)行,其余的使用者將可用更多數(shù)量的分區(qū)。
因此,消費(fèi)者消費(fèi)某個主題中的記錄,從Kafka及其所屬的其他消費(fèi)者分配的分區(qū)中提取了份額。就負(fù)載平衡而言,這應(yīng)該非常簡單。但是,這里有一個關(guān)鍵點,使用記錄的行為并不能將其刪除。起初這似乎是矛盾的,特別是如果將消耗行為與消耗聯(lián)系起來。(如果有的話,應(yīng)該將消費(fèi)者稱為"閱讀者"。)一個簡單的事實是,消費(fèi)者對主題及其分區(qū)絕對沒有任何影響。主題是僅追加,只能由生產(chǎn)者或Kafka本身(作為壓縮或清除的一部分)進(jìn)行追加記錄。消費(fèi)者的只讀操作是"便宜的",因此,可以讓許多人在不增加集群負(fù)擔(dān)的情況下tail日志。這是事務(wù)流和傳統(tǒng)消息隊列之間的又一區(qū)別,這是至關(guān)重要的。
消費(fèi)者在內(nèi)部維護(hù)一個偏移量,該偏移量指向分區(qū)中的下一個記錄,從而在每次連續(xù)讀取時都增加偏移量。消費(fèi)者首次訂閱主題時,可以選擇從主題的頭端或尾端開始。通過將auto.offset.reset屬性設(shè)置為latest, earliest 或者none,可以控制這個行為。在后一種情況下,如果消費(fèi)者組不存在先前的偏移量,則將觸發(fā)異常。
消費(fèi)者在本地保留其偏移狀態(tài)向量。由于不同消費(fèi)組中的消費(fèi)者不會互相干擾,因此可能有許多人同時閱讀同一主題。消費(fèi)者按照自己的偏移讀取消息;緩慢的或積壓的消費(fèi)者對其同組其他人也不會有影響。
為了說明這個概念,我們考慮一個包含兩個分區(qū)的主題為場景。兩個消費(fèi)者組-A和B-訂閱了該主題。每個組具有三個實例,使用者被命名為A1,A2,A3,B1,B2和B3。下圖說明了兩組如何共享主題,以及消費(fèi)者如何彼此獨(dú)立地瀏覽記錄。
 
仔細(xì)看上圖,會發(fā)現(xiàn)缺少某些東西。消費(fèi)者A3和B1不在上圖中。這是因為Kafka保證分區(qū)只能分配給其消費(fèi)組中的一個消費(fèi)者。由于每個組中有三個消費(fèi)者,但是只有兩個分區(qū),因此一個消費(fèi)者將保持空閑狀態(tài),等待其所在組中的另一個消費(fèi)者離開。以這種方式,消費(fèi)組不僅是負(fù)載平衡機(jī)制,而且還是用于建立高性能管道而又不犧牲安全性的類似柵欄的排他性控制,特別是在要求只能由一個線程處理記錄的情況下或在任何給定時間進(jìn)行處理。
消費(fèi)組也用于確保可用性。通過定期從主題中提取記錄,消費(fèi)者可以向集群隱式反饋集群為"健康"狀態(tài),從而將租約擴(kuò)展到其分區(qū)分配上。但是,如果消費(fèi)者未能在允許的期限內(nèi)再次閱讀,則將其視為有缺陷,并且將重新分配其分區(qū),分配給該組中其余的"健康"消費(fèi)者。該截止日期由max.poll.interval.ms在消費(fèi)者客戶端屬性控制,默認(rèn)情況下設(shè)置為五分鐘。
用交通系統(tǒng)來做個類比,主題就像是高速公路,分區(qū)就是車道。記錄就是等同于汽車,其乘客對應(yīng)于記錄值。只要保持行車路線,幾輛車就可以安全地在同一條高速公路上行駛。共享相同線路的汽車按順序行駛,形成隊列。現(xiàn)在,假設(shè)每條車道通向一個匝道,將其流量轉(zhuǎn)移到某個位置。如果一個匝道堆積了,其他匝道可能仍能順暢流動。
Kafka正是利用這種機(jī)制確保端到端的吞吐量,輕松地實現(xiàn)每秒達(dá)到數(shù)百萬條記錄的QPS。創(chuàng)建主題時,可以選擇分區(qū)計數(shù),通道數(shù)。分區(qū)在一個消費(fèi)組中的各個消費(fèi)者之間大致均勻地劃分,并確保不會將分區(qū)同時分配給兩個(或多個)消費(fèi)者。
注意:創(chuàng)建后,可以通過增加分區(qū)數(shù)來調(diào)整主題的大小。但是,無法在不重新創(chuàng)建主題的情況下減少分區(qū)數(shù)。
記錄對應(yīng)于事件、消息、命令或任何其他可流式傳輸?shù)膬?nèi)容。記錄的精確劃分方式由生產(chǎn)者決定。生產(chǎn)者可以在發(fā)布記錄時顯式分配分區(qū)索引,盡管這種方法很少使用。正如我們在前面的示例中所做的那樣,一種更常見的方法是為記錄分配鍵。鍵對Kafka完全不透明,換句話說,Kafka不會去解釋key的內(nèi)容,而是將其視為字節(jié)數(shù)組。使用一致的哈希技術(shù)對這些字節(jié)進(jìn)行哈希處理以得出分區(qū)索引。
共享相同散列的記錄可以保證占據(jù)相同的分區(qū)。假設(shè)一個主題具有多個分區(qū),則具有不同鍵的記錄可能最終會位于不同的分區(qū)中。但是,由于哈希鍵沖突,具有不同哈希值的記錄也可能最終會在同一分區(qū)中。
生產(chǎn)者無需關(guān)心記錄將映射到哪個特定分區(qū),只要相關(guān)記錄最終在同一分區(qū)中并且保留其順序。同樣,消費(fèi)者對也無需關(guān)心分配到那個分區(qū),只要它們以與發(fā)布相同的順序接收記錄,并且其分區(qū)分配不會與組中的其他消費(fèi)者重復(fù)。
案例:交易平臺
假設(shè)我們正在尋找上市股票的特定價格模式,并在確定特定模式后發(fā)出交易信號。有大量庫存,可以理解的是,希望將它們并行處理。但是,任何給定的股票代碼的時間序列必須在單個使用者上順序處理。
Kafka使這個用例以及其他類似用例幾乎不容易實現(xiàn)。我們將創(chuàng)建兩個主題:價格,用來存儲原始價格數(shù)據(jù)。訂單主題,用來保存任何由產(chǎn)生的訂單。我們可以多劃分一些分區(qū),可以讓我們充分的并行操作。
我們可以在價格主題上發(fā)布每個價格的記錄,并用股票代碼作為鍵。Kafka的自動分區(qū)分配將確保每個股票代號由其組中的一個消費(fèi)者處理。消費(fèi)者實例可以自由擴(kuò)展和擴(kuò)展以匹配處理負(fù)載。消費(fèi)者組應(yīng)該有意義地命名,理想地反映消費(fèi)應(yīng)用程序的目的。比如trading-strategy.abc,它是一種名為" ABC"的虛擬交易策略。
消費(fèi)者確定了價格模式后,就可以在訂單主題上發(fā)布另一條消息,訂單請求。我們將召集另一個消費(fèi)組,訂單執(zhí)行,負(fù)責(zé)讀取訂單并將其轉(zhuǎn)發(fā)給經(jīng)紀(jì)人。
在這個簡單的示例中,我們創(chuàng)建了一個完全由事件驅(qū)動且高度可擴(kuò)展的端到端交易管道,假設(shè)沒有其他瓶頸。我們可以在各個階段動態(tài)添加更多的處理節(jié)點,以應(yīng)對需要增加的負(fù)載的情況。
假設(shè)您需要在通用數(shù)據(jù)源的驅(qū)動下同時運(yùn)行的幾種交易策略。此外,交易策略將由不同的團(tuán)隊制定;目的是盡可能地使這些實現(xiàn)脫鉤,從而使團(tuán)隊能夠自主運(yùn)作,甚至可以使用不同的編程語言和工具鏈以各自的節(jié)奏進(jìn)行開發(fā)和部署。
 
Kafka靈活的多到多pub-sub體系結(jié)構(gòu)將狀態(tài)消耗與廣播語義相結(jié)合。通過使用不同的消費(fèi)群體,Kafka允許不同的應(yīng)用程序共享輸入主題,并按自己的進(jìn)度處理事件。第二種交易策略將需要一個專門的消費(fèi)群體:trading-strategy.xyz,將其特定的業(yè)務(wù)邏輯應(yīng)用于通用定價流,并將生成的訂單發(fā)布到相同的訂單主題。通過這種方式,Kafka能夠從易于重用和組合的離散元素構(gòu)建模塊化事件處理管道。
總結(jié)
事務(wù)流平臺是構(gòu)建模塊化、松耦合、事件驅(qū)動的應(yīng)用程序的高效構(gòu)建塊。在事務(wù)流的世界中,Kafka鞏固了其成為成功開源解決方案的地位,該解決方案兼顧了靈活性和高性能。并發(fā)和并行性是Kafka體系結(jié)構(gòu)的核心,形成部分排序的事務(wù)流,可以在可擴(kuò)展的消費(fèi)者生態(tài)系統(tǒng)中實現(xiàn)負(fù)載平衡。消費(fèi)者及其周圍組的簡單重新配置可以帶來非常不同的事件分配和處理語義。
當(dāng)然,Kafka并非沒有缺陷。可以說Kafka工具是低于標(biāo)準(zhǔn)的。大多數(shù)Kafka從業(yè)者長期以來都放棄了現(xiàn)成的CLI實用程序,而轉(zhuǎn)向其他開源工具(例如Kafdrop,Kafkacat和第三方商業(yè)產(chǎn)品(如Kafka Tool)。 Kafka的配置選項種類繁多,初學(xué)的默認(rèn)值有坑,新手可能會踩到這些坑。總而言之,Kafka代表了構(gòu)建和構(gòu)建復(fù)雜系統(tǒng)的方式的范式轉(zhuǎn)變,它的優(yōu)勢也是顯而易見的。
 
以上文章由北京艾銻無限科技發(fā)展有限公司整理
 

相關(guān)文章

IT外包服務(wù)
二維碼 關(guān)閉
主站蜘蛛池模板: AV天堂亚洲狼人在线 | 宅男噜噜噜66一区二区66 | 成人午夜视频网 | 中文字幕一区二区在线视频 | 风韵少妇性饥渴推油按摩视频 | 亚洲在线观看一区 | 18禁美女黄网站色大片免费观看 | 天堂在线最新版 | 日本一区二区高清不卡 | 国产高清视频在线免费观看 | 亚洲国产天堂久久综合网 | 日韩国产在线播放 | 1v1双性受整夜不拔bl | 奇米影视首页 | 国精产品99永久一区一区 | 偷窥自拍五月天 | 最新中文字幕日韩 | 国产欧美一区二区三区四区 | 久久久女人与动物群交毛片 | 免费刺激性视频大片区 | 国产伦理精品一区二区三区观看体验 | 成年女人天堂香蕉网 | 美国一级片网站 | 99ri在线| 亚洲一中文字幕 | 日韩欧美成人影院 | 国产欧美一区二区三区四区 | 日韩黄色精品视频 | 国产精品美女www视频 | av影院在线播放 | 青草久久免费视频 | 少妇伦子伦精品无吗在线观看 | 久久99影院 | gg55gg国产成人影院 | 公肉吊粗大双色翁浪妇无码AV | 亚洲AV综合色区无码一区爱AV | 亚洲日本va午夜中文字幕久久 | 97久久综合一区二区三区 | 亚洲欧洲无卡二区视頻 | 夜夜爱夜夜做夜夜爽 | 第四色播日韩第一页 |