redis緩存介紹以及常見問題

redis緩存介紹以及常見問題淺析

沒緩存的日子

image

對(duì)于web來(lái)說(shuō)烁涌,是用戶量和訪問量支持項(xiàng)目技術(shù)的更迭和前進(jìn)撮执。隨著服務(wù)用戶提升抒钱∧北遥可能會(huì)出現(xiàn)一下的一些狀況:

  1. 頁(yè)面并發(fā)量和訪問量并不多,mysql足以支撐自己邏輯業(yè)務(wù)的發(fā)展诅蝶。那么其實(shí)可以不加緩存调炬。最多對(duì)靜態(tài)頁(yè)面進(jìn)行緩存即可缰泡。
  2. 頁(yè)面的并發(fā)量顯著增多棘钞,數(shù)據(jù)庫(kù)有些壓力宜猜,并且有些數(shù)據(jù)更新頻率較低反復(fù)被查詢或者查詢速度較慢。那么就可以考慮使用緩存技術(shù)優(yōu)化溶锭。對(duì)高命中的對(duì)象存到key-value形式的redis中宝恶,那么,如果數(shù)據(jù)被命中,那么可以省經(jīng)效率很低的db垫毙。從高效的redis中查找到數(shù)據(jù)霹疫。
  3. 當(dāng)然,可能還會(huì)遇到其他問題综芥,你可以需要靜態(tài)頁(yè)面本地緩存丽蝎,cdn加速,甚至負(fù)載均衡這些方法提高系統(tǒng)并發(fā)量。這里就不做介紹。

緩存思想無(wú)處不在

我們從一個(gè)算法問題開始了解緩存的意義。

問題1:

  • 輸入一個(gè)數(shù)n(n<20),求n!呻引;

分析1

  • 單單考慮算法卢厂,不考慮數(shù)值越界問題。 當(dāng)然我們知道n!=n * (n-1) * (n-2) * ... * 1= n * (n-1)!; 那么我們可以用一個(gè)遞歸函數(shù)解決問題。
static long jiecheng(int n)
{
    if(n==1||n==0)return 1;
    else {
      return n*jiecheng(n-1);
    }
}

這樣每輸入求一次需要執(zhí)行n次。 問題2:

  • 輸入t組數(shù)據(jù)(可能成百上千),每組一個(gè)x(n<20),求x!

分析2

  • 如果使用遞歸,輸入t組數(shù)據(jù),每個(gè)位x氯析,那么每次都要執(zhí)行 [圖片上傳失敗...(image-8bf557-1565769531992)]Xi
    當(dāng)Xi過大或者n過大都會(huì)造成不小的負(fù)擔(dān)你辣!時(shí)間復(fù)雜度O(n2)
  • 那么能否換個(gè)思想的表悬。沒錯(cuò)、是打表(也可以理解位動(dòng)態(tài)規(guī)劃)。打表常用于ACM算法中卤恳,常用于解決多組輸入輸出本今、圖論搜索結(jié)果逛艰、路徑儲(chǔ)存問題。那么,對(duì)于這個(gè)求階乘圈驼。我們只需要申請(qǐng)一個(gè)數(shù)組。每個(gè)數(shù)據(jù)為前一個(gè)數(shù)據(jù)*當(dāng)前index芬沉。那么思想很明確啦捎谨!
import java.util.Scanner;
public class test3 {
public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner sc=new Scanner(System.in);
    int t=sc.nextInt();
    long jiecheng[]=new long[21];
    jiecheng[0]=1;
    for(int i=1;i<21;i++)
    {
        jiecheng[i]=jiecheng[i-1]*i;
    }
   for(int i=0;i<t;i++) {
        int x=sc.nextInt();
        System.out.println(jiecheng[x]);
    }
}  
}
  • 時(shí)間復(fù)雜度才O(n)。這里的思想就和緩存思想差不多。先將數(shù)據(jù)在jiecheng[21]數(shù)組中儲(chǔ)存斟或。執(zhí)行一次計(jì)算凤粗。當(dāng)后面繼續(xù)訪問的時(shí)候就相當(dāng)于當(dāng)問靜態(tài)數(shù)組值灰瞻。為O(1)。就能大大的減少查詢患民、執(zhí)行成本啦赦肃!

