1. 程式人生 > >libmemcached1.0.2 C/C++ API使用例項、測試及修改

libmemcached1.0.2 C/C++ API使用例項、測試及修改

        memcached是一個分散式的快取系統,且其分散式是一種“輕量級”的分散式,完全依賴客戶端庫來實現,libmemcached就是一個開源的C/C++庫。

        使用libmemcached的C/C++ API客戶端庫資料及官方資料都很少,且網路上存在的C/C++ libmemcached例項都是採用的MOD的分散式演算法,其缺點顯而易見,當存在失效的memcached server或重新加入新的server時,容易造成系統的“震盪”。libmemcached本身已經支援一致性hash演算法,一致性演算法在處理“加入”或“刪除”server方面具有優良的特性,這裡就不具體分析了,請查閱一致性演算法相關資料。

        今天對libmemcached-1.0.2版本的使用進行一個簡單的測試,以使應用支援dead server的自動隔離和自動連線。

        libmemcached的C/C++ API使用及測試例項如下:

    #include <stdio.h>  
    #include <stdlib.h> 
    #include <string.h>
    #include <time.h>
    #include <unistd.h>
    #include <libmemcached/memcached.h> 

    int main(int argc, char *argv[]) 
    { 
      memcached_st *memc; 
      memcached_return rc; 
      memcached_server_st *servers; 

      //connect multi server 
      memc = memcached_create(NULL); 

      servers = memcached_server_list_append(NULL, (char*)"localhost", 11211, &rc); 
      servers = memcached_server_list_append(servers, (char*)"localhost", 30000, &rc); 

      rc = memcached_server_push(memc, servers);
      memcached_server_free(servers);  
     
      memcached_behavior_set(memc,MEMCACHED_BEHAVIOR_DISTRIBUTION,MEMCACHED_DISTRIBUTION_CONSISTENT);
      memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 20) ;
      //  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, 1) ;  // 同時設定MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT 和 MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS
      memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 5) ;
      memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, true) ;

      int time_sl = 0 ;  
      int times = 0 ;
      while(times++<100000)
      {
          //save data 
          const char  *keys[]= {"key1", "key2", "key3","key4"}; 
          const  size_t key_length[]= {4, 4, 4, 4}; 
          char *values[] = {"This is 1 first value", "This is 2 second value", "This is 3 third value"," this is 4 forth value"}; 
          size_t val_length[]= {21, 22, 21, 22};
          int i = 0;
          for (; i < 4; i++)      
          {
              rc = memcached_set(memc, keys[i], key_length[i], values[i], val_length[i], (time_t)180,(uint32_t)0);     printf("key: %s  rc:%s\n", keys[i], memcached_strerror(memc, rc));   // 輸出狀態      
          } 
        printf("time: %d\n", time_sl++) ;
        sleep(1) ;
          
      } 
         //free 
          memcached_free(memc); 
          return 0; 
    }

        例項非常簡單,但包含了使用libmemcached的基本流程:

        1)建立memcached_st結構;

        2)新增memcached server;

        3)設定libmemcached庫的一些屬性(hash演算法,重試次數及重試時間等);

        4)呼叫基本的API(如get,set等)...;

        5)釋放memcached_st結構;

       本例項的關鍵在於3)中設定libmemcached庫的屬性。

        只有一致性演算法支援dead server的自動隔離和自動連線,參看run_distribution函式中只有分散式演算法為MEMCACHED_DISTRIBUTION_CONSISTENT*類的才呼叫update_continuum進行更新,其它都沒有任何操作,所以這裡設定了memcached_behavior_set(memc,MEMCACHED_BEHAVIOR_DISTRIBUTION,MEMCACHED_DISTRIBUTION_CONSISTENT);

        run_distribution函式為自動隔離dead server的程式碼,其主要呼叫在backoff_handling函式中:


呼叫條件同時滿足:server->server_failure_counter >= server->root->server_failure_limit 和memcached_st結構的flag設定了MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS標誌,如果不設定MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS標誌,則每次set/get等操作都試圖連線dead server。

     在函式update_continuum中,


next_retry小於當前時間時,則表示標誌當前server有效,如果不設定預設為0,在backoff_handling函式中設定為1,永遠小於當前時間,所以即使失效也不會自動剔除。MEMCACHED_BEHAVIOR_DEAD_TIMEOUT標誌就是設定它的重試時間。

實驗過程:

一、初始階段:在同一虛擬機器開啟2個memcached server(埠分別為11211和30000)

             # memcached -vv -u root -p 11211

            #  memcached -vv -u root -p 30000



二、啟動測試程式

其中下面兩行,表示當前servers包括2個:分別為:localhost:11211和localhost:30000,1和160分別表示weight和在一致性演算法中每個server在圓上的點數。

     ketama_weighted:localhost|11211|1|160
     ketama_weighted:localhost|30000|1|160

 同樣可以看出:key1、key2和key3對映到localhost:11211上,key4對映到localhost:30000上。

正常情況下,會一直處於此狀態下,下面模擬存在server down掉。

