mysql分庫(kù)分表相關(guān)問(wèn)題

垂直分表與水平分庫(kù)

垂直拆分的意思簸淀,就是把一個(gè)有很多字段的表給拆分成多個(gè)表,或者是多個(gè)庫(kù)上去毒返。每個(gè)庫(kù)表的結(jié)構(gòu)都不一樣租幕,每個(gè)庫(kù)表都包含部分字段。一般來(lái)說(shuō)拧簸,會(huì)將較少的訪問(wèn)頻率很高的字段放到一個(gè)表里去劲绪,然后將較多的訪問(wèn)頻率很低的字段放到另外一個(gè)表里去。因?yàn)閿?shù)據(jù)庫(kù)是有緩存的,你訪問(wèn)頻率高的行字段越少贾富,就可以在緩存里緩存更多的行歉眷,性能就越好。這個(gè)一般在表結(jié)構(gòu)設(shè)計(jì)的時(shí)候做的較多一些颤枪。

image.png

水平拆分的意思汗捡,就是把一個(gè)表的數(shù)據(jù)給弄到多個(gè)庫(kù)的多個(gè)表里去,但是每個(gè)庫(kù)的表結(jié)構(gòu)都一樣畏纲,只不過(guò)每個(gè)庫(kù)表放的數(shù)據(jù)是不同的扇住,所有庫(kù)表的數(shù)據(jù)加起來(lái)就是全部數(shù)據(jù)。水平拆分的意義霍骄,就是將數(shù)據(jù)均勻放更多的庫(kù)里台囱,然后用多個(gè)庫(kù)來(lái)扛更高的并發(fā),還有就是用多個(gè)庫(kù)的存儲(chǔ)容量來(lái)進(jìn)行擴(kuò)容读整。一般講的分庫(kù)分表就是指水平拆分的意思簿训。
image.png

兩種分庫(kù)分表方式

  • 1 按照 range 來(lái)分。
    就是每個(gè)庫(kù)一段連續(xù)的數(shù)據(jù)米间,這個(gè)一般是按比如時(shí)間范圍來(lái)的强品,但是這種一般較少用,因?yàn)楹苋菀桩a(chǎn)生熱點(diǎn)問(wèn)題屈糊,大量的流量都打在最新的數(shù)據(jù)上了的榛。range 來(lái)分,好處在于說(shuō)逻锐,擴(kuò)容的時(shí)候很簡(jiǎn)單夫晌,因?yàn)槟阒灰A(yù)備好,給每個(gè)月都準(zhǔn)備一個(gè)庫(kù)就可以了昧诱,到了一個(gè)新的月份的時(shí)候晓淀,自然而然,就會(huì)寫(xiě)新的庫(kù)了盏档;缺點(diǎn)凶掰,但是大部分的請(qǐng)求,都是訪問(wèn)最新的數(shù)據(jù)蜈亩。實(shí)際生產(chǎn)用 range懦窘,要看場(chǎng)景。
  • 2 按照某個(gè)字段 hash 一下均勻分散稚配,這個(gè)較為常用畅涂。
    hash 分發(fā),好處在于說(shuō)道川,可以平均分配每個(gè)庫(kù)的數(shù)據(jù)量和請(qǐng)求壓力午衰;壞處在于說(shuō)擴(kuò)容起來(lái)比較麻煩苹丸,會(huì)有一個(gè)數(shù)據(jù)遷移的過(guò)程,之前的數(shù)據(jù)需要重新計(jì)算 hash 值重新分配到不同的庫(kù)或表苇经。
數(shù)據(jù)遷移(單庫(kù)環(huán)境數(shù)據(jù)到分科分表環(huán)境數(shù)據(jù))