緩存的應(yīng)用場(chǎng)景

  • 緩存適用于高并發(fā)的場(chǎng)景,提升服務(wù)容量鸿市。主要是將從經(jīng)常被訪問的數(shù)據(jù)或者查詢成本較高從慢的介質(zhì)中存到比較快的介質(zhì)中,比如從硬盤—>內(nèi)存展东。我們知道大多數(shù)關(guān)系數(shù)據(jù)庫(kù)是基于硬盤讀寫的爪膊,其效率和資源有限推盛,而redis等非關(guān)系型就是基于內(nèi)存存儲(chǔ)。其效率差別很大疆栏。當(dāng)然膊爪,緩存也分為本地緩存和服務(wù)端緩存,這里只講redis的服務(wù)端緩存竹勉。
  • 舉個(gè)例子飞盆。例如如果一個(gè)接口sql查詢需要2s。你每次查詢都會(huì)2s并且加載的時(shí)候都會(huì)等在次乓,這個(gè)長(zhǎng)期等待給用戶的體驗(yàn)是非常糟糕的吓歇。而用戶能夠接受的往往是第一次的等待。如果你用了緩存技術(shù)檬输。你第一次查詢放到redis里面照瘾。然后數(shù)據(jù)再?gòu)膔edis返回給你。后面當(dāng)你繼續(xù)訪問這個(gè)數(shù)據(jù)的時(shí)候丧慈。查詢到redis中有備份析命,那么不需要通過db直接能從redis中獲取數(shù)據(jù)。那么逃默,你想想鹃愤,從一個(gè)key value的Nosql中取一個(gè)value能要多久呢!
  • 所以對(duì)于像樣的完域,有點(diǎn)規(guī)模的網(wǎng)站软吐,緩存is necessary的.redis也是必不可少的。并且服務(wù)端的緩存設(shè)計(jì)也是要根據(jù)業(yè)務(wù)有所區(qū)別的吟税。也要防止占用內(nèi)存過大凹耙,redis雪崩等問題。

需要注意的問題

  • 緩存使用不當(dāng)會(huì)帶來(lái)很多問題肠仪。所以需要對(duì)一些細(xì)節(jié)進(jìn)行認(rèn)真考量和設(shè)計(jì)肖抱。筆者對(duì)于分布式的經(jīng)驗(yàn)并不是很豐富,就相對(duì)于筆者的眼中談?wù)劸彺嬖O(shè)計(jì)不好會(huì)帶來(lái)那些問題异旧。

是否用緩存

  • 現(xiàn)在不少項(xiàng)目意述,為了緩存而緩存,然而緩存并不是適合所有場(chǎng)景,比如如果對(duì)數(shù)據(jù)一致性要求極高荤崇,又或者數(shù)據(jù)頻繁更改而查詢并不多拌屏。有的可以不需要緩存。因?yàn)槿绻褂胷edis緩存多多少少可能會(huì)遇到數(shù)據(jù)一致性問題术荤。那你可以考慮使用redis做成分布式鎖去鎖sql的數(shù)據(jù)倚喂。同樣如果頻繁更新數(shù)據(jù),那么redis能起到的作用就僅僅是多了一層中轉(zhuǎn)站喜每。反而浪費(fèi)資源务唐。使得傳輸過程臃腫雳攘。

過期策略選擇

  • 大部分場(chǎng)景不適合緩存一致存在带兜,首先,你的sql數(shù)據(jù)庫(kù)的內(nèi)容可能很多就不說(shuō)了吨灭,另外刚照,返回給你的對(duì)象如果是完整的pojo對(duì)象還好,但是如果是使用不同參數(shù)各種關(guān)聯(lián)查詢出來(lái)的結(jié)果那么redis中會(huì)儲(chǔ)存太多冷數(shù)據(jù)喧兄。占用資源而得不到銷毀无畔。我們學(xué)過操作系統(tǒng)也知道在計(jì)算機(jī)的緩存實(shí)現(xiàn)中有)先進(jìn)先出的算法(FIFO);最近最少使用算法(LRU)吠冤;最佳淘汰算法(OPT)浑彰;最少訪問頁(yè)面算法(LFR)等磁盤調(diào)度算法。對(duì)于web開發(fā)也可以借鑒拯辙。根據(jù)時(shí)間來(lái)的FIFO是最好實(shí)現(xiàn)的郭变。因?yàn)閞edis在全局key支持過期策略。
  • 而開發(fā)中可能還會(huì)遇到其他問題涯保。比如過期時(shí)間的選擇上诉濒,如果過久會(huì)導(dǎo)致數(shù)據(jù)聚集。而過少可能導(dǎo)致頻繁查詢數(shù)據(jù)庫(kù)甚至可能會(huì)導(dǎo)致緩存雪崩等問題夕春。
  • 所以未荒,過期策略一定要設(shè)置。并且對(duì)于關(guān)鍵key一定要小心謹(jǐn)慎設(shè)計(jì)及志。

