Redis面試題總結(jié)

redis 簡介

簡單來說 redis 就是一個數(shù)據(jù)庫,不過與傳統(tǒng)數(shù)據(jù)庫不同的是 redis 的數(shù)據(jù)是存在內(nèi)存中的,所以存寫速度非常快,因此 redis 被廣泛應(yīng)用于緩存方向。另外,redis 也經(jīng)常用來做分布式鎖。redis 提供了多種數(shù)據(jù)類型來支持不同的業(yè)務(wù)場景。除此之外,redis 支持事務(wù) 、持久化、LUA腳本、LRU驅(qū)動事件、多種集群方案。

為什么要用 redis /為什么要用緩存

主要從“高性能”和“高并發(fā)”這兩點(diǎn)來看待這個問題。

高性能:

假如用戶第一次訪問數(shù)據(jù)庫中的某些數(shù)據(jù)。這個過程會比較慢,因?yàn)槭菑挠脖P上讀取的。將該用戶訪問的數(shù)據(jù)存在數(shù)緩存中,這樣下一次再訪問這些數(shù)據(jù)的時候就可以直接從緩存中獲取了。操作緩存就是直接操作內(nèi)存,所以速度相當(dāng)快。如果數(shù)據(jù)庫中的對應(yīng)數(shù)據(jù)改變的之后,同步改變緩存中相應(yīng)的數(shù)據(jù)即可!

image

高并發(fā):

直接操作緩存能夠承受的請求是遠(yuǎn)遠(yuǎn)大于直接訪問數(shù)據(jù)庫的,所以我們可以考慮把數(shù)據(jù)庫中的部分?jǐn)?shù)據(jù)轉(zhuǎn)移到緩存中去,這樣用戶的一部分請求會直接到緩存這里而不用經(jīng)過數(shù)據(jù)庫。

image

為什么要用 redis 而不用 map/guava 做緩存?

緩存分為本地緩存和分布式緩存。以 Java 為例,使用自帶的 map 或者 guava 實(shí)現(xiàn)的是本地緩存,最主要的特點(diǎn)是輕量以及快速,生命周期隨著 jvm 的銷毀而結(jié)束,并且在多實(shí)例的情況下,每個實(shí)例都需要各自保存一份緩存,緩存不具有一致性。

使用 redis 或 memcached 之類的稱為分布式緩存,在多實(shí)例的情況下,各實(shí)例共用一份緩存數(shù)據(jù),緩存具有一致性。缺點(diǎn)是需要保持 redis 或 memcached服務(wù)的高可用,整個程序架構(gòu)上較為復(fù)雜。

redis 和 memcached 的區(qū)別

對于 redis 和 memcached 的區(qū)別有下面四點(diǎn)。

  1. redis支持更豐富的數(shù)據(jù)類型(支持更復(fù)雜的應(yīng)用場景):Redis不僅僅支持簡單的k/v類型的數(shù)據(jù),同時還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲。memcache支持簡單的數(shù)據(jù)類型,String。
  2. Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤中,重啟的時候可以再次加載進(jìn)行使用,而Memecache把數(shù)據(jù)全部存在內(nèi)存之中。
  3. 集群模式:memcached沒有原生的集群模式,需要依靠客戶端來實(shí)現(xiàn)往集群中分片寫入數(shù)據(jù);但是 redis 目前是原生支持 cluster 模式的.
  4. Memcached是多線程,非阻塞IO復(fù)用的網(wǎng)絡(luò)模型;Redis使用單線程的多路 IO 復(fù)用模型。
redis 和 memcached 的區(qū)別

redis 常見數(shù)據(jù)結(jié)構(gòu)以及使用場景分析

1. String

常用命令: set,get,decr,incr,mget 等。

String數(shù)據(jù)結(jié)構(gòu)是簡單的key-value類型,value其實(shí)不僅可以是String,也可以是數(shù)字。 常規(guī)key-value緩存應(yīng)用; 常規(guī)計數(shù):微博數(shù),粉絲數(shù)等。