1 最土的方法就是直接晚上網(wǎng)站停機(jī),然后程序員通宵把數(shù)據(jù)遷移到新的庫(kù)里面去宦言,這也是最土的方法扇单,假設(shè)當(dāng)晚沒(méi)有遷移成功,那就得代碼回滾奠旺,第二天接著停機(jī) 再遷移數(shù)據(jù)
2 雙寫(xiě)方案
簡(jiǎn)單來(lái)說(shuō)蜘澜,就是在線上系統(tǒng)里面,之前所有寫(xiě)庫(kù)的地方响疚,增刪改操作鄙信,除了對(duì)老庫(kù)增刪改,都加上對(duì)新庫(kù)的增刪改忿晕,這就是所謂的雙寫(xiě)装诡,同時(shí)寫(xiě)倆庫(kù),老庫(kù)和新庫(kù)践盼。

然后系統(tǒng)部署之后鸦采,新庫(kù)數(shù)據(jù)差太遠(yuǎn),用之前說(shuō)的導(dǎo)數(shù)工具咕幻,跑起來(lái)讀老庫(kù)數(shù)據(jù)寫(xiě)新庫(kù)渔伯,寫(xiě)的時(shí)候要根據(jù)數(shù)據(jù)的最后修改的時(shí)間,將剩余的老數(shù)據(jù)遷入到新庫(kù)中(新庫(kù)中有數(shù)據(jù)就更新肄程,沒(méi)有就插入) 锣吼,這樣就不用通宵遷移數(shù)據(jù)了。

生成全局唯一id
  • 1 數(shù)據(jù)庫(kù)自增 id
    這個(gè)就是說(shuō)你的系統(tǒng)里每次得到一個(gè) id蓝厌,都是往一個(gè)庫(kù)的一個(gè)表里插入一條沒(méi)什么業(yè)務(wù)含義的數(shù)據(jù)玄叠,然后獲取一個(gè)數(shù)據(jù)庫(kù)自增的一個(gè) id。拿到這個(gè) id 之后再往對(duì)應(yīng)的分庫(kù)分表里去寫(xiě)入褂始。

這個(gè)方案的好處就是方便簡(jiǎn)單诸典,誰(shuí)都會(huì)用;缺點(diǎn)就是單庫(kù)生成自增 id崎苗,要是高并發(fā)的話(huà)狐粱,就會(huì)有瓶頸的;如果你硬是要改進(jìn)一下胆数,那么就專(zhuān)門(mén)開(kāi)一個(gè)服務(wù)出來(lái)肌蜻,這個(gè)服務(wù)每次就拿到當(dāng)前 id 最大值,然后自己遞增幾個(gè) id必尼,一次性返回一批 id蒋搜,然后再把當(dāng)前最大 id 值修改成遞增幾個(gè) id 之后的一個(gè)值篡撵;但是無(wú)論如何都是基于單個(gè)數(shù)據(jù)庫(kù)。(都到了分庫(kù)分表層面了豆挽,數(shù)據(jù)庫(kù)讀寫(xiě)壓力應(yīng)該蠻大的育谬,所以這個(gè)方案應(yīng)該不會(huì)使用)

  • 2 設(shè)置數(shù)據(jù)庫(kù) sequence 或者表自增字段步長(zhǎng)


    image.png

