Redis面試寶典

Redis 的持久化機(jī)制使得內(nèi)存中的數(shù)據(jù)能夠持久化到磁盤虑绵,解決內(nèi)存數(shù)據(jù)掉電易失的問題,而且Redis是一款中間件祖乳,無需依賴jvm

1遥皂、Redis支持哪幾種數(shù)據(jù)類型力喷?

字符串String、字典Hash演训、列表List弟孟、集合Set、有序集合SortedSet; 如果你是Redis中高級(jí)用戶仇祭,還需要加上下面幾種數(shù)據(jù)結(jié)構(gòu)HyperLogLog披蕉、Geo、Pub/Sub乌奇。

? String字符串:

格式: set key value

string類型是二進(jìn)制安全的没讲。意思是redis的string可以包含任何數(shù)據(jù)。比如jpg圖片或者序列化的對(duì)象 礁苗。

string類型是Redis最基本的數(shù)據(jù)類型爬凑,一個(gè)鍵最大能存儲(chǔ)512MB。

? Hash(哈希)

格式: hmset name ?key1 value1 key2 value2

Redis hash 是一個(gè)鍵值(key=>value)對(duì)集合试伙。

Redis hash是一個(gè)string類型的field和value的映射表嘁信,hash特別適合用于存儲(chǔ)對(duì)象。

? List(列表)

Redis 列表是簡(jiǎn)單的字符串列表疏叨,按照插入順序排序潘靖。你可以添加一個(gè)元素到列表的頭部(左邊)或者尾部(右邊)

格式: lpush ?name ?value

在 key 對(duì)應(yīng) list 的頭部添加字符串元素

格式: rpush ?name ?value

在 key 對(duì)應(yīng) list 的尾部添加字符串元素

格式: lrem name ?index

key 對(duì)應(yīng) list 中刪除 count 個(gè)和 value 相同的元素

格式: llen name

返回 key 對(duì)應(yīng) list 的長度

? Set(集合)

格式: sadd ?name ?value

Redis的Set是string類型的無序集合。

集合是通過哈希表實(shí)現(xiàn)的蚤蔓,所以添加卦溢,刪除,查找的復(fù)雜度都是O(1)。

? zset(sorted set:有序集合)

格式: zadd ?name score value

Redis zset 和 set 一樣也是string類型元素的集合,且不允許重復(fù)的成員单寂。

不同的是每個(gè)元素都會(huì)關(guān)聯(lián)一個(gè)double類型的分?jǐn)?shù)贬芥。redis正是通過分?jǐn)?shù)來為集合中的成員進(jìn)行從小到大的排序。

zset的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)宣决。

2蘸劈、什么是緩存穿透

一般的緩存系統(tǒng),都是按照key去緩存查詢,如果不存在對(duì)應(yīng)的value,就應(yīng)該去數(shù)據(jù)庫查詢。一些惡意的請(qǐng)求會(huì)故意大量查詢不存在的key,就會(huì)對(duì)數(shù)據(jù)庫造成很大的壓力尊沸。這就叫做緩存穿透威沫。簡(jiǎn)單的說就是故意避開緩存去數(shù)據(jù)庫查詢數(shù)據(jù)。椒丧。場(chǎng)景:當(dāng)客戶端發(fā)起查詢時(shí)壹甥,緩存中沒有就會(huì)去查庫,庫里也沒有壶熏,就會(huì)返回給客戶端錯(cuò)誤信息句柠。這樣是沒問題的,看起來邏輯是完美的棒假,但是這里存在一個(gè)漏洞溯职,那就是無論什么樣的Key過來查,都接受它的請(qǐng)求帽哑,這就可能會(huì)被黑客抓住谜酒,發(fā)起大量請(qǐng)求,并且Key都是系統(tǒng)中沒有的妻枕,庫里也查不到對(duì)應(yīng)的值僻族,這樣的Key稱之為非法Key。那么當(dāng)大量這樣的請(qǐng)求過來時(shí)是不是都不會(huì)命中Redis屡谐,然后都會(huì)打到DB上述么,當(dāng)DB瞬時(shí)接收到如此多的連接時(shí),DB就有可能撐不住愕掏,掛掉度秘。這就是存在的一個(gè)隱藏的漏洞,黑客或者惡意攻擊者就會(huì)抓住這一點(diǎn)攻擊你的系統(tǒng)饵撑,使你的系統(tǒng)癱瘓剑梳。

? 采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmap中滑潘,一個(gè)一定不存在的數(shù)據(jù)會(huì)被 這個(gè)bitmap攔截掉垢乙,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力。

? 另外也有一個(gè)更為簡(jiǎn)單粗暴的方法(我們采用的就是這種)语卤,如果一個(gè)查詢返回的數(shù)據(jù)為空(不管是數(shù)據(jù)不存在追逮,還是系統(tǒng)故障)蓖租,我們?nèi)匀话堰@個(gè)空結(jié)果進(jìn)行緩存,但它的過期時(shí)間會(huì)很短羊壹,最長不超過五分鐘。

3齐婴、什么是緩存擊穿

是針對(duì)緩存中沒有但數(shù)據(jù)庫有的數(shù)據(jù)油猫。場(chǎng)景是,當(dāng)Key失效后柠偶,假如瞬間突然涌入大量的請(qǐng)求情妖,來請(qǐng)求同一個(gè)Key,這些請(qǐng)求不會(huì)命中Redis诱担,都會(huì)請(qǐng)求到DB毡证,導(dǎo)致數(shù)據(jù)庫壓力過大,甚至扛不住蔫仙,掛掉料睛。解決辦法:

? 設(shè)置熱點(diǎn)Key,自動(dòng)檢測(cè)熱點(diǎn)Key摇邦,將熱點(diǎn)Key的過期時(shí)間加大或者設(shè)置為永不過期恤煞,或者設(shè)置為邏輯上永不過期,具體設(shè)置方法待會(huì)說施籍。

