本文章是由機器翻譯。

預測:多雲

使用 SQL Azure 實現分支節點同步

Joseph Fultz

在我加入 Microsoft 之前和之後的幾年裡,我的工作主要與零售行業相關。有趣的是,在此期間,我曾“多次”看到分支節點同步問題隨著科技的進步而得到解決。

我目前的工作與石油和天然氣 (O&G) 行業有著相當廣泛的聯繫,因而發現這個行業也面臨在節點之間同步資料的問題。和連鎖零售業類似,O&G 公司也擁有為數眾多的設備,而且在連通方面也面臨著挑戰。無論是海洋石油平臺上不為人察覺的衛星連接,還是油田中的工程師,都要求獲得及時、準確的資料。

因此,綜合零售業和 O&G 行業的情況,我準備再次接受這一挑戰,但這次會借助 SQL Azure 和 Sync Framework 的一臂之力。我將論述雲如何説明解決在資料中心(公司)、分支(例如店面、鑽井架、集散中心等)以及各種設備(手持設備、共用終端、特殊設備等)之間移動資料的問題。

這個月,我將重點更多地放在一般性的體系結構上,不會過多涉及具體的實施問題。不過我還是會給出幾段示例代碼,用於設置節點和 SQL Azure 之間的同步,並採用過濾內容的方式來減少同步所需的流量和時間。在下個月的專欄中,我將探討使用基於服務的同步方法來提供可擴展的同步解決方案,不再局限于根據內容或地理分佈在 SQL Azure 資料庫中分散資料。

核心問題其實一直未變,改變的是由於技術進步而導致的其他要求。因此我們一開始並不去解決在節點之間移動資料的簡單問題,而是添加我們希望擁有的內容,例如增加資料量以獲得更多細節,涵蓋多種多樣的設備以收集和顯示資料,以及幾乎即時的源。

現實就是,我們擁有的越多,需要的也就越多。在大多數情況下,十年前就可以輕鬆地解決資料流程問題,但在今天,這樣的解決方案僅僅是為更可靠的解決方案提供了基礎而已。零售業的資料流程可能相當簡單:採用向下推送目錄類資料(功能表、倉庫等)並向上回傳交易記錄的形式;也可能相當複雜:從分支到公司以及在分支之間經常更新庫存水準、進行即時防損分析以及手工產品錄入。大體上,O&G 公司也具有相同的模式,但是所用設備的操作、評估和調整使得複雜程度有所增加。我按以下幾種方式考慮同步,從而對複雜程度有了一個大致的概念(實施和支援的複雜程度是逐步遞增的):

  1. 從公司到分支以及再向下推送唯讀資料。
  2. 兩次單向推送不同的資料:一次從公司到分支(例如目錄),一次從分支到公司(例如交易記錄和庫存)。這包括分支到分支的推送,但重點是這基本上是兩次或多次單向同步。
  3. 公司與節點之間雙向資料同步(例如手動產品錄入或員工資訊)。
  4. 分支之間以及分支和公司之間的對等同步。

第 4 種類型是迄今為止最複雜的問題,通常會導致很多衝突。因此,我儘量避免使用此模式,而必須採用此模式的兩項標準就是:需要在節點之間即時更新;如果公司資料存儲不能訪問,要求能夠同步各個分支。因為在很多節點之間即時或准即時更新通常會導致過大的流量,所以通常不是合理的解決方案,而我真正需要注意的標準就是在沒有主存儲的情況下進行同步的能力。在某些情況下,節點之間需要即時資訊,但資料同步通常並不需要即時資訊。相反,它是一個事件通知方案,採用不同的方法來解決需求。

定義解決方案的體系結構

一般來說,我看到的最常見模式是從公司主要資料庫(通過某種類型的分發程式)將資料直接向下推送到分支的伺服器以及移動使用者。到工作站、銷售點 (POS) 終端和其他此類設備的資料分發通常是在分支處的伺服器(通常稱為“後臺伺服器”)完成,而與移動使用者(例如筆記型電腦)之間的同步則是通過用戶端發起的同步進程直接從公司到機器之間完成(請參見圖 1)。

圖 1 資料分發的典型體系結構

某些組織通過關係數據庫管理系統 (RDBMS) 內置的複製功能實現資料的分發,另外一些組織則構建相關的過程來處理資料的分發和收集。我將採用這種模式,但會使用 SQL Azure 實例替代分發程式,使用支援 SQL Azure 的 Sync Framework 替代複製功能。因此,我只需在分發程式和分支之間添加一層(請參見圖 2)。

圖 2 使用 SQL Azure 和 Sync Framework 的基本體系結構