適合的場(chǎng)景:在用戶(hù)防止產(chǎn)生的 ID 重復(fù)時(shí),這種方案實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單帮哈,也能達(dá)到性能目標(biāo)膛檀。但是服務(wù)節(jié)點(diǎn)固定,步長(zhǎng)也固定娘侍,將來(lái)如果還要增加服務(wù)節(jié)點(diǎn)咖刃,就不好搞了。

  • 3 UUID
    好處就是本地生成憾筏,不要基于數(shù)據(jù)庫(kù)來(lái)了嚎杨;不好之處就是,UUID 太長(zhǎng)了氧腰、占用空間大枫浙,作為主鍵性能太差了;更重要的是古拴,UUID 不具有有序性自脯,會(huì)導(dǎo)致 B+ 樹(shù)索引在寫(xiě)的時(shí)候有過(guò)多的隨機(jī)寫(xiě)操作(連續(xù)的 ID 可以產(chǎn)生部分順序?qū)懀€有斤富,由于在寫(xiě)的時(shí)候不能產(chǎn)生有順序的 append 操作膏潮,而需要進(jìn)行 insert 操作,將會(huì)讀取整個(gè) B+ 樹(shù)節(jié)點(diǎn)到內(nèi)存满力,在插入這條記錄后會(huì)將整個(gè)節(jié)點(diǎn)寫(xiě)回磁盤(pán)焕参,這種操作在記錄占用空間比較大的情況下,性能下降明顯油额。

  • 4 系統(tǒng)當(dāng)前時(shí)間
    這個(gè)就是獲取當(dāng)前時(shí)間即可叠纷,但是問(wèn)題是,并發(fā)很高的時(shí)候潦嘶,比如一秒并發(fā)幾千涩嚣,會(huì)有重復(fù)的情況,這個(gè)是肯定不合適的掂僵『胶瘢基本就不用考慮了。

適合的場(chǎng)景:一般如果用這個(gè)方案锰蓬,是將當(dāng)前時(shí)間跟很多其他的業(yè)務(wù)字段拼接起來(lái)幔睬,作為一個(gè) id,如果業(yè)務(wù)上你覺(jué)得可以接受芹扭,那么也是可以的麻顶。你可以將別的業(yè)務(wù)字段值跟當(dāng)前時(shí)間拼接起來(lái)赦抖,組成一個(gè)全局唯一的編號(hào)。

  • 5 snowflake 算法

  • 1 bit:第一個(gè)數(shù)字表示正負(fù)位辅肾,0正1負(fù)队萤,因?yàn)樯傻挠肋h(yuǎn)是一個(gè)正常,這里這里永遠(yuǎn)是0矫钓。

  • 41 bit:這個(gè)41位數(shù)字是當(dāng)前時(shí)間戳做一些計(jì)算浮禾,然后以41位的二進(jìn)制來(lái)表示。

  • 5 bit:這5位表示機(jī)房id份汗,總共可以有32位機(jī)房。

  • 5 bit:這5位表示機(jī)機(jī)器id蝴簇,每個(gè)機(jī)房可以擁有最多32個(gè)機(jī)器杯活。
    12 bit:這個(gè)是用來(lái)記錄同一個(gè)毫秒內(nèi)產(chǎn)生的不同 id,12 bit 可以代表的最大正整數(shù)是 2^12 - 1 = 4096熬词,也就是說(shuō)可以用這個(gè) 12 bit 代表的數(shù)字來(lái)區(qū)分同一個(gè)毫秒內(nèi)的 4096 個(gè)不同的 id旁钧。
    0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000

public class IdWorker {

    private long workerId;
    private long datacenterId;
    private long sequence;

    public IdWorker(long workerId, long datacenterId, long sequence) {
        // sanity check for workerId
        // 這兒不就檢查了一下,要求就是你傳遞進(jìn)來(lái)的機(jī)房id和機(jī)器id不能超過(guò)32互拾,不能小于0
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(
                    String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
        }
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException(
                    String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
        }
        System.out.printf(
                "worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d",
                timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId);

        this.workerId = workerId;
        this.datacenterId = datacenterId;
        this.sequence = sequence;
    }

    private long twepoch = 1288834974657L;

    private long workerIdBits = 5L;
    private long datacenterIdBits = 5L;

    // 這個(gè)是二進(jìn)制運(yùn)算歪今,就是 5 bit最多只能有31個(gè)數(shù)字,也就是說(shuō)機(jī)器id最多只能是32以?xún)?nèi)
    private long maxWorkerId = -1L ^ (-1L << workerIdBits);

    // 這個(gè)是一個(gè)意思颜矿,就是 5 bit最多只能有31個(gè)數(shù)字寄猩,機(jī)房id最多只能是32以?xún)?nèi)
    private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
    private long sequenceBits = 12L;

