zoukankan      html  css  js  c++  java
  • Couchbase I

    Couchbase第一印象(架构特性)

    • 面向文档 保存的字节流总有一个 DOCUMENT ID(Object_ID)

    • 高并发性,高灵活性,高拓展性,容错性好

    • 面向文档的集群存储系统

    • 每个文档用一个唯一的Doc ID

    • 均衡负载

    Buckets vs vBuckets

    1. Buckets

    • couchbase的存储逻辑单元叫Bucket

    • 每个bucket有个名字

    • 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');
  • 相关阅读:
    Linux下常用命令以及应用场景
    Java通过代理访问网络的几种方法
    Linux下模拟Http发送的Get和Post请求
    Postgresql常用函数整理
    java-日期Calendar类
    利用数组保存 6 个 Circle 对象,创建 Circle 对象时可传递半径,半 径值由 Math 类的 Random()方法产生( 10 以内,保持一位小数),分别求其面积 (四舍五入,保持两位小数)
    第十讲 Java 资源结构-api
    浅谈面向对象与女娲造人 (摘自 Nerxious)
    java-打印字母表
    java反射机制
  • 原文地址:https://www.cnblogs.com/rosanshao/p/8099540.html
Copyright © 2011-2022 走看看