2.Hash

常用命令: hget,hset,hgetall 等。

Hash 是一個 string 類型的 field 和 value 的映射表,hash 特別適合用于存儲對象,后續(xù)操作的時候,你可以直接僅僅修改這個對象中的某個字段的值。 比如我們可以Hash數(shù)據(jù)結(jié)構(gòu)來存儲用戶信息,商品信息等等。比如下面我就用 hash 類型存放了我本人的一些信息:

key=JavaUser293847
value={
  “id”: 1,
  “name”: “SnailClimb”,
  “age”: 22,
  “l(fā)ocation”: “Wuhan, Hubei”
}

3.List

常用命令: lpush,rpush,lpop,rpop,lrange等

list 就是鏈表,Redis list 的應(yīng)用場景非常多,也是Redis最重要的數(shù)據(jù)結(jié)構(gòu)之一,比如微博的關(guān)注列表,粉絲列表,消息列表等功能都可以用Redis的 list 結(jié)構(gòu)來實(shí)現(xiàn)。

Redis list 的實(shí)現(xiàn)為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內(nèi)存開銷。

另外可以通過 lrange 命令,就是從某個元素開始讀取多少個元素,可以基于 list 實(shí)現(xiàn)分頁查詢,這個很棒的一個功能,基于 redis 實(shí)現(xiàn)簡單的高性能分頁,可以做類似微博那種下拉不斷分頁的東西(一頁一頁的往下走),性能高。

4.Set

常用命令: sadd,spop,smembers,sunion 等

set 對外提供的功能與list類似是一個列表的功能,特殊之處在于 set 是可以自動排重的。

當(dāng)你需要存儲一個列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時,set是一個很好的選擇,并且set提供了判斷某個成員是否在一個set集合內(nèi)的重要接口,這個也是list所不能提供的。可以基于 set 輕易實(shí)現(xiàn)交集、并集、差集的操作。

比如:在微博應(yīng)用中,可以將一個用戶所有的關(guān)注人存在一個集合中,將其所有粉絲存在一個集合。Redis可以非常方便的實(shí)現(xiàn)如共同關(guān)注、共同粉絲、共同喜好等功能。這個過程也就是求交集的過程,具體命令如下:

sinterstore key1 key2 key3     將交集存在key1內(nèi)

5.Sorted Set

常用命令: zadd,zrange,zrem,zcard等

和set相比,sorted set增加了一個權(quán)重參數(shù)score,使得集合中的元素能夠按score進(jìn)行有序排列。

舉例: 在直播系統(tǒng)中,實(shí)時排行信息包含直播間在線用戶列表,各種禮物排行榜,彈幕消息(可以理解為按消息維度的消息排行榜)等信息,適合使用 Redis 中的 SortedSet 結(jié)構(gòu)進(jìn)行存儲。

redis 設(shè)置過期時間

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

我們 set key 的時候,都可以給一個 expire time,就是過期時間,通過過期時間我們可以指定這個 key 可以存活的時間。

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

定期刪除+惰性刪除。

通過名字大概就能猜出這兩個刪除方式的意思了。

  • 定期刪除:redis默認(rèn)是每隔 100ms 就隨機(jī)抽取一些設(shè)置了過期時間的key,檢查其是否過期,如果過期就刪除。注意這里是隨機(jī)抽取的。為什么要隨機(jī)呢?你想一想假如 redis 存了幾十萬個 key ,每隔100ms就遍歷所有的設(shè)置過期時間的 key 的話,就會給 CPU 帶來很大的負(fù)載!
  • 惰性刪除 :定期刪除可能會導(dǎo)致很多過期 key 到了時間并沒有被刪除掉。所以就有了惰性刪除。假如你的過期 key,靠定期刪除沒有被刪除掉,還停留在內(nèi)存里,除非你的系統(tǒng)去查一下那個 key,才會被redis給刪除掉。這就是所謂的惰性刪除,也是夠懶的哈!

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

