網際網路級別大變革:本地優先軟體!在本地擁有自己的資料,使用CRDT資料結構實現分散式資料合併!

banq發表於2019-05-04

Google Docs和Trello等雲應用程式很受歡迎,因為它們可以實現與同事的實時協作,並且使我們可以輕鬆地從所有裝置訪問我們的工作。但是,透過在伺服器上集中資料儲存,雲應用程式還會剝奪使用者的所有權和代理權。如果服務關閉,則軟體將停止執行,並且使用該軟體建立的資料將丟失。
在本文中,我們提出了“本地優先軟體”軟體原則,可以為使用者提供協作和所有權。本地優先理念包括跨多個裝置離線工作和協作的能力,同時還提高資料的安全性,隱私性,長期儲存和使用者控制。
我們調查了現有的資料儲存和共享方法,從電子郵件附件到網路應用程式,再到Firebase支援的移動應用程式,我們研究了每種方法的權衡。我們認為:無衝突複製資料型別(CRDT)一開始就是多使用者的資料結構,同時也基本上是本地和私有的。CRDT有可能成為實現本地優先軟體的基礎技術。
我們在幾年的時間裡,在Ink&Switch開發本地首個軟體原型,分享了我們的一些發現。這些實驗在實踐中測試CRDT的可行性,並探索這種新資料模型的使用者介面挑戰。最後,我們建議採取一些後續步驟,轉向本地第一軟體:研究人員,應用程式開發人員以及創業者的創業機會。

(文章比較長,點選標題見原文,這裡從CRDT開始)

CRDT作為基礎技術
CRDT 於2011年從學術電腦科學研究中脫穎而出。它們是如同雜湊Map和列表List一樣的通用資料結構,但關於它們的特殊之處在於它們是從頭開始的多使用者。
每個應用程式都需要一些資料結構來儲存其文件狀態。例如,如果您的應用程式是文字編輯器,則核心資料結構是組成文件的字元陣列。如果您的應用程式是電子表格,則資料結構是包含引用其他單元格的文字,數字或公式的單元格矩陣。如果它是向量圖形應用程式,則資料結構是圖形物件的樹,例如文字物件,矩形,線條和其他形狀。
如果要構建單使用者應用程式,則可以使用模型物件,雜湊對映,列表,記錄/結構等在記憶體中維護這些資料結構。如果要構建協作式多使用者應用程式,則可以將這些資料結構替換為CRDT。
這意味著如果您擁有文件的複製副本,則可以對CRDT進行更改,並且資料結構會跟蹤更改。這些更改可以編碼為位元組字串,並透過您喜歡的任何通訊渠道傳送給您的協作者(例如,透過伺服器,透過點對點連線,透過本地裝置之間的藍芽,甚至是USB記憶棒)。
您的協作者可以接收這些更改並將其應用於其文件副本。與Git中需要手動解決合併衝突不同的是:CRDT會自動執行合併

特點:

  • 無衝突:當多個協作者進行更改時,它們可以自動合併到一致的文件檢視中;
  • 複製:每個協作者都有自己的資料副本,儲存在本地裝置上;
  • 資料型別:通用資料結構,如地圖和列表。

這些屬性直接對映到我們的本地優先理想。在本地擁有資料副本而不是依賴於伺服器,可實現離線工作,長壽,良好效能和使用者控制。能夠自動合併更改可實現多裝置使用和協作。通訊通道的靈活性允許加密,從而提高隱私和安全性。
CRDT跟蹤的更改可以像單個按鍵一樣小,從而實現Google Docs風格的實時協作。但您也可以收集更多更改並將其作為批處理傳送給協作者,更像是Git中的pull請求。由於資料結構是通用的,我們可以開發用於儲存,通訊和管理CRDT的通用工具,從而使我們不必在每個應用程式中重新實現這些功能。

有關CRDT的更多技術介紹,我們建議:

Ink&Switch開發了一種名為Automerge的開源JavaScript CRDT實現。它基於我們之前對JSON CRDT的研究。然後我們將Automerge與Dat網路堆疊結合起來形成Hypermerge。我們並不認為這些圖書館完全實現了本地優先理想 - 仍然需要做更多的工作。
但是,根據我們的經驗,我們相信CRDT有可能成為新一代軟體的基礎。正如分組交換是網際網路和網路的支援技術一樣,或者電容式觸控式螢幕是智慧手機的支援技術,因此我們認為CRDT可能是協作軟體的基礎,可為使用者提供對其資料的完全所有權。

Ink & Switch的原型
雖然學術研究在設計CRDT演算法和驗證其理論正確性方面取得了很好的進展,但迄今為止這些技術的工業應用相對較少。此外,大多數工業CRDT一直用於以伺服器為中心的計算,但我們相信這項技術在創造性工作的客戶端應用程式中具有巨大潛力。

使用CRDT的以伺服器為中心的系統包括Azure Cosmos DBRiakWeave MeshSoundCloud的RoshiFacebook的OpenR。但是,我們最感興趣的是在終端使用者裝置上使用CRDT。

這是我們實驗室開發一系列實驗原型的動機,這些原型具有基於CRDT構建的協作式本地優先應用程式。每個原型都提供了終端使用者體驗,模仿現有的創意工作應用程式,如Trello,Figma或Milanote。
這些實驗探討了三個方面的問題:

  • 技術可行性。CRDT與工作軟體有多接近?我們需要什麼才能開始網路通訊或安裝軟體?
  • 使用者體驗。本地優先軟體如何使用?如果沒有權威的集中式伺服器,我們能否獲得無縫的Google Docs實時協作體驗?對於除原始碼之外的資料型別,Git,離線友好,非同步協作體驗如何?一般來說,沒有集中式伺服器,使用者介面如何變化?
  • 開發經驗。對於應用程式開發人員,如何使用基於CRDT的資料層與現有儲存層(如SQL資料庫,檔案系統或核心資料)進行比較?分散式系統難以編寫軟體嗎?我們需要模式和型別檢查嗎?開發人員將使用什麼來除錯和內省應用程式的資料層?


我們使用Electron,JavaScript和React構建了三個原型。這為我們提供了Web技術的快速開發能力,同時也為我們的使用者提供了他們可以下載和安裝的軟體,我們發現這是本地第一感覺的重要組成部分。

1. Trellis是一款以流行的Trello專案管理軟體為藍本的看板
2. PixelPusher是一個協作繪圖程式,為Javier ValenciaPixel Art帶來了類似Figma的實時體驗。
3. PushPin是一個類似於MiroMilanote的混合媒體畫布工作區。作為我們構建在Automerge上的第三個專案,它是這三個中最完全實現的。我們的團隊和外部測試使用者的真實使用給底層資料層帶來了更大的壓力。

經驗教訓
我們從構建和使用這些原型中學到了以下經驗教訓。

1.CRDT技術是有效的。
從一開始我們就對Automerge的可靠性感到驚喜。我們團隊中的應用程式開發人員能夠相對輕鬆地整合庫,並且資料的自動合併幾乎總是簡單而無縫。

2.離線工作的使用者體驗非常出色。
離線,繼續工作的過程只要你想要,然後重新連線以便與同事合併更改效果很好。

3. 與功能反應程式設計(FRP)結合使用時,開發人員的經驗是可行的。

React的FRP模型非常適合CRDT。基於CRDT的資料層意味著使用者的文件同時從本地使用者獲得更新(例如,當他們鍵入文字文件時),但也來自網路(當其他使用者和其他裝置對文件進行更改時)。
由於FRP模型可靠地將應用程式的可見狀態與共享文件的基礎狀態同步,因此開發人員可以免除跟蹤來自其他使用者的更改並將其與當前檢視進行協調的繁瑣工作。此外,透過確保透過單個函式(“reducer”)對基礎狀態進行所有更改,可以輕鬆確保將所有相關的本地更改傳送給其他使用者。
這個模型的結果是我們所有的原型都可以透過應用程式開發人員輕鬆實現實時協作和完全離線功能。這是一個重要的好處,因為它允許應用程式開發人員專注於他們的應用程式而不是資料分發的挑戰。