插入 SQL Azure 有什麼好處呢?分支節點方案的部分優勢包括:

  1. 擴展資料服務而無需擴大資料中心。
  2. 無需額外的成本和工作,即可確保資料的高可用性。
  3. 減小潛在的安全隱憂,因為它不是主資料存儲。

在第一種方案中,如果公司連接或資料存儲宕機,所有用戶端都必須暫停交易。如前文所述,如果等待連接時找不到設備或設備上的空間不足以存儲交易,則這種方案很容易導致資料丟失。此外,如果分支擁有公用資料(例如倉庫的庫存資料),它們將一直使用舊資料工作,直到公司恢復正常。儘管並不存在完美的解決方案,SQL Azure 通過自動複製資料並提供自動的容錯移轉,足以應對這種情況。而且,通過將資料流程分散到多個 SQL Azure 資料庫,我可以減小宕機的風險。因為不僅可以使用獨立的實例,還可以使用不同的資料中心,還能進一步減小負載壓力。

從設計角度而言,我必須考慮從分支或從伺服器開始同步的影響。如果將應用程式設計為從主存儲或分發程式到節點進行同步,我得到的好處就是減少管理和支援工作;而不好的地方就在於會給實施帶來一些限制,要求:

  1. 瞭解端點。
  2. 瞭解每個目標的合理範圍。
  3. 為了使多個節點的同步能夠並行發生,同步過程有一定的複雜度;API 語義一次只能有一對端點和一個範圍。

通過從目標(例如節點或分支)開始同步,同步代碼的複雜度降低了,因為這樣:

  • 可以集中在應用程式/設備的範圍。
  • 更容易處理偶爾連通的情況。
  • 只需瞭解和管理少數要同步分發資料的端點。

但是,這會給目標設備上的應用程式增加一定的複雜度,而且可能因必須調試每台設備上的同步過程或代理而使支援和維護變得更加複雜。理想情況下,如果必須在不同的應用程式之間同步資料,應該創建一個獨立的過程,根據設定檔管理同步。設定檔中應該定義範圍、頻率和連接字串,以便同步代理在運行時使用。此同步代理應該存在於應用程式(設備上的資料使用者)外部,儘管該過程可以讓特定的應用程式啟動其資料的同步。這樣做的優勢在於可以從節點啟動同步,而且還減少了支援和維護工作,因為它最終會形成一個過程。

使用 Sync Framework,我傾向于採用混合同步模型,即從主資料存儲啟動與 SQL Azure 的同步,然後從節點啟動 SQL Azure 與節點之間的同步。換言之,可以看作從主存儲推出資料,從分支拉出資料,這樣一來 SQL Azure 就成為主存儲與分支之間一個高度可用的中心集散地。根據解決方案的需求和限制,我考慮了將同步程序控制權從一個點移動到鏈條中的另一個點(例如,設備到雲或公司到雲)所需要的成本以及各種優勢。只有幾個問題需要考慮,例如:

  • 主存儲是否有地方放置該過程?
  • 將同步過程放在 SQL Azure 中是否會與安全政策衝突?
  • 每個層級有多少節點要同步?
  • 目標設備能夠實際支援同步過程嗎?
  • 關於資料同步的時效性,有哪些要求?

更重要的是,這些問題都需要從多個層次去考慮,設計可能的解決方案時必須審視每個問題。雖然不存在普適的設計,我還是要從前面介紹的模型開始著手,或者執行多個單向同步以實現類似于雙向資料同步的效果,或者在設備/公司資料庫與 SQL Azure 之間使用雙向同步。之後,我將考慮那些無效的方案,對設計進行修改。一般來說,我唯一需要避免的同步模式就是對等同步。

設置同步

使用 Sync Framework 2.1 設置同步的方法有兩種:雲中的同步用戶端和本地機器上的同步用戶端。目前我將主要介紹後者。簡而言之,設置同步關係的步驟如下所示:

  1. 找出要同步的資料和資料流程的方向。這在定義同步資料的範圍 (SqlSyncScopeProvisioning) 時要用到。
  2. 下載並安裝 Sync Framework 2.1 (bit.ly/gKQODZ)。注意:如果目標平臺是 x64,則需要添加針對 x64 的生成目標,否則 SyncOrchestrator 無法解析其依賴關係。
  3. 配置要同步的資料庫和表;可以配置整個資料庫,也可以配置特定的表,或者限定為特定的列。
  4. 添加必要的篩檢程式。如果希望水準分割資料或以其他方式過濾資料,可以使用篩檢程式。
  5. 創建和運行同步過程。

我會詳細解釋這個示例,因為它有助於說明問題。我假設兩端的資料庫已經存在。我創建一個到本地資料庫的連接,檢索要同步的表的定義 (DbSyncTableDescription),並將這個表添加到範圍 (DbSyncScopeDescription) 中。此外,我將指定某些列,但如果只是要同步整個表,則無需指定列。將同步關係限定到具體的列是優化頻寬使用和加快處理速度的有效方法(請參見圖 3)。