三、memcached server 失效和恢復

        起始是使用libmemcached-1.0.2進行的測試,發現存在明顯的錯誤(至少2處),如果還沒有升級或使用1.0.2版本的,那麼可以直接使用1.0.3版本即可(寫此文時的最新版本),否則需要儘快升級,很快官方釋出了libmemcached-1.0.3版本,測試基本正常。

1、libmemcached-1.0.2版本測試圖:

1)關閉memcached server,測試set失敗情況

       在time:1339時刻停止了memcached server localhost:30000伺服器,memcached_set結果返回SERVER HAS FAILED AND IS DISABLED UNTIL TIMED RETRY(使用memcached_strerror轉換的錯誤資訊),此時set、get等並不能實現重新對映到新的server,所以對於之前對映到localhost:11211上的資料,如果此server不恢復,將一直會set失敗,get同樣失敗,不能實現dead server的自動剔除(這是個問題)。


2)重新啟動memcached server,測試重新連線情況:

        在time:1372時刻啟動memcached server,在大致time:1381或1382時刻重新set key4成功,時間大致為20s,即MEMCACHED_BEHAVIOR_RETRY_TIMEOUT設定時間,也就是它的超時重試時間,當到達這個時間後會重新連線dead的server。



3)重新關閉memcached server,測試永久失效

       在time:1386時刻,關閉localhost:30000,此時key4設定失敗,直到time:1471時刻,ketama_weighted:localhost|11211|1|160表示當前只有一個memcached server有效,且localhost:30000被標記為DEAD,之後key4對映到localhost:11211上。經過時間大致為:1471-1386=85s。

        經測試,之後即使重新啟動localhost:30000伺服器,永遠也不能自動連線進來了(這是個問題)。


2、原始碼修改之後測試圖:

      1)關閉memcached server,測試重新對映情況

        在time:10時刻,關閉localhost:30000,則key4設定失敗,從失敗次數可以看出失敗5次後,localhost:30000被自動剔除,key4重新對映到localhost:11211上,這裡的5就是測試用例中設定的:

             memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 5) ;


2)重新啟動memcached server,測試重新連線情況:

        在time:561時刻啟動localhost:30000,在time:580時刻,localhost:30000自動連線,key4重新對映到其上,時間大概20s,即為設定的 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 20) ;

        經測試,即使localhost:30000失效更長的時候,每個MEMCACHED_BEHAVIOR_RETRY_TIMEOUT時間都會重新嘗試連線它,如果連線成功則自動恢復其對映。

3)在重試次數(這裡為5次)內,如果memcached server恢復,則直接set/get資料成功

上圖:time:548時刻,關閉localhost:30000;

中圖:time:552時刻,重試4次時,重啟啟動localhost:30000;

下圖:time:552時刻,成功連線到localhost:30000,set成功;

基於上面1.0.2版本提到的2個問題(或許有更多,或許稱為不足),經過簡單修改:

        第一個問題:backoff_handling函式中 server->server_failure_counter只增不減,導致一旦到達重試次數,它狀態將不能恢復。這裡將其重置為0:server->server_failure_counter= 0;

        所以這裡的重試次數與通常我們理解的重試次數是不同的,這裡是重試時間的次數,1.0.2版本中在”重試時間*重試次數“時間段內,任何對映到dead server上面的資料都失敗,經過”重試時間*重試次數“的時間後,server自動隔離,此時設定成功的時候為”重試時間“,所以多數情況下,這些資料都處於不可用狀態,導致效能很低。

        對第二個問題修改的總的原則是:快隔離,慢恢復!快隔離:如果存在server失效,則迅速將其自動剔除;避免set及get等操作失敗持續時間較長(通常memcached應用於密集型操作set/get,所以快隔離還算合理)。慢恢復:失效的server啟動後,並不是立即進行連線,需要經過MEMCACHED_BEHAVIOR_RETRY_TIMEOUT時間,以避免剛剛重新對映的資料立即失效(從理論來講也不一定好,需要具體問題具體分析)。然後將”重試次數“理解為set、get等操作失敗的次數,我的修改方案並不優雅,只是功能實現而已,這裡就不貼圖了,如果需要請自行查閱修改後的原始碼

       上述版本在原始碼1.0.3版本中並不能獲得預期的效果,在上述程式碼基礎上,需要設定如下引數:

            memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DEAD_TIMEOUT, 20) ;

        具體的測試類似於1.0.2版本。

相關推薦

libmemcached1.0.2 C/C++ API使用例項測試修改

        memcached是一個分散式的快取系統,且其分散式是一種“輕量級”的分散式,完全依賴客戶端庫來實現,libmemcached就是一個開源的C/C++庫。         使用libmemcached的C/C++ API客戶端庫資料及官方資料都很少,且網路上

C/C++ Windows API——關閉啟動查詢服務狀態

// ServiceDemo.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <Windows.h> int m

C++ XML的建立讀取和修改(一)

