Couchbase第一印象(架構特性)

 

Couchbase第一印象(架構特性)

  • 面向文檔 保存的字節流總有一個 DOCUMENT ID(Object_ID)php

  • 高併發性,高靈活性,高拓展性,容錯性好python

  • 面向文檔的集羣存儲系統git

  • 每一個文檔用一個惟一的Doc IDgithub

  • 均衡負載算法

Buckets vs vBuckets

1. Buckets

  • couchbase的存儲邏輯單元叫Bucket數據庫

  • 每一個bucket有個名字json

  • couchbase 一個節點當前限制10及如下buckets數組

  • bucket 有兩種類型 couchbase和memcached緩存

  • bucket有可選的密碼控權 SASL authentication安全

  • 每一個bucket有可控的內存配額和複製策略設定,獨立可監控和管理

2. vBuckets

  • 主要用來管理維護集羣節點之間的bucket分佈和路由

  • doc id的算法使分佈式成爲可能

Time To Live (TTL)

  • 可用於控制過時時間(默認爲一小時)

  • 可用於seesion緩存等功能

  • 後臺管理過時,自動刪除過時數據,釋放內存和硬盤

數據一致性

併發性

Views, Indexs, Queries

Views
  • 這裏的views概念徹底和SQL的view概念不一樣

  • views做爲數據翻譯轉換層,將數據轉換爲特定格式結構的數據形式如JSON

  • views 經過 map/reduce功能完成, map將文檔結構轉換爲表輸出結構, reduce用來作計數,統計等彙集功能

indexes
  • 每當views創建時, 就會創建indexes, index的更新和以往的數據庫索引更新區別很大。 好比如今有1W數據,更新了200條,索引只須要更新200條,而不須要更新全部數據,map/reduce功能基於index的懶更新行爲,大大得益。

  • 創建views和index後能夠用來Queries

用戶用例

  • 替代memcached的緩存層, 提供兼容memcached協議接口

  • Amazon S3相似服務

  • session

安裝、管理 與客戶端接口

三思然後行(安裝初始化)

數據存儲的路徑

Couchbase數據須要持久化到硬盤,須要分配硬盤空間和路徑,在Linux與Windows默認是couchbase安裝路徑

Server Quota(服務緩存層的內存分配)

Couchbase的數據會被緩存,服務層的緩存內存配額配置被各個節點所共享。 如是:如今有一個節點(Node)分配的是2G RAM,那麼在加三個節點後,就增長6G RAM來還緩存數據了 ,故一共有8G RAM被分配用來緩存了。

Bucket Quota

集羣能夠用多個bucket,bucket用來保存一組特別數據或應用,如一個bucket用來作session,另外一個bucket用來作作副本。bucket RAM quota的策略,對server quota設定是相輔相成的蓮藕關係,很大程度影響cache的內存配額。

安裝與管理

  1. Memory Size

  2. Replicas

    默認bucket副本是3個。 index replica 開啓選項 默認的選項,couchbase的策略比較靈活。只有當數據和節點足夠多時,纔會開始備份。

  3. Flush

    禁用或開啓(默認禁用),用於清空bucket的數據

  4. Auto-compaction

    持久化的數據和view,index,長期會產生碎片,開啓功能時,會自動整理硬盤數據碎片

客戶端接口

  • Python

    > pip install couchbase
  • PHP

    $servers = array("192.168.0.72:8091","127.0.0.1:8091");
    foreach($servers as $server) {
        $cb = new Couchbase($server, "", "", "default");
        if ($cb) {
            echo "Connected to $server";
            break;
        }
    }
  • C

  • JAVA

基於面向文檔的設計開發

Model

JSON

  • Number (either integer or floating-point).

  • Boolean

    {'value' : true}
  • String

    "hello world"
  • Array

    [1, 4, 5]
  • Object

    { 'title' : 'google',
      'url' : 'https://www.google.com/'
    }

實體之間的關聯

  1. 內嵌

    { 'author' : 'Matin',
      'books' : [ {'title' : 'Refactor' , 'IBSN' : '485-566'},...]
    }
  2. 外部文檔,引用其docment id

    { 'author' : 'Matin',
      'books' : [ 'AD3D63D6-2FE0-11E2-93F9-898688C79046_book',...]
    }

事務

存儲操做伊始