? 加互斥鎖居扒。當(dāng)發(fā)現(xiàn)沒有命中Redis,去查數(shù)據(jù)庫的時(shí)候丑慎,在執(zhí)行更新緩存的操作上加鎖喜喂,誰拿到鎖誰去更新,同時(shí)在拿到鎖之后先從緩存再獲取一次如果有就返回竿裂,沒有就查庫然后更新玉吁。(雙重校驗(yàn))

4、什么是緩存雪崩

緩存雪崩是指緩存中數(shù)據(jù)大批量到過期時(shí)間铛绰,而查詢數(shù)據(jù)量巨大诈茧,引起數(shù)據(jù)庫壓力過大甚至down機(jī)。和緩存擊穿不同的是, 緩存擊穿指并發(fā)查同一條數(shù)據(jù)捂掰,緩存雪崩是不同數(shù)據(jù)都過期了敢会,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫。簡(jiǎn)單地說就是緩存大量過期去數(shù)據(jù)庫查詢數(shù)據(jù)这嚣。

解決辦法:

? 緩存數(shù)據(jù)的過期時(shí)間設(shè)置隨機(jī)鸥昏,防止同一時(shí)間大量數(shù)據(jù)過期現(xiàn)象發(fā)生。

? 如果緩存數(shù)據(jù)庫是分布式部署姐帚,將熱點(diǎn)數(shù)據(jù)均勻分布在不同搞得緩存數(shù)據(jù)庫中吏垮。

? 設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期。

5、Redis有哪些架構(gòu)模式膳汪?各有什么特點(diǎn)

? 單機(jī)版

特點(diǎn):

簡(jiǎn)單

問題:

1唯蝶、內(nèi)存容量有限

2、處理能力有限

3遗嗽、無法高可用粘我。

? 主從復(fù)制

Redis 的復(fù)制(replication)功能允許用戶根據(jù)一個(gè) Redis 服務(wù)器來創(chuàng)建任意多個(gè)該服務(wù)器的復(fù)制品,其中被復(fù)制的服務(wù)器為主服務(wù)器(master)痹换,而通過復(fù)制創(chuàng)建出來的服務(wù)器復(fù)制品則為從服務(wù)器(slave)征字。只要主從服務(wù)器之間的網(wǎng)絡(luò)連接正常,主從服務(wù)器兩者會(huì)具有相同的數(shù)據(jù)娇豫,主服務(wù)器就會(huì)一直將發(fā)生在自己身上的數(shù)據(jù)更新同步 給從服務(wù)器匙姜,從而一直保證主從服務(wù)器的數(shù)據(jù)相同。

特點(diǎn):

1冯痢、master/slave 角色

2氮昧、master/slave 數(shù)據(jù)相同

3、降低 master 讀壓力在轉(zhuǎn)交從庫

問題:

無法保證高可用

沒有解決 master 寫的壓力

? 哨兵

Redis sentinel 是一個(gè)分布式系統(tǒng)中監(jiān)控 redis 主從服務(wù)器系羞,并在主服務(wù)器下線時(shí)自動(dòng)進(jìn)行故障轉(zhuǎn)移郭计。其中三個(gè)特性:

監(jiān)控(Monitoring):? ?Sentinel ?會(huì)不斷地檢查你的主服務(wù)器和從服務(wù)器是否運(yùn)作正常。

提醒(Notification):當(dāng)被監(jiān)控的某個(gè) Redis 服務(wù)器出現(xiàn)問題時(shí)椒振, Sentinel 可以通過 API 向管理員或者其他應(yīng)用程序發(fā)送通知昭伸。

自動(dòng)故障遷移(Automatic failover):當(dāng)一個(gè)主服務(wù)器不能正常工作時(shí), Sentinel 會(huì)開始一次自動(dòng)故障遷移操作澎迎。

特點(diǎn):

1庐杨、保證高可用

2、監(jiān)控各個(gè)節(jié)點(diǎn)

3夹供、自動(dòng)故障遷移

缺點(diǎn):主從模式灵份,切換需要時(shí)間丟數(shù)據(jù)

沒有解決 master寫的壓力

? 集群(proxy 型)

Twemproxy 是一個(gè) Twitter 開源的一個(gè) redis 和 memcache 快速/輕量級(jí)代理服務(wù)器;Twemproxy 是一個(gè)快速的單線程代理程序哮洽,支持 Memcached ASCII 協(xié)議和 redis 協(xié)議填渠。

特點(diǎn):

1、多種 hash 算法:MD5鸟辅、CRC16氛什、CRC32、CRC32a匪凉、hsieh枪眉、murmur、Jenkins

2再层、支持失敗節(jié)點(diǎn)自動(dòng)刪除

3贸铜、后端 Sharding 分片邏輯對(duì)業(yè)務(wù)透明堡纬,業(yè)務(wù)方的讀寫方式和操作單個(gè) Redis 一致

缺點(diǎn):

增加了新的 proxy,需要維護(hù)其高可用蒿秦。

failover 邏輯需要自己實(shí)現(xiàn)烤镐,其本身不能支持故障的自動(dòng)轉(zhuǎn)移可擴(kuò)展性差,進(jìn)行擴(kuò)縮容都需要手動(dòng)干預(yù)

? 集群(直連型)

從redis 3.0之后版本支持redis-cluster集群棍鳖,Redis-Cluster采用無中心結(jié)構(gòu)职车,每個(gè)節(jié)點(diǎn)保存數(shù)據(jù)和整個(gè)集群狀態(tài),每個(gè)節(jié)點(diǎn)都和其他所有節(jié)點(diǎn)連接。

特點(diǎn):

1鹊杖、無中心架構(gòu)(不存在哪個(gè)節(jié)點(diǎn)影響性能瓶頸),少了 proxy 層扛芽。

2骂蓖、數(shù)據(jù)按照 slot 存儲(chǔ)分布在多個(gè)節(jié)點(diǎn),節(jié)點(diǎn)間數(shù)據(jù)共享川尖,可動(dòng)態(tài)調(diào)整數(shù)據(jù)分布登下。

