日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

分布式一致性协议Raft原理与实例

發(fā)布時間:2024/9/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分布式一致性协议Raft原理与实例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

來源:http://m635674608.iteye.com/blog/2283621

1.Raft協(xié)議

1.1 Raft簡介

Raft是由Stanford提出的一種更易理解的一致性算法,意在取代目前廣為使用的Paxos算法。目前,在各種主流語言中都有了一些開源實現(xiàn),比如本文中將使用的基于JGroups的Raft協(xié)議實現(xiàn)。關(guān)于Raft的原理,強烈推薦動畫版Raft講解。

1.2 Raft原理

在Raft中,每個結(jié)點會處于下面三種狀態(tài)中的一種:

  • follower:所有結(jié)點都以follower的狀態(tài)開始。如果沒收到leader消息則會變成candidate狀態(tài)
  • candidate:會向其他結(jié)點“拉選票”,如果得到大部分的票則成為leader。這個過程就叫做Leader選舉(Leader Election)
  • leader:所有對系統(tǒng)的修改都會先經(jīng)過leader。每個修改都會寫一條日志(log entry)。leader收到修改請求后的過程如下,這個過程叫做日志復(fù)制(Log Replication):?
  • 復(fù)制日志到所有follower結(jié)點(replicate entry)
  • 大部分結(jié)點響應(yīng)時才提交日志
  • 通知所有follower結(jié)點日志已提交
  • 所有follower也提交日志
  • 現(xiàn)在整個系統(tǒng)處于一致的狀態(tài)

1.2.1 Leader Election

當(dāng)follower在選舉超時時間(election timeout)內(nèi)未收到leader的心跳消息(append entries),則變成candidate狀態(tài)。為了避免選舉沖突,這個超時時間是一個150~300ms之間的隨機數(shù)

