天天看點

Linux版本Membase無法寫入default bucket的問題分析

最近項目中使用的membase發現出了點問題,生産環境中讀寫各種資料都正常,可是新搭建的開發環境下,隻有default bucket寫不進去資料,調用store總是傳回FALSE,配置檔案也是一模一樣,實在不知道哪裡出問題了,其他的幾個bucket都正常讀寫,而且,在開發環境的membase上在建立一個bucket也是正常讀寫的。最後發現生産上windows版本的membase,而開發環境是Linux(centos)版本,懷疑可能跟server版本有關系,于是新裝了一個windows版本的,果然,一切正常。至于Linux版本的(couchbase)為什麼出這個問題,還是得花時間找找原因的。

項目使用的dll:membase.dll 2.14.0.0,Enyim.Caching.dll 2.11.0.0,反編譯是可以看到代碼的,但是不好調試,可以在網上找到相應的源碼:

  • https://github.com/enyim/EnyimMemcached
  • https://github.com/xianrendzw/LightFramework.Net

第二個是把membase的源碼包在了LightFramework.Caching項目中,我就是那這個代碼來查原因的。

既然是store失敗,那我們單步跟蹤,看看default的bucket和其他bucket在store方法中有哪裡不一樣。

public bool Store(StoreMode mode, string key, object value)
{
    ulong tmp = 0;
    return this.PerformStore(mode, key, value, 0, ref tmp);
}
           

可以看到實際調用的是PerformStore方法,跟進去後發現var node = this.pool.Locate(hashedKey);會傳回null,也就是沒有找到對應的bucket了,

那還寫什麼資料啊。

Linux版本Membase無法寫入default bucket的問題分析

查查為什麼傳回是null,我們發現在初始化membaseclient執行個體時,需要向注冊的serverurl擷取該bucket資訊(是否合法,狀态是否正常等),

調用ResolveBucket方法,結果異常了。401錯誤,未授權!

Linux版本Membase無法寫入default bucket的問題分析
Linux版本Membase無法寫入default bucket的問題分析
Linux版本Membase無法寫入default bucket的問題分析
Linux版本Membase無法寫入default bucket的問題分析

我們使用其他bucket初始化時,發現該方法的client參數中credential是有值的(username、password),而default的bucket卻都是null。

應該就是這個原因導緻的。手動将credential的username設為default,再次請求bucket驗證資訊,果然,正确傳回了。

Linux版本Membase無法寫入default bucket的問題分析
Linux版本Membase無法寫入default bucket的問題分析

納悶了,不是預設的default不能設定密碼的麼,怎麼這裡有需要驗證呢?Google相關的問題,發現不少人都不知道怎麼破,甚至說是membase的bug:

  • http://grokbase.com/t/gg/enyim-memcached/11anh26mtr/membase-client-401-getting-config-from-pool-url
  • https://issues.couchbase.com/browse/MB-2166
  • http://qnalist.com/questions/5796245/membase-client-401-getting-config-from-pool-url
  • http://grokbase.com/t/gg/enyim-memcached/11anh26mtr/membase-client-401-getting-config-from-pool-url

在查找問題的過程中,我發現如果bucket是default,membase.dll會将其bucketname和password都置空,意思是不需要身份驗證,走的是特殊端口11210(其他bucket走的是11211驗證),既然注釋都這麼講了,那為毛在bucket驗證資訊的請求中還需要身份驗證呢?

Linux版本Membase無法寫入default bucket的問題分析
Linux版本Membase無法寫入default bucket的問題分析

Default無法寫入的問題就是由上面的原因導緻的,對于windows版本的membase server是不存在的,我測試過,對于default bucket沒有身份驗證的限制。

而對于Linux版本,通過源碼跟蹤過程中,将身份驗證資訊手動改好,也是可以正常讀寫的,可惜的是,無法在外部初始化membaseclient時将其credential配置正确。

有另一個解決方案,就是使用MemcachedClient,因為membase是相容memcached sdk的,是以可以按照下面的方式初始化操作執行個體:

var config = new MemcachedClientConfiguration();
config.AddServer("192.168.1.12",11211);
var client = new MemcachedClient(config);
client.Store(StoreMode.Set, DateTime.Now.ToString("HHmmss"), "testValue");
           

這種方式讀寫default bucket也是正常的。