3、可擴(kuò)展性叮喳,可線性擴(kuò)展到 1000 個(gè)節(jié)點(diǎn)被芳,節(jié)點(diǎn)可動(dòng)態(tài)添加或刪除。

4馍悟、高可用性畔濒,部分節(jié)點(diǎn)不可用時(shí),集群仍可用锣咒。通過增加 Slave 做備份數(shù)據(jù)副本

5侵状、實(shí)現(xiàn)故障自動(dòng) failover,節(jié)點(diǎn)之間通過 gossip 協(xié)議交換狀態(tài)信息毅整,用投票機(jī)制完成 Slave到 Master 的角色提升趣兄。

缺點(diǎn):

1、資源隔離性較差悼嫉,容易出現(xiàn)相互影響的情況艇潭。

2、數(shù)據(jù)通過異步復(fù)制,不保證數(shù)據(jù)的強(qiáng)一致性

6戏蔑、Redis AOF文件過大蹋凝?AOF重寫的作用?

隨著命令不斷的寫入數(shù)據(jù)辛臊,AOF文件會(huì)越來越大仙粱。為了解決這個(gè)問題,redis 引入了 AOF文件重寫機(jī)制彻舰,以便壓縮 AOF體積 伐割,更小的 AOF文件可以更快的被redis加載

從 Redis 2.4開始候味, AOF重寫由 Redis自行觸發(fā), 可以使用BGREWRITEAOF手動(dòng)觸發(fā)重寫操作

? AOF重寫的作用

減少磁盤占用量 隔心、加速恢復(fù)速度

7白群、Redis內(nèi)部數(shù)據(jù)結(jié)構(gòu)

? 簡(jiǎn)單動(dòng)態(tài)字符串 simple dynamic string,SDS

? 鏈表

? 字典 又稱為符號(hào)表或者關(guān)聯(lián)數(shù)組、或映射(map)

? 跳躍表 skiplist

? 整數(shù)集合 intset

? 壓縮列表 ziplist

8硬霍、Redis過期key處理策略

Redis中有個(gè)設(shè)置時(shí)間過期的功能帜慢,即對(duì)存儲(chǔ)在 redis 數(shù)據(jù)庫中的值可以設(shè)置一個(gè)過期時(shí)間。作為一個(gè)緩存數(shù)據(jù)庫唯卖,這是非常實(shí)用的粱玲。如項(xiàng)目中的 token 或者一些登錄信息,尤其是短信驗(yàn)證碼都是有時(shí)間限制的拜轨,按照傳統(tǒng)的數(shù)據(jù)庫處理方式抽减,一般都是自己判斷過期,這樣無疑會(huì)嚴(yán)重影響項(xiàng)目性能橄碾。

操作set key 的時(shí)候卵沉,都可以給一個(gè) expire time,就是過期時(shí)間法牲,通過過期時(shí)間可以指定這個(gè) key可以存活的時(shí)間史汗。

如果假設(shè)你設(shè)置了一批 key 只能存活1個(gè)小時(shí),那么接下來1小時(shí)后拒垃,redis是怎么對(duì)這批key進(jìn)行刪除的停撞?

定期刪除 + 惰性刪除 ? ?通過名字大概就能猜出這兩個(gè)刪除方式的意思了。

? 定期刪除:redis默認(rèn)是每隔 100ms 就隨機(jī)抽取一些設(shè)置了過期時(shí)間的key悼瓮,檢查其是否過期怜森,如果過期就刪除。注意這里是隨機(jī)抽取的谤牡。為什么要隨機(jī)呢副硅?你想一想假如 redis 存了幾十萬個(gè) key ,每隔100ms就遍歷所有的設(shè)置過期時(shí)間的 key 的話翅萤,就會(huì)給 CPU 帶來很大的負(fù)載恐疲!

? 惰性刪除 :定期刪除可能會(huì)導(dǎo)致很多過期 key 到了時(shí)間并沒有被刪除掉。所以就有了惰性刪除套么。假如你的過期 key培己,靠定期刪除沒有被刪除掉,還停留在內(nèi)存里胚泌,除非你的系統(tǒng)去查一下那個(gè) key省咨,才會(huì)被redis給刪除掉。這就是所謂的惰性刪除玷室,也是夠懶的哈零蓉!

僅僅通過設(shè)置過期時(shí)間還是有問題的笤受。想一下:如果定期刪除漏掉了很多過期 key,然后也沒及時(shí)去查敌蜂,也就沒走惰性刪除箩兽,此時(shí)會(huì)怎么樣?如果大量過期key堆積在內(nèi)存里章喉,導(dǎo)致redis內(nèi)存塊耗盡了汗贫。怎么解決這個(gè)問題呢?

9秸脱、Redis事務(wù)

Redis通過 MULTI落包、EXEC、WATCH等命令來實(shí)現(xiàn)事務(wù)(transaction)功能摊唇。事務(wù)提供了一種將多個(gè)命令請(qǐng)求打包妥色,然后一次性、按順序地執(zhí)行多個(gè)命令的機(jī)制遏片,并且在事務(wù)執(zhí)行期間,服務(wù)器不會(huì)中斷事務(wù)而改去執(zhí)行其他客戶端的命令請(qǐng)求撮竿,它會(huì)將事務(wù)中的所有命令都執(zhí)行完畢吮便,然后才去處理其他客戶端的命令請(qǐng)求。

在傳統(tǒng)的關(guān)系式數(shù)據(jù)庫中幢踏,常常用ACID性質(zhì)來檢驗(yàn)事務(wù)功能的可靠性和安全性髓需。在 Redis中,事務(wù)總是具有原子性(Atomicity)房蝉、一致性(Consistency)和隔離性(Isolation)僚匆,并且當(dāng) Redis 運(yùn)行在某種特定的持久化模式下時(shí),事務(wù)也具有持久性(Durability)搭幻。

10咧擂、如何保證緩存與數(shù)據(jù)庫雙寫時(shí)的數(shù)據(jù)一致性