數(shù)據(jù)一致性問題★

上面其實(shí)提到數(shù)據(jù)一致性問題片排。如果對(duì)一致性要求極高那么不建議使用緩存。下面稍微梳理一下緩存的數(shù)據(jù)速侈。 在redis緩存中經(jīng)常會(huì)遇到數(shù)據(jù)一致性問題率寡。對(duì)于一個(gè)緩存。下面羅列逼仄

read:從redis中讀取锌畸,如果redis中沒有勇劣,那么就從mysql中獲取更新redis緩存。 該流程圖描述常規(guī)場(chǎng)景。一般沒啥爭(zhēng)議比默。

image

寫1:先更新數(shù)據(jù)庫(kù)幻捏,再更新緩存(普通低并發(fā))

image
  • 更新數(shù)據(jù)庫(kù)信息,再更新redis緩存命咐。這是常規(guī)做法篡九,緩存基于數(shù)據(jù)庫(kù),取自數(shù)據(jù)庫(kù)醋奠。但是其中可能遇到一些問題榛臼。例如上述如果更新緩存失敗(宕機(jī)等其他狀況),將會(huì)使得數(shù)據(jù)庫(kù)和redis數(shù)據(jù)不一致窜司。造成DB新數(shù)據(jù)沛善,緩存舊數(shù)據(jù)

寫2:先刪除緩存塞祈,再寫入數(shù)據(jù)庫(kù)(低并發(fā)優(yōu)化)

image

解決的問題

  • 這種情況能夠有效避免寫1中防止寫入redis失敗的問題金刁。將緩存刪除進(jìn)行更新。理想是讓下次訪問redis為空去mysql取得最新值到緩存中议薪。但是這種情況僅限于低并發(fā)的場(chǎng)景中而不適用高并發(fā)場(chǎng)景尤蛮。

存在的問題

  • 寫2雖然能夠看似寫入redis異常的問題∷挂椋看似較為好的解決方案但是在高并發(fā)的方案中其實(shí)還是有問題的产捞。我們?cè)趯?討論過如果更新庫(kù)成功,緩存更新失敗會(huì)導(dǎo)致臟數(shù)據(jù)哼御。我們理想是刪除緩存讓下一個(gè)線程訪問適合更新緩存坯临。問題是:如果這下一個(gè)線程來(lái)的太早、太巧了呢艇搀?
image
  • 因?yàn)槎嗑€程你也不知道誰(shuí)先誰(shuí)后尿扯,誰(shuí)快誰(shuí)慢。如上圖所示情況焰雕,將會(huì)出現(xiàn)redis緩存數(shù)據(jù)和mysql不一致衷笋。當(dāng)然你可以對(duì)key進(jìn)行上鎖。但是鎖這種重量級(jí)的東西對(duì)并發(fā)功能影響太大矩屁,能不用鎖就別用辟宗!上述情況就高并發(fā)下依然會(huì)造成緩存是舊數(shù)據(jù),DB是新數(shù)據(jù)吝秕。并且如果緩存沒有過期這個(gè)問題會(huì)一致存在泊脐。

寫3:延時(shí)雙刪策略

