• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            專職C++

            不能停止的腳步

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              163 Posts :: 7 Stories :: 135 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(28)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            來源:http://blog.csdn.net/pingnning/archive/2009/10/24/4724377.aspx
            "tyrant分析-總體設計"中已經提到,slave起一個線程(do_slave)做主從復制,它和master建立tcp連接,發送請求命令和起始時間rts +1(上次的更新時間加1秒)給master,然后循環的從master那里接收一條條的記錄,更新自己db、ulog和rts file。do_slave是以1秒為頻率執行的。(實際是等待一次do_slave執行完畢后,再等待1秒,然后進入下一次的do_slave,依次循環。所以"以1秒為頻率執行"的表達似乎并不準確。從下面可以看到一次do_slave有可能執行較長時間)

            主從復制是一個主、從交互的過程。本節依次描述協議細節、slave細節、master細節。

            ------------

            協議細節:

             do_slave(slave)          do_repl(master)

             -------------------

             | TTMAGICNUM|

             | TTCMDREPL  |

             | ts (+1)        |

             | sid         |   send and recv (with timeout)

             -------------------  ------------------------>

                        -----------------

                 send and cnd wait      | NOP      |

                 <---------------------      -----------------

                        -----------------------

                        | TCULMAGICNUM |

                        | rts         |

                        | rsid         |

                        | rsiz          |

                   content send       | rsiz-content        |

                 <---------------------      ------------------------

                   next content send

                 <---------------------

                 ......

            rsiz-content格式:

              MAGIC + cmd + ksize + vsize + key + value

            其中:

             cmd: TTCMDPUT | TTCMDOUT | ...

             ksize,vsize分別是本條記錄的key,value的長度;

             slave就根據cmd和key-value對對db進行相應操作。

            master的ulog由一條條獨立記錄組成,每條記錄有相同格式:

             MAGIC + ts + sid + size + content

            其中:

             ts : 本條記錄對應的時間戳。slave請求時會帶上上次更新時間戳,master根據它們來判斷需要傳送哪些記錄給slave;

             sid : server id. 唯一標識server。

             size : 后面"content"長度

             content格式即上面"rsiz-content"的格式,描述了一條key-value對以及對它做的操作命令。

            --------------

            do_slave流程:

             打開rts文件(默認為ttserver.rts),讀取上次的rts(replication timestamp);

             和master建立socket連接(參數:-mhost,-mport),并設置socket選項:

              SO_RCVTIMEO、SO_SNDTIMEO - 發送、接收超時設置為0.25秒

              TCP_NODELAY - 禁止nagle算法

             發送REPL請求(詳見協議細節);

             循環:

              用recv接收數據;

              解析接收數據,根據數據中指定的命令(TTCMDPUT、TTCMDOUT等)更新db和slave自己的ulog;

              用接收數據里的最新rts更新slave的rts文件;

             最后關閉連接

            解釋:

             1、slave不能因偶然的網絡故障之類永遠阻塞在send或recv中,這樣的話更新就會永遠停滯了。所以它要設置發送和接收的超時。如果超時,則這次do_slave失敗,等待1秒后進行下一次。send | recv失敗時,它并不會用新的rts(可能壓根就沒請求到它)去更新自己的rts文件,所以下次還是會用舊的rts去請求,所以不會因do_slave失敗而導致slave數據不全。

             2、禁止nagle算法是因為有小數據的命令包的交互,不能拖延。

             3、請求只發送一次,但數據是一直循環接收的。循環失敗的條件是:recv失敗(或超時),收到SIGINT或SIGTERM,或是更新庫失敗或寫文件失敗等;

            ---------------

            do_repl流程:

             根據slave的請求ts找到合適的ulog文件(文件名使用數字編號,依次遞增),邏輯是:

              從編號最大的文件依次往編號小的文件:(編號越大,ulog內容越新,ts越大)

               打開文件查看它的第一條記錄的ts,如果請求ts大于它,則該文件即為要找的ulog文件。

             循環。當對端連接未關閉且沒收到SIGINT、SIGTERM信號時:

              發送NOP(測試對端連接是否關閉);

              pthread_cond_timedwait等待ulog更新信號,超時值為1秒;

              循環:

               一次讀取一條日志記錄;

               加上頭部(MAGIC,rts,rsid,rsiz。見"協議細節");

               發送給slave。

               當上面讀取日志失敗或發送失敗時,退出循環。

            解釋:

             1、ulog由一條條的記錄組成,每條記錄有相同格式: MAGIC + ts + sid + size + content

             2、因為ulog文件有大小上限,所以寫滿一個后會寫下一個。按上面所說那樣,文件名用數字編號,依次遞增;

             3、找合適ulog文件的邏輯。因為是按內容從新到舊的順序(也即ts從大到小的順序)查看文件,所以最先找到的其中第一條記錄ts小于slave所請求ts的那個文件就是合適的文件;(該文件里ts會隨著一條條記錄慢慢增加,直到大于等于請求ts,這時就到了slave需要的數據處);

             4、關于這兩層循環的邏輯。內層循環一次發送一條記錄,它是希望盡可能多地發送記錄給slave,直到發送完所有記錄(意外發送故障不考慮下)。退出到外層邏輯時希望這時又有ulog更新,能繼續進行發送。這兩層循環的目的都是希望能盡可能長地維持與slave的一次連接,從而讓數據的同步更及時。

             

            本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/pingnning/archive/2009/10/24/4724377.aspx

            posted on 2010-12-28 23:00 冬瓜 閱讀(895) 評論(0)  編輯 收藏 引用 所屬分類: 轉貼
            久久婷婷国产综合精品| 狠狠精品久久久无码中文字幕| 久久久久无码精品| 久久综合给合综合久久| 老男人久久青草av高清| 国内精品久久人妻互换| 久久天天躁狠狠躁夜夜av浪潮 | 青青草原综合久久| 久久精品极品盛宴观看| 青青青青久久精品国产| 久久人做人爽一区二区三区| 久久午夜电影网| 国产69精品久久久久APP下载| 九九99精品久久久久久| 久久久久久精品无码人妻| 很黄很污的网站久久mimi色| 久久久久久国产精品免费无码 | 国产成人久久精品区一区二区| 久久综合伊人77777| 91久久精品视频| 久久精品国产亚洲av水果派| 久久91精品国产91久| 99久久国产综合精品五月天喷水| 久久人人爽人人爽人人片AV东京热 | 国产精品青草久久久久福利99| 1000部精品久久久久久久久| 久久婷婷国产剧情内射白浆| 狠狠人妻久久久久久综合| 91精品国产高清久久久久久io| 一本色综合网久久| 麻豆av久久av盛宴av| 青青青青久久精品国产h久久精品五福影院1421 | 亚洲欧美一区二区三区久久| 久久国产V一级毛多内射| 久久夜色精品国产噜噜噜亚洲AV| 伊人久久大香线蕉AV一区二区| 久久久久九九精品影院| 久久久久国产亚洲AV麻豆| 久久久久国产一区二区| 久久无码精品一区二区三区| 热久久国产欧美一区二区精品 |