• <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 冬瓜 閱讀(892) 評論(0)  編輯 收藏 引用 所屬分類: 轉貼
            狠狠人妻久久久久久综合蜜桃| 国产L精品国产亚洲区久久| 精品久久久无码中文字幕| 性做久久久久久久| 久久99精品久久久大学生| 亚洲乱码日产精品a级毛片久久 | 无码国内精品久久人妻麻豆按摩| 99久久久精品| 精品久久久久香蕉网| 久久久精品2019免费观看| 久久精品人人槡人妻人人玩AV| 天天躁日日躁狠狠久久| 人人狠狠综合久久88成人| 色综合久久中文字幕无码| 伊人久久大香线蕉综合Av | 久久狠狠爱亚洲综合影院| 久久亚洲AV无码精品色午夜| 久久精品国产亚洲av麻豆图片| 亚洲精品乱码久久久久久按摩 | 久久er99热精品一区二区| 久久成人国产精品| 精品国产一区二区三区久久| 狠狠狠色丁香婷婷综合久久俺| 久久线看观看精品香蕉国产| 久久夜色精品国产www| 一本色道久久综合狠狠躁篇| 亚洲∧v久久久无码精品| 久久综合综合久久97色| 免费一级做a爰片久久毛片潮| 精品久久久久久国产| 韩国无遮挡三级久久| 免费一级欧美大片久久网| 久久夜色精品国产噜噜亚洲AV| 狠狠色丁香婷婷久久综合不卡 | 久久这里只有精品首页| 久久久久久午夜成人影院| 色偷偷888欧美精品久久久| 久久人人爽人人爽人人片AV高清 | 久久国产精品一区二区| 无码乱码观看精品久久| 国产精品一久久香蕉国产线看观看|