一致性模型

有時候朱监,在跟一些同學(xué)討論 TiKV 事務(wù)模型的時候,我都提到了 Linearizability,也提到了 Snapshot Isolation臀玄,以及需要手動 lock 來保證 Serializable Snapshot Isolation,很多時候畅蹂,當我嘴里面蹦出來這些名詞的時候健无,有些同學(xué)就一臉懵逼了。所以我覺得有必要仔細來解釋一下液斜,順帶讓我自己將所有的 isolation 以及 consistency 這些情況都歸納總結(jié)一遍累贤,讓自己也理解透徹一點。

幸運的是旗唁,業(yè)內(nèi)已經(jīng)有很多人做了這個事情畦浓,譬如在 Highly Available Transactions: Virtues and Limitations 這篇論文里面,作者就總結(jié)了不同模型是否能滿足 Highly Available Transactions(HATs)检疫。

途中,紅色圓圈里面的模型屬于 Unavailable祷嘶,藍色的屬于 Sticky Available屎媳,其余的就是 Highly Available。這里解釋下相關(guān)的含義:

  • Unavailable: 當出現(xiàn)網(wǎng)絡(luò)隔離等問題的時候论巍,為了保證數(shù)據(jù)的一致性烛谊,不提供服務(wù)。熟悉 CAP 理論的同學(xué)應(yīng)該清楚嘉汰,這就是典型的 CP 系統(tǒng)了丹禀。
  • Sticky Available: 即使一些節(jié)點出現(xiàn)問題,在一些還沒出現(xiàn)故障的節(jié)點鞋怀,仍然保證可用双泪,但需要保證 client 的操作是一致的。
  • Highly Available: 就是網(wǎng)絡(luò)全掛掉密似,在沒有出現(xiàn)問題的節(jié)點上面焙矛,仍然可用。

Unavailable 比較容易理解残腌,這里在討論下 Sticky 和 Highly村斟,對于 Highly Available 來說贫导,如果一個 server 掛掉了,client 可以去連接任意的其他 server蟆盹,如果這時候仍然能獲取到結(jié)果孩灯,那么就是 Highly Available 的。但對于 Sticky 來說逾滥,還需要保證 client 操作的一致性钱反,譬如 client 現(xiàn)在 server 1 上面進行了很多操作,這時候 server 1 掛掉了匣距,client 切換到 server 2面哥,但在 server 2 上面看不到 client 之前的操作結(jié)果,那么這個系統(tǒng)就不是 Sticky 的毅待。所有能在 Highly Available 系統(tǒng)上面保證的事情一定也能在 Sticky Available 系統(tǒng)上面保證尚卫,但反過來就不一定了。

Jepsen 在官網(wǎng)上面有一個簡化但更好看一點的圖

下面尸红,我會按照 Jepsen 里面的圖吱涉,對不同的 model 進行解釋一下。至于為啥選擇 Jepsen 里面的例子外里,一個是因為 Jepsen 現(xiàn)在是一款主流的測試不同分布式系統(tǒng)一致性的工具怎爵,它的測試用例就是測試的是上圖提到的模型,我們自然也會關(guān)心這些模型盅蝗。另外一個就是這個模型已經(jīng)覆蓋了大多數(shù)場景了鳖链,理解了這些,大部分都能游刃有余處理了墩莫。

如果大家仔細觀察芙委,可以發(fā)現(xiàn),從根節(jié)點 Strict Serializable狂秦,其實是有兩個分支的灌侣,一個對應(yīng)的就是數(shù)據(jù)庫里面的 Isolation(ACID 里面的 I),另一個其實對應(yīng)的是分布式系統(tǒng)的 Consistency(CAP 里面的 C)裂问,在 HATs 里面侧啼,叫做 Session Guarantees。

Isolation

要對 Isolation 有個快速的理解堪簿,其實只需要看 A Critique of ANSI SQL Isolation Levels 這篇論文就足夠了痊乾,里面詳細的介紹了數(shù)據(jù)庫實現(xiàn)中遇到的各種各樣的 isolation 問題,以及不同的 isolation level 到底能不能解決戴甩。