    private long workerIdShift = sequenceBits;
    private long datacenterIdShift = sequenceBits + workerIdBits;
    private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
    private long sequenceMask = -1L ^ (-1L << sequenceBits);

    private long lastTimestamp = -1L;

    public long getWorkerId() {
        return workerId;
    }

    public long getDatacenterId() {
        return datacenterId;
    }

    public long getTimestamp() {
        return System.currentTimeMillis();
    }

    public synchronized long nextId() {
        // 這兒就是獲取當(dāng)前時(shí)間戳,單位是毫秒
        long timestamp = timeGen();

        if (timestamp < lastTimestamp) {
            System.err.printf("clock is moving backwards.  Rejecting requests until %d.", lastTimestamp);
            throw new RuntimeException(String.format(
                    "Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
        }

        if (lastTimestamp == timestamp) {
            // 這個(gè)意思是說(shuō)一個(gè)毫秒內(nèi)最多只能有4096個(gè)數(shù)字
            // 無(wú)論你傳遞多少進(jìn)來(lái)骑疆,這個(gè)位運(yùn)算保證始終就是在4096這個(gè)范圍內(nèi)田篇,避免你自己傳遞個(gè)sequence超過(guò)了4096這個(gè)范圍
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0;
        }

        // 這兒記錄一下最近一次生成id的時(shí)間戳,單位是毫秒
        lastTimestamp = timestamp;

        // 這兒就是將時(shí)間戳左移箍铭,放到 41 bit那兒泊柬;
        // 將機(jī)房 id左移放到 5 bit那兒;
        // 將機(jī)器id左移放到5 bit那兒诈火;將序號(hào)放最后12 bit兽赁;
        // 最后拼接起來(lái)成一個(gè) 64 bit的二進(jìn)制數(shù)字,轉(zhuǎn)換成 10 進(jìn)制就是個(gè) long 型
        return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift)
                | (workerId << workerIdShift) | sequence;
    }

    private long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    private long timeGen() {
        return System.currentTimeMillis();
    }

    // ---------------測(cè)試---------------
    public static void main(String[] args) {
        // 最多32個(gè)機(jī)房冷守,每個(gè)機(jī)房最多32個(gè)機(jī)器
        IdWorker worker = new IdWorker(1, 1, 1);
        long s = System.currentTimeMillis();
        //100萬(wàn)個(gè)id只需要3秒生成
        for (int i = 0; i < 1000000 ; i++) {
            System.out.println(worker.nextId());
        }
        long e = System.currentTimeMillis();
        System.out.println(e-s);
    }
}

怎么說(shuō)呢刀崖,大概這個(gè)意思吧,就是說(shuō) 41 bit 是當(dāng)前毫秒單位的一個(gè)時(shí)間戳拍摇,就這意思蒲跨;然后 5 bit 是你傳遞進(jìn)來(lái)的一個(gè)機(jī)房 id(但是最大只能是 32 以?xún)?nèi)),另外 5 bit 是你傳遞進(jìn)來(lái)的機(jī)器 id(但是最大只能是 32 以?xún)?nèi))授翻,剩下的那個(gè) 12 bit序列號(hào)或悲,就是如果跟你上次生成 id 的時(shí)間還在一個(gè)毫秒內(nèi)孙咪,那么會(huì)把順序給你累加,最多在 4096 個(gè)序號(hào)以?xún)?nèi)巡语。

所以你自己利用這個(gè)工具類(lèi)翎蹈,自己搞一個(gè)服務(wù),然后對(duì)每個(gè)機(jī)房的每個(gè)機(jī)器都初始化這么一個(gè)東西男公,剛開(kāi)始這個(gè)機(jī)房的這個(gè)機(jī)器的序號(hào)就是 0荤堪。然后每次接收到一個(gè)請(qǐng)求,說(shuō)這個(gè)機(jī)房的這個(gè)機(jī)器要生成一個(gè) id枢赔,你就找到對(duì)應(yīng)的 Worker 生成澄阳。

