C1. 由 FIN 所引發的 TCP 連線中斷
當 TCPCP 運作行程正常或不正常中斷時,該行程所使用的 descriptor 都將會被關閉,
使得該行程發送 FIN 到 client 端來結束連線。一旦 client 端結束連線,standby 便無法再恢 復連線。另外假如在當 standby 啟用原 active 的 IP 與設定 ICI 至 kernel 這段期間,client 有 封包傳送給 standby(如圖三十三),此時也會引發 FIN 的傳送。解決方法是在 failover 發生 時啟動 filtering 機制,使得 FIN 無法傳送到 client 端,此時便可順利恢復 client 與 standby 之間的連線。實現上可藉由行程不正常中斷時,接收作業系統所發出的 signal,並在 signal handler 裡啟動 filter 的機制。
C2. active 與 standby 之間 TCP 連線狀態的衝突
由於 HA Middleware Generic Functionality 中的 checkpoint 是間歇性地運作且 failover 的 圖三十二、應用程式設計架構.
圖三十三、client 有封包傳送給 standby 時所引發 FIN 的傳送情形
狀況大都是不可預期的,所以從上次做 checkpoint 的時間點到 failover 發生的時間點之間,
可能會使得 TCP 的 send/receive buffer 的資料或 TCP 連線狀態不一致的問題。以下將針對 server 接收來自 client 端資料的部份,以及 server 傳送至 client 端資料的部份,分別討論其 可能發生的問題以及可能的解決方法。此外尚有一些提高效能的可能作法。
z server 接收自 client 的資料
如圖三十四所示,在上次 checkpoint 至 failover 的期間,client 可能已經從其 send buffer 送出一些資料、server 可能已經回了 acks 他所收到的資料、而且 server application 可能已經 從其 receive buffer 擷取出了資料。此時,當 standby server 嘗試利用上一次的 checkpoint 資 料來恢復服務時,client 的 send buffer 此時已無法再重送稍早之前的資料了(因為已經被 acknowledged 了)。
此狀況在某些應用服務下是可以容忍的。例如 SSH/Telnet、SIP 或其它強調即時性的連 線,舊資料皆可能不會影響之後的運作,因此可以丟棄。此類的連線在服務轉移到 standby server 之後,只須利用來自 client 的封包,將 sequence number 等 TCP 連線的資訊更新即可。
而對於強烈要求資料一致性的服務,我們希望可以延遲 server 端 ack 的傳送,直到下 次 checkpoint 的時候,才傳遞自上次 checkpoint 到此次 checkpoint 間收到的資料的 ack,藉 此讓 client 有機會重傳因 active server 發生錯誤而遺失的資料。但此方法可能會造成效能的 降低,必須設法將影響降至最低。例如盡可能在 client 傳送 congestion window 大小的資料 量之前,就執行 checkpoint,並回傳 ack 給 client,當 client 收到 ack 後,就可持續傳遞新的 資料,藉此保持 client 的傳送速度。此外,延遲 server 端 ack 的傳送將會造成 client 對於 round-trip time 的誤判,亦需設法排除。
z server 傳送資料至 client
當 active server 發生錯誤而將服務轉移到 standby server 後,standby server 會重新傳送 舊資料,若碰巧舊資料的 sequence number 與 client 欲接收的新資料的 sequence number 相 同,而將舊資料誤以為新資料,並將其接收。此情形稱為 sequence number wrapped。
要防止此情形發生的第一種方法是:必須確保兩次 checkpoint 的時間之間,不會傳送 超過總 sequence number 一半大小的資料量,即 231bytes。因為若 server 連續送出 sequence number 0~231(共 231+1 bytes)的資料後,仍無執行 checkpoint,此時發生 failover 的話,由於 client 預期接收的資料的 sequence number 已變更為 231+1~232-1 以及 0 (共 231bytes),而 standby server 退回上次 checkpoint,重新傳送已傳送過的 sequence number 為 0 的舊資料,
此資料卻被 client 誤認為新資料而將其接收,造成 sequence number wrapped。故須限定兩次 圖三十四、當 failover 發生在 checkpoint 之間時所會產稱的問題
checkpoint 的時間內,不能傳送超過 231bytes 的資料量,以排除此問題。
第二種方法則是使用 Protect Against Wrapped Sequence number(PAWS)機制,也就是在 packet 中加入 timestamp。client 除了確保新資料的 sequence number 沒錯以外,還須確保新 資料的 timestamp 比舊資料的 timestamp 新才會將其接收,藉此避免 sequence number wrapped 的問題。利用此方法的話,則兩次 checkpoint 的時間內就沒有不得傳送超過 231bytesr 資料量的限制,藉此可以放寬 checkpoint 的週期,降低 server 花在執行 checkpoint 上的負 擔。但若使用此機制,則必須將 active server 與 standby server 的時間同步才行,以免 standby server 重傳資料時,卻因 timestamp 的不同步,導致 client 誤將舊資料當成新資料接收,或 將新資料當成舊資料丟棄。
C3. active 與 standby 之間同步資料量
TCP 連線的 send/receive buffer,佔了 active 與 standby 之間連線狀態同步的絕大部份。
在一擁有大量連線的 server 中執行 checkpoint 時,大量的 TCP 連線狀態資料及 send/receive buffer 等資料須被記錄及同步到 standby server。隨著連線個數的增加,checkpoint 的執行對 於系統的負擔也越重。為改善其效能,可將連線類型加以分類。對於不要求資料一致性的 連線,如 SSH/Telnet、SIP 或其它強調資料即時性的連線,可不必記錄與同步其 send/receive buffer 的資料。當此類連線所佔比例高時,可大量減少平均每個連線需記錄及同步的資料 量,改善執行 checkpoint 所需的負擔,提高最大的可連線數。另外,亦可調整 TCP 連線的 buffer size,以空間換取更多連線的存活率,如圖三十五所示。
C4. 新連線的壅塞控制(congestion control)
目前 TCPCP 對於在連線轉移時所面對的 congestion control 的方面,是採取高度保守的 方法,即在連線轉移後所採取的 congestion control 都是由 slow-start 開始。
圖三十六表示當連線轉移到 standby 端時所可能採取的 congestion control state。若 standby server 端位於連線特徵已知的環境中,例如 active 與 standby 同在一個 LAN 中,則 可延用連線轉移前的 congestion control state;反之,如果 server 端位於連線特徵未知的環境 中,例如 active 與 standby 在 WAN 中,則進入 slow-start 的狀態,也就是從 congestion window
= 1 可能會是比較保險的方法。
另外也可以嘗試採取 congestion control 中 fast recovery 的方法,將原本 congestion control state 中 congestion window 與 slow-start threshold 變成一半,或者直接延用原本的 congestion control state,如此就不用從 slow-start 開始。