跟C#不太一樣,需要呼叫一個TinyXML庫來生成XML,庫的原始碼地址為https://github.com/leethomason/tinyxml2,找到“clone or down”進行下載,,解壓之後,將tinyxml2.h 和 tinyxml2.cpp放入工程檔案中,呼

C語言編譯器設計原始碼資料彙編(一)

    我相信有不少的人對編譯器的有很大興趣,但是虎書(《編譯原理》)上的理論知識雖然很全面很詳細,但是相當的枯燥無味,讓人難以下決心鑽研。我就是被虎書嚇壞了,各種看不懂(本人非CS專業,全靠自己啃)。。。《程式語言設計》也太厚了,後來在圖書館找書的時候,發現了一本適合入門P

C編譯器MinGW安裝下載在notepad++中運行C程序

cto 配置 notepad++ 成功 tro www. img rect wid 一、C編譯器MinGW的下載及安裝步驟 打開MinGW官網:http://www.mingw.org/

ZABBIX4.0.2監控歷史數據存放Elasticsearch集群高可用方案

php more lar math 高可用方案 glib lock 內核參數 ec2 一、概述 Zabbix 4.0.2是一個長期支持版本(LTS),至少提供 5 年的技術支持;下面簡單看一下Zabbix 4.0.2 新特征更具時效的監控項值檢查(Checking item

HTTP 報頭設定例項響應總結

 eg: @WebServlet("/Refresh") public class Refresh extends HttpServlet{ /** * */ private static final long serialVersionUID = 1L; @Ove

CentOS6.0 中java的解除安裝安裝配置

1、解除安裝當前系統自帶OpenJDK 檢視當前系統JDK資訊: rpm -qa | grep gcj 顯示如下資訊: java-1.4.2-gcj-compat-1.4.2.0-40jpp.115 java-1

mongodb 3.0.2與wiredTiger儲存引擎安裝測試

[[email protected] local]# [[email protected] local]# rm -fR /data/mongodb30/ [[email protected] local]# mkdir -p /data/mongodb30/{db,logs}

[開源地址] 放棄Flink,.NET5.0開發CSharpFlink,簡要設計部署二次開發說明。

github地址:https://github.com/wxzz/CSharpFlinkgitee地址:https://gitee.com/wxzz/CSharpFlink  1 概述及背景       我們有一個全國性質的面向工業的公

Elasticsearch索引的建立檢視修改

mapping的寫入與檢視    使用elasticsearch儲存資料之前建立索引非常關鍵,一個好的索引使後續業務的查詢更加方便快捷,我們建立索引時如果不指定相關資訊,會按照預設設定建立,如果我們想要更加強大的功能,比如中文檢索、拼音檢索、首拼檢索,就需要我們自己規劃索引

先鋒機器人ROS入門——rosaria安裝測試學習

1.安裝MobileSim MobileSim是一個移動機器人模擬軟體,即啟動之後,在不連線實體機器人的情況下,執行rosaria不會報錯,即是連線上了一個虛擬的機器人主機。進入MobileSim下載選擇下載 mobilesim_0.9.8+ubuntu12_

Android URL中引數的獲取拼接修改

1、獲取引數 Uri uri = Uri.parse(url); String type = uri.getQueryParameter("key"); 2、拼接 Uri.Builder builder = Uri.parse(url).buildUpo

c語言】求方程式 ax^2+bx+c=0 的根,分別考慮:1有兩個不等的實根 2有兩個相等的實根

// 求方程式 ax^2+bx+c=0 的根,分別考慮:1、有兩個不等的實根 2、有兩個相等的實根 #include <stdio.h> #include <math.h> int main() { int d; int a,b,c; do

習題 14.1 求一元二次方程式ax^2+bx+c=0的實根,如果方程沒有實根,則輸出有關警告資訊。

C++程式設計(第三版) 譚浩強 習題14.1 個人設計 習題 14.1 求一元二次方程式 a x

C#程式設計基礎第四課2:使用if語句if-else語句多重if語句巢狀if語句完成的C#控制檯小程式

知識點:基本算術運算、簡單if語句、if-else語句的練習。利用語句完成簡單C#控制檯程式。 1、運用if-else語句,判斷使用者輸入的年份是否是閏年 static void Main(string[] args) { /*

分數轉化為整int,int a=2/3,是0; int c=7/5;是1;不存在四捨五入。

不存在四捨五入。 #include <iostream>   using namespace std;   int main () {     int a=2/3;     int b=3/4;

【足跡C++primer】38關聯容器操作(2)

關聯容器操作(2) map的下標操作 map的下標操作 map和unordered_map容器提供了下標運算符合一個相應的at函式 對於一個map使用下標操作,其行為與陣列或vector上的下標操作非常不同樣: 使用一個不再容器中的keywo

起航--ASP.NET Web API 2C#)

HTTP 是不侷限於網頁的網路協議。同樣,HTTP在對外的服務和資料中,也能夠發揮出強大的作用。因為它簡單,靈活,且普遍被應用。在你所能想到的很多平臺裡,都封裝了HTTP類庫(library),所以HTTP被廣泛應用於客戶端,譬如瀏覽器,手機裝置和傳統的桌面應