图 3 创建同步范围

SqlConnection azureConn = new SqlConnection(AzureConnectionString);
SqlConnection onPremiseConn = new SqlConnection(LocalConnectionString);

// List of columns to include
Collection<string> columnsToInclude = new Collection<string>();
columnsToInclude.Add("au_id");
columnsToInclude.Add("au_lname");
columnsToInclude.Add("au_fname");
columnsToInclude.Add("phone");
columnsToInclude.Add("address");
columnsToInclude.Add("city");
columnsToInclude.Add("state");
columnsToInclude.Add("zip");
columnsToInclude.Add("contact");

// Definition for authors from local DB
DbSyncTableDescription authorsDescription =
  SqlSyncDescriptionBuilder.GetDescriptionForTable("authors", 
  columnsToInclude, onPremiseConn);

// Create a scope and add tables to it
DbSyncScopeDescription authorScopeDesc = new DbSyncScopeDescription(ScopeName);

// Add the authors table to the sync scope
authorsScopeDesc.Tables.Add(authorsDescription);

對於每個要同步的結構,需要增加一點代碼以進行說明;之後您必須將其添加到範圍中。 下一步是獲取範圍配置物件,並使用該物件配置每個資料庫(如果該資料庫中尚不存在範圍),如圖 4 所示。

图 4 配置范围

// Create a provisioning object for "customers" and 
// apply it to the on-premises database
SqlSyncScopeProvisioning onPremScopeConfig = 
  new SqlSyncScopeProvisioning(onPremiseConn, authorsScopeDesc);
if (!(onPremScopeConfig.ScopeExists(authorsScopeDesc.ScopeName)))
{
  onPremScopeConfig.Apply():
}
// Provision the SQL Azure database from the on-premises SQL Server database
SqlSyncScopeProvisioning azureScopeConfig = 
  new SqlSyncScopeProvisioning(azureConn, authorsScopeDesc);
if (!(azureScopeConfig.ScopeExists(authorsScopeDesc.ScopeName)))
{
  azureScopeConfig.Apply();
}

因為這是第一次在資料庫中配置範圍,所以會有一些新的表用於存儲範圍資訊,還有一個表專門用於跟蹤資料庫中配置的 Authors 範圍。Sync Framework 團隊的博客 bit.ly/dCt6T0 上提供了一個非常好的主控台應用程式示例,用於配置或同步本地與 SQL Azure 資料庫。

邊欄:SQL Azure 資料同步

SQL Azure 資料同步是 Windows Azure 中提供的一項基於雲的服務,使用它可以在 SQL Server 和 SQL Azure 之間同步整個資料庫或特定的表。在 2010 年 Microsoft 專業開發者大會期間,我們宣佈推出該服務的更新SQL Azure 資料同步社區技術預覽 (CTP) 2。各個組織可以利用此更新,將本地的 SQL Server 資料庫擴展到雲中,從而分階段將應用程式遷移到雲中。利用 SQL Azure 資料同步構建的解決方案可讓使用者繼續訪問本地資料,並在發生更改時將更改無縫同步到 SQL Azure。與此類似,應用程式對 SQL Azure 的更改也可以同步回本地的 SQL Server。

資料始終同步

SQL Azure 資料同步可為所有同步關係提供一個集中的基於雲的管理系統。管理員可以從任意流覽器連接到該公共服務,管理和監控各種資料庫端點。此外,SQL Azure 資料同步還提供一項計畫服務,可使同步的頻率高達每五分鐘一次;也可以將首選項設置為在非高峰期執行同步,降低頻率。

在最近的 SQL Azure 資料同步 CTP 2 更新中,我們還引入一個新元件,名為 SQL Azure資料同步代理。此代理是一項 Windows 服務,安裝在客戶內部,通過安全的出站 HTTPS 連接將本地 SQL Server 資料庫連結到 SQL Azure 資料同步。因此從防火牆或安全配置角度而言,無需任何要求,就能快速完成設置工作。該代理的工作是監控和記錄任務,並從 SQL Azure 資料同步啟動同步請求。

新方案

使用 SQL Azure 資料同步,SQL Server 和 SQL Azure 資料庫之間的同步能夠提供大量新的方案,這些方案在過去都是很難構建的。假設您希望與分支辦事處或零售店的資料庫共用資料。使用 SQL Azure 資料同步,這將變得很容易,因為管理員可以創建“同步組”,用來定義要在資料庫之間共用的資料。這些同步組可以包含公司的 SQL Server,該 SQL Server 將資料同步到中心的 SQL Azure“資料集散地”。然後,所有遠端或區域性的 SQL Server 資料庫可以從這個資料集散地同步資料更改,將資料帶給使用者,從而大幅減少頻寬以及對虛擬私人網路絡 (VPN) 的需求。