4. 衝突並不像我們擔心的那樣嚴重。
我們很好奇使用者在與他人合作時遇到工作衝突的頻率。我們驚喜地發現,使用者具有直觀的人與人之間的協作感,並避免與他們的協作者產生衝突。在確實發生衝突的情況下,無論如何解決和滿足衝突往往是任意的。例如,如果兩個使用者在文件標題中修正了拼寫錯誤,他們可能不會以相同的方式執行此操作,但他們通常不關心選擇哪個結果。
當不同的使用者同時修改文件狀態的不同部分時,Automerge將毫不費力地合併這些更改。例如,使用看板應用程式,一個使用者可以在卡片上釋出評論,另一個使用者可以將其移動到另一個列,合併的結果將反映這兩個變化。
如果衝突解決不明確,Automerge會保留衝突的值並允許應用程式解決它們。在PixelPusher原型中,我們探索了用於解決衝突的使用者介面。將這些特徵與變更歷史檢查相結合是一個開放的研究問題。

5. 視覺化文件歷史記錄非常重要。
在分散式協作系統中,其他使用者可以隨時向您提供任意數量的更改。與伺服器調解變更的集中式系統不同,本地優先應用程式需要找到自己的解決方案來解決這些問題。如果沒有合適的工具,就很難理解文件的工作方式,文件的版本或貢獻的來源。
在Trellis專案中,我們嘗試了“時間旅行”介面,允許使用者及時移回以檢視合併文件的早期狀態,並在從其他使用者收到更改時自動突出顯示最近更改的元素。以線性方式遍歷可能複雜的合併文件歷史記錄的能力有助於提供上下文,並且可以成為理解協作的通用工具。

6.URL是一種很好的共享機制。
我們嘗試了許多與其他使用者共享文件的機制,並發現受Web啟發的URL模型對使用者和開發人員最有意義。可以複製和貼上URL,並透過電子郵件或聊天等通訊渠道進行共享。超出秘密URL的文件的訪問許可權仍然是一個開放的研究問題。

7.點對點系統永遠不會完全“線上”或“離線”,並且很難推斷資料如何在其中移動。
傳統的集中式系統通常是“向上”或“向下”,由每個客戶端透過其維持與伺服器的穩定網路連線的能力來定義的狀態。伺服器確定給定資料的真實性。
在分散的系統中,我們的資料可能具有千變萬化的複雜性。任何使用者可能對他們擁有的資料,選擇共享或接受的資料有不同的看法。例如,一個使用者對文件的編輯可能在飛機上的膝上型電腦上; 當飛機降落並且計算機重新連線時,這些更改將分發給其他使用者。其他使用者可能會選擇接受對其文件版本的全部,部分或全部更改。
文件的不同版本可能會導致混淆。與Git儲存庫一樣,特定使用者在“主”分支中看到的內容是他們上次與其他使用者通訊時的功能。新到的更改可能會意外地修改您正在處理的文件的某些部分,但手動合併每個使用者的每個更改都很繁瑣。分散文件使使用者能夠控制自己的資料,但需要進一步研究,以瞭解這在實際使用者介面術語中意味著什麼。

8.CRDT累積了大量的更改歷史記錄,從而產生了效能問題。
我們的團隊將PushPin用於“真實”文件,例如sprint規劃。效能和記憶體/磁碟使用很快成為一個問題,因為CRDT儲存所有歷史記錄,包括逐個字元的文字編輯。這些堆積起來,但不容易被截斷,因為無法知道有人可能在六個月之後重新連線到您的共享文件並且需要合併從那一點開始的更改。
我們繼續最佳化Automerge,但這是正在進行的工作的一個主要領域。