在論文里面符喝,作者詳細的列舉了多種異常現(xiàn)象甜孤,這里大概介紹一下协饲。

P0 - Dirty Write

Dirty Write 就是一個事務(wù)畏腕,覆蓋了另一個之前還未提交事務(wù)寫入的值。假設(shè)現(xiàn)在我們有兩個事務(wù)茉稠,一個事務(wù)寫入 x = y = 1描馅,而另一個事務(wù)寫入 x = y = 2,那么最終的結(jié)果而线,我們是希望看到 x 和 y 要不全等于 1铭污,要不全等于 2。但在 Dirty Write 情況下面膀篮,可能會出現(xiàn)如下情況:

+------+-------+-------+-------+-------+
| T1   | Wx(1) |       |       | Wy(1) |
+------+-------+-------+-------+-------+
| T2   |       | Wx(2) | Wy(2) |       |
+------+-------+-------+-------+-------+
| x(0) | 1     | 2     | 2     | 2     |
+------+-------+-------+-------+-------+
| y(0) | 0     | 0     | 2     | 1     |
+------+-------+-------+-------+-------+

可以看到嘹狞,最終的值是 x = 2 而 y = 1,已經(jīng)破壞了數(shù)據(jù)的一致性了誓竿。

P1 - Dirty Read

Dirty Read 出現(xiàn)在一個事務(wù)讀取到了另一個還未提交事務(wù)的修改數(shù)據(jù)磅网。假設(shè)現(xiàn)在我們有一個兩個賬戶,x 和 y筷屡,各自有 50 塊錢涧偷,x 需要給 y 轉(zhuǎn) 40 元錢,那么無論怎樣毙死,x + y = 100 這個約束是不能打破的燎潮,但在 Dirty Read 下面,可能出現(xiàn):

+-------+--------+--------+--------+--------+
| T1    | Wx(10) |        |        | Wy(90) |
+-------+--------+--------+--------+--------+
| T2    |        | Rx(10) | Ry(50) |        |
+-------+--------+--------+--------+--------+
| x(50) | 10     | 10     | 10     | 10     |
+-------+--------+--------+--------+--------+
| y(50) | 50     | 50     | 50     | 90     |
+-------+--------+--------+--------+--------+

在事務(wù) T2扼倘,讀取到的 x + y = 60确封,已經(jīng)打破了約束條件了。

P2 - Fuzzy Read

Fuzzy Read 也叫做 Non-Repeatable Read唉锌,也就是一個還在執(zhí)行的事務(wù)讀取到了另一個事務(wù)的更新操作隅肥,仍然是上面的轉(zhuǎn)賬例子:

+-------+--------+--------+--------+--------+
| T1    | Rx(50) |        |        | Ry(90) |
+-------+--------+--------+--------+--------+
| T2    |        | Wx(10) | Wy(90) |        |
+-------+--------+--------+--------+--------+
| x(50) | 50     | 10     | 10     | 10     |
+-------+--------+--------+--------+--------+
| y(50) | 50     | 50     | 90     | 90     |
+-------+--------+--------+--------+--------+

在 T1 還在運行的過程中,T2 已經(jīng)完成了轉(zhuǎn)賬袄简,但 T1 這時候能讀到最新的值,也就是 x + y = 140 了泛啸,破壞了約束條件绿语。

P3 - Phantom

Phantom 通常發(fā)生在一個事務(wù)首先進行了一次按照某個條件的 read 操作,譬如 SQL 里面的 SELECT WHERE P候址,然后在這個事務(wù)還沒結(jié)束的時候吕粹,另外的事務(wù)寫入了一個新的滿足這個條件的數(shù)據(jù),這時候這個新寫入的數(shù)據(jù)就是 Phantom 的了岗仑。