image
  • 這個(gè)就是延時(shí)雙刪策略,能過緩解在寫2中在更新mysql過程中有讀的線程進(jìn)入造成redis緩存與mysql數(shù)據(jù)不一致烁峭。方法就是刪除緩存->更新緩存->延時(shí)(幾百ms)(可異步)再次刪除緩存容客。即使在更新緩存途中發(fā)生寫2的問題秕铛。造成數(shù)據(jù)不一致,但是延時(shí)(具體實(shí)間根據(jù)業(yè)務(wù)來(lái)缩挑,一般幾百ms)再次刪除也能很快的解決不一致但两。
  • 但是就寫的方案其實(shí)還是有漏洞的,比如第二次刪除錯(cuò)誤供置、多寫多讀高并發(fā)情況下對(duì)mysql訪問的壓力等等谨湘。當(dāng)然你可以選擇用mq等消息隊(duì)列異步解決。其實(shí)實(shí)際的解決很難顧及到萬(wàn)無(wú)一失芥丧,所以不少大佬在設(shè)計(jì)這一環(huán)節(jié)可能會(huì)因?yàn)?code>一些紕漏會(huì)被噴紧阔。作為菜菜的筆者在這里就更不獻(xiàn)丑了,策略只是提供大綱续担,具體設(shè)計(jì)還是需要自己團(tuán)隊(duì)實(shí)踐和摸索擅耽。并且也對(duì)一致性的要求級(jí)別有所區(qū)別。

寫4:直接操作緩存赤拒,定期寫入sql(適合高并發(fā))

  • 當(dāng)有一堆并發(fā)(寫)扔過來(lái)的后秫筏,前面幾個(gè)方案即使使用消息隊(duì)列異步通信但也很難給用戶一個(gè)舒適的體驗(yàn)。并且對(duì)大規(guī)模操作sql對(duì)系統(tǒng)也會(huì)造成不小的壓力挎挖。所以還有一種方案就是直接操作緩存,將緩存定期寫入sql航夺。因?yàn)閞edis這種非關(guān)系數(shù)據(jù)庫(kù)又基于內(nèi)存操作KV相比傳統(tǒng)關(guān)系型要快很多(找值最多多碰撞幾次)蕉朵。

[圖片上傳失敗...(image-521252-1565770519509)]

  • 上面適用于高并發(fā)情況下業(yè)務(wù)設(shè)計(jì),這個(gè)時(shí)候以redis數(shù)據(jù)為主阳掐,mysql數(shù)據(jù)為輔助始衅。定期插入(好像數(shù)據(jù)備份庫(kù)一樣)。當(dāng)然缭保,這種高并發(fā)往往會(huì)因?yàn)闃I(yè)務(wù)對(duì)汛闸、的順序等等可能有不同要求,可能還要借助消息隊(duì)列以及完成針對(duì)業(yè)務(wù)上對(duì)數(shù)據(jù)和順序可能會(huì)因?yàn)?code>高并發(fā)艺骂、多線程帶來(lái)的不確定性和不穩(wěn)定性诸老。提高業(yè)務(wù)可靠性。

總之钳恕,越是高并發(fā)别伏、越是對(duì)數(shù)據(jù)一致性要求高的方案在數(shù)據(jù)一致性的設(shè)計(jì)方案需要考慮和顧及越復(fù)雜、越多忧额。上述也是筆者針對(duì)redis數(shù)據(jù)一致性問題的學(xué)習(xí)和自我發(fā)散(胡扯)學(xué)習(xí)厘肮。如果有解釋理解不合理或者還請(qǐng)聯(lián)系告知!

緩存穿透睦番、緩存雪崩和緩存擊穿

如果不了解类茂,可能對(duì)這幾個(gè)概念都不了解耍属,聽著感覺太高大上,至少筆者剛開始是這么覺得巩检,本文并不是詳細(xì)介紹如何解決和完美解決恬涧,更主要的是認(rèn)識(shí)和認(rèn)知吧。

redis緩存穿透

image

理解

  • 重在穿透吧碴巾,也就是訪問透過redis直接經(jīng)過mysql溯捆,通常是一個(gè)不存在的key,在數(shù)據(jù)庫(kù)查詢?yōu)?code>null。每次請(qǐng)求落在數(shù)據(jù)庫(kù)厦瓢、并且高并發(fā)提揍。數(shù)據(jù)庫(kù)扛不住會(huì)掛掉。

解決方案

  • 可以將查到的null設(shè)成該key的緩存對(duì)象煮仇。
  • 當(dāng)然劳跃,也可以根據(jù)明顯錯(cuò)誤的key在邏輯層就就行驗(yàn)證
  • 同時(shí)浙垫,你也可以分析用戶行為刨仑,是否為故意請(qǐng)求或者爬蟲、攻擊者夹姥。針對(duì)用戶訪問做限制杉武。
  • 其他等等,比如看到其他人用布隆過濾器(超大型hashmap)過濾辙售。

redis緩存雪崩