如果不是嚴(yán)格要求“緩存和數(shù)據(jù)庫”必須保證一致性的話,最好不要做這個(gè)方案:即 讀請(qǐng)求和寫請(qǐng)求串行化檀蹋,串到一個(gè)內(nèi)存隊(duì)列里面去松申。串行化可以保證一定不會(huì)出現(xiàn)不一致的情況,但會(huì)導(dǎo)致系統(tǒng)吞吐量大幅度降低俯逾。

解決這個(gè)問題的最經(jīng)典的模式贸桶,就是Cache Aside Pattern。

Cache Aside Pattern:

? 讀的時(shí)候先讀緩存桌肴,如果緩存不存在的話就讀數(shù)據(jù)庫皇筛,取出數(shù)據(jù)庫后更新緩存;如果存在的話直接讀取緩存的信息坠七。

? 寫的時(shí)候水醋,先更新數(shù)據(jù)庫旗笔,再刪除緩存。

說到這個(gè)問題离例,又會(huì)出現(xiàn)很多問題:

? 為什么是刪除緩存换团,而不是更新緩存?

? 為什么是先更新數(shù)據(jù)庫宫蛆,再刪除緩存艘包?不是先刪除緩存,再更新數(shù)據(jù)庫耀盗?

寫的時(shí)候?yàn)槭裁词莿h除緩存不是更新緩存想虎?

很多時(shí)候復(fù)雜的緩存場(chǎng)景,緩存不是僅僅從數(shù)據(jù)庫中取出來的值叛拷∩喑可能是關(guān)聯(lián)多張表的數(shù)據(jù)并通過計(jì)算才是緩存需要的值。并且忿薇,更新緩存的代價(jià)有時(shí)候很高裙椭。對(duì)于需要頻繁寫操作,而讀操作很少的時(shí)候署浩,每次進(jìn)行數(shù)據(jù)庫的修改揉燃,緩存也要隨之更新,會(huì)造成系統(tǒng)吞吐的下降筋栋,但此時(shí)緩存并不會(huì)被頻繁訪問到炊汤,用到的緩存才去算緩存。

刪除緩存而不是更新緩存弊攘,是一種懶加載的思想抢腐,不是每次都重復(fù)更新緩存,只有用到的時(shí)候才去更新緩存襟交,同時(shí)即使有大量的讀請(qǐng)求迈倍,實(shí)際也就更新了一次,后面的請(qǐng)求不會(huì)重復(fù)讀捣域。

Cache Aside Pattern存在的問題

問題:先更新數(shù)據(jù)庫授瘦,再刪除緩存,如果更新緩存失敗了竟宋,導(dǎo)致數(shù)據(jù)庫中是新數(shù)據(jù)提完,緩存中是舊數(shù)據(jù),就出現(xiàn)數(shù)據(jù)不一致的問題丘侠。

解決思路:先刪除緩存徒欣,再更新數(shù)據(jù)庫。

緩存刪除失斘献帧:如果緩存刪除失敗打肝,那么數(shù)據(jù)庫信息沒有被修改脂新,保持了數(shù)據(jù)的一致性;

緩存刪除成功粗梭,數(shù)據(jù)庫更新失斦恪:此時(shí)數(shù)據(jù)庫里的是舊數(shù)據(jù),緩存是空的断医,查詢時(shí)發(fā)現(xiàn)緩存不存在滞乙,就查詢數(shù)據(jù)庫并更新緩存,數(shù)據(jù)保持一致鉴嗤。問題:上面的方案存在不足斩启,如果刪除完緩存更新數(shù)據(jù)庫時(shí),如果一個(gè)請(qǐng)求過來查詢數(shù)據(jù)醉锅,緩存不存在兔簇,就查詢數(shù)據(jù)庫的舊數(shù)據(jù),更新舊數(shù)據(jù)到緩存中硬耍。隨后數(shù)據(jù)更新完成垄琐,修改了數(shù)據(jù)庫的數(shù)據(jù),此時(shí)緩存和數(shù)據(jù)庫的數(shù)據(jù)就會(huì)出現(xiàn)不一致了经柴。高并發(fā)下會(huì)出現(xiàn)這種數(shù)據(jù)庫+緩存不一致的情況狸窘。如果不采用給緩存設(shè)置過期時(shí)間策略,該數(shù)據(jù)永遠(yuǎn)都是臟數(shù)據(jù)口锭。

解決方案:采用雙刪除策略。寫請(qǐng)求先刪除緩存介杆,再去更新數(shù)據(jù)庫鹃操,等待一段時(shí)間后異步刪除緩存。這樣可以保證在讀取錯(cuò)誤數(shù)據(jù)時(shí)能及時(shí)被修正過來春哨。

還有一種策略荆隘,就是:寫請(qǐng)求先修改緩存為指定值,然后再去更新數(shù)據(jù)庫赴背,再更新緩存椰拒。讀請(qǐng)求過來后,會(huì)先讀緩存凰荚,判斷是指定值后就進(jìn)入循環(huán)讀取狀態(tài)燃观,等到寫請(qǐng)求更新緩存。如果循環(huán)超時(shí)就去數(shù)據(jù)庫讀取數(shù)據(jù)便瑟,更新緩存缆毁。

這種方案保證了讀寫的一致性,但由于讀請(qǐng)求等待寫請(qǐng)求的完成到涂,會(huì)降低系統(tǒng)的吞吐量脊框。

11颁督、何解決Redis的并發(fā)競(jìng)爭(zhēng)Key問題

所謂Redis的并發(fā)競(jìng)爭(zhēng)Key的問題也就是多個(gè)系統(tǒng)同時(shí)對(duì)一個(gè)key進(jìn)行操作,但是最后執(zhí)行的順序與期望的順序一致浇雹,這樣也就導(dǎo)致了結(jié)果的不同沉御!