redis 內(nèi)存淘汰機(jī)制。

redis 內(nèi)存淘汰機(jī)制(MySQL里有2000w數(shù)據(jù),Redis中只存20w的數(shù)據(jù),如何保證Redis中的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)?)

redis 配置文件 redis.conf 中有相關(guān)注釋,大家可以自行查閱或者通過這個網(wǎng)址查看: http://download.redis.io/redis-stable/redis.conf

redis 提供 6種數(shù)據(jù)淘汰策略:

  1. volatile-lru:從已設(shè)置過期時間的數(shù)據(jù)集(server.db[i].expires)中挑選最近最少使用的數(shù)據(jù)淘汰
  2. volatile-ttl:從已設(shè)置過期時間的數(shù)據(jù)集(server.db[i].expires)中挑選將要過期的數(shù)據(jù)淘汰
  3. volatile-random:從已設(shè)置過期時間的數(shù)據(jù)集(server.db[i].expires)中任意選擇數(shù)據(jù)淘汰
  4. allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時,在鍵空間中,移除最近最少使用的key(這個是最常用的).
  5. allkeys-random:從數(shù)據(jù)集(server.db[i].dict)中任意選擇數(shù)據(jù)淘汰
  6. no-eviction:禁止驅(qū)逐數(shù)據(jù),也就是說當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時,新寫入操作會報錯。這個應(yīng)該沒人使用吧!

備注: 關(guān)于 redis 設(shè)置過期時間以及內(nèi)存淘汰機(jī)制,我這里只是簡單的總結(jié)一下,后面會專門寫一篇文章來總結(jié)!

redis 持久化機(jī)制(怎么保證 redis 掛掉之后再重啟數(shù)據(jù)可以進(jìn)行恢復(fù))

很多時候我們需要持久化數(shù)據(jù)也就是將內(nèi)存中的數(shù)據(jù)寫入到硬盤里面,大部分原因是為了之后重用數(shù)據(jù)(比如重啟機(jī)器、機(jī)器故障之后回復(fù)數(shù)據(jù)),或者是為了防止系統(tǒng)故障而將數(shù)據(jù)備份到一個遠(yuǎn)程位置。

Redis不同于Memcached的很重一點(diǎn)就是,Redis支持持久化,而且支持兩種不同的持久化操作。Redis的一種持久化方式叫快照(snapshotting,RDB),另一種方式是只追加文件(append-only file,AOF).這兩種方法各有千秋,下面我會詳細(xì)這兩種持久化方法是什么,怎么用,如何選擇適合自己的持久化方法。

快照(snapshotting)持久化(RDB)

Redis可以通過創(chuàng)建快照來獲得存儲在內(nèi)存里面的數(shù)據(jù)在某個時間點(diǎn)上的副本。Redis創(chuàng)建快照之后,可以對快照進(jìn)行備份,可以將快照復(fù)制到其他服務(wù)器從而創(chuàng)建具有相同數(shù)據(jù)的服務(wù)器副本(Redis主從結(jié)構(gòu),主要用來提高Redis性能),還可以將快照留在原地以便重啟服務(wù)器的時候使用。

快照持久化是Redis默認(rèn)采用的持久化方式,在redis.conf配置文件中默認(rèn)有此下配置:

save 900 1              #在900秒(15分鐘)之后,如果至少有1個key發(fā)生變化,Redis就會自動觸發(fā)BGSAVE命令創(chuàng)建快照。

save 300 10            #在300秒(5分鐘)之后,如果至少有10個key發(fā)生變化,Redis就會自動觸發(fā)BGSAVE命令創(chuàng)建快照。

save 60 10000        #在60秒(1分鐘)之后,如果至少有10000個key發(fā)生變化,Redis就會自動觸發(fā)BGSAVE命令創(chuàng)建快照。