+----------------+-----------+--------------+--------------+--------------+
| T1             | {a, b, c} |              |              | R(4)         |
+----------------+-----------+--------------+--------------+--------------+
| T2             |           | W(d)         | W(4)         |              |
+----------------+-----------+--------------+--------------+--------------+
| Employees      | {a, b, c} | {a, b, c, d} | {a, b, c, d} | {a, b, c, d} |
+----------------+-----------+--------------+--------------+--------------+
| Employee Count | 3         | 3            | 4            | 4            |
+----------------+-----------+--------------+--------------+--------------+

假設(shè)現(xiàn)在 T1 按照某個條件讀取到了所有雇員 a匹耕,b,c荠雕,這時候 count 是 3稳其,然后 T2 插入了一個新的雇員 d驶赏,同時更新了 count 為 4,但這時候 T1 在讀取 count 的時候會得到 4既鞠,已經(jīng)跟之前讀取到的 a煤傍,b,c 沖突了嘱蛋。

P4 - Lost Update

我們有時候也會遇到一種 Lost Update 的問題蚯姆,如下

+--------+-----+---------+---------+
| T1     |     |         | Wx(110) |
+--------+-----+---------+---------+
| T2     |     | Wx(120) |         |
+--------+-----+---------+---------+
| x(100) | 100 | 120     | 110     |
+--------+-----+---------+---------+

在上面的例子中,我們沒有任何 dirty write洒敏,因為 T2 在 T1 更新之前已經(jīng)提交成功龄恋,也沒有任何 dirty read,因為我們在 write 之后沒有任何 read 操作凶伙,但是郭毕,當整個事務(wù)結(jié)束之后,T2 的更新其實丟失了镊靴。

P4C - Cursor Lost Update

Cursor Lost Update 是上面 Lost Update 的一個變種铣卡,跟 SQL 的 cursor 相關(guān)。在下面的例子中偏竟,RC(x) 表明在 cursor 下面 read x煮落,而 WC(x) 則表明在 cursor 下面寫入 x。

+--------+----------+---------+----------+
| T1     | RCx(100) |         | Wx(110) |
+--------+----------+---------+----------+
| T2     |          | Wx(75) |          |
+--------+----------+---------+----------+
| x(100) | 100      | 75      | 110      |
+--------+----------+---------+----------+

如果我們允許 T2 在 T1 RC 和 WC 之間寫入數(shù)據(jù)踊谋,那么 T2 的更新也會丟失蝉仇。

A5A - Read Skew

Read Skew 發(fā)生在兩個或者多個有完整性約束的數(shù)據(jù)上面,還是傳統(tǒng)的轉(zhuǎn)賬例子殖蚕,需要保證 x + y = 100轿衔,那么 T1 就會看到不一致的數(shù)據(jù)了。

+-------+--------+--------+--------+--------+
| T1    | Rx(50) |        |        | Ry(75) |
+-------+--------+--------+--------+--------+
| T2    |        | Wx(25) | Wy(75) |        |
+-------+--------+--------+--------+--------+
| x(50) | 50     | 25     | 25     | 25     |
+-------+--------+--------+--------+--------+
| y(50) | 50     | 50     | 75     | 75     |
+-------+--------+--------+--------+--------+

A5B - Write Skew

Write Skew 跟 Read Skew 比較類似睦疫,假設(shè) x + y <= 100害驹,T1 和 T2 在執(zhí)行的時候都發(fā)現(xiàn)滿足約束,然后 T1 更新了 y蛤育,而 T2 更新了 x宛官,然后最終結(jié)果打破了約束,如下:

+-------+--------+--------+--------+--------+
| T1    | Rx(30) | Ry(10) | Wy(60) |        |
+-------+--------+--------+--------+--------+
| T2    | Rx(30) | Ry(10) |        | Wx(50) |
+-------+--------+--------+--------+--------+
| x(30) | 30     | 30     | 30     | 50     |
+-------+--------+--------+--------+--------+
| y(10) | 10     | 10     | 60     | 60     |
+-------+--------+--------+--------+--------+

Isolation Levels