推薦一種方案:分布式鎖(zookeeper和redis都可以實(shí)現(xiàn)分布式鎖)。如果不存在Redis的并發(fā)競(jìng)爭(zhēng)Key問題昭灵,不要使用分布式鎖吠裆,這樣會(huì)影響性能

基于zookeeper臨時(shí)有序節(jié)點(diǎn)可以實(shí)現(xiàn)的分布式鎖。大致思想為:每個(gè)客戶端對(duì)某個(gè)方法加鎖時(shí)虎锚,在zookeeper上的與該方法對(duì)應(yīng)的指定節(jié)點(diǎn)的目錄下硫痰,生成一個(gè)唯一的瞬時(shí)有序節(jié)點(diǎn)。判斷是否獲取鎖的方式很簡(jiǎn)單窜护,只需要判斷有序節(jié)點(diǎn)中序號(hào)最小的一個(gè)效斑。當(dāng)釋放鎖的時(shí)候,只需將這個(gè)瞬時(shí)節(jié)點(diǎn)刪除即可柱徙。同時(shí)缓屠,其可以避免服務(wù)宕機(jī)導(dǎo)致的鎖無法釋放,而產(chǎn)生的死鎖問題护侮。完成業(yè)務(wù)流程后敌完,刪除對(duì)應(yīng)的子節(jié)點(diǎn)釋放鎖。

在實(shí)踐中羊初,當(dāng)然是從以可靠性為主; 所以首推Zookeeper滨溉。

12、Redis分布式鎖的注意事項(xiàng)

互斥性长赞。在任意時(shí)刻晦攒,只有一個(gè)客戶端能持有鎖。

不會(huì)發(fā)生死鎖得哆。即使有一個(gè)客戶端在持有鎖的期間崩潰而沒有主動(dòng)解鎖脯颜,也能保證后續(xù)其他客戶端能加鎖。

具有容錯(cuò)性贩据。只要大部分的Redis節(jié)點(diǎn)正常運(yùn)行栋操,客戶端就可以加鎖和解鎖。

解鈴還須系鈴人饱亮。加鎖和解鎖必須是同一個(gè)客戶端矾芙,客戶端自己不能把別人加的鎖給解了。

業(yè)務(wù)執(zhí)行時(shí)間超過鎖的有效期時(shí)近上,如何有效進(jìn)行延遲鎖的有效期蠕啄。添加一個(gè)看門狗線程,進(jìn)行鎖有效期檢測(cè)

13、假如Redis里面有1億個(gè)key歼跟,其中有10w個(gè)key是以某個(gè)固定的已知的前綴開頭的和媳,如果將它們?nèi)空页? 來?

使用keys指令可以掃出指定模式的key列表:keys pre*

14哈街、如果這個(gè)redis正在給線上的業(yè)務(wù)提供服務(wù)留瞳,那使用keys指令會(huì)有什么問題?

這個(gè)時(shí)候你要回答redis關(guān)鍵的一個(gè)特性:redis的單線程的骚秦。keys指令會(huì)導(dǎo)致線程阻塞一段時(shí)間她倘,線上服務(wù)會(huì)停頓,直到指令執(zhí)行完畢作箍,服務(wù)才能恢復(fù)硬梁。

這個(gè)時(shí)候可以使用scan指令,scan指令可以無阻塞的提取出指定模式的key列表胞得,但是會(huì)有一定的重復(fù)概率荧止,在客戶端做一次去重就可以了,但是整體所花費(fèi)的時(shí)間會(huì)比直接用keys指令長阶剑。

15跃巡、 使用過Redis做異步隊(duì)列么,你是怎么用的牧愁?

一般使用list結(jié)構(gòu)作為隊(duì)列素邪,rpush生產(chǎn)消息,lpop消費(fèi)消息猪半。當(dāng)lpop沒有消息的時(shí)候兔朦,要適當(dāng)sleep一會(huì)再重試。

如果對(duì)方追問可不可以不用sleep呢磨确?list還有個(gè)指令叫blpop沽甥,在沒有消息的時(shí)候,它會(huì)阻塞住直到消息到來俐填。

如果對(duì)方追問能不能生產(chǎn)一次消費(fèi)多次呢安接?使用pub/sub主題訂閱者模式翔忽,可以實(shí)現(xiàn)1:N的消息隊(duì)列英融。

如果對(duì)方追問pub/sub有什么缺點(diǎn)?在消費(fèi)者下線的情況下歇式,生產(chǎn)的消息會(huì)丟失驶悟,得使用專業(yè)的消息隊(duì)列如rabbitmq等。redis中pub/sub缺陷

16材失、如果對(duì)方追問redis如何實(shí)現(xiàn)延時(shí)隊(duì)列痕鳍?

使用有序集合,拿時(shí)間戳作為score,消息內(nèi)容作為key調(diào)用zadd來生產(chǎn)消息笼呆,消費(fèi)者用zrangebyscore指令獲取N秒之前的數(shù)據(jù)輪詢進(jìn)行處理熊响。

66、如果有大量的key需要設(shè)置同一時(shí)間過期诗赌,一般需要注意什么

如果大量的key過期時(shí)間設(shè)置的過于集中汗茄,到過期的那個(gè)時(shí)間點(diǎn),redis可能會(huì)出現(xiàn)短暫的卡頓現(xiàn)象铭若。一般需要在時(shí)間上加一個(gè)隨機(jī)值洪碳,使得過期時(shí)間分散一些。

17叼屠、 Redis如何做持久化的瞳腌?

? RDB做鏡像全量持久化,AOF做增量持久化镜雨。

RDB持久化也分兩種:SAVE和BGSAVE嫂侍。

SAVE是阻塞式的RDB持久化,當(dāng)執(zhí)行這個(gè)命令時(shí)redis的主進(jìn)程把內(nèi)存里的數(shù)據(jù)庫狀態(tài)寫入到RDB文件中冷离,直到該文件創(chuàng)建完畢的這段時(shí)間內(nèi)redis將不能處理任何命令請(qǐng)求吵冒;1 BGSAVE屬于非阻塞式的持久化,它會(huì)創(chuàng)建一個(gè)子進(jìn)程專門去把內(nèi)存中的數(shù)據(jù)庫狀態(tài)寫入RDB文件里西剥,同時(shí)主進(jìn)程還可以處理來自客戶端的命令請(qǐng)求痹栖。