此外,還可以在多個 SQL Azure 資料中心之間同步資料,因此更容易將負載擴展到多個地理區域。假設您每個季度都需要報告,而這會給 SQL Server 資料庫施加巨大的週期性負載。為什麼不在需要時將部分資料同步到遍佈全世界的 SQL Azure 資料庫呢?這樣一來,使用者就可以訪問離他們最近的資料,同時減少對本地 SQL Server 的可伸縮性要求。

有關 CTP 2 的更多資訊以及註冊使用資訊,請訪問 microsoft.com/en-us/sqlazure/datasync.aspx

—SQL Azure 資料同步高級專案經理 Liam Cavanagh

同步資料

正確配置資料庫之後,同步資料就很容易了。您需要為每個指定了範圍的活動端創建 SqlSyncProvider。這需要使用 SyncOrchestrator 物件,它的作用就是找出更改,並在活動端之間移動更改。其代碼如下所示:

SqlConnection LocalConnection = new SqlConnection(LocalConnectionString);
SqlConnection AzureConnection = new SqlConnection(AzureConnectionString);

SqlSyncProvider LocalProvider = new SqlSyncProvider(ScopeName, LocalConnection);
SqlSyncProvider AzureProvider = new SqlSyncProvider(ScopeName, AzureConnection);

SyncOrchestrator orch= new SynOrchestrator();
orch.LocalProvider = new SqlSyncProvider(ScopeName, LocalConnection);
orch.RemoteProvider = new SqlSyncProvder(ScopeName, AzureConnection);
orch.Direction = SyncDirectionOrder.DownloadAndUpload;
orch.Synchronize();

資料和地理位置分散

處理簡單的資料複製之後,我就能集中精力優化部署體系結構和資料流程。使用 Sync Framework,我可以指定篩檢程式。篩檢程式與 SQL Azure 結合,可以為分支節點體系結構帶來巨大的益處。通過綜合利用這兩者,只需同步對某個區域或資料群體很重要的資料,我就可以讓資料離最終使用者更近,優化頻寬利用率(以及由此產生的費用)。無需在不同的地理位置使用資料伺服器,資料可以同步到該地理區域中的 SQL Azure 實例,然後該地區的用戶端再進行同步即可。

通過將資料分散到各個地理位置,並指定特定資料同步時的範圍和頻率,我們就可以精細控制傳輸的資料流程內容、如何傳輸、何時傳輸以及傳輸多少,從而改善使用者體驗,因為使用者體驗與資料可用性和新鮮度直接相關。此外,對於要在各個地點之間穿梭的最終使用者來說,能夠瞭解所處位置是非常不錯的,同步代理可以自行定位,以獲得針對當前位置的同步資料。很多在製造/工廠環境中移動辦公的工人獲得的最新統計資訊或報警資訊,以及零售連鎖業的區域經理獲得的當日銷售記錄就是這一領域中很好的例證(請參見圖 5)。

圖 5 使用篩檢程式同步資料

啟用篩檢程式並不比配置同步範圍困難。因此,可以指定多個範圍,使用不同的篩檢程式,或者不使用篩檢程式。對於每個要添加的篩檢程式,所需的改變只是添加兩行代碼:第一行向表中添加篩檢程式列,第二行添加篩檢程式子句,基本上是“where”條件。在我的示例中,我添加了一個州篩檢程式,以便只同步猶他州 (UT) 的資料更改,如下所示:

onPremScopeConfig.Tables["authors"].AddFilterColumn("state");
onPremScopeConfig.Tables["authors"].FilterClause = "[authors].[state] = 'UT'";

如果我希望根據篩檢程式進行雙向同步,則需要添加兩個範圍,因為需要在兩端配置範圍。

更進一步以及散發資料

向體系結構中添加 SQL Azure(無論是單個實例還是多個資料庫),即添加日益重要的間接層,可以在同步節點時真正增強資料可用性,改善整體性能。 因為 SQL Azure 無需設計、配置和管理基礎設施等工作,即可獲得性能、可擴展性和可靠性。 在下個月的專欄中,我將介紹具體的實施方法,演示如何使用十月份最新發佈的 Sync Framework 4.0 CTP (bit.ly/dpyMP8) 將 Windows Azure 加入同步體系結構中。

Joseph Fultz 是達拉斯 Microsoft 技術中心的架構師,協助企業客戶和 ISV 設計和製作軟體解決方案以滿足商業和市場需求。.他在 Tech·Ed 及類似的內部培訓活動中做過講座。

衷心感謝以下技術專家對本文的審閱: David Browne