AOF(append-only file)持久化

與快照持久化相比,AOF持久化 的實(shí)時性更好,因此已成為主流的持久化方案。默認(rèn)情況下Redis沒有開啟AOF(append only file)方式的持久化,可以通過appendonly參數(shù)開啟:

appendonly yes

開啟AOF持久化后每執(zhí)行一條會更改Redis中的數(shù)據(jù)的命令,Redis就會將該命令寫入硬盤中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通過dir參數(shù)設(shè)置的,默認(rèn)的文件名是appendonly.aof。

在Redis的配置文件中存在三種不同的 AOF 持久化方式,它們分別是:

appendfsync always     #每次有數(shù)據(jù)修改發(fā)生時都會寫入AOF文件,這樣會嚴(yán)重降低Redis的速度
appendfsync everysec  #每秒鐘同步一次,顯示地將多個寫命令同步到硬盤
appendfsync no      #讓操作系統(tǒng)決定何時進(jìn)行同步

為了兼顧數(shù)據(jù)和寫入性能,用戶可以考慮 appendfsync everysec選項 ,讓Redis每秒同步一次AOF文件,Redis性能幾乎沒受到任何影響。而且這樣即使出現(xiàn)系統(tǒng)崩潰,用戶最多只會丟失一秒之內(nèi)產(chǎn)生的數(shù)據(jù)。當(dāng)硬盤忙于執(zhí)行寫入操作的時候,Redis還會優(yōu)雅的放慢自己的速度以便適應(yīng)硬盤的最大寫入速度。

Redis 4.0 對于持久化機(jī)制的優(yōu)化

Redis 4.0 開始支持 RDB 和 AOF 的混合持久化(默認(rèn)關(guān)閉,可以通過配置項 aof-use-rdb-preamble 開啟)。

如果把混合持久化打開,AOF 重寫的時候就直接把 RDB 的內(nèi)容寫到 AOF 文件開頭。這樣做的好處是可以結(jié)合 RDB 和 AOF 的優(yōu)點(diǎn), 快速加載同時避免丟失過多的數(shù)據(jù)。當(dāng)然缺點(diǎn)也是有的, AOF 里面的 RDB 部分是壓縮格式不再是 AOF 格式,可讀性較差。

補(bǔ)充內(nèi)容:AOF 重寫

AOF重寫可以產(chǎn)生一個新的AOF文件,這個新的AOF文件和原有的AOF文件所保存的數(shù)據(jù)庫狀態(tài)一樣,但體積更小。

AOF重寫是一個有歧義的名字,該功能是通過讀取數(shù)據(jù)庫中的鍵值對來實(shí)現(xiàn)的,程序無須對現(xiàn)有AOF文件進(jìn)行任伺讀入、分析或者寫入操作。

在執(zhí)行 BGREWRITEAOF 命令時,Redis 服務(wù)器會維護(hù)一個 AOF 重寫緩沖區(qū),該緩沖區(qū)會在子進(jìn)程創(chuàng)建新AOF文件期間,記錄服務(wù)器執(zhí)行的所有寫命令。當(dāng)子進(jìn)程完成創(chuàng)建新AOF文件的工作之后,服務(wù)器會將重寫緩沖區(qū)中的所有內(nèi)容追加到新AOF文件的末尾,使得新舊兩個AOF文件所保存的數(shù)據(jù)庫狀態(tài)一致。最后,服務(wù)器用新的AOF文件替換舊的AOF文件,以此來完成AOF文件重寫操作

redis 事務(wù)

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

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

緩存雪崩和緩存穿透問題解決方案

緩存雪崩

簡介:緩存同一時間大面積的失效,所以,后面的請求都會落到數(shù)據(jù)庫上,造成數(shù)據(jù)庫短時間內(nèi)承受大量請求而崩掉。