上面我們介紹了不同的異常情況瓦糕,下面的表格說明了底洗,在不同的隔離級別下面,那些異常情況可能發(fā)生:

P0 P1 P4C P4 P2 P3 A5A A5B
Read Uncommitted NP P P P P P P P
Read Committed NP NP P P P P P P
Cursor Stability NP NP NP SP SP P P SP
Repeatable Read NP NP NP NP NP P NP NP
Snapshot NP NP NP NP NP SP NP P
Serializable NP NP NP NP NP NP NP NP
  • NP - Not Possible咕娄,在該隔離級別下面不可能發(fā)生
  • SP - Sometimes Possible亥揖,在該隔離級別下面有時候可能發(fā)生
  • P - Possible,在該隔離級別下面會發(fā)生

鑒于網(wǎng)上已經(jīng)對不同的 Isolation Level圣勒,尤其是 MySQL 的解釋的太多了费变,這里就簡單的解釋一下摧扇。

  • Read Uncommitted - 能讀到另外事務(wù)未提交的修改。
  • Read Committed - 能讀到另外事務(wù)已經(jīng)提交的修改胡控。
  • Cursor Stability - 使用 cursor 在事務(wù)里面引用特定的數(shù)據(jù)扳剿,當一個事務(wù)用 cursor 來讀取某個數(shù)據(jù)的時候,這個數(shù)據(jù)不可能被其他事務(wù)更改昼激,除非 cursor 被釋放庇绽,或者事務(wù)提交。
  • Monotonic Atomic View - 這個級別是 read committed 的增強橙困,提供了一個原子性的約束瞧掺,當一個在 T1 里面的 write 被另外事務(wù) T2 觀察到的時候,T1 里面所有的修改都會被 T2 給觀察到凡傅。
  • Repeatable Read - 可重復(fù)讀辟狈,也就是對于某一個數(shù)據(jù),即使另外的事務(wù)有修改夏跷,也會讀取到一樣的值哼转。
  • Snapshot - 每個事務(wù)都會在各自獨立,一致的 snapshot 上面對數(shù)據(jù)庫進行操作槽华。所有修改只有在提交的時候才會對外可見壹蔓。如果 T1 修改了某個數(shù)據(jù),在提交之前另外的事務(wù) T2 修改并提交了猫态,那么 T1 會回滾佣蓉。
  • Serializable - 事務(wù)按照一定順序執(zhí)行。

另外需要注意亲雪,上面提到的 isolation level 都不保證實時約束勇凭,如果一個進程 A 完成了一次寫入 w,然后另外的進程 B 開始了一次讀取 r义辕,r 并不能保證觀察到 w 的結(jié)果虾标。另外,在不同事務(wù)之間灌砖,這些 isolation level 也不保證不同進程的順序夺巩。一個進程可能在一次事務(wù)里面看到一次寫入 w,但可能在后面的事務(wù)上面沒看到同樣的 w周崭。事實上,一個進程甚至可能看不到在這個進程上面之前的寫入喳张,如果這些寫入都是發(fā)生在不同的事務(wù)里面续镇。有時候,他們還可能會對事務(wù)進行排序销部,譬如將 write-only 的事務(wù)放到所有的 read 事務(wù)的后面摸航。

要解決這些問題制跟,我們需要引入順序約束,這也就是下面 Session Guarantee 要干的事情酱虎。

Session Guarantee

在 HATs 論文里面雨膨,相關(guān)的概念叫做 Session Guarantee,主要是用來保證在一個 session 里面的實時性約束以及客戶端的操作順序读串。

Writes Follow Reads

如果某個進程讀到了一次寫入 w1 寫入的值 v聊记,然后進行了一次新的寫入 w2,那么 w2 寫入的值將會在 w1 之后可見恢暖。

Monotonic Reads

如果一個進程開始了一次讀取 r1排监,然后在開始另一次讀取 r2,那么 r2 不可能看到 r1 之前數(shù)據(jù)杰捂。

Monotonic Writes