利用這個(gè) snowflake 算法,你可以開(kāi)發(fā)自己公司的服務(wù)踏拜,甚至對(duì)于機(jī)房 id 和機(jī)器 id碎赢,反正給你預(yù)留了 5 bit + 5 bit,你換成別的有業(yè)務(wù)含義的東西也可以的速梗。

這個(gè) snowflake 算法相對(duì)來(lái)說(shuō)還是比較靠譜的肮塞,所以你要真是搞分布式 id 生成,如果是高并發(fā)啥的姻锁,那么用這個(gè)應(yīng)該性能比較好枕赵,一般每秒幾萬(wàn)并發(fā)的場(chǎng)景,也足夠你用了位隶。

如何實(shí)現(xiàn) MySQL 的讀寫(xiě)分離拷窜?主從復(fù)制原理?解決 MySQL 主從同步的延時(shí)問(wèn)題涧黄?
image.png

Mysql讀寫(xiě)分離是基于主從復(fù)制來(lái)做的装黑,主庫(kù)將變更寫(xiě)入 binlog 日志,然后從庫(kù)連接到主庫(kù)之后弓熏,從庫(kù)有一個(gè) IO 線程恋谭,將主庫(kù)的 binlog 日志拷貝到自己本地,寫(xiě)入一個(gè) relay 中繼日志中挽鞠。接著從庫(kù)中有一個(gè) SQL 線程會(huì)從中繼日志讀取 binlog疚颊,然后執(zhí)行 binlog 日志中的內(nèi)容,也就是在自己本地再次執(zhí)行一遍 SQL信认,這樣就可以保證自己跟主庫(kù)的數(shù)據(jù)是一樣的材义。

從庫(kù)數(shù)據(jù)延時(shí)的原因: 就是從庫(kù)同步主庫(kù)數(shù)據(jù)的過(guò)程是串行化的,也就是說(shuō)主庫(kù)上并行的操作嫁赏,在從庫(kù)上會(huì)串行執(zhí)行其掂。所以這就是一個(gè)非常重要的點(diǎn)了,由于從庫(kù)從主庫(kù)拷貝日志以及串行執(zhí)行 SQL 的特點(diǎn)潦蝇,在高并發(fā)場(chǎng)景下款熬,從庫(kù)的數(shù)據(jù)一定會(huì)比主庫(kù)慢一些深寥,是有延時(shí)的。所以經(jīng)常出現(xiàn)贤牛,剛寫(xiě)入主庫(kù)的數(shù)據(jù)可能是讀不到的惋鹅,要過(guò)幾十毫秒,甚至幾百毫秒才能讀取到殉簸。主庫(kù)并發(fā)量越高闰集,從庫(kù)的延遲就越久。
另外:就是如果主庫(kù)突然宕機(jī)般卑,然后恰好數(shù)據(jù)還沒(méi)同步到從庫(kù)武鲁,那么有些數(shù)據(jù)可能在從庫(kù)上是沒(méi)有的,有些數(shù)據(jù)可能就丟失了蝠检。