9.網路通訊仍然是一個未解決的問題。
CRDT演算法僅提供資料合併,但並沒有說明不同使用者的編輯是如何到達同一物理計算機。
在這些實驗中,我們嘗試透過WebRTC進行網路通訊; 使用Dropbox和USB金鑰複製檔案的“sneakernet”實現; 可能使用IPFS協議 ; 並最終選擇了DatHypercore點對點庫。
CRDT不需要對等網路層; 使用伺服器進行通訊對CRDT來說很好。但是,為了充分實現本地優先軟體的長壽目標,我們希望應用程式能夠超過其供應商管理的任何後端服務,因此分散式解決方案是合乎邏輯的最終目標。
在我們的原型中使用P2P技術產生了不同的結果。一方面,這些技術還遠未達到生產準備階段:特別是NAT遍歷不可靠,具體取決於使用者當前連線的特定路由器或網路拓撲。但P2P協議和分散式網路社群所建議的承諾是巨大的。在沒有網際網路訪問的計算機之間進行實時協作在依賴集中式API的世界中感覺像魔術一樣。

10.雲伺服器仍然可以用於發現,備份和突發計算。
像PushPin這樣的實時協作原型允許使用者在沒有中間伺服器的情況下與其他使用者共享他們的文件。這非常適合隱私和所有權,但可能會導致使用者共享文件,然後在其他使用者連線之前關閉膝上型電腦蓋。如果使用者不在同一時間,則無法相互連線。
因此,伺服器可以在本地第一世界中發揮作用 - 不是作為中央機構,而是作為支援客戶端應用程式而不是關鍵路徑的“雲對等體”。例如,儲存文件副本並在其上線時將其轉發給其他對等方的雲對等方可以解決上面關閉的膝上型電腦問題。

HashbaseDat and Beaker Browser的雲對等和橋接的示例。

同樣,雲同行可能是:

  • 檔案/備份位置(特別是對於儲存有限的電話或其他裝置);
  • 傳統伺服器API的橋樑(例如天氣預報或股票行情);
  • 突發計算資源的提供者(如使用強大的GPU渲染影片)。


傳統系統與本地優先系統之間的關鍵區別不在於缺少伺服器,而在於其職責的變化:它們是支援角色,而不是真相的唯一來源。

結論
計算機是人類有史以來最重要的創作工具之一。軟體已成為我們完成工作的渠道和工作所在的儲存庫。
為了追求更好的工具,我們將許多應用程式遷移到雲端。雲端計算軟體在很多方面都優於“老式”軟體:它提供了可在世界任何地方訪問的協作式,始終最新的應用程式。我們不再擔心我們正在執行的軟體版本,或者檔案所在的機器。
但是,在雲中,資料的所有權屬於伺服器,而不是使用者,因此我們成為了自己資料的借用者。在雲應用程式中建立的文件註定會在這些服務的建立者停止維護時消失。雲服務無法長期儲存。沒有Wayback Machine可以恢復落伍的Web應用程式。網際網路檔案館無法保留您的Google文件。
在本文中,我們探索了未來軟體的新方法。我們已經證明,使用者可以保留對資料的所有權和控制權,同時還可以從與雲相關的功能中受益:無縫協作和從任何地方訪問。它可以充分利用這兩個世界。
但是,在實踐中需要做更多的工作來實現本地優先的方法。應用程式開發人員可以採取漸進的步驟,例如改進離線支援並更好地利用裝置上的儲存。研究人員可以繼續改進本地優先軟體的演算法,程式設計模型和使用者介面。企業家可以將CRDT和點對點網路等基礎技術開發成能夠為下一代應用提供動力的成熟產品。
今天,很容易建立一個Web應用程式,其中伺服器獲取所有資料的所有權。但是,構建尊重使用者所有權和代理權的協作軟體太難了。為了改變平衡,我們需要改進開發本地優先軟體的工具。
 

相關文章