如果一個進程先進行了一次寫入 w1舆床,然后在進行了一次寫入 w2,那么所有其他的進程都會觀察到 w1 在 w2 之前發(fā)生嫁佳。

Read Your Writes

如果一個進程先進行了一次寫入 w挨队,然后后面執(zhí)行了一次讀取 r,那么 r 一定會看到 w 的改動蒿往。

PRAM

PRAM 就是 Pipeline Random Access Memory盛垦,對于單個進程的寫操作都被觀察到是順序的,但不同的進程寫會觀察到不同的順序熄浓。譬如下面這個操作是滿足 PRAM 的情臭,但不滿足后面說的 Causal。

+----+------+------+------+------+------+
| P1 | W(1) |      |      |      |      |
+----+------+------+------+------+------+
| P2 |      | R(1) | W(2) |      |      |
+----+------+------+------+------+------+
| P3 |      |      |      | R(2) | R(1) |
+----+------+------+------+------+------+
| P4 |      |      |      | R(1) | R(2) |
+----+------+------+------+------+------+

Causal

Causal 確定了有因果關(guān)系的操作在所有進程間的一致順序赌蔑。譬如下面這個

+----+------+------+------+------+------+------+
| P1 | W(1) |      |      |      |      |      |
+----+------+------+------+------+------+------+
| P2 |      | W(2) |      |      |      |      |
+----+------+------+------+------+------+------+
| P3 |      |      | R(2) |      | R(1) |      |
+----+------+------+------+------+------+------+
| P4 |      |      |      | R(1) |      | R(2) |
+----+------+------+------+------+------+------+

對于 P3 和 P4 來說俯在,無論是先讀到 2,還是先讀到 1娃惯, 都是沒問題的跷乐,因為 P1 和 P2 里面的 write 操作并沒有因果性,是并行的趾浅。但是下面這個

+----+------+------+------+------+------+------+
| P1 | W(1) |      |      |      |      |      |
+----+------+------+------+------+------+------+
| P2 |      | R(1) | W(2) |      |      |      |
+----+------+------+------+------+------+------+
| P3 |      |      |      | R(2) | R(1) |      |
+----+------+------+------+------+------+------+
| P4 |      |      |      | R(1) |      | R(2) |
+----+------+------+------+------+------+------+

就不滿足 Cansal 的一致性要求了愕提,因為對于 P2 來說,在 Write 2 之前皿哨,進行了一次 Read 1 的操作浅侨,已經(jīng)確定了 Write 1 會在 Write 2 之前發(fā)生,也就是確定了因果關(guān)系证膨,所以 P3 打破了這個關(guān)系如输。

Sequential

Sequential 會保證操作按照一定順序發(fā)生,并且這個順序會在不同的進程上面都是一致的。一個進程會比另外的進程超前不见,或者落后澳化,譬如這個進程可能讀到了已經(jīng)是陳舊的數(shù)據(jù),但是稳吮,如果一個進程 A 從進程 B 讀到了某個狀態(tài)缎谷,那么它就不可能在讀到 B 之前的狀態(tài)了。

譬如下面的操作就是滿足 Sequential 的

+----+------+------+------+------+------+------+
| P1 | W(1) |      |      |      |      |      |
+----+------+------+------+------+------+------+
| P2 |      | W(2) |      |      |      |      |
+----+------+------+------+------+------+------+
| P3 |      |      | R(1) |      | R(2) |      |
+----+------+------+------+------+------+------+
| P4 |      |      |      | R(2) |      | R(2) |
+----+------+------+------+------+------+------+

對于 P3 來說灶似,它仍然能讀到之前的 stale 狀態(tài) 1列林。但下面的就不對了:

+----+------+------+------+------+------+------+
| P1 | W(1) |      |      |      |      |      |
+----+------+------+------+------+------+------+
| P2 |      | W(2) |      |      |      |      |
+----+------+------+------+------+------+------+
| P3 |      |      | R(2) |      | R(1) |      |
+----+------+------+------+------+------+------+
| P4 |      |      |      | R(2) |      | R(2) |
+----+------+------+------+------+------+------+