理解

  • 雪崩轻抱,就是某東西蜂擁而至的意思,像雪崩一樣旦部。在這里祈搜,就是redis緩存集體大規(guī)模集體失效,在高并發(fā)情況下突然使得key大規(guī)模訪問mysql士八,使得數(shù)據(jù)庫(kù)崩掉容燕。可以想象下國(guó)家人口老年化婚度。以后那天人集中在70-80歲蘸秘,就沒人干活了。國(guó)家勞動(dòng)力就造成壓力陕见。
image

解決方案

  • 通常的解決方案是將key的過期時(shí)間后面加上一個(gè)隨機(jī)數(shù)秘血,讓key均勻的失效。
  • 考慮用隊(duì)列或者鎖讓程序執(zhí)行在壓力范圍之內(nèi)评甜,當(dāng)然這種方案可能會(huì)影響并發(fā)量灰粮。

redis緩存擊穿

理解

image
  • 擊穿和穿透不同,穿透的意思是想法繞過redis去使得數(shù)據(jù)庫(kù)崩掉忍坷。而擊穿你可以理解為正面剛擊穿,這種通常為大量并發(fā)對(duì)一個(gè)key進(jìn)行大規(guī)模的讀寫操作粘舟。這個(gè)key在緩存失效期間大量請(qǐng)求數(shù)據(jù)庫(kù)熔脂,對(duì)數(shù)據(jù)庫(kù)造成太大壓力使得數(shù)據(jù)庫(kù)崩掉。就比如在秒殺場(chǎng)景下10000塊錢的mac和100塊的mac這個(gè)100塊的那個(gè)訂單肯定會(huì)被搶到爆柑肴。所以緩存擊穿就是針對(duì)某個(gè)常用key大量請(qǐng)求導(dǎo)致數(shù)據(jù)庫(kù)崩潰霞揉。

解決方案

  • 能夠達(dá)到這種場(chǎng)景的公司其實(shí)不多,我也不清楚他們的具體處理方法晰骑,但是一個(gè)鎖攔截請(qǐng)求總是能防止數(shù)據(jù)庫(kù)崩掉吧适秩。

總結(jié)與感悟

其實(shí)緩存看起來(lái),理解起來(lái)看似簡(jiǎn)單然而實(shí)際上的設(shè)計(jì)方案非常有學(xué)問硕舆。在細(xì)節(jié)設(shè)計(jì)上還會(huì)遇到消息隊(duì)列秽荞、布隆過濾器、分布式鎖抚官、服務(wù)降級(jí)扬跋、熔斷、分流這些凌节。在緩存處理上甚至還有緩存預(yù)熱(提前緩存部分熱點(diǎn)數(shù)據(jù)防止剛開始緩存全部命中導(dǎo)致服務(wù)崩掉)等其他熱門名詞和問題這里就不做介紹了钦听。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市倍奢,隨后出現(xiàn)的幾起案子朴上,更是在濱河造成了極大的恐慌,老刑警劉巖娱挨,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件余指,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡跷坝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門碉碉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)柴钻,“玉大人,你說(shuō)我怎么就攤上這事垢粮√欤” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蜡吧,是天一觀的道長(zhǎng)毫蚓。 經(jīng)常有香客問我,道長(zhǎng)昔善,這世上最難降的妖魔是什么元潘? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮君仆,結(jié)果婚禮上翩概,老公的妹妹穿的比我還像新娘牲距。我一直安慰自己,他們只是感情好钥庇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布牍鞠。 她就那樣靜靜地躺著,像睡著了一般评姨。 火紅的嫁衣襯著肌膚如雪难述。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天吐句,我揣著相機(jī)與錄音胁后,去河邊找鬼。 笑死蕴侧,一個(gè)胖子當(dāng)著我的面吹牛墓赴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裳仆,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拒炎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了择葡?” 一聲冷哼從身側(cè)響起紧武,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎敏储,沒想到半個(gè)月后阻星,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡已添,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年妥箕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片更舞。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡畦幢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出缆蝉,到底是詐尸還是另有隱情宇葱,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布刊头,位于F島的核電站黍瞧,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏原杂。R本人自食惡果不足惜印颤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望污尉。 院中可真熱鬧膀哲,春花似錦往产、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至兴喂,卻和暖如春蔼囊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衣迷。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工畏鼓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人壶谒。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓云矫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親汗菜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子让禀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354