但子進(jìn)程基本是復(fù)制的父進(jìn)程,這等于兩個(gè)相同大小的redis進(jìn)程在系統(tǒng)上運(yùn)行瞭空,會(huì)造成內(nèi)存使用率的大幅增加揪阿。

? AOF的持久化是通過命令追加、文件寫入和文件同步三個(gè)步驟實(shí)現(xiàn)的咆畏。

當(dāng)reids開啟AOF后(redis備份方式默認(rèn)是RDB);

服務(wù)端每執(zhí)行一次寫操作(如set南捂、sadd、rpush)就會(huì)把該條命令追加到一個(gè)單獨(dú)的AOF緩沖區(qū)的末尾旧找,這就是命令追加溺健;

然后把AOF緩沖區(qū)的內(nèi)容寫入AOF文件里∨ブ耄看上去第二步就已經(jīng)完成AOF持久化了那第三步是干什么的呢鞭缭?這就需要從系統(tǒng)的文件寫入機(jī)制說起:一般我們現(xiàn)在所使用的操作系統(tǒng),為了提高文件的寫入效率魏颓,都會(huì)有一個(gè)寫入策略岭辣,即當(dāng)你往

硬盤寫入數(shù)據(jù)時(shí),操作系統(tǒng)不是實(shí)時(shí)的將數(shù)據(jù)寫入硬盤甸饱,而是先把數(shù)據(jù)暫時(shí)的保存在一個(gè)內(nèi)存緩沖區(qū)里念颈,等到這個(gè)內(nèi)存緩沖區(qū)的空間被填滿或者是超過了設(shè)定的時(shí)限后才會(huì)真正的把緩沖區(qū)內(nèi)的數(shù)據(jù)寫入硬盤中。也就是說當(dāng)redis進(jìn)行到第二

步文件寫入的時(shí)候涯捻,從用戶的角度看是已經(jīng)把AOF緩沖區(qū)里的數(shù)據(jù)寫入到AOF文件了皇忿,但對(duì)系統(tǒng)而言只不過是把AOF緩沖區(qū)的內(nèi)容放到了另一個(gè)內(nèi)存緩沖區(qū)里而已,之后redis還需要進(jìn)行文件同步把該內(nèi)存緩沖區(qū)里的數(shù)據(jù)真正寫入硬盤上

才算是完成了一次持久化。而何時(shí)進(jìn)行文件同步則是根據(jù)配置的appendfsync來進(jìn)行:appendfsync有三個(gè)選項(xiàng):always、everysec和no:

18、Pipeline有什么好處矗烛,為什么要用pipeline?

可以將多次IO往返的時(shí)間縮減為一次箩溃,前提是pipeline執(zhí)行的指令之間沒有因果相關(guān)性瞭吃。使用redis-benchmark進(jìn)行壓測(cè)的時(shí)候可以發(fā)現(xiàn)影響redis的QPS峰值的一個(gè)重要因素是pipeline批次指令的數(shù)目。

19涣旨、Redis的同步機(jī)制了解么歪架?

Redis可以使用主從同步,從從同步霹陡。第一次同步時(shí)和蚪,主節(jié)點(diǎn)做一次bgsave,并同時(shí)將后續(xù)修改操作記錄到內(nèi)存buffer烹棉,待完成后將rdb文件全量同步到復(fù)制節(jié)點(diǎn)攒霹,復(fù)制節(jié)點(diǎn)接受完成后將rdb鏡像加載到內(nèi)存。

加載完成后浆洗,再通知主節(jié)點(diǎn)將期間修改的操作記錄同步到復(fù)制節(jié)點(diǎn)進(jìn)行重放就完成了同步過程催束。

20、是否使用過Redis集群伏社,集群的原理是什么抠刺?

Redis Sentinal著眼于高可用,在master宕機(jī)時(shí)會(huì)自動(dòng)將slave提升為master摘昌,繼續(xù)提供服務(wù)速妖。

Redis Cluster著眼于擴(kuò)展性,在單個(gè)redis內(nèi)存不足時(shí)聪黎,使用Cluster進(jìn)行分片存儲(chǔ)罕容。

21、使用redis有哪些好處稿饰?

? 速度快锦秒,因?yàn)閿?shù)據(jù)存在內(nèi)存中,類似于HashMap湘纵,HashMap的優(yōu)勢(shì)就是查找和操作的時(shí)間復(fù)雜度都是O(1)

? 支持豐富數(shù)據(jù)類型脂崔,支持string滤淳,list梧喷,set,sorted set,hash

? 支持事務(wù)铺敌,操作都是原子性汇歹,所謂的原子性就是對(duì)數(shù)據(jù)的更改要么全部執(zhí)行,要么全部不執(zhí)行

? 豐富的特性:可用于緩存偿凭,消息产弹,按key設(shè)置過期時(shí)間,過期后將會(huì)自動(dòng)刪除

22弯囊、redis相比memcached有哪些優(yōu)勢(shì)痰哨?Memcache與Redis的區(qū)別都有哪些?

? 優(yōu)勢(shì)

memcached所有的值均是簡(jiǎn)單的字符串匾嘱,redis作為其替代者斤斧,支持更為豐富的數(shù)據(jù)類型

redis的速度比memcached快很多

redis可以持久化其數(shù)據(jù)

? 區(qū)別

存儲(chǔ)方式 Memecache把數(shù)據(jù)全部存在內(nèi)存之中,斷電后會(huì)掛掉霎烙,數(shù)據(jù)不能超過內(nèi)存大小撬讽。Redis有部份存在硬盤上,這樣能保證數(shù)據(jù)的持久性悬垃。

