Kafka broker 調(diào)優(yōu)

這些優(yōu)化可以去官網(wǎng)看,官網(wǎng)有說明

Kafka 的架構(gòu)這里就不多做介紹了泉蝌,直接步入正題。

這里主要是 Kafka 集群基本配置的相關(guān)內(nèi)容。

硬件要求

Kafka 集群基本硬件的保證

集群規(guī)模 內(nèi)存 CPU 存儲(chǔ)
Kafka Brokers 3+ 24GB+(小規(guī)模)汹胃;64GB+(大規(guī)模) 多核(12CPU+),并允許超線程 6+ 1TB 的專屬磁盤(RAID 或 JBOD)
Zookeeper 3(小規(guī)模)东臀;5(大規(guī)模) 8GB+(小規(guī)模)着饥;24GB+(大規(guī)模) 2核+ SSD 用于中間的日志傳輸

OS 調(diào)優(yōu)

可能不需要太多操作系統(tǒng)級(jí)別的調(diào)優(yōu),但有一些重要的操作系統(tǒng)級(jí)別配置:

  • 文件句柄數(shù) 限制:100k+惰赋;
  • 最大socket緩沖區(qū)大小:可以像這里描述的那樣增加數(shù)據(jù)中心之間的高性能數(shù)據(jù)傳輸宰掉。
  • JVM 配置
    1. JDK 8 并且使用 G1 垃圾收集器;
    2. 至少要分配 6-8 GB 的堆內(nèi)存。
      優(yōu)化成G1GC轨奄,堆內(nèi)存6-8G

broker_java_opts -server -XX:MetaspaceSize=96m -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M -XX:MinMetaspaceFreeRatio=50 -XX:MaxMetaspaceFreeRatio=80 -Djava.awt.headless=true

mirror_maker_max_heap_size 8G
broker_max_heap_size 6G

Kafka 磁盤存儲(chǔ)

  • 使用多塊磁盤孟害,并配置為 Kafka 專用的磁盤,確保良好的延遲戚绕;
  • kafka本身有備份機(jī)制纹坐,使用RAID在負(fù)載和性能方面并沒有很大提升,所以RAID沒什么必要舞丛。
  • 文件系統(tǒng):使用 EXT 或 XFS耘子;

Broker 配置

Broker 級(jí)別有幾個(gè)比較重要的配置,一般需要根據(jù)實(shí)際情況進(jìn)行相應(yīng)配置的:

  • 基礎(chǔ)配置
    default.replication.factor: 3 // 全局默認(rèn)副本數(shù)
    auto.create.topics.enable: true // 默認(rèn)true 是否開啟自動(dòng)創(chuàng)建topic的功能
    delete.topic.enable: true // 默認(rèn)true 是否開啟刪除topic的功能
    num.partitions: 27 // partition 數(shù)量

  • 副本
    Partition 有兩種副本:Leader球切,F(xiàn)ollower谷誓;
    Leader 負(fù)責(zé)維護(hù) in-sync-replicas(ISR)
    replica.lag.time.max.ms:10000
    默認(rèn)10s,如果在這個(gè)時(shí)間內(nèi)吨凑,follower沒有同步leader數(shù)據(jù)捍歪,則把follower從ISR剔除;按照follower和leader之間相差消息數(shù)的參數(shù)(replica.lag.max.messages was removed)在0.9.0版本已經(jīng)被廢棄鸵钝。
    num.replica.fetchers: 6 //副本之間同步數(shù)據(jù)的線程數(shù)糙臼,默認(rèn)1
    min.insync.replicas: 1 //這個(gè)參數(shù)設(shè)定ISR中的最小副本數(shù)是多少,默認(rèn)值為1
    如果同步狀態(tài)的副本小于該值恩商,服務(wù)器將不再接受request.required.acks為-1或all的寫入請(qǐng)求变逃,即write服務(wù)掛了。
    unclean.leader.election.enable: flase //默認(rèn)為flase, 不嚴(yán)格的leader選舉怠堪,有助于集群健壯揽乱,但是存在數(shù)據(jù)丟失風(fēng)險(xiǎn)。
    如果關(guān)閉粟矿,leader只能從ISR中選舉凰棉;如果開啟,在ISR集合為空時(shí)陌粹,選擇任一副本作為leader撒犀,這樣做可能會(huì)導(dǎo)致數(shù)據(jù)丟失。

  • 線程優(yōu)化