成為candidate的結(jié)點發(fā)起新的選舉期(election term)去“拉選票”:

  • 重置自己的計時器
  • 投自己一票
  • 發(fā)送?Request Vote消息
  • 如果接收結(jié)點在新term內(nèi)沒有投過票那它就會投給此candidate,并重置它自己的選舉超時時間。candidate拉到大部分選票就會成為leader,并定時發(fā)送心跳——Append Entries消息,去重置各個follower的計時器。當(dāng)前Term會繼續(xù)直到某個follower接收不到心跳并成為candidate。

    如果不巧兩個結(jié)點同時成為candidate都去“拉票”怎么辦?這時會發(fā)生Splite Vote情況。兩個結(jié)點可能都拉到了同樣多的選票,難分勝負(fù),選舉失敗,本term沒有l(wèi)eader。之后又有計時器超時的follower會變成candidate,將term加一并開始新一輪的投票。

    1.2.2 Log Replication

    當(dāng)發(fā)生改變時,leader會復(fù)制日志給follower結(jié)點,這也是通過Append Entries心跳消息完成的。前面已經(jīng)列舉了Log Replication的過程,這里就不重復(fù)了。

    Raft能夠正確地處理網(wǎng)絡(luò)分區(qū)(“腦裂”)問題。假設(shè)A~E五個結(jié)點,B是leader。如果發(fā)生“腦裂”,A、B成為一個子分區(qū),C、D、E成 為一個子分區(qū)。此時C、D、E會發(fā)生選舉,選出C作為新term的leader。這樣我們在兩個子分區(qū)內(nèi)就有了不同term的兩個leader。這時如果 有客戶端寫A時,因為B無法復(fù)制日志到大部分follower所以日志處于uncommitted未提交狀態(tài)。而同時另一個客戶端對C的寫操作卻能夠正確 完成,因為C是新的leader,它只知道D和E。

    當(dāng)網(wǎng)絡(luò)通信恢復(fù),B能夠發(fā)送心跳給C、D、E了,卻發(fā)現(xiàn)“改朝換代”了,因為C的term值更大,所以B自動降格為follower。然后A和B都回滾未提交的日志,并從新leader那里復(fù)制最新的日志。但這樣是不是就會丟失更新?


    2.JGroups-raft介紹

    2.1 JGroups中的Raft

    JGroups是Java里比較流行的網(wǎng)絡(luò)通信框架,近期順應(yīng)潮流,它也推出了Raft基于JGroups的實現(xiàn)。簡單試用了一下,還比較容易上 手,底層Raft的內(nèi)部機制都被API屏蔽掉了。下面就通過一個分布式計數(shù)器的實例來學(xué)習(xí)一下Raft協(xié)議在JGroups中的實際用法。

    Maven依賴如下:

    Prettyprint代碼??
  • <code?class="language-xml?hljs??has-numbering">????<span?class="hljs-tag"><<span?class="hljs-title">dependency</span>></span>??
  • ????????<span?class="hljs-tag"><<span?class="hljs-title">groupId</span>></span>org.jgroups<span?class="hljs-tag"></<span?class="hljs-title">groupId</span>></span>??
  • ????????<span?class="hljs-tag"><<span?class="hljs-title">artifactId</span>></span>jgroups-raft<span?class="hljs-tag"></<span?class="hljs-title">artifactId</span>></span>??
  • ????????<span?class="hljs-tag"><<span?class="hljs-title">version</span>></span>0.2<span?class="hljs-tag"></<span?class="hljs-title">version</span>></span>??
  • ????<span?class="hljs-tag"></<span?class="hljs-title">dependency</span>></span></code>??
    • 1
    • 2
    • 3
    • 4
    • 5

    其實JGroups-raft的Jar包中已經(jīng)自帶了一個Counter的Demo,但仔細(xì)看了一下,有的地方寫的有些麻煩,不太容易把握住Raft這根主線。所以這里就參照官方的例子,進行了簡寫,突出Raft協(xié)議的基本使用方法。JGroups-raft目前資料不多,InfoQ上的這篇文章很不錯,還有官方文檔。

    2.2 核心API

    使用JGroups-raft時,我們一般會實現(xiàn)兩個接口:RAFT.RoleChange和StateMachine

    • 實現(xiàn)RAFT.RoleChange接口的方法能通知我們當(dāng)前哪個結(jié)點是leader
    • 實現(xiàn)StateMachine執(zhí)行要實現(xiàn)一致性的操作

    典型單點服務(wù)實現(xiàn)方式就是:

    Prettyprint代碼??
  • <code?class="language-java?hljs??has-numbering">JChannel?ch?=?<span?class="hljs-keyword">null</span>;??
  • RaftHandle?handle?=?<span?class="hljs-keyword">new</span>?RaftHandle(ch,?<span?class="hljs-keyword">this</span>);??
  • handle.addRoleListener(role?->?{??
  • ????<span?class="hljs-keyword">if</span>(role?==?Role.Leader)??
  • ????????<span?class="hljs-comment">//?start?singleton?services</span>??
  • ????<span?class="hljs-keyword">else</span>??
  • ????????<span?class="hljs-comment">//?stop?singleton?services</span>??
  • });</code>??
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.3 默認(rèn)配置

    jgroups-raft.jar中已經(jīng)帶了一個raft.xml配置文件,作為實例程序我們可以直接使用它。

    簡要解釋一下最核心的幾個配置項,參照GitHub上的文檔:

    • UDP:IP多播配置
    • raft.NO_DUPES:是否檢測新加入結(jié)點的ID與老結(jié)點有重復(fù)
    • raft.ELECTION:選舉超時時間的隨機化范圍
    • raft.RAFT所有Raft集群的成員必須在這里聲明,也可以在運行時通過addServer/removeServer動態(tài)修改
    • raft.REDIRECT:是否轉(zhuǎn)發(fā)請求給leader
    • raft.CLIENT:在哪個IP和端口上接收客戶端請求
    Prettyprint代碼??
  • <code?class="language-xml?hljs??has-numbering"><span?class="hljs-comment"><!--??
  • ??Default?stack?using?IP?multicasting.?It?is?similar?to?the?"udp"??
  • ??stack?in?stacks.xml,?but?doesn't?use?streaming?state?transfer?and?flushing??
  • ??author:?Bela?Ban??
  • --></span>??
  • ??
  • <span?class="hljs-tag"><<span?class="hljs-title">config</span>?<span?class="hljs-attribute">xmlns</span>=<span?class="hljs-value">"urn:org:jgroups"</span>??
  • ????????<span?class="hljs-attribute">xmlns:xsi</span>=<span?class="hljs-value">"http://www.w3.org/2001/XMLSchema-instance"</span>??
  • ????????<span?class="hljs-attribute">xsi:schemaLocation</span>=<span?class="hljs-value">"urn:org:jgroups?http://www.jgroups.org/schema/jgroups.xsd"</span>></span>??
  • ????<span?class="hljs-tag"><<span?class="hljs-title">UDP??
  • </span>?????????<span?class="hljs-attribute">mcast_addr</span>=<span?class="hljs-value">"228.5.5.5"</span>??
  • ?????????<span?class="hljs-attribute">mcast_port</span>=<span?class="hljs-value">"${jgroups.udp.mcast_port:45588}"</span>??
  • ?????????<span?class="hljs-attribute">...</span>?/></span>??
  • ????...??
  • ????<span?class="hljs-tag"><<span?class="hljs-title">raft.NO_DUPES</span>/></span>??
  • ????<span?class="hljs-tag"><<span?class="hljs-title">raft.ELECTION</span>?<span?class="hljs-attribute">election_min_interval</span>=<span?class="hljs-value">"100"</span>?<span?class="hljs-attribute">election_max_interval</span>=<span?class="hljs-value">"500"</span>/></span>??
  • ????<span?class="hljs-tag"><<span?class="hljs-title">raft.RAFT</span>?<span?class="hljs-attribute">members</span>=<span?class="hljs-value">"A,B,C"</span>?<span?class="hljs-attribute">raft_id</span>=<span?class="hljs-value">"${raft_id:undefined}"</span>/></span>??
  • ????<span?class="hljs-tag"><<span?class="hljs-title">raft.REDIRECT</span>/></span>??
  • ????<span?class="hljs-tag"><<span?class="hljs-title">raft.CLIENT</span>?<span?class="hljs-attribute">bind_addr</span>=<span?class="hljs-value">"0.0.0.0"</span>?/></span>??
  • <span?class="hljs-tag"></<span?class="hljs-title">config</span>></span></code>??
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.JGroups-raft實例

    實例很簡單,只有JGroupsRaftTest和CounterService兩個類組成。JGroupsRaftTest是測試啟動類,而CounterService就是利用Raft協(xié)議實現(xiàn)的分布式計數(shù)服務(wù)類。

    3.1 JGroupsRaftTest

    JGroupsRaftTest的職責(zé)主要有三個:

    • 創(chuàng)建Raft協(xié)議的JChannel
    • 創(chuàng)建CounterService
    • 循環(huán)讀取用戶輸入

    目前簡單實現(xiàn)了幾種操作包括:初始化計數(shù)器、加一、減一、讀取計數(shù)器、查看Raft日志、做Raft快照(用于壓縮日志文件)等。其中對計數(shù)器的操作,因為要與其他Raft成員進行分布式通信,所以當(dāng)前集群必須要多于一個結(jié)點時才能進行操作。如果要支持單結(jié)點時的操作,需要做特殊處理

    Prettyprint代碼??
  • <code?class="language-java?hljs??has-numbering"><span?class="hljs-keyword">import</span>?org.jgroups.JChannel;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.protocols.raft.RAFT;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.util.Util;??
  • ??
  • <span?class="hljs-javadoc">/**??
  • ?*?Test?jgroups?raft?algorithm?implementation.??
  • ?*/</span>??
  • <span?class="hljs-keyword">public</span>?<span?class="hljs-class"><span?class="hljs-keyword">class</span>?<span?class="hljs-title">JGroupsRaftTest</span>?{</span>??
  • ??
  • ????<span?class="hljs-keyword">private</span>?<span?class="hljs-keyword">static</span>?<span?class="hljs-keyword">final</span>?String?CLUSTER_NAME?=?<span?class="hljs-string">"ctr-cluster"</span>;??
  • ????<span?class="hljs-keyword">private</span>?<span?class="hljs-keyword">static</span>?<span?class="hljs-keyword">final</span>?String?COUNTER_NAME?=?<span?class="hljs-string">"counter"</span>;??
  • ????<span?class="hljs-keyword">private</span>?<span?class="hljs-keyword">static</span>?<span?class="hljs-keyword">final</span>?String?RAFT_XML?=?<span?class="hljs-string">"raft.xml"</span>;??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">static</span>?<span?class="hljs-keyword">void</span>?<span?class="hljs-title">main</span>(String[]?args)?<span?class="hljs-keyword">throws</span>?Exception?{??
  • ????????JChannel?ch?=?<span?class="hljs-keyword">new</span>?JChannel(RAFT_XML).name(args[<span?class="hljs-number">0</span>]);??
  • ????????CounterService?counter?=?<span?class="hljs-keyword">new</span>?CounterService(ch);??
  • ??
  • ????????<span?class="hljs-keyword">try</span>?{??
  • ????????????doConnect(ch,?CLUSTER_NAME);??
  • ????????????doLoop(ch,?counter);??
  • ????????}?<span?class="hljs-keyword">finally</span>?{??
  • ????????????Util.close(ch);??
  • ????????}??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">private</span>?<span?class="hljs-keyword">static</span>?<span?class="hljs-keyword">void</span>?<span?class="hljs-title">doConnect</span>(JChannel?ch,?String?clusterName)?<span?class="hljs-keyword">throws</span>?Exception?{??
  • ????????ch.connect(clusterName);??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">private</span>?<span?class="hljs-keyword">static</span>?<span?class="hljs-keyword">void</span>?<span?class="hljs-title">doLoop</span>(JChannel?ch,?CounterService?counter)?{??
  • ????????<span?class="hljs-keyword">boolean</span>?looping?=?<span?class="hljs-keyword">true</span>;??
  • ????????<span?class="hljs-keyword">while</span>?(looping)?{??
  • ????????????<span?class="hljs-keyword">int</span>?key?=?Util.keyPress(<span?class="hljs-string">"\n[0]?Create?[1]?Increment?[2]?Decrement?[3]?Dump?log?[4]?Snapshot?[x]?Exit\n"</span>?+??
  • ????????????????????<span?class="hljs-string">"first-applied="</span>?+?((RAFT)?ch.getProtocolStack().findProtocol(RAFT.class)).log().firstApplied()?+??
  • ????????????????????<span?class="hljs-string">",?last-applied="</span>?+?counter.lastApplied()?+??
  • ????????????????????<span?class="hljs-string">",?commit-index="</span>?+?counter.commitIndex()?+??
  • ????????????????????<span?class="hljs-string">",?log?size="</span>?+?Util.printBytes(counter.logSize())?+?<span?class="hljs-string">":?"</span>);??
  • ??
  • ????????????<span?class="hljs-keyword">if</span>?((key?==?<span?class="hljs-string">'0'</span>?||?key?==?<span?class="hljs-string">'1'</span>?||?key?==?<span?class="hljs-string">'2'</span>)?&&?!counter.isLeaderExist())?{??
  • ????????????????System.out.println(<span?class="hljs-string">"Cannot?perform?cause?there?is?no?leader?by?now"</span>);??
  • ????????????????<span?class="hljs-keyword">continue</span>;??
  • ????????????}??
  • ??
  • ????????????<span?class="hljs-keyword">long</span>?val;??
  • ????????????<span?class="hljs-keyword">switch</span>?(key)?{??
  • ????????????????<span?class="hljs-keyword">case</span>?<span?class="hljs-string">'0'</span>:??
  • ????????????????????counter.getOrCreateCounter(COUNTER_NAME,?<span?class="hljs-number">1</span>L);??
  • ????????????????????<span?class="hljs-keyword">break</span>;??
  • ????????????????<span?class="hljs-keyword">case</span>?<span?class="hljs-string">'1'</span>:??
  • ????????????????????val?=?counter.incrementAndGet(COUNTER_NAME);??
  • ????????????????????System.out.printf(<span?class="hljs-string">"%s:?%s\n"</span>,?COUNTER_NAME,?val);??
  • ????????????????????<span?class="hljs-keyword">break</span>;??
  • ????????????????<span?class="hljs-keyword">case</span>?<span?class="hljs-string">'2'</span>:??
  • ????????????????????val?=?counter.decrementAndGet(COUNTER_NAME);??
  • ????????????????????System.out.printf(<span?class="hljs-string">"%s:?%s\n"</span>,?COUNTER_NAME,?val);??
  • ????????????????????<span?class="hljs-keyword">break</span>;??
  • ????????????????<span?class="hljs-keyword">case</span>?<span?class="hljs-string">'3'</span>:??
  • ????????????????????counter.dumpLog();??
  • ????????????????????<span?class="hljs-keyword">break</span>;??
  • ????????????????<span?class="hljs-keyword">case</span>?<span?class="hljs-string">'4'</span>:??
  • ????????????????????counter.snapshot();??
  • ????????????????????<span?class="hljs-keyword">break</span>;??
  • ????????????????<span?class="hljs-keyword">case</span>?<span?class="hljs-string">'x'</span>:??
  • ????????????????????looping?=?<span?class="hljs-keyword">false</span>;??
  • ????????????????????<span?class="hljs-keyword">break</span>;??
  • ????????????????<span?class="hljs-keyword">case</span>?<span?class="hljs-string">'\n'</span>:??
  • ????????????????????System.out.println(COUNTER_NAME?+?<span?class="hljs-string">":?"</span>?+?counter.get(COUNTER_NAME)?+?<span?class="hljs-string">"\n"</span>);??
  • ????????????????????<span?class="hljs-keyword">break</span>;??
  • ????????????}??
  • ????????}??
  • ????}??
  • ??
  • }</code>??
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    3.2 CounterService

    CounterService是我們的核心類,利用Raft實現(xiàn)了分布式的計數(shù)器操作,它的API主要由四部分組成:

    • Raft Local API:操作本地Raft的狀態(tài),像日志大小、做快照等
    • Raft API:實現(xiàn)Raft的監(jiān)聽器和狀態(tài)機的方法?
      • roleChanged:本地Raft的角色發(fā)生變化
      • apply:分布式通信消息
      • readContentFrom/writeContentTo:讀寫快照
    • Counter API:計數(shù)器的分布式API
    • Counter Native API:計數(shù)器的本地API。直接使用的話相當(dāng)于臟讀
    Prettyprint代碼??
  • <code?class="language-java?hljs??has-numbering"><span?class="hljs-keyword">import</span>?org.jgroups.Channel;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.protocols.raft.RAFT;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.protocols.raft.Role;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.protocols.raft.StateMachine;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.raft.RaftHandle;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.util.AsciiString;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.util.Bits;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.util.ByteArrayDataInputStream;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.util.ByteArrayDataOutputStream;??
  • <span?class="hljs-keyword">import</span>?org.jgroups.util.Util;??
  • ??
  • <span?class="hljs-keyword">import</span>?java.io.DataInput;??
  • <span?class="hljs-keyword">import</span>?java.io.DataOutput;??
  • <span?class="hljs-keyword">import</span>?java.io.IOException;??
  • <span?class="hljs-keyword">import</span>?java.text.SimpleDateFormat;??
  • <span?class="hljs-keyword">import</span>?java.util.Date;??
  • <span?class="hljs-keyword">import</span>?java.util.HashMap;??
  • <span?class="hljs-keyword">import</span>?java.util.Map;??
  • ??
  • <span?class="hljs-javadoc">/**??
  • ?*?Distribute?counter?service?based?on?Raft?consensus?algorithm.??
  • ?*/</span>??
  • class?CounterService?implements?StateMachine,?RAFT.RoleChange?{??
  • ??
  • ????<span?class="hljs-keyword">private</span>?RaftHandle?raft;??
  • ??
  • ????<span?class="hljs-keyword">private</span>?<span?class="hljs-keyword">final</span>?Map<String,?Long>?counters;??
  • ??
  • ????<span?class="hljs-keyword">private</span>?<span?class="hljs-keyword">enum</span>?Command?{??
  • ????????CREATE,?INCREMENT_AND_GET,?DECREMENT_AND_GET,?GET,?SET??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-title">CounterService</span>(Channel?ch)?{??
  • ????????<span?class="hljs-keyword">this</span>.raft?=?<span?class="hljs-keyword">new</span>?RaftHandle(ch,?<span?class="hljs-keyword">this</span>);??
  • ????????<span?class="hljs-keyword">this</span>.counters?=?<span?class="hljs-keyword">new</span>?HashMap<>();??
  • ??
  • ????????raft.raftId(ch.getName())??
  • ????????????.addRoleListener(<span?class="hljs-keyword">this</span>);??
  • ????}??
  • ??
  • ????<span?class="hljs-comment">//?===========================================</span>??
  • ????<span?class="hljs-comment">//??????????????Raft?Status?API</span>??
  • ????<span?class="hljs-comment">//?===========================================</span>??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">int</span>?<span?class="hljs-title">lastApplied</span>()?{??
  • ????????<span?class="hljs-keyword">return</span>?raft.lastApplied();??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">int</span>?<span?class="hljs-title">commitIndex</span>()?{??
  • ????????<span?class="hljs-keyword">return</span>?raft.commitIndex();??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">int</span>?<span?class="hljs-title">logSize</span>()?{??
  • ????????<span?class="hljs-keyword">return</span>?raft.logSize();??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">void</span>?<span?class="hljs-title">dumpLog</span>()?{??
  • ????????System.out.println(<span?class="hljs-string">"\nindex?(term):?command\n---------------------"</span>);??
  • ????????raft.logEntries((entry,?index)?->?{??
  • ????????????StringBuilder?log?=?<span?class="hljs-keyword">new</span>?StringBuilder()??
  • ????????????????????.append(index)??
  • ????????????????????.append(<span?class="hljs-string">"?("</span>).append(entry.term()).append(<span?class="hljs-string">"):?"</span>);??
  • ??
  • ????????????<span?class="hljs-keyword">if</span>?(entry.command()?==?<span?class="hljs-keyword">null</span>?)?{??
  • ????????????????System.out.println(log.append(<span?class="hljs-string">"<marker?record>"</span>));??
  • ????????????????<span?class="hljs-keyword">return</span>;??
  • ????????????}?<span?class="hljs-keyword">else</span>?<span?class="hljs-keyword">if</span>?(entry.internal())?{??
  • ????????????????System.out.println(log.append(<span?class="hljs-string">"<internal?command>"</span>));??
  • ????????????????<span?class="hljs-keyword">return</span>;??
  • ????????????}??
  • ??
  • ????????????ByteArrayDataInputStream?in?=?<span?class="hljs-keyword">new</span>?ByteArrayDataInputStream(??
  • ????????????????????entry.command(),?entry.offset(),?entry.length()??
  • ????????????);??
  • ????????????<span?class="hljs-keyword">try</span>?{??
  • ????????????????Command?cmd?=?Command.values()[in.readByte()];??
  • ????????????????String?name?=?Bits.readAsciiString(in).toString();??
  • ????????????????<span?class="hljs-keyword">switch</span>?(cmd)?{??
  • ????????????????????<span?class="hljs-keyword">case</span>?CREATE:??
  • ????????????????????????log.append(cmd)??
  • ????????????????????????????.append(<span?class="hljs-string">"("</span>).append(name).append(<span?class="hljs-string">",?"</span>)??
  • ????????????????????????????.append(Bits.readLong(in))??
  • ????????????????????????????.append(<span?class="hljs-string">")"</span>);??
  • ????????????????????????<span?class="hljs-keyword">break</span>;??
  • ????????????????????<span?class="hljs-keyword">case</span>?GET:??
  • ????????????????????<span?class="hljs-keyword">case</span>?INCREMENT_AND_GET:??
  • ????????????????????<span?class="hljs-keyword">case</span>?DECREMENT_AND_GET:??
  • ????????????????????????log.append(cmd)??
  • ????????????????????????????.append(<span?class="hljs-string">"("</span>).append(name).append(<span?class="hljs-string">")"</span>);??
  • ????????????????????????<span?class="hljs-keyword">break</span>;??
  • ????????????????????<span?class="hljs-keyword">default</span>:??
  • ????????????????????????<span?class="hljs-keyword">throw</span>?<span?class="hljs-keyword">new</span>?IllegalArgumentException(<span?class="hljs-string">"Command?"</span>?+?cmd?+?<span?class="hljs-string">"is?unknown"</span>);??
  • ????????????????}??
  • ????????????????System.out.println(log);??
  • ????????????}??
  • ????????????<span?class="hljs-keyword">catch</span>?(IOException?e)?{??
  • ????????????????<span?class="hljs-keyword">throw</span>?<span?class="hljs-keyword">new</span>?IllegalStateException(<span?class="hljs-string">"Error?when?dump?log"</span>,?e);??
  • ????????????}??
  • ????????});??
  • ????????System.out.println();??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">void</span>?<span?class="hljs-title">snapshot</span>()?{??
  • ????????<span?class="hljs-keyword">try</span>?{??
  • ????????????raft.snapshot();??
  • ????????}?<span?class="hljs-keyword">catch</span>?(Exception?e)?{??
  • ????????????<span?class="hljs-keyword">throw</span>?<span?class="hljs-keyword">new</span>?IllegalStateException(<span?class="hljs-string">"Error?when?snapshot"</span>,?e);??
  • ????????}??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">boolean</span>?<span?class="hljs-title">isLeaderExist</span>()?{??
  • ????????<span?class="hljs-keyword">return</span>?raft.leader()?!=?<span?class="hljs-keyword">null</span>;??
  • ????}??
  • ??
  • ????<span?class="hljs-comment">//?===========================================</span>??
  • ????<span?class="hljs-comment">//??????????????Raft?API</span>??
  • ????<span?class="hljs-comment">//?===========================================</span>??
  • ??
  • ????<span?class="hljs-annotation">@Override</span>??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">void</span>?<span?class="hljs-title">roleChanged</span>(Role?role)?{??
  • ????????System.out.println(<span?class="hljs-string">"roleChanged?to:?"</span>?+?role);??
  • ????}??
  • ??
  • ????<span?class="hljs-annotation">@Override</span>??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">byte</span>[]?<span?class="hljs-title">apply</span>(<span?class="hljs-keyword">byte</span>[]?data,?<span?class="hljs-keyword">int</span>?offset,?<span?class="hljs-keyword">int</span>?length)?<span?class="hljs-keyword">throws</span>?Exception?{??
  • ????????ByteArrayDataInputStream?in?=?<span?class="hljs-keyword">new</span>?ByteArrayDataInputStream(data,?offset,?length);??
  • ????????Command?cmd?=?Command.values()[in.readByte()];??
  • ????????String?name?=?Bits.readAsciiString(in).toString();??
  • ????????System.out.println(<span?class="hljs-string">"["</span>?+?<span?class="hljs-keyword">new</span>?SimpleDateFormat(<span?class="hljs-string">"HH:mm:ss.SSS"</span>).format(<span?class="hljs-keyword">new</span>?Date())??
  • ????????????????+?<span?class="hljs-string">"]?Apply:?cmd=["</span>?+?cmd?+?<span?class="hljs-string">"]"</span>);??
  • ??
  • ????????<span?class="hljs-keyword">long</span>?v1,?retVal;??
  • ????????<span?class="hljs-keyword">switch</span>?(cmd)?{??
  • ????????????<span?class="hljs-keyword">case</span>?CREATE:??
  • ????????????????v1?=?Bits.readLong(in);??
  • ????????????????retVal?=?create0(name,?v1);??
  • ????????????????<span?class="hljs-keyword">return</span>?Util.objectToByteBuffer(retVal);??
  • ????????????<span?class="hljs-keyword">case</span>?GET:??
  • ????????????????retVal?=?get0(name);??
  • ????????????????<span?class="hljs-keyword">return</span>?Util.objectToByteBuffer(retVal);??
  • ????????????<span?class="hljs-keyword">case</span>?INCREMENT_AND_GET:??
  • ????????????????retVal?=?add0(name,?<span?class="hljs-number">1</span>L);??
  • ????????????????<span?class="hljs-keyword">return</span>?Util.objectToByteBuffer(retVal);??
  • ????????????<span?class="hljs-keyword">case</span>?DECREMENT_AND_GET:??
  • ????????????????retVal?=?add0(name,?-<span?class="hljs-number">1</span>L);??
  • ????????????????<span?class="hljs-keyword">return</span>?Util.objectToByteBuffer(retVal);??
  • ????????????<span?class="hljs-keyword">default</span>:??
  • ????????????????<span?class="hljs-keyword">throw</span>?<span?class="hljs-keyword">new</span>?IllegalArgumentException(<span?class="hljs-string">"Command?"</span>?+?cmd?+?<span?class="hljs-string">"is?unknown"</span>);??
  • ????????}??
  • ????}??
  • ??
  • ????<span?class="hljs-annotation">@Override</span>??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">void</span>?<span?class="hljs-title">readContentFrom</span>(DataInput?in)?<span?class="hljs-keyword">throws</span>?Exception?{??
  • ????????<span?class="hljs-keyword">int</span>?size?=?in.readInt();??
  • ????????System.out.println(<span?class="hljs-string">"ReadContentFrom:?size=["</span>?+?size?+?<span?class="hljs-string">"]"</span>);??
  • ????????<span?class="hljs-keyword">for</span>?(<span?class="hljs-keyword">int</span>?i?=?<span?class="hljs-number">0</span>;?i?<?size;?i++)?{??
  • ????????????AsciiString?name?=?Bits.readAsciiString(in);??
  • ????????????Long?value?=?Bits.readLong(in);??
  • ????????????counters.put(name.toString(),?value);??
  • ????????}??
  • ????}??
  • ??
  • ????<span?class="hljs-annotation">@Override</span>??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">void</span>?<span?class="hljs-title">writeContentTo</span>(DataOutput?out)?<span?class="hljs-keyword">throws</span>?Exception?{??
  • ????????<span?class="hljs-keyword">synchronized</span>?(counters)?{??
  • ????????????<span?class="hljs-keyword">int</span>?size?=?counters.size();??
  • ????????????System.out.println(<span?class="hljs-string">"WriteContentFrom:?size=["</span>?+?size?+?<span?class="hljs-string">"]"</span>);??
  • ????????????out.writeInt(size);??
  • ????????????<span?class="hljs-keyword">for</span>?(Map.Entry<String,?Long>?entry?:?counters.entrySet())?{??
  • ????????????????AsciiString?name?=?<span?class="hljs-keyword">new</span>?AsciiString(entry.getKey());??
  • ????????????????Long?value?=?entry.getValue();??
  • ????????????????Bits.writeAsciiString(name,?out);??
  • ????????????????Bits.writeLong(value,?out);??
  • ????????????}??
  • ????????}??
  • ????}??
  • ??
  • ????<span?class="hljs-comment">//?===========================================</span>??
  • ????<span?class="hljs-comment">//??????????????Counter?API</span>??
  • ????<span?class="hljs-comment">//?===========================================</span>??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">void</span>?<span?class="hljs-title">getOrCreateCounter</span>(String?name,?<span?class="hljs-keyword">long</span>?initVal)?{??
  • ????????Object?retVal?=?invoke(Command.CREATE,?name,?<span?class="hljs-keyword">false</span>,?initVal);??
  • ????????counters.put(name,?(Long)?retVal);??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">long</span>?<span?class="hljs-title">incrementAndGet</span>(String?name)?{??
  • ????????<span?class="hljs-keyword">return</span>?(<span?class="hljs-keyword">long</span>)?invoke(Command.INCREMENT_AND_GET,?name,?<span?class="hljs-keyword">false</span>);??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">long</span>?<span?class="hljs-title">decrementAndGet</span>(String?name)?{??
  • ????????<span?class="hljs-keyword">return</span>?(<span?class="hljs-keyword">long</span>)?invoke(Command.DECREMENT_AND_GET,?name,?<span?class="hljs-keyword">false</span>);??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">long</span>?<span?class="hljs-title">get</span>(String?name)?{??
  • ????????<span?class="hljs-keyword">return</span>?(<span?class="hljs-keyword">long</span>)?invoke(Command.GET,?name,?<span?class="hljs-keyword">false</span>);??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">private</span>?Object?<span?class="hljs-title">invoke</span>(Command?cmd,?String?name,?<span?class="hljs-keyword">boolean</span>?ignoreRetVal,?<span?class="hljs-keyword">long</span>...?values)?{??
  • ????????ByteArrayDataOutputStream?out?=?<span?class="hljs-keyword">new</span>?ByteArrayDataOutputStream(<span?class="hljs-number">256</span>);??
  • ????????<span?class="hljs-keyword">try</span>?{??
  • ????????????out.writeByte(cmd.ordinal());??
  • ????????????Bits.writeAsciiString(<span?class="hljs-keyword">new</span>?AsciiString(name),?out);??
  • ????????????<span?class="hljs-keyword">for</span>?(<span?class="hljs-keyword">long</span>?val?:?values)?{??
  • ????????????????Bits.writeLong(val,?out);??
  • ????????????}??
  • ??
  • ????????????<span?class="hljs-keyword">byte</span>[]?rsp?=?raft.set(out.buffer(),?<span?class="hljs-number">0</span>,?out.position());??
  • ????????????<span?class="hljs-keyword">return</span>?ignoreRetVal???<span?class="hljs-keyword">null</span>?:?Util.objectFromByteBuffer(rsp);??
  • ????????}??
  • ????????<span?class="hljs-keyword">catch</span>?(IOException?ex)?{??
  • ????????????<span?class="hljs-keyword">throw</span>?<span?class="hljs-keyword">new</span>?RuntimeException(<span?class="hljs-string">"Serialization?failure?(cmd="</span>??
  • ????????????????????+?cmd?+?<span?class="hljs-string">",?name="</span>?+?name?+?<span?class="hljs-string">")"</span>,?ex);??
  • ????????}??
  • ????????<span?class="hljs-keyword">catch</span>?(Exception?ex)?{??
  • ????????????<span?class="hljs-keyword">throw</span>?<span?class="hljs-keyword">new</span>?RuntimeException(<span?class="hljs-string">"Raft?set?failure?(cmd="</span>??
  • ????????????????????+?cmd?+?<span?class="hljs-string">",?name="</span>?+?name?+?<span?class="hljs-string">")"</span>,?ex);??
  • ????????}??
  • ????}??
  • ??
  • ????<span?class="hljs-comment">//?===========================================</span>??
  • ????<span?class="hljs-comment">//??????????????Counter?Native?API</span>??
  • ????<span?class="hljs-comment">//?===========================================</span>??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">synchronized</span>?Long?<span?class="hljs-title">create0</span>(String?name,?<span?class="hljs-keyword">long</span>?initVal)?{??
  • ????????counters.putIfAbsent(name,?initVal);??
  • ????????<span?class="hljs-keyword">return</span>?counters.get(name);??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">synchronized</span>?Long?<span?class="hljs-title">get0</span>(String?name)?{??
  • ????????<span?class="hljs-keyword">return</span>?counters.getOrDefault(name,?<span?class="hljs-number">0</span>L);??
  • ????}??
  • ??
  • ????<span?class="hljs-keyword">public</span>?<span?class="hljs-keyword">synchronized</span>?Long?<span?class="hljs-title">add0</span>(String?name,?<span?class="hljs-keyword">long</span>?delta)?{??
  • ????????Long?oldVal?=?counters.getOrDefault(name,?<span?class="hljs-number">0</span>L);??
  • ????????<span?class="hljs-keyword">return</span>?counters.put(name,?oldVal?+?delta);??
  • ????}??
  • }</code>??
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238

    3.3 運行測試

    我們分別以A、B、C為參數(shù),啟動三個JGroupsRaftTest服務(wù)。這樣會自動在C:\Users\cdai\AppData\Local\Temp下生成A.log、B.log、C.log三個日志文件夾。

    Prettyprint代碼??
  • <code?class="hljs?livecodeserver?has-numbering">cdai@vm?/cygdrive/c/Users/cdai/AppData/Local/Temp??
  • $?tree?A.<span?class="hljs-built_in">log</span>/?B.<span?class="hljs-built_in">log</span>/?C.<span?class="hljs-built_in">log</span>/??
  • A.<span?class="hljs-built_in">log</span>/??
  • |<span?class="hljs-comment">--?000005.sst</span>??
  • |<span?class="hljs-comment">--?000006.log</span>??
  • |<span?class="hljs-comment">--?CURRENT</span>??
  • |<span?class="hljs-comment">--?LOCK</span>??
  • |<span?class="hljs-comment">--?LOG</span>??
  • |<span?class="hljs-comment">--?LOG.old</span>??
  • `<span?class="hljs-comment">--?MANIFEST-000004</span>??
  • B.<span?class="hljs-built_in">log</span>/??
  • |<span?class="hljs-comment">--?000003.log</span>??
  • |<span?class="hljs-comment">--?CURRENT</span>??
  • |<span?class="hljs-comment">--?LOCK</span>??
  • |<span?class="hljs-comment">--?LOG</span>??
  • `<span?class="hljs-comment">--?MANIFEST-000002</span>??
  • C.<span?class="hljs-built_in">log</span>/??
  • |<span?class="hljs-comment">--?000003.log</span>??
  • |<span?class="hljs-comment">--?CURRENT</span>??
  • |<span?class="hljs-comment">--?LOCK</span>??
  • |<span?class="hljs-comment">--?LOG</span>??
  • `<span?class="hljs-comment">--?MANIFEST-000002</span>??
  • ??
  • <span?class="hljs-number">0</span>?<span?class="hljs-built_in">directories</span>,?<span?class="hljs-number">17</span>?<span?class="hljs-built_in">files</span></code>??
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3.3.1 分布式一致性

    首先A創(chuàng)建計數(shù)器,B“加一”,C“減一”。可以看到盡管我們是分別在A、B、C上執(zhí)行這三個操作,但三個結(jié)點都先后(leader提交日志后通知follower)通過apply()方法收到消息,并在本地的計數(shù)器Map上同步執(zhí)行操作,保證了數(shù)據(jù)的一致性。最后停掉A服務(wù),可以看到B通過roleChanged()得到消息,提升為新的Leader,并與C一同繼續(xù)提供服務(wù)。

    A的控制臺輸出:

    Prettyprint代碼??
  • <code?class="hljs?asciidoc?has-numbering"><span?class="hljs-code">-------------------------------------------------------------------??
  • GMS:?address=A,?cluster=ctr-cluster,?physical?address=2001:0:9d38:6abd:cbb:1f78:3f57:50f6:50100??
  • -------------------------------------------------------------------</span>??
  • ??
  • [0]?Create?[1]?Increment?[2]?Decrement?[3]?Dump?log?[4]?Snapshot?[x]?Exit??
  • first-applied=0,?last-applied=0,?commit-index=0,?log?size=0b:???
  • roleChanged?to:?Candidate??
  • roleChanged?to:?Leader??
  • 0??
  • <span?class="hljs-attribute">[14:16:00.744]?Apply:?cmd=[CREATE]</span>??
  • ??
  • [0]?Create?[1]?Increment?[2]?Decrement?[3]?Dump?log?[4]?Snapshot?[x]?Exit??
  • first-applied=0,?last-applied=1,?commit-index=1,?log?size=1b:???
  • <span?class="hljs-attribute">[14:16:07.002]?Apply:?cmd=[INCREMENT_AND_GET]</span>??
  • <span?class="hljs-attribute">[14:16:14.264]?Apply:?cmd=[DECREMENT_AND_GET]</span>??
  • 3??
  • ??
  • <span?class="hljs-header">index?(term):?command??
  • ---------------------</span>??
  • 1?(29):?CREATE(counter,?1)??
  • 2?(29):?INCREMENT<span?class="hljs-emphasis">_AND_</span>GET(counter)??
  • 3?(29):?DECREMENT<span?class="hljs-emphasis">_AND_</span>GET(counter)</code>??
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    B的控制臺輸出:

    Prettyprint代碼??
  • <code?class="hljs?sql?has-numbering"><span?class="hljs-comment">-------------------------------------------------------------------</span>??
  • GMS:?address=B,?cluster=ctr-cluster,?physical?address=2001:0:9d38:6abd:cbb:1f78:3f57:50f6:50101??
  • <span?class="hljs-comment">-------------------------------------------------------------------</span>??
  • ??
  • [0]?<span?class="hljs-operator"><span?class="hljs-keyword">Create</span>?[<span?class="hljs-number">1</span>]?Increment?[<span?class="hljs-number">2</span>]?Decrement?[<span?class="hljs-number">3</span>]?Dump?log?[<span?class="hljs-number">4</span>]?Snapshot?[x]?Exit??
  • <span?class="hljs-keyword">first</span>-applied=<span?class="hljs-number">0</span>,?<span?class="hljs-keyword">last</span>-applied=<span?class="hljs-number">0</span>,?<span?class="hljs-keyword">commit</span>-index=<span?class="hljs-number">0</span>,?log?<span?class="hljs-keyword">size</span>=<span?class="hljs-number">0</span>b:???
  • [<span?class="hljs-number">14</span>:<span?class="hljs-number">16</span>:<span?class="hljs-number">01.300</span>]?Apply:?cmd=[<span?class="hljs-keyword">CREATE</span>]??
  • <span?class="hljs-number">1</span>??
  • counter:?<span?class="hljs-number">2</span>??
  • ??
  • [<span?class="hljs-number">0</span>]?<span?class="hljs-keyword">Create</span>?[<span?class="hljs-number">1</span>]?Increment?[<span?class="hljs-number">2</span>]?Decrement?[<span?class="hljs-number">3</span>]?Dump?log?[<span?class="hljs-number">4</span>]?Snapshot?[x]?Exit??
  • <span?class="hljs-keyword">first</span>-applied=<span?class="hljs-number">0</span>,?<span?class="hljs-keyword">last</span>-applied=<span?class="hljs-number">2</span>,?<span?class="hljs-keyword">commit</span>-index=<span?class="hljs-number">1</span>,?log?<span?class="hljs-keyword">size</span>=<span?class="hljs-number">2</span>b:???
  • [<span?class="hljs-number">14</span>:<span?class="hljs-number">16</span>:<span?class="hljs-number">07.299</span>]?Apply:?cmd=[INCREMENT_AND_GET]??
  • [<span?class="hljs-number">14</span>:<span?class="hljs-number">16</span>:<span?class="hljs-number">14.304</span>]?Apply:?cmd=[DECREMENT_AND_GET]??
  • roleChanged?<span?class="hljs-keyword">to</span>:?Candidate??
  • roleChanged?<span?class="hljs-keyword">to</span>:?Leader</span></code>??
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    C的控制臺輸出:

    Prettyprint代碼??
  • <code?class="hljs?sql?has-numbering"><span?class="hljs-comment">-------------------------------------------------------------------</span>??
  • GMS:?address=C,?cluster=ctr-cluster,?physical?address=2001:0:9d38:6abd:cbb:1f78:3f57:50f6:55800??
  • <span?class="hljs-comment">-------------------------------------------------------------------</span>??
  • ??
  • [0]?<span?class="hljs-operator"><span?class="hljs-keyword">Create</span>?[<span?class="hljs-number">1</span>]?Increment?[<span?class="hljs-number">2</span>]?Decrement?[<span?class="hljs-number">3</span>]?Dump?log?[<span?class="hljs-number">4</span>]?Snapshot?[x]?Exit??
  • <span?class="hljs-keyword">first</span>-applied=<span?class="hljs-number">0</span>,?<span?class="hljs-keyword">last</span>-applied=<span?class="hljs-number">0</span>,?<span?class="hljs-keyword">commit</span>-index=<span?class="hljs-number">0</span>,?log?<span?class="hljs-keyword">size</span>=<span?class="hljs-number">0</span>b:???
  • [<span?class="hljs-number">14</span>:<span?class="hljs-number">16</span>:<span?class="hljs-number">01.300</span>]?Apply:?cmd=[<span?class="hljs-keyword">CREATE</span>]??
  • [<span?class="hljs-number">14</span>:<span?class="hljs-number">16</span>:<span?class="hljs-number">07.299</span>]?Apply:?cmd=[INCREMENT_AND_GET]??
  • <span?class="hljs-number">2</span>??
  • counter:?<span?class="hljs-number">3</span>??
  • ??
  • [<span?class="hljs-number">0</span>]?<span?class="hljs-keyword">Create</span>?[<span?class="hljs-number">1</span>]?Increment?[<span?class="hljs-number">2</span>]?Decrement?[<span?class="hljs-number">3</span>]?Dump?log?[<span?class="hljs-number">4</span>]?Snapshot?[x]?Exit??
  • <span?class="hljs-keyword">first</span>-applied=<span?class="hljs-number">0</span>,?<span?class="hljs-keyword">last</span>-applied=<span?class="hljs-number">3</span>,?<span?class="hljs-keyword">commit</span>-index=<span?class="hljs-number">2</span>,?log?<span?class="hljs-keyword">size</span>=<span?class="hljs-number">3</span>b:???
  • [<span?class="hljs-number">14</span>:<span?class="hljs-number">16</span>:<span?class="hljs-number">14.304</span>]?Apply:?cmd=[DECREMENT_AND_GET]</span></code>??
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.3.2 服務(wù)恢復(fù)

    在只有B和C的集群中,我們執(zhí)行了一次“加一”。當(dāng)我們重新啟動A服務(wù)時,它會自動執(zhí)行這條日志,保持與B和C的一致。從日志的index能夠看出,69是一個Term,也就是A為Leader時的“任期”,而70也就是B為Leader時。

    A的控制臺輸出:

    Prettyprint代碼??
  • <code?class="hljs?asciidoc?has-numbering"><span?class="hljs-code">-------------------------------------------------------------------??
  • GMS:?address=A,?cluster=ctr-cluster,?physical?address=2001:0:9d38:6abd:cbb:1f78:3f57:50f6:53237??
  • -------------------------------------------------------------------</span>??
  • ??
  • [0]?Create?[1]?Increment?[2]?Decrement?[3]?Dump?log?[4]?Snapshot?[x]?Exit??
  • first-applied=0,?last-applied=3,?commit-index=3,?log?size=3b:???
  • <span?class="hljs-attribute">[14:18:45.275]?Apply:?cmd=[INCREMENT_AND_GET]</span>??
  • <span?class="hljs-attribute">[14:18:45.277]?Apply:?cmd=[GET]</span>??
  • 3??
  • ??
  • <span?class="hljs-header">index?(term):?command??
  • ---------------------</span>??
  • 1?(69):?CREATE(counter,?1)??
  • 2?(69):?INCREMENT<span?class="hljs-emphasis">_AND_</span>GET(counter)??
  • 3?(69):?DECREMENT<span?class="hljs-emphasis">_AND_</span>GET(counter)??
  • 4?(70):?INCREMENT<span?class="hljs-emphasis">_AND_</span>GET(counter)??
  • 5?(70):?GET(counter)</code>??
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    http://blog.csdn.net/dc_726/article/details/48832405

    總結(jié)

    以上是生活随笔為你收集整理的分布式一致性协议Raft原理与实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    久久久久久久久久久久久9999 | 久久久毛片 | 久久成| 最近中文字幕国语免费高清6 | 欧美午夜理伦三级在线观看 | 亚洲va欧美 | 中文字幕在线观看一区二区三区 | 97国产精品 | 国产黄影院色大全免费 | 九九在线视频 | 成人黄在线 | 99色视频在线 | 国产精品v欧美精品 | 中文字幕久久精品 | 免费精品人在线二线三线 | 国产福利资源 | 超碰97人人干 | 成年人在线免费看视频 | 天天综合人人 | 亚洲情感电影大片 | 在线综合色 | 中文字幕在线日 | 国产成人99av超碰超爽 | 91精品视频免费观看 | 97精品一区二区三区 | 粉嫩av一区二区三区四区 | 日韩av免费观看网站 | 免费h精品视频在线播放 | 亚洲少妇影院 | 日日婷婷夜日日天干 | 久久精品精品 | 噜噜色官网 | 九九免费在线视频 | www操操操| 精品久久福利 | 天天色天天综合 | 国产一区二区三区高清播放 | 国产精品无av码在线观看 | 91看片淫黄大片一级在线观看 | 99精品久久久久久久 | 久久99精品久久久久久三级 | 中文字幕免 | 亚洲黄色片 | 久久久久久久久艹 | 国内丰满少妇猛烈精品播 | 一本一本久久a久久精品牛牛影视 | 精品国产亚洲在线 | 99这里只有精品视频 | www.xxx.性狂虐 | 中文字幕成人在线观看 | 久久国产精品免费 | 亚洲在线激情 | 欧美a级在线 | 免费观看黄色av | 欧美日韩高清一区二区 国产亚洲免费看 | 视频一区二区国产 | 国产精品剧情 | 欧美天堂久久 | 国产手机视频 | 亚洲高清91| 伊人婷婷综合 | 国产高清在线永久 | 国产精品久久久久久一区二区三区 | 狂野欧美激情性xxxx | 亚洲一级电影 | 99精品久久久久久久 | 国产精品videossex国产高清 | 久久免费在线观看 | 伊人精品影院 | 欧美精品久久久久久 | 亚洲国产丝袜在线观看 | 亚洲欧美日韩国产一区二区 | 免费观看成年人视频 | 欧美一区二区在线看 | 91av视频| 亚洲综合在线视频 | 一区二区三区高清不卡 | 极品美女被弄高潮视频网站 | 成人午夜精品福利免费 | 日本特黄特色aaa大片免费 | 久久99国产综合精品 | 日日爱网址 | 国产女人18毛片水真多18精品 | 97福利在线观看 | 成人毛片a | 九九热在线免费观看 | 国产精品69av | 日韩理论电影在线 | 欧美性生爱| 狠狠干干 | 日韩av在线看 | 亚洲成a人片在线观看网站口工 | www免费网站在线观看 | 在线观看激情av | 免费视频97 | www欧美xxxx | 五月激情姐姐 | 色全色在线资源网 | 精品电影一区 | 色婷婷久久久综合中文字幕 | 深夜成人av | 九九视频免费观看视频精品 | 免费看的黄色小视频 | 亚洲乱码精品 | 久久免费99 | 国内视频一区二区 | 中文一区二区三区在线观看 | 狠狠狠色丁香婷婷综合激情 | 91网在线 | 亚洲视频一级 | 永久av免费在线观看 | 久久精品三 | 91av欧美| 91热视频 | 久久精彩视频 | 福利视频一区二区 | 成人黄色小说在线观看 | 欧洲在线免费视频 | 免费在线观看黄 | 日韩视频一二三区 | 免费观看黄色12片一级视频 | www免费视频com━ | 天天干天天做天天操 | 毛片美女网站 | 最新国产精品视频 | 国产五月 | 99久e精品热线免费 99国产精品久久久久久久久久 | 亚洲视频 在线观看 | 久久电影色 | 亚洲激情在线播放 | 毛片网站免费在线观看 | 久久久久久久久久久免费视频 | 波多野结衣久久资源 | 欧美日韩中文字幕视频 | 日韩天天干 | av免费在线观看1 | 一区二区三区高清在线 | 91精品中文字幕 | 黄色软件在线观看免费 | 网站在线观看日韩 | 国产精品久久久久久久久大全 | 国产精品 视频 | 亚洲网站在线 | 91福利视频免费 | 日本精品二区 | 超碰99在线 | 日本在线观看视频一区 | 久久国内视频 | 中文字幕丝袜美腿 | 字幕网在线观看 | 国产一区二区高清不卡 | 狠狠网亚洲精品 | 成人国产一区二区 | 精品视频中文字幕 | 日韩高清在线不卡 | 色视频国产直接看 | 91免费在线视频 | 成人在线视频一区 | 99久久毛片 | 成人国产精品久久久久久亚洲 | 国内99视频 | 欧美日韩久| 99久e精品热线免费 99国产精品久久久久久久久久 | 亚洲免费成人av电影 | 精品免费久久久久 | 成人av教育 | 91视频一8mav| 美女在线国产 | 亚洲美女久久 | 在线观看中文字幕2021 | 日韩高清一二区 | 91香蕉视频好色先生 | 少妇按摩av | 人人添人人澡人人澡人人人爽 | 久久成人欧美 | 中文字幕久久网 | 正在播放五月婷婷狠狠干 | 日韩av高清在线观看 | 日韩av成人在线观看 | 四虎国产精品成人免费影视 | 亚洲情婷婷 | 日韩电影在线观看一区二区三区 | 激情综合网色播五月 | 欧美一区二区伦理片 | 在线视频婷婷 | 天天色播 | 99麻豆视频 | 在线视频 一区二区 | 国产理论免费 | 国精产品一二三线999 | 日韩欧美视频在线播放 | 伊人久久国产精品 | 97在线观视频免费观看 | 日本中文在线 | 成年人免费在线 | 丁香婷婷激情啪啪 | 亚洲动漫在线观看 | 香蕉视频在线播放 | 亚洲日韩精品欧美一区二区 | 精品a级片| 久久视频精品在线 | 99国产精品 | 激情综合色播五月 | 天天操操操操操 | 成人黄色毛片 | 免费的国产精品 | 九九热在线视频 | 九九热免费在线视频 | 色播五月婷婷 | 人人爽人人澡人人添人人人人 | 夜夜看av| 香蕉视频在线免费看 | 成人h动漫精品一区二 | 中文字幕av免费观看 | 人人澡澡人人 | 视频国产一区二区三区 | 97热在线观看 | 国产精品乱码高清在线看 | 久久精品99国产精品酒店日本 | 久久精品资源 | 色视频成人在线观看免 | 天天鲁一鲁摸一摸爽一爽 | 亚洲精品99久久久久久 | 久久影院午夜论 | 精品二区久久 | 91精选 | 日韩黄色免费 | 不卡av免费在线观看 | 国产亚洲日 | 国产明星视频三级a三级点| 91亚洲在线观看 | 日韩偷拍精品 | 午夜婷婷综合 | 国产高清在线观看av | 欧美视频18 | 久久久综合九色合综国产精品 | 国产精品乱看 | 欧美另类美少妇69xxxx | 久草综合视频 | 你操综合| 91看片在线免费观看 | 美女视频久久 | 女人高潮特级毛片 | 91精品在线麻豆 | 国产美女免费观看 | av九九| 精品在线视频一区二区三区 | 麻豆视频在线看 | 国产成人三级一区二区在线观看一 | 黄色字幕网 | 欧洲精品码一区二区三区免费看 | 91女子私密保健养生少妇 | 在线视频电影 | 成人黄色在线观看视频 | 国产香蕉视频在线播放 | 五月激情亚洲 | 久久高清精品 | 手机看片99 | 又紧又大又爽精品一区二区 | 黄色免费网战 | 欧美另类巨大 | 精品一区 在线 | 91精品国产欧美一区二区成人 | 亚洲激情在线观看 | 亚洲精品乱码久久久久 | 在线观看一级片 | 欧美午夜寂寞影院 | 久久久免费看视频 | 国产精品美女999 | 亚洲精品啊啊啊 | 国产做a爱一级久久 | 国产福利精品一区二区 | 91丨九色丨91啦蝌蚪老版 | 丁香六月天 | 极品中文字幕 | 国产在线美女 | 丝袜美女视频网站 | 91在线你懂的 | 欧美日韩高清国产 | 色噜噜狠狠狠狠色综合久不 | 天天五月天色 | 天天操天天操天天操天天操天天操天天操 | 久久精品一区二区三区视频 | www四虎影院 | 国产视频69 | 亚洲天堂网站 | 欧美色综合天天久久综合精品 | 99精品国产高清在线观看 | 亚洲精品成人免费 | 国产原创在线 | 91久久久久久久一区二区 | 免费进去里的视频 | 91久久国产精品 | 午夜电影中文字幕 | 视频国产 | 九九热免费在线视频 | 6699私人影院 | 久久婷婷一区二区三区 | 在线免费黄 | 亚洲欧美一区二区三区孕妇写真 | 亚洲最大成人免费网站 | 久精品视频免费观看2 | 中文字幕在线观看免费 | 亚洲综合少妇 | 国产一级片网站 | 免费在线观看av网站 | a在线免费观看视频 | 99久久这里只有精品 | 国产无套精品久久久久久 | 欧美色久| 99精品国产aⅴ | 国产精品久久久久久久久婷婷 | 亚洲国产成人精品在线观看 | 不卡中文字幕在线 | 亚洲黄色大片 | 久草免费新视频 | 久久综合久久综合九色 | 狠狠干夜夜操天天爽 | 91福利视频免费观看 | 99中文字幕在线观看 | 日日麻批40分钟视频免费观看 | 日韩免费三区 | www.福利视频 | 91探花在线 | 91视频高清免费 | 伊人资源视频在线 | 免费日韩 精品中文字幕视频在线 | 天天色天天爱天天射综合 | 日本中文字幕在线电影 | 国产综合激情 | 亚洲黄色区 | 久久99婷婷 | 亚洲一区二区三区在线看 | 久久有精品 | aaa亚洲精品一二三区 | 91免费视频网站在线观看 | 激情偷乱人伦小说视频在线观看 | av五月婷婷| 婷婷久久网站 | 一区二区三区免费在线播放 | 午夜久久影视 | 91视频 - v11av| 日韩av免费在线电影 | 久久国产精品99国产 | 国产成人精品一区一区一区 | 久久有精品 | 人人要人人澡人人爽人人dvd | 久久久久久久久久久网站 | 国产成人精品国内自产拍免费看 | 天天综合网天天 | 99久久夜色精品国产亚洲96 | 欧美成人h版在线观看 | 激情影院在线观看 | 一区二区 久久 | 成人av久久| 在线中文字幕电影 | 色狠狠综合天天综合综合 | 亚洲网站在线 | 99在线播放| 久久精品国产精品亚洲精品 | 国产精品福利视频 | 人人精品 | 亚洲午夜久久久综合37日本 | 在线观看中文字幕 | av黄色亚洲| 日韩欧美在线视频一区二区 | 久久综合中文色婷婷 | 日韩一区二区三 | 在线v片| 91在线国内视频 | 国产精品999久久久 久产久精国产品 | 国产一级电影免费观看 | 久久人人精品 | 亚洲成人xxx | 国产偷v国产偷∨精品视频 在线草 | 五月天久久久久久 | 91免费版在线 | 夜夜操天天操 | 日韩偷拍精品 | 丁香久久综合 | 香蕉视频在线播放 | 五月激情久久久 | 色婷婷丁香 | 精品欧美小视频在线观看 | 免费观看的av网站 | 免费又黄又爽的视频 | 国产欧美日韩视频 | 高清有码中文字幕 | 91在线入口| 国产精品成人一区二区 | 国产三级精品在线 | 在线观看视频国产一区 | 激情视频免费观看 | 久久精品4| 热久久最新地址 | 国产免费又粗又猛又爽 | av电影免费在线看 | 人人澡人人爽 | 色五月激情五月 | 国产乱对白刺激视频在线观看女王 | 色橹橹欧美在线观看视频高清 | 久久久久亚洲精品 | 91资源在线免费观看 | 日韩两性视频 | 超碰在线日本 | 蜜桃麻豆www久久囤产精品 | 久久er99热精品一区二区 | 欧美日本国产在线观看 | 亚洲国产成人在线观看 | 69欧美视频| 亚洲成人国产精品 | 亚洲精品一区二区三区在线观看 | 亚洲成人av在线播放 | 黄色a一级视频 | 国产永久免费高清在线观看视频 | 欧美日韩中字 | 欧美日韩18| 最近中文字幕国语免费高清6 | 国产精品第 | 69人人 | av高清不卡| 亚洲情影院 | 精品亚洲视频在线 | 四虎成人网 | 亚洲伦理中文字幕 | 在线亚洲午夜片av大片 | 国产一区二区三区高清播放 | 国产男男gay做爰 | 国产一级精品视频 | 激情视频一区二区三区 | 亚洲自拍偷拍色图 | 欧美aaa大片 | 999久久久免费精品国产 | 狠狠色丁香婷婷综合橹88 | 午夜久久影视 | www.天天射.com | 婷婷午夜天 | 亚洲黄污| 999热线在线观看 | 九九久久久 | 日韩三级免费观看 | 五月婷丁香网 | a视频免费看 | 亚洲视频2| 美女天天操 | 婷婷伊人五月 | 欧洲视频一区 | 国产一区二区三区黄 | 免费视频国产 | 午夜精品久久久久久久久久 | 蜜桃av观看 | 欧美性久久久久久 | 亚洲天堂网视频在线观看 | 亚洲六月丁香色婷婷综合久久 | 激情视频在线观看网址 | 天天操网址 | 九九综合在线 | 久草在 | 天堂av免费观看 | 亚洲国产小视频在线观看 | 337p日本欧洲亚洲大胆裸体艺术 | 国产色区 | 超碰97在线人人 | 午夜视频久久久 | av不卡中文字幕 | 69亚洲乱| 男女拍拍免费视频 | 特级大胆西西4444www | 日韩在线中文字幕 | 日韩av在线看 | 日本精品久久久一区二区三区 | 成人在线观看资源 | 国产精品久久久久久久av电影 | 日本免费久久高清视频 | 5月丁香婷婷综合 | 国内精品在线观看视频 | 免费网站黄 | 精品国产乱码久久久久久久 | 日日干夜夜草 | 国产一级高清视频 | 99热这里有 | www.xxxx变态.com | 一本一本久久a久久精品综合小说 | 黄色app网站在线观看 | 欧美日韩精品免费观看视频 | 精品免费观看 | 91看片淫黄大片在线播放 | 91精品久久久久久久91蜜桃 | 国产精品免费久久久久久久久久中文 | 色综合久久88色综合天天人守婷 | 在线va视频 | 日韩精品三区四区 | 91成品人影院 | 精品视频123区在线观看 | 免费看一及片 | 免费在线观看成年人视频 | 97在线精品视频 | 亚洲精品美女久久久 | 激情视频免费在线 | 欧美激情视频一二区 | 久久精品专区 | 亚洲免费a | 中文字幕精品一区 | 免费日韩一级片 | 国产手机在线观看 | 五月婷婷视频在线 | 国产剧情一区在线 | 欧美性另类 | 久久伊人爱 | 五月激情五月激情 | 久久艹影院 | 日韩av福利在线 | 在线精品视频免费观看 | 欧美色伊人 | 久草久| 免费看黄的视频 | 国产又粗又硬又爽的视频 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 一区二区三区四区五区在线视频 | 麻豆 videos| 最近中文字幕高清字幕免费mv | 精品国产亚洲日本 | 91香蕉视频好色先生 | 亚洲精品欧美专区 | 色婷婷亚洲 | 国产在线一线 | 日本精品午夜 | 久草在线播放视频 | 在线国产高清 | 99九九免费视频 | 久草在线免费新视频 | 免费在线观看成人 | 日韩电影在线观看中文字幕 | 在线视频 一区二区 | 在线观看成人网 | 激情综合色图 | 亚洲激情电影在线 | 国产91成人 | 操操操日日| 玖玖999| av电影在线免费观看 | 国产精品视频久久 | 日韩视频在线播放 | 欧美精品一区在线发布 | 国产精品日韩在线 | 日韩成人精品一区二区三区 | 国产在线观看地址 | 精品9999| 在线免费中文字幕 | a色视频 | 狠狠的操狠狠的干 | 久久精品一 | 国产999精品久久久久久 | 国产小视频国产精品 | 久草在线在线精品观看 | 日韩黄色免费在线观看 | 中文亚洲欧美日韩 | 欧美精彩视频 | 精品一区二区三区久久久 | 国内免费的中文字幕 | 国产色爽 | 99热官网 | 在线国产片 | 国内精品久久天天躁人人爽 | 亚洲免费不卡 | 日韩在线观看视频在线 | 欧美二区视频 | 操少妇视频 | 伊香蕉大综综综合久久啪 | 一区二区视频欧美 | 久久国产剧场电影 | 久久一本综合 | av理论电影 | 在线精品一区二区 | 国产一区二区三区免费在线 | 亚洲三级黄色 | 青青河边草观看完整版高清 | 午夜av免费观看 | 欧美精品久久久久久久久久久 | 天天爱综合| 一区二区三区精品在线视频 | 成人黄色av网站 | 日韩精品欧美专区 | 国产精品自产拍在线观看中文 | 欧美亚洲国产精品久久高清浪潮 | 久久区二区 | 欧美性色19p | 国产拍在线 | 亚洲精品影院在线观看 | 91观看视频| 精品专区一区二区 | 久久艹中文字幕 | 天天操天天操天天操 | 亚洲色图av| 久草精品视频在线看网站免费 | 在线国产视频观看 | 国产一级免费片 | 亚洲精品在线看 | 亚洲国产精品一区二区久久hs | 麻豆一精品传二传媒短视频 | 91中文字幕一区 | 香蕉视频在线免费 | 欧美少妇的秘密 | 亚洲欧美日本一区二区三区 | www久久久| 日本一区二区高清不卡 | 九九久久成人 | www.久久精品视频 | 天天操天天干天天综合网 | 免费精品在线 | 欧美成人精品欧美一级乱黄 | 欧美与欧洲交xxxx免费观看 | 婷婷五月在线视频 | 五月花激情 | 日韩av网址在线 | 国产综合片 | 日本中文一级片 | 亚洲欧美激情精品一区二区 | 亚洲色图 校园春色 | 香蕉视频久久久 | 亚洲国产精品500在线观看 | a级黄色片视频 | 久久久久久久久久久久亚洲 | 国内精品久久久久久久97牛牛 | 久草在线免费资源 | 久草视频免费观 | 日韩av一区在线观看 | 久久人人爽爽人人爽人人片av | av一区二区三区在线播放 | 在线看91| 免费看的av片 | 日操干| 国产涩涩网站 | 日韩av成人 | 99热手机在线观看 | 中文字幕在线字幕中文 | 丝袜少妇在线 | 欧美 日韩 性 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 日韩在线电影一区二区 | 超碰在线官网 | 色94色欧美 | 精品国产伦一区二区三区观看方式 | 色婷婷伊人| 婷婷中文字幕综合 | 亚洲成av片人久久久 | 日韩精品视 | 久久一区91| 精品综合久久 | 欧美日本三级 | 日韩电影精品一区 | 国产999| 日本久久精品 | 国产裸体视频bbbbb | 一区免费观看 | 伊人狠狠 | 永久免费精品视频网站 | 国产视频一区二区在线 | 国产高清免费av | 婷婷在线视频 | 欧美另类xxx| 天天天天天干 | 黄av在线| 亚洲无人区小视频 | 中文字幕a∨在线乱码免费看 | 麻豆一二三精选视频 | 成年人免费电影在线观看 | 欧美a视频在线观看 | 在线国产专区 | 欧美少妇的秘密 | 狠狠狠狠狠狠狠干 | 在线电影 一区 | 成人国产一区 | 99 久久久久 | 九九精品毛片 | 日韩精品一区二区在线 | 婷婷视频导航 | 日本福利视频在线 | 很黄很黄的网站免费的 | 久久久久黄色 | 91精品国产欧美一区二区 | 日本精品久久久久 | 91成人免费看片 | 天天操夜夜看 | 免费日韩 | 日本中文字幕网址 | 黄色特级一级片 | 欧美二区在线播放 | www.xxx.性狂虐| av中文国产 | 69中文字幕| www.com.日本一级 | 超碰97久久| 国产成人精品三级 | 黄色国产区 | 国产精品二区三区 | av免费在线观 | 欧美专区日韩专区 | 中文字幕中文字幕 | 中文字幕不卡在线88 | 婷婷伊人五月天 | 国产精品久久久久久久久搜平片 | 91香蕉视频在线下载 | 国产黄色大片免费看 | 国产在线日本 | 综合网中文字幕 | 99视频这里只有 | 欧美另类69| 国产黄色成人 | 在线观看国产 | 国产91区| 久草网站 | 人成午夜视频 | 四虎影视成人精品国库在线观看 | 97精品国产97久久久久久久久久久久 | 国产成人久久77777精品 | 国产码电影 | 日韩激情片在线观看 | av短片在线 | 久久夜视频 | 色www免费视频 | 亚洲va欧美va人人爽春色影视 | 夜夜爽夜夜操 | 亚洲激情 欧美激情 | 成人免费视频视频在线观看 免费 | 日本精品视频免费观看 | 久久久久9999亚洲精品 | 欧美午夜性 | 亚洲无吗av | 在线观看一区二区精品 | 激情五月激情综合网 | 99自拍视频在线观看 | 欧美视屏一区二区 | 玖玖在线精品 | 黄色精品一区 | www.黄色网.com | 久久国产系列 | www五月天com | 天天干天天干天天干天天干天天干天天干 | 国产精品久久99综合免费观看尤物 | 日韩成人在线一区二区 | 国产精品一级视频 | 91入口在线观看 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 精品亚洲视频在线 | 日韩电影在线看 | 激情影院在线 | av在线网站观看 | 精品一区二区av | 999久久久欧美日韩黑人 | 国产字幕在线看 | 久久线视频 | 中文字幕一区二区三区四区在线视频 | 免费欧美| av亚洲产国偷v产偷v自拍小说 | 国产视频亚洲 | 久久久网址 | 免费 在线 中文 日本 | 一区中文字幕在线观看 | 亚洲精品美女在线 | 国产麻豆精品一区二区 | 久久国产精品99国产精 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 成人av一区二区兰花在线播放 | 亚洲激情中文 | 精品一区二区在线观看 | 国产精品日韩在线播放 | 欧美成天堂网地址 | 99综合电影在线视频 | 国产成人久久av免费高清密臂 | 一 级 黄 色 片免费看的 | 亚洲人成人在线 | 伊人资源站 | 久久国产精品色婷婷 | 亚洲高清视频一区二区三区 | 久久国产精品电影 | 亚洲第一成网站 | 天堂av免费观看 | 九九av| 久久精品一区二区三区四区 | 欧美精品久久人人躁人人爽 | 免费看v片网站 | 国产精品嫩草影院123 | 91在线区 | 人人射网站| 亚洲春色综合另类校园电影 | 免费在线黄 | 久久精品久久精品久久精品 | 91大神在线观看视频 | 成人精品在线 | 亚洲欧洲成人精品av97 | 国产中文字幕视频在线 | 国产成人av电影 | 免费看的黄网站软件 | 91视频久久 | 亚洲成a人片在线观看中文 中文字幕在线视频第一页 狠狠色丁香婷婷综合 | 美女免费电影 | 欧美日韩在线观看一区二区 | 国产高清av免费在线观看 | 97超碰人人澡| 综合在线色 | 久久久性 | 欧美热久久 | 91亚洲精 | 福利视频在线看 | 欧美一级看片 | av免费网 | 国产在线视频一区二区三区 | 久久国产福利 | 一级黄色a视频 | 午夜精品电影一区二区在线 | 久久神马影院 | 日韩中文字幕免费视频 | 亚洲国产影院 | 激情网在线视频 | 午夜视频福利 | 狠狠色丁香久久综合网 | 国产福利91精品张津瑜 | 91网址在线看 | 天天操天天操 | 91亚色在线观看 | 天天色综合久久 | 一级黄色在线视频 | 精品国产精品一区二区夜夜嗨 | 欧洲精品视频一区二区 | 在线高清 | 精品专区 | 在线精品视频免费观看 | 最近能播放的中文字幕 | 福利在线看片 | 国产精品久久久久久99 | 中文字幕免费播放 | 欧美成天堂网地址 | 在线色亚洲 | 国产录像在线观看 | 91视频高清免费 | www.久久久.com | 国产啊v在线 | 久久综合中文字幕 | 中文字幕 国产视频 | 国产精品欧美久久 | 国产精品毛片一区二区在线看 | 欧美一级性 | 国产真实精品久久二三区 | 国内精品久久久久久久久 | 欧美一二三视频 | 黄色成人毛片 | 天天综合网久久综合网 | 婷婷六月天综合 | 久久综合色天天久久综合图片 | 久久国产免费看 | 日韩免费一级a毛片在线播放一级 | 日韩在线视频国产 | 亚洲妇女av | 日韩电影在线看 | 一本一本久久a久久精品牛牛影视 | 最新超碰在线 | 91cn国产在线 | 二区在线播放 | 亚洲精品国产免费 | 韩国av三级 | 日韩在线视频免费观看 | 亚洲国产欧美一区二区三区丁香婷 | 欧美久久久久久久久中文字幕 | 欧美日韩三区二区 | 97超级碰碰碰视频在线观看 | 久久视频二区 | 亚洲一区精品人人爽人人躁 | 在线观看mv的中文字幕网站 | 91视视频在线直接观看在线看网页在线看 | 午夜精品久久久久久久99婷婷 | 欧美日比视频 | 亚洲国产理论片 | 91精品国产亚洲 | 欧美乱码精品一区二区 | 99久久精品免费看国产一区二区三区 | 亚洲影院国产 | 国产成人综 | 狠狠色丁香婷婷综合最新地址 | 在线免费国产 | 1024久久 | 一区二区三区在线观看免费 | 久免费 | avwww在线| 九九九在线观看视频 | 国产探花 | 免费91在线观看 | 午夜免费视频网站 | 91精选在线观看 | 久草在线视频新 | 丁香六月婷婷开心 | 日韩成人不卡 | 中文一区在线观看 | av女优中文字幕在线观看 | 中文字幕视频观看 | 国产三级国产精品国产专区50 | 亚洲天堂网在线观看视频 | 92精品国产成人观看免费 | 国产天天爽| 日韩视频免费在线观看 | 久久夜色精品国产欧美乱 | 97超碰在线免费 | 亚洲国产成人精品在线观看 | 999视频精品 | 高清色免费 | 中文字幕日本电影 | 天天综合精品 | 色99之美女主播在线视频 | 久久免费a| 日日综合 | 国内久久久久 | 成人免费 在线播放 | av在线com | 国产精品女同一区二区三区久久夜 | 在线播放 日韩专区 | 国产第一页在线观看 | 免费看污网站 | av免费在线网站 | 国产免费不卡av | 免费视频一区二区 | 91在线视频免费观看 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 色婷婷播放 | 69亚洲视频| 久操视频在线免费看 | 综合网伊人| 国产精品毛片久久久 | 久久精品视频在线免费观看 | 国产精品久久艹 | 国产日韩欧美在线观看视频 | 日韩激情视频在线 | 西西4444www大胆艺术 | 国产精品伦一区二区三区视频 | 久久99亚洲网美利坚合众国 | 国产亚洲观看 | 国产成人综合图片 | 人人爽人人爽人人爽 | 国产vs久久| 亚洲成年人免费网站 | 最新av免费 | 亚洲精品9 | 中文字幕在线视频一区 | 国产精品伦一区二区三区视频 | 国产精品视频久久久 | 国产一区视频在线观看免费 | 在线免费av电影 | 天天干天天色2020 | 在线观看视频黄色 | 一区二区中文字幕在线播放 | 久久久久久久久久久黄色 | 亚洲无人区小视频 | 久久久精品电影 | 欧美日韩国产区 | 日韩国产精品久久 | 91亚色在线观看 | 日韩久久视频 | 爱爱av网 | av在线电影网站 | 又污又黄的网站 | 日韩 在线 | 久久精品国产一区二区三区 | 91精品麻豆| 亚洲精品国产第一综合99久久 | 国产99久久久国产精品成人免费 | av网站播放| 久久精品91久久久久久再现 | 国产精品国产三级国产专区53 | 亚洲精品456在线播放乱码 | av直接看 | 超碰av在线免费观看 | 日韩精品免费一区二区三区 | 国产男女无遮挡猛进猛出在线观看 | 日韩国产精品久久久久久亚洲 | 欧美成人一区二区 | 在线观看不卡的av | 在线免费观看国产视频 | 99精品国产福利在线观看免费 | 人人爱夜夜操 | 国产精品18久久久久久首页狼 | 91爱爱视频| 亚洲精品1区2区3区 超碰成人网 | 久草9视频 | 天天激情天天干 | 久久综合给合久久狠狠色 | 成人免费观看在线视频 | 精品国产99| 不卡精品 | 国产一级电影网 | 天天夜夜亚洲 | 久久精品婷婷 | 欧美成人手机版 | 福利一区二区在线 | 美女网站视频色 | 中文字幕在线看视频国产 | 免费在线观看av网站 | 国产在线观看91 | 日韩欧美一区二区在线播放 | 97超碰人人干 |