2017-06-09 32 views
0

我在深入挖掘CouchDB 2,並發現一些意外的序列號。在一個案例中,我發現,在_changes飼料的早期變化有序列號CouchDB 2中的序列號錯誤還是有另一種比較序號的方法嗎?

99-g1AAAAI-eJyd0EsOgjAQBuAGiI-dN9C9LmrBwqzkJtrSNkgQV6z1JnoTvYneBEvbhA0aMU1mkj6-_NMSITTJfYFm2anOcsFT10mpTzyG-LxpmiL32eqoN8aEAcWE9dz_jPCFrnzrHGQchiFM4kSgaV0JqQ6VFF-AtAV2DggMgCEGxrNhQfatc3bOyDiKUalg2EBVoCu66KapazcUh41e69-GssjNIvcWWRokk2oNofwj0MNazy4QFURhGQ0J9LKI-SHPIBHEgiak51nxBhxnrRk 

我_changes最後一個序列號的飼料,對於相同的DB,是

228-g1AAAAJFeJyd0EkOgjAUBuAGTJCdN9AjlIKFruQm2jFAEFes9SZ6E72J3gQ7JW7QCGnyXtLhy-vfAgCWVSjAip96XglW-o5afRJQwNbDMDRVSOuj3ogQJRgiOnL_O8I2urKdd4B1KCRpkRcCxH0npKo7KX4ApQH2HogsAElOKOPTBjkY5-yd2DqKYqnItA91C13BRTdNXY0VWouRrV7JDOvmrLuxlLW4VAlJ5Qzr4aznJ2wskIIy-y9sh7wcYoMKLJKRXOACjTxr3uHcsBE 

在瀏覽器控制檯,以下是假

'228-g1AAAAJFeJyd0EkOgjAUBuAGTJCdN9AjlIKFruQm2jFAEFes9SZ6E72J3gQ7JW7QCGnyXtLhy-vfAgCWVSjAip96XglW-o5afRJQwNbDMDRVSOuj3ogQJRgiOnL_O8I2urKdd4B1KCRpkRcCxH0npKo7KX4ApQH2HogsAElOKOPTBjkY5-yd2DqKYqnItA91C13BRTdNXY0VWouRrV7JDOvmrLuxlLW4VAlJ5Qzr4aznJ2wskIIy-y9sh7wcYoMKLJKRXOACjTxr3uHcsBE' > '99-g1AAAAI-eJyd0EsOgjAQBuAGiI-dN9C9LmrBwqzkJtrSNkgQV6z1JnoTvYneBEvbhA0aMU1mkj6-_NMSITTJfYFm2anOcsFT10mpTzyG-LxpmiL32eqoN8aEAcWE9dz_jPCFrnzrHGQchiFM4kSgaV0JqQ6VFF-AtAV2DggMgCEGxrNhQfatc3bOyDiKUalg2EBVoCu66KapazcUh41e69-GssjNIvcWWRokk2oNofwj0MNazy4QFURhGQ0J9LKI-SHPIBHEgiak51nxBhxnrRk' 

這是bug還是我需要使用一些其他的方法來比較序列號?

查看我的_changes feed中的其他序列號,它看起來像它們通常按我的預期排序,但在這種情況下,看起來當第一個數字99,從2位數跳轉到3位數,訂購中斷。如果你把它歸結爲一個簡單的字符串比較例子,你可以看到'228'>'99'=> false

+0

當你按照字母數字順序對數字進行排序時,這總是如何排序。 – Flimzy

回答

1

以下答案包含來自@rnewson的電子郵件線索的摘錄。我希望它能幫助別人瞭解CouchDB 2中的序列號。謝謝,羅伯特!

背景:

有沒有簡單的方法,他們在2.0比較,併爲他們 沒有要求符合規定。簡而言之,它們不是設計用於檢查的,或者是在couchdb之外進行比較的;對待他們不透明。

在前面的數字是在第二部分編碼的單獨的更新序列 的總和與只存在欺騙舊版本的 CouchDB的複製成使檢查點。

序列字符串的後半部分是{節點, 範圍,seq}元組的編碼列表(其中seq是您從 版本發佈之前獲得的整數值)。當序列字符串傳回時,作爲=參數的 ,couchdb對此字符串進行解碼並將 適當的整數seq值傳遞給單獨的分片。

所有這一切說,一般前面的數字應該增加。完整的 字符串本身不具有可比性,因爲對編碼列表沒有定義的順序 (因此可以生成兩個字符串,它們編碼的方式不同,但解碼爲相同的元組列表,只是以 不同的順序)。

對此的另一個方面是,更改Feed並非完全按照訂購的 。對於給定的分片,其完全訂購(分片爲 與具有整數序列的前置2.0數據庫相同),則couchdb 不會混洗該輸出(儘管如果確實如此,複製的正確性將保留 )。儘管('q'值,默認爲4 iirc),但是羣集數據庫由幾個 碎片組成。集羣 更改提要將這些單獨的更改合併爲一個提交,但不會將整個訂單強加於此。我們不這樣做 ,因爲這將是昂貴和不必要的。

的解決方案,如果你要聽上_changes飼料,然後重新從你以後離開的地方 :

的正確消費的變化餵養的算法是:

  1. read/dbname/_changes
  2. idempotently處理每行
  3. 定期(每X秒或每X行)存儲您處理

如果你崩潰的最後一行的「序列」的值,或者如果你沒有使用連續= true,則可以做到這 同樣的程序,但在步驟1中修改;

修訂1.讀/ DBNAME/_changes?因爲= X

其中X如果你不使用 連續模式,那麼你可以只記錄「last_seq」值是您在步驟3中保存的值在 結束消耗非連續響應。儘管如此,你冒着 重新處理更多物品的風險。

使用此方案(複製器和所有索引器遵循),您不需要關心結果是否出現亂碼,您不需要比較 任何兩個seq值。

需要確保您可以多次正確處理相同的更改 。舉一個例子,考慮複製器,當 它看到來自變化feed的一行時,它向目標數據庫詢問它的 是否包含該行的_id和_rev值。如果確實如此, 複製器會移到下一行。如果沒有,它會嘗試將 該行中的文檔寫入目標數據庫。如果發生 崩潰事件,並且因此調用_changes,並在處理該行時從之前的 開始seq值,它會詢問目標數據庫是否再次有_id/_rev,只有這次目標會說yes。