num.io.threads: 8 // 集群用作處理磁盤io的線程數(shù)申屹,默認(rèn)為8绘证,建議cpu的2倍
num.recovery.threads.per.data.dir: 1 //默認(rèn)值為1,建議調(diào)整為log.dirs中目錄的個(gè)數(shù)哗讥?每個(gè)數(shù)據(jù)目錄的線程數(shù),被用作集群啟動(dòng)恢復(fù)數(shù)據(jù)胞枕,集群停止事刷新數(shù)據(jù)

  • 日志留存策略

默認(rèn)日志留存策略是delete留存策略杆煞,可以按時(shí)間、空間、偏移量三個(gè)維度delete

log.retention.hours: 168 //日志保留時(shí)間决乎,過期刪除 默認(rèn)7天
log.retention.check.interval.ms: 300000 //檢查日志是否需要清除队询,是否過期, 默認(rèn)5分鐘

  • 數(shù)據(jù)文件刷新策略
    log.flush.interval.ms: 10000 //數(shù)據(jù)刷磁盤策略 按照時(shí)間 10s
    log.flush.interval.messages: 20000 //數(shù)據(jù)刷磁盤策略 按照按照數(shù)據(jù)條數(shù) 2w條
    log.flush.scheduler.interval.ms: 2000 //檢查日志是否需要刷新到磁盤 2s

log.segment.bytes: 1073741824 //單個(gè)日志文件的最大值 默認(rèn)1G
log.dirs: /data/1/kafka,/data/2/kafka,/data/3/kafka,/data/4/kafka,/data/5/kafka,/data/6/kafka //日志存放目錄

  • Balancing leadership

auto.leader.rebalance.enable: true // 默認(rèn)true,如果設(shè)為true构诚,復(fù)制控制器會(huì)周期性的自動(dòng)嘗試蚌斩,為所有的broker的每個(gè)partition平衡leadership,為更優(yōu)先(preferred)的replica分配leadership范嘱。

leader.imbalance.per.broker.percentage: 10 // 默認(rèn)值10 每個(gè)broker允許的不平衡的leader的百分比, 即leader均勻的分配在每個(gè)broker上 送膳。如果每個(gè)broker超過了這個(gè)百分比,復(fù)制控制器會(huì)重新平衡leadership丑蛤。

leader.imbalance.check.interval.seconds: 300 // 默認(rèn)5分鐘 檢查leader不平衡的時(shí)間間隔叠聋。

Kafka replica 相關(guān)配置及監(jiān)控

Under Replicated Partitions

當(dāng)發(fā)現(xiàn) replica 的配置與集群的不同時(shí),一般情況都是集群上的 replica 少于配置數(shù)時(shí)受裹,可以從以下幾個(gè)角度來排查問題:

  • JMX 監(jiān)控項(xiàng):kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions碌补;
  • 可能的原因:
    • Broker 掛了?
    • Controller 的問題棉饶?
    • ZooKeeper 的問題厦章?
    • Network 的問題?
  • 解決辦法:
    • 調(diào)整 ISR 的設(shè)置照藻;
    • Broker 擴(kuò)容袜啃。

Controller

  • 負(fù)責(zé)管理 partition 生命周期;
  • 避免 Controller’s ZK 會(huì)話超時(shí):
    • ISR 抖動(dòng)岩梳;
    • ZK Server 性能問題囊骤;
    • Broker 長時(shí)間的 GC;
    • 網(wǎng)絡(luò) IO 問題冀值;
  • 監(jiān)控:
    • kafka.controller:type=KafkaController,name=ActiveControllerCount也物,應(yīng)該為1;
    • LeaderElectionRate列疗。

Unclean leader 選舉

允許不在 isr 中 replica 被選舉為 leader滑蚯。

  • 這是 Availability 和 Correctness 之間選擇,Kafka 默認(rèn)選擇了可用性抵栈;
  • unclean.leader.election.enable:默認(rèn)為 true告材,即允許不在 isr 中 replica 選為 leader,這個(gè)配置可以全局配置古劲,也可以在 topic 級(jí)別配置斥赋;