數(shù)據(jù)支持類型 Memcache對(duì)數(shù)據(jù)類型支持相對(duì)簡(jiǎn)單游昼。Redis有復(fù)雜的數(shù)據(jù)類型。

使用底層模型不同 它們之間底層實(shí)現(xiàn)方式 以及與客戶端之間通信的應(yīng)用協(xié)議不一樣尝蠕。Redis直接自己構(gòu)建了VM 機(jī)制 烘豌,因?yàn)橐话愕南到y(tǒng)調(diào)用系統(tǒng)函數(shù)的話,會(huì)浪費(fèi)一定的時(shí)間去移動(dòng)和請(qǐng)求看彼。

23扇谣、redis常見性能問題和解決方案:

Master寫內(nèi)存快照,save命令調(diào)度rdbSave函數(shù)闲昭,會(huì)阻塞主線程的工作罐寨,當(dāng)快照比較大時(shí)對(duì)性能影響是非常大的,會(huì)間斷性暫停服務(wù)序矩,所以Master最好不要寫內(nèi)存快照鸯绿。

Master AOF持久化,如果不重寫AOF文件簸淀,這個(gè)持久化方式對(duì)性能的影響是最小的瓶蝴,但是AOF文件會(huì)不斷增大,AOF文件過大會(huì)影響Master重啟的恢復(fù)速度租幕。

Master最好不要做任何持久化工作舷手,包括內(nèi)存快照和AOF日志文件,特別是不要啟用內(nèi)存快照做持久化,如果數(shù)據(jù)比較關(guān)鍵劲绪,某個(gè)Slave開啟AOF備份數(shù)據(jù)男窟,策略為每秒同步一次盆赤。

Master調(diào)用BGREWRITEAOF重寫AOF文件,AOF在重寫的時(shí)候會(huì)占大量的CPU和內(nèi)存資源歉眷,導(dǎo)致服務(wù)load過高牺六,出現(xiàn)短暫服務(wù)暫停現(xiàn)象汗捡。

Redis主從復(fù)制的性能問題淑际,為了主從復(fù)制的速度和連接的穩(wěn)定性,Slave和Master最好在同一個(gè)局域網(wǎng)內(nèi)

24扇住、為什么redis需要把所有數(shù)據(jù)放到內(nèi)存中?

Redis為了達(dá)到最快的讀寫速度將數(shù)據(jù)都讀到內(nèi)存中春缕,并通過異步的方式將數(shù)據(jù)寫入磁盤。所以redis具有快速和數(shù)據(jù)持久化的特征艘蹋。如果不將數(shù)據(jù)放在內(nèi)存中淡溯,磁盤I/O速度為嚴(yán)重影響redis的性能。

在內(nèi)存越來越便宜的今天簿训,redis將會(huì)越來越受歡迎咱娶。如果設(shè)置了最大使用的內(nèi)存,則數(shù)據(jù)已有記錄數(shù)達(dá)到內(nèi)存限值后不能繼續(xù)插入新值强品。

25膘侮、Redis是單進(jìn)程單線程的

redis利用隊(duì)列技術(shù)將并發(fā)訪問變?yōu)榇性L問,消除了傳統(tǒng)數(shù)據(jù)庫串行控制的開銷的榛。

26琼了、redis的并發(fā)競(jìng)爭(zhēng)問題如何解決?

Redis為單進(jìn)程單線程模式,采用隊(duì)列模式將并發(fā)訪問變?yōu)榇性L問夫晌。Redis本身沒有鎖的概念雕薪,Redis對(duì)于多個(gè)客戶端連接并不存在競(jìng)爭(zhēng),但是在Jedis客戶端對(duì)Redis進(jìn)行并發(fā)訪問時(shí)會(huì)發(fā)生連接超時(shí)晓淀、數(shù)據(jù)轉(zhuǎn)換錯(cuò)誤所袁、阻塞、客戶端關(guān)閉連接等問題凶掰,這些問題均是由于客戶端連接混亂造成燥爷。對(duì)此有2種解決方法:

? 客戶端角度,為保證每個(gè)客戶端間正常有序與Redis進(jìn)行通信懦窘,對(duì)連接進(jìn)行池化前翎,同時(shí)對(duì)客戶端讀寫Redis操作采用內(nèi)部鎖synchronized。

+服務(wù)器角度畅涂,利用setnx實(shí)現(xiàn)鎖港华。

注:對(duì)于第一種,需要應(yīng)用程序自己處理資源的同步午衰,可以使用的方法比較通俗立宜,可以使用synchronized也可以使用lock冒萄;第二種需要用到Redis的setnx命令,但是需要注意一些問題赘理。

27、redis事物的了解CAS(check-and-set 操作實(shí)現(xiàn)樂觀鎖 )?

和眾多其它數(shù)據(jù)庫一樣扇单,Redis作為NoSQL數(shù)據(jù)庫也同樣提供了事務(wù)機(jī)制商模。在Redis中,MULTI/EXEC/DISCARD/WATCH這四個(gè)命令是我們實(shí)現(xiàn)事務(wù)的基石蜘澜。相信對(duì)有關(guān)系型數(shù)據(jù)庫開發(fā)經(jīng)驗(yàn)的開發(fā)者而言這一概念并不陌生施流,即便如此,我們還是會(huì)簡(jiǎn)要的列出Redis中事務(wù)的實(shí)現(xiàn)特征:

? 在事務(wù)中的所有命令都將會(huì)被串行化的順序執(zhí)行鄙信,事務(wù)執(zhí)行期間瞪醋,Redis不會(huì)再為其它客戶端的請(qǐng)求提供任何服務(wù),從而保證了事物中的所有命令被原子的執(zhí)行装诡。

? 和關(guān)系型數(shù)據(jù)庫中的事務(wù)相比银受,在Redis事務(wù)中如果有某一條命令執(zhí)行失敗,其后的命令仍然會(huì)被繼續(xù)執(zhí)行鸦采。