解決辦法:

  • 事前:盡量保證整個 redis 集群的高可用性,發(fā)現(xiàn)機(jī)器宕機(jī)盡快補(bǔ)上。選擇合適的內(nèi)存淘汰策略。
  • 事中:本地ehcache緩存 + hystrix限流&降級,避免MySQL崩掉
  • 事后:利用 redis 持久化機(jī)制保存的數(shù)據(jù)盡快恢復(fù)緩存
image

緩存穿透

簡介:一般是黑客故意去請求緩存中不存在的數(shù)據(jù),導(dǎo)致所有的請求都落到數(shù)據(jù)庫上,造成數(shù)據(jù)庫短時間內(nèi)承受大量請求而崩掉。

解決辦法: 有很多種方法可以有效地解決緩存穿透問題,最常見的則是采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個足夠大的bitmap中,一個一定不存在的數(shù)據(jù)會被 這個bitmap攔截掉,從而避免了對底層存儲系統(tǒng)的查詢壓力。另外也有一個更為簡單粗暴的方法(我們采用的就是這種),如果一個查詢返回的數(shù)據(jù)為空(不管是數(shù) 據(jù)不存在,還是系統(tǒng)故障),我們?nèi)匀话堰@個空結(jié)果進(jìn)行緩存,但它的過期時間會很短,最長不超過五分鐘。

如何解決 Redis 的并發(fā)競爭 Key 問題

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

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

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

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

參考:

如何保證緩存與數(shù)據(jù)庫雙寫時的數(shù)據(jù)一致性?

你只要用緩存,就可能會涉及到緩存與數(shù)據(jù)庫雙存儲雙寫,你只要是雙寫,就一定會有數(shù)據(jù)一致性的問題,那么你如何解決一致性問題?

一般來說,就是如果你的系統(tǒng)不是嚴(yán)格要求緩存+數(shù)據(jù)庫必須一致性的話,緩存可以稍微的跟數(shù)據(jù)庫偶爾有不一致的情況,最好不要做這個方案,讀請求和寫請求串行化,串到一個內(nèi)存隊列里去,這樣就可以保證一定不會出現(xiàn)不一致的情況

串行化之后,就會導(dǎo)致系統(tǒng)的吞吐量會大幅度的降低,用比正常情況下多幾倍的機(jī)器去支撐線上的一個請求。

還有一種方式就是可能會暫時產(chǎn)生不一致的情況,但是發(fā)生的幾率特別小,就是先更新數(shù)據(jù)庫,然后再刪除緩存。

這種情況不存在并發(fā)問題么?

不是的。假設(shè)這會有兩個請求,一個請求A做查詢操作,一個請求B做更新操作,那么會有如下情形產(chǎn)生

(1)緩存剛好失效
(2)請求A查詢數(shù)據(jù)庫,得一個舊值
(3)請求B將新值寫入數(shù)據(jù)庫
(4)請求B刪除緩存
(5)請求A將查到的舊值寫入緩存

ok,如果發(fā)生上述情況,確實(shí)是會發(fā)生臟數(shù)據(jù)。

然而,發(fā)生這種情況的概率又有多少呢?

發(fā)生上述情況有一個先天性條件,就是步驟(3)的寫數(shù)據(jù)庫操作比步驟(2)的讀數(shù)據(jù)庫操作耗時更短,才有可能使得步驟(4)先于步驟(5)。可是,大家想想,數(shù)據(jù)庫的讀操作的速度遠(yuǎn)快于寫操作的(不然做讀寫分離干嘛,做讀寫分離的意義就是因?yàn)樽x操作比較快,耗資源少),因此步驟(3)耗時比步驟(2)更短,這一情形很難出現(xiàn)。

如何解決上述并發(fā)問題?

首先,給緩存設(shè)有效時間是一種方案。其次,采用異步延時刪除策略,保證讀請求完成以后,再進(jìn)行刪除操作。

參考:http://www.lxweimin.com/p/ca92e6588662

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,991評論 2 374