不嚴(yán)格的leader選舉,有助于集群健壯产艾,但是存在數(shù)據(jù)丟失風(fēng)險(xiǎn)疤剑。
如果關(guān)閉滑绒,leader只能從ISR中選舉;如果開啟隘膘,在ISR集合為空時(shí)疑故,選擇任一副本作為leader,這樣做可能會(huì)導(dǎo)致數(shù)據(jù)丟失弯菊。

  • 監(jiān)控:kafka.controller:type=ControllerStats,name=UncleanLeaderElectionsPerSec纵势。

Kafka 相關(guān)資源的評(píng)估

集群評(píng)估

  • Broker 評(píng)估
    • 每個(gè) Broker 的 Partition 數(shù)不應(yīng)該超過2k;
    • 控制 partition 大泄芮(不要超過25GB)钦铁;
  • 集群評(píng)估(Broker 的數(shù)量根據(jù)以下條件配置)
    • 數(shù)據(jù)保留時(shí)間;
    • 集群的流量大刑G丁育瓜;
  • 集群擴(kuò)容:
    • 磁盤使用率應(yīng)該在 60% 以下;
    • 網(wǎng)絡(luò)使用率應(yīng)該在 75% 以下栽烂;
  • 集群監(jiān)控
    • 保持負(fù)載均衡躏仇;
    • 確保 topic 的 partition 均勻分布在所有 Broker 上;
    • 確保集群的階段沒有耗盡磁盤或帶寬腺办。

kafka集群服務(wù)器監(jiān)控

Kafka 集群需要監(jiān)控的一些指標(biāo)焰手,這些指標(biāo)反應(yīng)了集群的健康度。

  • CPU 負(fù)載怀喉;
  • Network Metrics书妻;
  • File Handle 使用;
  • 磁盤空間躬拢;
  • 磁盤 IO 性能躲履;
  • GC 信息;
  • ZooKeeper 監(jiān)控聊闯。

Broker 監(jiān)控

  • Partition 數(shù):kafka.server:type=ReplicaManager,name=PartitionCount工猜;
  • Leader 副本數(shù):kafka.server:type=ReplicaManager,name=LeaderCount;
  • ISR 擴(kuò)容/縮容率:kafka.server:type=ReplicaManager,name=IsrExpandsPerSec菱蔬;
  • 讀寫速率:Message in rate/Byte in rate/Byte out rate篷帅;
  • 網(wǎng)絡(luò)請(qǐng)求的平均空閑率:NetworkProcessorAvgIdlePercent;
  • 請(qǐng)求處理平均空閑率:RequestHandlerAvgIdlePercent拴泌。

Topic 評(píng)估

  • partition 數(shù)
    • Partition 數(shù)應(yīng)該至少與最大 consumer group 中 consumer 線程數(shù)一致魏身;
    • 對(duì)于使用頻繁的 topic,應(yīng)該設(shè)置更多的 partition蚪腐;
    • 控制 partition 的大屑恰(25GB 左右);
    • 考慮應(yīng)用未來的增長(可以使用一種機(jī)制進(jìn)行自動(dòng)擴(kuò)容)回季;
  • 使用帶 key 的 topic宙枷;
  • partition 擴(kuò)容:當(dāng) partition 的數(shù)據(jù)量超過一個(gè)閾值時(shí)應(yīng)該自動(dòng)擴(kuò)容(實(shí)際上還應(yīng)該考慮網(wǎng)絡(luò)流量)掉房。

合理地設(shè)置 partition

  • 根據(jù)吞吐量的要求設(shè)置 partition 數(shù):
    • 假設(shè) Producer 單 partition 的吞吐量為 P茧跋;
    • consumer 消費(fèi)一個(gè) partition 的吞吐量為 C慰丛;
    • 而要求的吞吐量為 T;
    • 那么 partition 數(shù)至少應(yīng)該大于 T/P瘾杭、T/c 的最大值诅病;
  • 更多的 partition,意味著:
    • 更多的 fd粥烁;
    • 可能增加 Unavailability(可能會(huì)增加不可用的時(shí)間)贤笆;
    • 可能增加端到端的延遲;
    • client 端將會(huì)使用更多的內(nèi)存讨阻。