對于 P3 來說,它已經(jīng)讀到了最新的狀態(tài) 2喻奥,就不可能在讀到之前的狀態(tài) 1 了席纽。

Linearizable

Linearizability 要求所有的操作都是按照一定的順序原子的發(fā)生,而這個順序可以認為就是跟操作發(fā)生的時間一致的撞蚕。也就是說润梯,如果一個操作 A 在 B 開始之前就結(jié)束了,那么 B 只可能在 A 之后才能產(chǎn)生作用甥厦。

譬如下面的操作:

+----+------+------+------+------+------+
| P1 | W(1) |      |      |      |      |
+----+------+------+------+------+------+
| P2 |      | W(2) |      |      |      |
+----+------+------+------+------+------+
| P3 |      |      | R(2) | R(2) |      |
+----+------+------+------+------+------+
| P4 |      |      |      | R(2) | R(2) |
+----+------+------+------+------+------+

對于 P3 和 P4 來說纺铭,因為之前已經(jīng)有新的寫入,所以他們只能讀到 2刀疙,不可能讀到 1舶赔。

Strict Serializable

終于來到了 Strict Serializable,大家可以看到谦秧,它結(jié)合了 serializable 以及 linearizable竟纳,也就是說,它會讓所有操作按照實時的順序依次操作疚鲤,也就是所有的進程會觀察到完全一致的順序锥累,這也是最強的一致性模型了。

TiKV

好了集歇,最后再來聊聊 TiKV桶略,TiKV 是一個支持分布式事務(wù)的 key-value database。對于某個事務(wù)诲宇,TiKV 會通過 PD 這個服務(wù)在事務(wù)開始的時候分配一個 start timestamp际歼,以及事務(wù)提交的時候分配一個 commit timestamp。因為我們的授時是通過 PD 這個單點服務(wù)進行的姑蓝,所以時間是一定能保證單調(diào)遞增的鹅心,也就是說,我們所有的操作都能跟保證實時有序纺荧,也就是滿足 Linearizable巴帮。

TiKV 采用的是常用的 MVCC 模型溯泣,也就是每個 key-value 實際存儲的時候,會在 key 上面帶一個 timestamp榕茧,我們就可以用 timestamp 來生成整個數(shù)據(jù)庫的 snapshot 了,所以 TiKV 是 snapshot isolation 的客给。既然是 snapshot isolation用押,那么就會遇到 write skew 問題,所以 TiKV 額外提供了 serializable snapshot isolation靶剑,用戶需要顯示的對要操作的數(shù)據(jù)進行 lock 操作蜻拨。

但現(xiàn)在 TiKV 并不支持對 range 加 lock,所以不能完全的防止 phantom桩引,譬如假設(shè)最多允許 8 個任務(wù)缎讼,現(xiàn)在已經(jīng)有 7 個任務(wù)了,我們還可以添加一個任務(wù)坑匠,但這時候另外一個事務(wù)也做了同樣的事情血崭,但添加的是不同的任務(wù),這時候就會變成 9 個任務(wù)厘灼,另外的事務(wù)在 scan 的時候就會發(fā)現(xiàn)打破了約束夹纫。這個也就是 A Critique of ANSI SQL Isolation Levels 里面提到的 sometimes possible。

所以设凹,TiKV 是 snapshot isolation + linearizable舰讹。雖然 TiKV 也可以支持 Read Committed,但通常不建議在生產(chǎn)環(huán)境中使用闪朱,因為 TiKV 的 Read Committed 跟傳統(tǒng)的還不太一樣月匣,可能會出現(xiàn)能讀到一個事務(wù)提交到某個節(jié)點的數(shù)據(jù),但這時候在另外的節(jié)點還讀不到這個事務(wù)提交的數(shù)據(jù)奋姿,畢竟在分布式系統(tǒng)下面锄开,不同節(jié)點的事務(wù)提交也是有網(wǎng)絡(luò)延遲的,不可能同時執(zhí)行胀蛮。