? 可以通過MULTI命令開啟一個(gè)事務(wù)宾巍,有關(guān)系型數(shù)據(jù)庫開發(fā)經(jīng)驗(yàn)的人可以將其理解為"BEGIN TRANSACTION"語句。在該語句之后執(zhí)行的命令都將被視為事務(wù)之內(nèi)的操作渔伯,最后我們可以通過執(zhí)行

EXEC/DISCARD命令來提交/回滾該事務(wù)內(nèi)的所有操作顶霞。這兩個(gè)Redis命令可被視為等同于關(guān)系型數(shù)據(jù)庫中的COMMIT/ROLLBACK語句。

? 在事務(wù)開啟之前锣吼,如果客戶端與服務(wù)器之間出現(xiàn)通訊故障并導(dǎo)致網(wǎng)絡(luò)斷開选浑,其后所有待執(zhí)行的語句都將不會(huì)被服務(wù)器執(zhí)行。然而如果網(wǎng)絡(luò)中斷事件是發(fā)生在客戶端執(zhí)行EXEC命令之后玄叠,那么該事務(wù)中的所有命令都會(huì)被服務(wù)器執(zhí)行古徒。

? 當(dāng)使用Append-Only模式時(shí),Redis會(huì)通過調(diào)用系統(tǒng)函數(shù)write將該事務(wù)內(nèi)的所有寫操作在本次調(diào)用中全部寫入磁盤读恃。然而如果在寫入的過程中出現(xiàn)系統(tǒng)崩潰描函,如電源故障導(dǎo)致的宕機(jī),那么此時(shí)也許只有部分?jǐn)?shù)據(jù)被寫入到磁盤狐粱,

而另外一部分?jǐn)?shù)據(jù)卻已經(jīng)丟失舀寓。Redis服務(wù)器會(huì)在重新啟動(dòng)時(shí)執(zhí)行一系列必要的一致性檢測(cè),一旦發(fā)現(xiàn)類似問題肌蜻,就會(huì)立即退出并給出相應(yīng)的錯(cuò)誤提示互墓。此時(shí),我們就要充分利用Redis工具包中提供的redis-check-aof工具蒋搜,

該工具可以幫助我們定位到數(shù)據(jù)不一致的錯(cuò)誤篡撵,并將已經(jīng)寫入的部分?jǐn)?shù)據(jù)進(jìn)行回滾判莉。修復(fù)之后我們就可以再次重新啟動(dòng)Redis服務(wù)器了。

28育谬、 redis持久化的幾種方式

? 快照(snapshots)

缺省情況情況下券盅,Redis把數(shù)據(jù)快照存放在磁盤上的二進(jìn)制文件中,文件名為dump.rdb膛檀。你可以配置Redis的持久化策略锰镀,例如數(shù)據(jù)集中每N秒鐘有超過M次更新,就將數(shù)據(jù)寫入磁盤咖刃;或者你可以手工調(diào)用命令SAVE或BGSAVE泳炉。

工作原理:Redis forks. 子進(jìn)程開始將數(shù)據(jù)寫到臨時(shí)RDB文件中。當(dāng)子進(jìn)程完成寫RDB文件嚎杨,用新文件替換老文件花鹅。這種方式可以使Redis使用copy-on-write技術(shù)。

? AOF

快照模式并不健壯枫浙,當(dāng)系統(tǒng)停止刨肃,或者無意中Redis被kill掉,最后寫入Redis的數(shù)據(jù)就會(huì)丟失箩帚。這對(duì)某些應(yīng)用也許不是大問題之景,但對(duì)于要求高可靠性的應(yīng)用來說,Redis就不是一個(gè)合適的選擇膏潮。Append-only文件模式是另一種選擇锻狗。你可以在配置文件中打開AOF模式。

? 虛擬內(nèi)存方式

當(dāng)你的key很小而value很大時(shí),使用VM的效果會(huì)比較好.因?yàn)檫@樣節(jié)約的內(nèi)存比較大. 當(dāng)你的key不小時(shí),可以考慮使用一些非常方法將很大的key變成很大的value,比如你可以考慮將key,value組合成一個(gè)新的value. vm-max-threads這個(gè)參數(shù),可以設(shè)置訪問swap文件的線程數(shù),設(shè)置最好不要超過機(jī)器的核數(shù),如果設(shè)置為0,那么所有對(duì)swap文件的操作都是串行的.可能會(huì)造成比較長時(shí)間的延遲,但是對(duì)數(shù)據(jù)完整性有很好的保證.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末焕参,一起剝皮案震驚了整個(gè)濱河市轻纪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌叠纷,老刑警劉巖刻帚,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異涩嚣,居然都是意外死亡崇众,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門航厚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顷歌,“玉大人,你說我怎么就攤上這事幔睬∶袖觯” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赦抖。 經(jīng)常有香客問我舱卡,道長,這世上最難降的妖魔是什么队萤? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任轮锥,我火速辦了婚禮,結(jié)果婚禮上要尔,老公的妹妹穿的比我還像新娘舍杜。我一直安慰自己,他們只是感情好盈电,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布蝴簇。 她就那樣靜靜地躺著杯活,像睡著了一般匆帚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上旁钧,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天吸重,我揣著相機(jī)與錄音,去河邊找鬼歪今。 笑死嚎幸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的寄猩。 我是一名探鬼主播嫉晶,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼田篇!你這毒婦竟也來了替废?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤泊柬,失蹤者是張志新(化名)和其女友劉穎椎镣,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體兽赁,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡状答,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了刀崖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惊科。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖亮钦,靈堂內(nèi)的尸體忽然破棺而出译断,到底是詐尸還是另有隱情,我是刑警寧澤或悲,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布孙咪,位于F島的核電站堪唐,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏翎蹈。R本人自食惡果不足惜淮菠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荤堪。 院中可真熱鬧合陵,春花似錦、人聲如沸澄阳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碎赢。三九已至低剔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肮塞,已是汗流浹背襟齿。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枕赵,地道東北人猜欺。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像拷窜,于是被迫代替她去往敵國和親开皿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355