Mysql為了緩解上面兩個(gè)問(wèn)題沐鼠,有兩個(gè)機(jī)制來(lái)緩解:半同步復(fù)制和并行復(fù)制
半同步復(fù)制:也叫 semi-sync 復(fù)制,指的就是主庫(kù)寫(xiě)入 binlog 日志之后蝇率,就會(huì)將強(qiáng)制此時(shí)立即將數(shù)據(jù)同步到從庫(kù),從庫(kù)將日志寫(xiě)入自己本地的 relay log 之后刽沾,接著會(huì)返回一個(gè) ack 給主庫(kù)本慕,主庫(kù)接收到至少一個(gè)從庫(kù)的 ack之后才會(huì)認(rèn)為寫(xiě)操作完成了。
并行復(fù)制侧漓,指的是從庫(kù)開(kāi)啟多個(gè)線程锅尘,并行讀取 relay log 中不同庫(kù)的日志,然后并行重放不同庫(kù)的日志布蔗,這是庫(kù)級(jí)別的并行藤违。
MySQL 主從同步延時(shí)問(wèn)題的解決方案
假設(shè)有以下邏輯代碼:1 先插入一條數(shù)據(jù)(走主庫(kù)),2 再把它查出來(lái)(走從庫(kù))纵揍,3 然后更新這條數(shù)據(jù) (走主庫(kù))顿乒。在主從復(fù)制環(huán)境下,當(dāng)主庫(kù)并發(fā)量寫(xiě)很高時(shí)泽谨,第二步獲取的結(jié)果有可能是空的璧榄,從而導(dǎo)致錯(cuò)誤的發(fā)生。
解決辦法:

  • 分庫(kù)吧雹,將一個(gè)主庫(kù)拆分為多個(gè)主庫(kù)骨杂,每個(gè)主庫(kù)的寫(xiě)并發(fā)就減少了幾倍,此時(shí)主從延遲可以忽略不計(jì)雄卷。
  • 打開(kāi) MySQL 支持的并行復(fù)制搓蚪,多個(gè)庫(kù)并行復(fù)制。但是 如果說(shuō)某個(gè)庫(kù)的寫(xiě)入并發(fā)就是特別高丁鹉,單庫(kù)寫(xiě)并發(fā)達(dá)到了 2000/s妒潭,并行復(fù)制還是沒(méi)意義悴能,因?yàn)椴⑿袕?fù)制是庫(kù)層面的。并行復(fù)制的意義并不是很大
  • 重寫(xiě)代碼杜耙,寫(xiě)代碼的同學(xué)搜骡,要慎重,插入數(shù)據(jù)時(shí)立馬查詢(xún)可能查不到佑女。
  • 如果確實(shí)是存在必須先插入记靡,立馬要求就查詢(xún)到,然后立馬就要反過(guò)來(lái)執(zhí)行一些操作团驱,對(duì)這個(gè)查詢(xún)?cè)O(shè)置直連主庫(kù)摸吠。但是不推薦這種方法,你要是這么搞嚎花,讀寫(xiě)分離的意義就喪失了寸痢。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市紊选,隨后出現(xiàn)的幾起案子啼止,更是在濱河造成了極大的恐慌,老刑警劉巖兵罢,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件献烦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡卖词,警方通過(guò)查閱死者的電腦和手機(jī)巩那,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)此蜈,“玉大人即横,你說(shuō)我怎么就攤上這事●烧裕” “怎么了东囚?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)战授。 經(jīng)常有香客問(wèn)我舔庶,道長(zhǎng),這世上最難降的妖魔是什么陈醒? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任惕橙,我火速辦了婚禮,結(jié)果婚禮上钉跷,老公的妹妹穿的比我還像新娘弥鹦。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布彬坏。 她就那樣靜靜地躺著朦促,像睡著了一般。 火紅的嫁衣襯著肌膚如雪栓始。 梳的紋絲不亂的頭發(fā)上务冕,一...
    開(kāi)封第一講書(shū)人閱讀 49,985評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音幻赚,去河邊找鬼禀忆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛落恼,可吹牛的內(nèi)容都是我干的箩退。 我是一名探鬼主播,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼佳谦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼戴涝!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起钻蔑,我...
    開(kāi)封第一講書(shū)人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤啥刻,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后咪笑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體可帽,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年蒲肋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蘑拯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钝满。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兜粘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弯蚜,到底是詐尸還是另有隱情孔轴,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布碎捺,位于F島的核電站路鹰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏收厨。R本人自食惡果不足惜晋柱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诵叁。 院中可真熱鬧雁竞,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至进栽,卻和暖如春德挣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背快毛。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工格嗅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人祸泪。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓吗浩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親没隘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子懂扼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350