CURD

  • add(id, document [, expiry]) Add an item if ID doesn’t already exist
  • set(id, document [, expiry]) Store a document with ID
  • replace(id, document [, expiry]) Update the document for an existing ID
  • cas(id, document, check [, expiry]) Update the document for an existing ID providing the check matches
  • get(id) :Get the specified document
  • incr(id [, offset])Increment the document value by offset
  • decr(id [, offset] Decrement the document value by offset
  • append(id, value) Append the content to the end of the current document
  • prepend(id, value) Prepend the content to the beginning of the current document
  • delete(id) Delete the specified document

Document Indentifer

與Mongodb相比,Couchbase的存儲方式爲Key/Value,Value的類型很爲單一, 不支持數組。另外也不會自動建立doc id, couchbase須要爲每一docment指定一個用於存儲的Document Indentifer。

爲document建立標示符:
  1. 使用惟一的字段作標示符

    如在session中,可使用用戶的email, username做爲惟一標示符

  2. 對象與自增策略

    單首創建一自增數據(Document Indentifer),如 add('user',0) 每次建立一個用戶時,能夠自增'user', 而後獲得 'user:1233'等

  3. 使用uuid

標示符的命名規範與最佳實踐

使用couchbase的bucket策略 自定義方式 (加前綴)

實踐列舉:

1. 網站訪問量(PAGE VIW)

    若咱們須要用couchbase統計網站PV
    那麼命名如 'pv:index', 'pv:blog', 'pv:about'。

2. 用戶朋友圈

    爲用戶創建一個朋友圈
    apend('user#1233','user#444,user#666,')

Time To Live (TTL)

經常使用來作cache,session,購物車使用,驗證碼等。ttl經過傳入一個數字表示, couchbase會對數字做以下的判斷:

  1. 小於30天(606024*30)的一秒爲單位的數字,如600表示10分鐘過時。

  2. 大於三十天的數字(秒),採用從公元開始的計數,如1381921696表示16th October 2013。

  3. 爲0的表示永不過時。

保存數據

set和add都是原子性操做,是多線程環境安全的操做。

set(docid, docdata [, expiry])

set不存在docid數據時會建立,存在時替換存在的docid的內容。 過時設定expiry是可選的。

$cb->set('message', 'Hello World!');
    $cb->set('message', 'Hello World!', 10); /*設定過時時限*/
    if ($cb->set("spoon", "Hello World!", 10)) {
        /*操做結果決斷*/
        echo "Message stored!";
    }
add(docid, docdata [, expiry])

與set不一樣的是,若是docid內容存在時會,會更新失敗。

$cb->add('message', 'Hello World!');
    /*下面語句會失敗*/
    $cb->add('message', 'I pushed the button, but nothing happened!');

獲取數據 get(docid)

  1. 單文檔返回

    在php中若是docid不存在會返回undef:

    $message = $cb->get('message')
  2. 多文檔返回 (Retrieving in Bulk)

    不一樣庫的多文檔返回實現不一樣,多文檔返回比單獨返回要快,由於請求和響應有延遲。 php的會返回一個關聯數組:

    $ret = $cb->getMulti(array('recipe1','recipe2'));

更新數據 replace(id, document [, expiry])

在set,add後可使用replace更新數據:

$message = $cb->get('message');
    $message = $message . " How are you today?";
    $cb->replace('message',$message);

併發更新 cas(id, document, check [, expiry])

在併發環境中,有必要保證併發更新

  • 情景一:

    1.A 獲取了文檔'櫻花怒放'
    2.B 也獲取了文檔'櫻花怒放'
    3.A 向文檔加入信息並更新。
    4.以後,B 也向文檔修改並更新'櫻花怒放'

這樣A的努力徹底被B給覆蓋了

爲了防止以上狀況,須要使用cas功能作版本檢查

  • 情景 cas版:

    1.音 獲取了文檔'櫻花怒放'並加入本身的cas id
    2.曖 也獲取了文檔'櫻花怒放', 並加入本身的cas id
    3.音 向文檔作修改,並使用本身的cas id檢查後成功更新。
    4.以後,曖 也向文檔修改並更新'櫻花怒放'。使用本身的cas id檢查後更新失敗,由於 音已經更新了,使cas id不同。

cas如是:檢查要更新的文檔是否是「原來的版本」(使用get換取的本來)。

$value = client->get("customer", NULL, $casvalue);
    $response = client->cas($casvalue, "customer", "new string value");

cas的缺點是數據更新比起set要慢不少,作大量更新事務併發版本控制並不是很完美。另外若是有用戶使用set或replace操做不帶cas,會使cas失效。

強制鎖

cas雖有鎖的一些性質,但不能防止期間有不帶cas設置的set,replace打亂cas版本。故須要強鎖 使用強制鎖時,其餘用戶能夠獲取數據,但若是沒有相應的cas是不能更新文檔。

$article = $ai->getAndLock('櫻花怒放', &$cas);
    $article = '櫻花飄落的速度是每秒五釐米哦';
    # This will fail, because we are not supplying the CAS value
    $ai->set('櫻花怒放', $article);
    # This will succeed and then unlock document
    $ai->set('櫻花怒放', $article, 0, $cas);

鎖也能夠設定過時時間,另外也能夠釋放鎖:

$ai->unlock('recipe1',$cas);

藝術與文學同在(異步)

不一樣的客戶端接口實現不一樣:

/*使用異步*/
    $format_recipe = function($key, $value) {
        return ('<li>' . $value['title'] . '</li>');
    };
    $ret = $cb->getDelayed(array('recipe1','recipe2'),0,$format_recipe);

    /*單獨迭代獲取*/
    $ret = $cb->getDelayed(array('recipe1','recipe2'),0,$format_recipe);
    while ($ret = $cb->fetch()) {
        echo('<li>' . $ret[value]['title'] . '</li>');
    }

服務端更新 (Server-side Updates)

Increment And Decrement

用於頁面訪問量更新,數據統計等功能:

/*To increment by 1*/
    $cb->set('counter',10);
    $cb->increment('counter');
    /*To increment by 10:*/
    $cb->set('counter',10);
    $cb->increment('counter', 10);
Append And Perpend

向文檔首尾追加內容:

$user->set('userlist','martin,');
    $user->append('userlist', 'stuart,');
    $user->append('userlist', 'sharon,');

刪除數據

當數據存在時,可使用delete刪除:

$cb->delete('message');
相關文章
相關標籤/搜索