關(guān)于 Partition 的設(shè)置可以參考這篇文章How to choose the number of topics/partitions in a Kafka cluster?芥永,這里簡單講述一下,Partition 的增加將會(huì)帶來以下幾個(gè)優(yōu)點(diǎn)和缺點(diǎn):

  1. 增加吞吐量:對(duì)于 consumer 來說钝吮,一個(gè) partition 只能被一個(gè) consumer 線程所消費(fèi)埋涧,適當(dāng)增加 partition 數(shù),可以增加 consumer 的并發(fā)奇瘦,進(jìn)而增加系統(tǒng)的吞吐量棘催;
  2. 需要更多的 fd:對(duì)于每一個(gè) segment,在 broker 都會(huì)有一個(gè)對(duì)應(yīng)的 index 和實(shí)際數(shù)據(jù)文件耳标,而對(duì)于 Kafka Broker醇坝,它將會(huì)對(duì)于每個(gè) segment 每個(gè) index 和數(shù)據(jù)文件都會(huì)打開相應(yīng)的 file handle(可以理解為 fd),因此次坡,partition 越多呼猪,將會(huì)帶來更多的 fd;
  3. 可能會(huì)增加數(shù)據(jù)不可用性(主要是指增加不可用時(shí)間):主要是指 broker 宕機(jī)的情況砸琅,越多的 partition 將會(huì)意味著越多的 partition 需要 leader 選舉(leader 在宕機(jī)這臺(tái) broker 的 partition 需要重新選舉)宋距,特別是如果剛好 controller 宕機(jī),重新選舉的 controller 將會(huì)首先讀取所有 partition 的 metadata明棍,然后才進(jìn)行相應(yīng)的 leader 選舉乡革,這將會(huì)帶來更大不可用時(shí)間;
  4. 可能增加 End-to-end 延遲:一條消息只有其被同步到 isr 的所有 broker 上后摊腋,才能被消費(fèi)沸版,partition 越多,不同節(jié)點(diǎn)之間同步就越多兴蒸,這可能會(huì)帶來毫秒級(jí)甚至數(shù)十毫秒級(jí)的延遲视粮;
  5. Client 將會(huì)需要更多的內(nèi)存:Producer 和 Consumer 都會(huì)按照 partition 去緩存數(shù)據(jù),每個(gè) partition 都會(huì)帶來數(shù)十 KB 的消耗橙凳,partition 越多, Client 將會(huì)占用更多的內(nèi)存蕾殴。

Producer 的相關(guān)配置笑撞、性能調(diào)優(yōu)及監(jiān)控

Quotas

  • 避免被惡意 Client 攻擊,保證 SLA钓觉;
  • 設(shè)置 produce 和 fetch 請(qǐng)求的字節(jié)速率閾值茴肥;
  • 可以應(yīng)用在 user、client-id荡灾、或者 user 和 client-id groups瓤狐;
  • Broker 端的 metrics 監(jiān)控:throttle-rate、byte-rate批幌;
  • replica.fetch.response.max.bytes:用于限制 replica 拉取請(qǐng)求的內(nèi)存使用础锐;
  • 進(jìn)行數(shù)據(jù)遷移時(shí)限制貸款的使用,kafka-reassign-partitions.sh -- -throttle option荧缘。

Kafka Producer

  • 使用 Java 版的 Client皆警;
  • 使用 kafka-producer-perf-test.sh 測試你的環(huán)境;
  • 設(shè)置內(nèi)存截粗、CPU信姓、batch 壓縮;
    • batch.size:該值設(shè)置越大桐愉,吞吐越大财破,但延遲也會(huì)越大;
    • linger.ms:表示 batch 的超時(shí)時(shí)間从诲,該值越大左痢,吞吐越大、但延遲也會(huì)越大系洛;
    • max.in.flight.requests.per.connection:默認(rèn)為5俊性,表示 client 在 blocking 之前向單個(gè)連接(broker)發(fā)送的未確認(rèn)請(qǐng)求的最大數(shù),超過1時(shí)描扯,將會(huì)影響數(shù)據(jù)的順序性定页;
    • compression.type:壓縮設(shè)置,會(huì)提高吞吐量绽诚;
    • acks:數(shù)據(jù) durability 的設(shè)置典徊;
  • 避免大消息
    • 會(huì)使用更多的內(nèi)存;
    • 降低 Broker 的處理速度恩够;

