實現一個大規模的文檔存儲服務

以前,我們解釋了為什么我們決定為Genius Scan選擇在文檔存儲服務上工作,以及我們是怎樣逼近這個工程的挑戰的。我們認為這個過程是值得分享得,我們也希望能夠從社區獲得反饋。

背景信息

在Grizzly實驗室,我們創建了非常有幫助的生產率應用。我們的主要產品是Genius Scan,它是一個IOSAndroid掃描器。它是最流行得移動應用之一,自從2010年6月誕生以來,網絡上有超過1500萬得下載量,我們從沒有在廣告上花一分錢,但是我們卻經常收到大量的反饋。

Genius Scan是一個物理介質和數字世界之間的接口。它可以讓你對一個紙質文檔形成快照,糾正透視失真,并且可以將其處理的就像真的掃描儀一樣。多做幾次掃描之 后,你可以構建一個多頁PDF文檔。Genius Scan也非常擅長將數據導出到任何你想要的地方(Box, Dropbox, Email, Evernote, Expensify, Google Drive, OneNote, OneDrive, FTP, WebDAV…)

實現一個大規模的文檔存儲服務

當我們期望用戶使用Genius Scan掃描并導出文檔時,我們注意到他們中的許多人使用Genius Scan長時間存儲所掃描的數據。

要解決的用戶問題

Genius Scan把文檔存儲在手機應用的本地文件夾里。由于應用是運行在沙盒里的,因此只有Genius Scan才可以訪問這個文件夾,而且文檔是無法在各種設備間實現同步的。除非你決定導出文件,否則這些文檔是不會脫離手機的(對IOS自動備份例外)。這 么做有兩個優點:實現簡單,隱私性強。

然而, 經過4年對支持問題的郵件答復,我們可以清晰地看到用戶所要求的模型:

  • 備份。用戶可能由于許多原因而丟失文檔:無意間刪除,不正確地安裝新的OS更新,手機丟失或者被盜。假設用戶使用了iCould,那么不太滿意的解決方法就是自iCloud上完整地恢復手機備份。

  • 設備間遷移(把文檔從舊設備遷移到新設備)。跨平臺遷移時就會出現問題,通常出現在iOS和安卓 平臺之間。此時,用戶沒有一個明確的方法去訪問他們在前一個平臺上創建的文檔。解決的方法是把文檔導出到像Dropbox這樣的云服務上。然后,用戶就可 以通過新設備上安裝的Dropbox應用來訪問這些文檔了。我們對這個安卓應用的備份和恢復進行了測試,得到的結果是它也不是一個完美的解決方法。在升級 iOS設備的時候如果用戶沒有進行設備備份安裝,那么這樣的問題也會出現。

  • 同步(在另外的設備上訪問這些文檔)。用戶用他們的手機對文檔進行掃描,然后想在平板上閱讀。目前,做到這一點的唯一方法就是把文檔導出到像Dropbox這樣的服務上,然后通過平板上安裝的Dropbox應用來訪問。采用同樣的方法,用戶可以在桌面電腦上查看這些文檔。

  • 其他功能:要求有其他處理能力或者后臺服務。例如這樣的功能:OCR,OCR索引(類似 Evernote 所做),文檔簽名和分享。

所有這些反饋都向我們呈現出這樣的需求,即文檔存儲服務要具有同步功能。

自己添加的需求

我們要面對的主要挑戰之一就是Genius Scan已經大規模的使用了。每月數百萬使用用戶每天大約掃描 250,000個新文檔,而且已經掃描的文檔要超過2億個。我們能找到實現新產品的方法,不過我們不能只是為了以后的擴展而設計一個簡單的架構。

看起來每周一都是忙著掃描的日子,不過沒有看到有人掃描火雞啊:)
我們的服務程序需要滿足以下需求:

  • 安全性和私密性:很顯然,這個我們的服務程序首先要實現的功能。

  • 數據完整性:用戶把非常重要的文檔存儲在Genius Scan里(丟失要寫入的數據會體現為數千美元的損失。)在用戶啟用同步的情況下不能有任何文檔丟失。

  • 處理網絡變化的能力:移動設備長時間處于離線狀態,仍可回到在線狀態(例如:用戶在乘飛機飛行期間掃描文檔)。

  • 跨平臺:我們需要支持iOS,安卓和其他可能的平臺。

  • 功能可選:用戶可以不需要啟動同步,尤其在他們關心隱私的情況下。

  • 資金上可持續:我們規劃出能夠長期運行這項服務的所有可能的費用。簡單的電子表格和幾項評估就足以說明費用的組成。在我們規劃的費用表格里,每月的存儲費用(S3)是最重要的。

其他選擇