小結(jié)

在分布式系統(tǒng)里面院刁,一致性是非常重要的一個概念,理解了它粪狼,在自己設(shè)計分布式系統(tǒng)的時候退腥,就能充分的考慮到底系統(tǒng)應(yīng)該提供怎樣的一致性模型。譬如對于 TP 數(shù)據(jù)庫來說再榄,就需要有一個比較 strong 的一致性模型狡刘,而對于一些不重要的系統(tǒng),譬如 cache 這些困鸥,就可以使用一些比較 weak 的模型嗅蔬。對 TiKV 來說剑按,我們在 Percolator 基礎(chǔ)上面,也一直在致力于分布式事務(wù)的優(yōu)化澜术,如果你對這方面感興趣艺蝴,歡迎聯(lián)系我 tl@pingcap.com

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鸟废,一起剝皮案震驚了整個濱河市猜敢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盒延,老刑警劉巖缩擂,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異添寺,居然都是意外死亡胯盯,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門计露,熙熙樓的掌柜王于貴愁眉苦臉地迎上來博脑,“玉大人,你說我怎么就攤上這事薄坏∏骼鳎” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵胶坠,是天一觀的道長君账。 經(jīng)常有香客問我,道長沈善,這世上最難降的妖魔是什么乡数? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮闻牡,結(jié)果婚禮上净赴,老公的妹妹穿的比我還像新娘。我一直安慰自己罩润,他們只是感情好玖翅,可當我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著割以,像睡著了一般金度。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上严沥,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天猜极,我揣著相機與錄音,去河邊找鬼消玄。 笑死跟伏,一個胖子當著我的面吹牛丢胚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播受扳,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼携龟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辞色?” 一聲冷哼從身側(cè)響起骨宠,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎相满,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桦卒,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡立美,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了方灾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片建蹄。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖裕偿,靈堂內(nèi)的尸體忽然破棺而出洞慎,到底是詐尸還是另有隱情,我是刑警寧澤嘿棘,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布劲腿,位于F島的核電站,受9級特大地震影響鸟妙,放射性物質(zhì)發(fā)生泄漏焦人。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一重父、第九天 我趴在偏房一處隱蔽的房頂上張望花椭。 院中可真熱鬧,春花似錦房午、人聲如沸矿辽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽袋倔。三九已至,卻和暖如春沪曙,著一層夾襖步出監(jiān)牢的瞬間奕污,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工液走, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碳默,地道東北人贾陷。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像嘱根,于是被迫代替她去往敵國和親髓废。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,033評論 2 355

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

  • Mysql概述 數(shù)據(jù)庫是一個易于訪問和修改的信息集合该抒。它允許使用事務(wù)來確保數(shù)據(jù)的安全性和一致性慌洪,并能快速處理百萬條...
    彥幀閱讀 13,678評論 10 461
  • 對于容許數(shù)據(jù)副本不一致的協(xié)議, 我們很難用一個單一的維度來定義或者歸類這些協(xié)議凑保,對于這些協(xié)議來說冈爹,更關(guān)鍵的問題在于...
    三川_8f54閱讀 2,207評論 1 10
  • 問題當我們在生成線上用一臺服務(wù)器來提供數(shù)據(jù)服務(wù)時,我們會遇到如下兩個問題:1.一臺服務(wù)器性能不足以提供足夠的能力服...
    _Henry_閱讀 548評論 0 0
  • 問題的提出 在計算機科學(xué)領(lǐng)域欧引,分布式一致性是一個相當重要且被廣泛探索與論證問題频伤,首先來看三種業(yè)務(wù)場景。 1芝此、火車站...
    lqsss閱讀 895評論 0 1
  • 她喜歡養(yǎng)貓憋肖,以前是大貍貓,現(xiàn)在是大花貓婚苹。 今天去見她時岸更,她又瘦了,80多年的光陰流轉(zhuǎn)已耗去體肉膊升,仿佛只剩下骨頭怎炊。見...
    句子總是林林總總閱讀 201評論 0 0