性能調(diào)優(yōu)

  • 如果吞吐量小于網(wǎng)絡(luò)帶寬
    • 增加線程卒落;
    • 提高 batch.size;
    • 增加更多 producer 實(shí)例蜂桶;
    • 增加 partition 數(shù)儡毕;
  • 設(shè)置 acks=-1 時(shí),如果延遲增大:可以增大 num.replica.fetchers(follower 同步數(shù)據(jù)的線程數(shù))來調(diào)解扑媚;
  • 跨數(shù)據(jù)中心的傳輸:增加 socket 緩沖區(qū)設(shè)置以及 OS tcp 緩沖區(qū)設(shè)置腰湾。

Prodcuer 監(jiān)控

  • batch-size-avg
  • compression-rate-avg
  • waiting-threads
  • buffer-available-bytes
  • record-queue-time-max
  • record-send-rate
  • records-per-request-avg

Kafka Consumer 配置雷恃、性能調(diào)優(yōu)及監(jiān)控

Kafka Consumer

  • 使用 kafka-consumer-perf-test.sh 測試環(huán)境;
  • 吞吐量問題:
    • partition 數(shù)太少费坊;
    • OS page cache:分配足夠的內(nèi)存來緩存數(shù)據(jù)倒槐;
    • 應(yīng)用的處理邏輯;
  • offset topic(__consumer_offsets
    • offsets.topic.replication.factor:默認(rèn)為3葵萎;
    • offsets.retention.minutes:默認(rèn)為1440导犹,即 1day;
      – MonitorISR羡忘,topicsize;
  • offset commit較慢:異步 commit 或 手動(dòng) commit磕昼。

Consumer 配置

  • fetch.min.bytes 卷雕、fetch.max.wait.ms
  • max.poll.interval.ms:調(diào)用 poll() 之后延遲的最大時(shí)間票从,超過這個(gè)時(shí)間沒有調(diào)用 poll() 的話漫雕,就會(huì)認(rèn)為這個(gè) consumer 掛掉了,將會(huì)進(jìn)行 rebalance峰鄙;
  • max.poll.records:當(dāng)調(diào)用 poll() 之后返回最大的 record 數(shù)浸间,默認(rèn)為500;
  • session.timeout.ms吟榴;
  • Consumer Rebalance
    – check timeouts
    – check processing times/logic
    – GC Issues
  • 網(wǎng)絡(luò)配置魁蒜;

Consumer 監(jiān)控

consumer 是否跟得上數(shù)據(jù)的發(fā)送速度。

  • Consumer Lag:consumer offset 與 the end of log(partition 可以消費(fèi)的最大 offset) 的差值吩翻;
  • 監(jiān)控
    • metric 監(jiān)控:records-lag-max兜看;
    • 通過 bin/kafka-consumer-groups.sh 查看;
    • 用于 consumer 監(jiān)控的 LinkedIn’s Burrow狭瞎;
  • 減少 Lag
    • 分析 consumer:是 GC 問題還是 Consumer hang 住了细移;
    • 增加 Consumer 的線程;
    • 增加分區(qū)數(shù)和 consumer 線程熊锭;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弧轧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子碗殷,更是在濱河造成了極大的恐慌精绎,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件亿扁,死亡現(xiàn)場離奇詭異捺典,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)从祝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門襟己,熙熙樓的掌柜王于貴愁眉苦臉地迎上來引谜,“玉大人,你說我怎么就攤上這事擎浴≡毖剩” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵贮预,是天一觀的道長贝室。 經(jīng)常有香客問我,道長仿吞,這世上最難降的妖魔是什么滑频? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮唤冈,結(jié)果婚禮上峡迷,老公的妹妹穿的比我還像新娘。我一直安慰自己你虹,他們只是感情好绘搞,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著傅物,像睡著了一般夯辖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上董饰,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天蒿褂,我揣著相機(jī)與錄音,去河邊找鬼尖阔。 笑死贮缅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的介却。 我是一名探鬼主播谴供,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼齿坷!你這毒婦竟也來了桂肌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤永淌,失蹤者是張志新(化名)和其女友劉穎崎场,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體遂蛀,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谭跨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片螃宙。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛮瞄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谆扎,到底是詐尸還是另有隱情挂捅,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布堂湖,位于F島的核電站闲先,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏无蜂。R本人自食惡果不足惜伺糠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望酱讶。 院中可真熱鬧退盯,春花似錦、人聲如沸泻肯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灶挟。三九已至,卻和暖如春毒租,著一層夾襖步出監(jiān)牢的瞬間稚铣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工墅垮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惕医,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓算色,卻偏偏與公主長得像抬伺,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子灾梦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容