同步是非常常見的問題,可以選擇許多其他方式來實現同步:

  • 使用 iClould,iCloud 驅動,不要求在服務端做任何工作了。不過無法解決備份、設備間遷移問題,只是解決了同步問題。iCloud最讓我們揪心的問題是它不穩定,不過在iOS7和8上這個問題解決了。

  • CloudKit 也是一個可選的解決方案。不過,考慮到我們的存儲容量,這個方案不是很適合,因為它有存儲容量限制。除此之外,這個方案還僅限于iOS。

  • 跨平臺的云存儲服務:Dropbox,Box,OneDrive...我們可以把這些服務當做后臺服 務,來解決備份、設備間遷移和同步問題,這樣我們就不需要在制作一套這樣的東西了。不過存在幾個缺陷:我們需要適應它們的同步模式-在Dropbox里, 同步的單元是文件-另外,我們還依賴第三方平臺。最后,更難提供任何新增的功能了(索引、搜索,OCR),因為我們無法管理文檔存儲。

  • Ensembles: 由Drew McComack開發的Ensembles給人印象深刻,是一個很適合的解決方案。不過,它只同步存儲在核心數據里的對象:實現對掃描文件自身的同步就很 困難。另外,它還不支持安卓平臺(雖然這么說,不過Ensemebles 1.x是開源項目,可以進行擴展)。這個云服務是用來做臨時傳輸的(采用的是p2p同步模式),不適合于數據存儲,因此不能用來備份和添加新功能。

  • 我們自己的服務:它將解決各種不同的功能需求,不過主要的缺點是我們需要重新編寫一套軟件。

通過與舊金山和法國的幾個頂級公司接觸之后,再加上其他的解決方案都存在缺陷,因此我們決定著手實現我們自己的服務。

開發方式

早早地確認問題所在對我們來說非常重要。不過,持續不斷地列出可能出現的問題和極端情形,延緩實現則更容易些,因此我們決定采用迭代的方法實現我們的目標。

指標

我們正在通過測量和調查兩個渠道對我們每個月數百萬的活躍用戶(MAU)在服務上所產生的負荷進行評估。可以對許多指標進行測量。至于調查,我們可以在Genius Scan里顯示內置的廣告條來詢問用戶。我們還可以請求用戶聯系我們以獲得支持。

一個重要的測量指標是普通用戶(以及超級用戶)通常存儲多少文檔。我們還希望評估每天掃描文檔的最大數量。

除此之外,對用戶的調查還可以讓我們理解資金是否可持續:用戶是否已經準備為這個服務付費了?我們是不是應該給每個用戶提供功能受限的測試版呢?等等。

在安卓應用中使用Dropbox SDK

起初,我們想將某種同步功能與各版本的Genius Scan整合到一塊。我們首先實現了一個簡單的原型,通過使用 Dropbox Sync API修改了安卓版的Genius Scan。這項工作相當快,幾天時間就做了一個粗略的實現。

這樣的原型有幾個好處:第一,關于項目可行性方面它給了我們自信。第二,它讓我們有一些具體東西可以考慮到客戶端應用的用戶體驗;最后,識別安卓上的潛在問題通常是第一步(比如典型得同步沖突是什么,我們所期望的用戶行為是什么)。

自定義實現

下一步我們將開發我們自己的C/S解決方案。這一次,我們專注于IOS應用。我們使用Sinatra開發了一個簡單的后臺。我們服務器端的實現包含了廣泛使用的IOS應用specsRuby

我們得架構是基于Evernote同步。同步的核心在客戶端,服務器存儲狀態。在某些方面來說,模型結構比較類似:在 Genius Scan中,文檔包含頁面,可以選擇性標記。在Evernote中,筆記本包含筆記,也可以選擇性標記。

我們客戶端實現很好地適配了Genius Scan 以前編寫的核心數據代碼。另外,令人吃驚的是代碼不是嵌入的:所有的同步是在各自不同的管理對象里進行的,而且管理對象間是通過分離的通知來進行通信的。

這個iOS原型使我對同步的理解更為深刻。此實現的第一次迭代花費了不到一周的時間進行開發,期間并沒有出現任何沖突。

我們正在對早期的實現進行改善(有關這方面的內容,我們計劃寫一篇更加注重技術方面的博客文章。)。注意,這次改善仍然大量的集中在客戶端,而且服 務器部分是運行在本地的高速網絡上的。接下來的一個行動就是在實際的網絡環境下對這次改善實現的測試,其中包括網絡延遲和網絡出錯。

結論

我們兩個工作在這個項目上是超級興奮的,我們已經推遲了一段時間。我們想盡可能的快來給我們的用戶提供服務。但是,我們不著急。因為我們完全沒有壓力,我們可以花時間將它做好。

如果你讀到這了,我們對您的反饋(Hacker News)也很感興趣。無論如何放心好了,我們會及時通知您我們的進展的。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!