面向文档 保存的字节流总有一个 DOCUMENT ID(Object_ID)php
高并发性,高灵活性,高拓展性,容错性好python
面向文档的集群存储系统git
每一个文档用一个惟一的Doc IDgithub
均衡负载算法
couchbase的存储逻辑单元叫Bucket数据库
每一个bucket有个名字json
couchbase 一个节点当前限制10及如下buckets数组
bucket 有两种类型 couchbase和memcached缓存
bucket有可选的密码控权 SASL authentication安全
每一个bucket有可控的内存配额和复制策略设定,独立可监控和管理
主要用来管理维护集群节点之间的bucket分布和路由
doc id的算法使分布式成为可能
可用于控制过时时间(默认为一小时)
可用于seesion缓存等功能
后台管理过时,自动删除过时数据,释放内存和硬盘
这里的views概念彻底和SQL的view概念不一样
views做为数据翻译转换层,将数据转换为特定格式结构的数据形式如JSON
views 经过 map/reduce功能完成, map将文档结构转换为表输出结构, reduce用来作计数,统计等汇集功能
每当views创建时, 就会创建indexes, index的更新和以往的数据库索引更新区别很大。 好比如今有1W数据,更新了200条,索引只须要更新200条,而不须要更新全部数据,map/reduce功能基于index的懒更新行为,大大得益。
创建views和index后能够用来Queries
替代memcached的缓存层, 提供兼容memcached协议接口
Amazon S3相似服务
session
Couchbase数据须要持久化到硬盘,须要分配硬盘空间和路径,在Linux与Windows默认是couchbase安装路径
Couchbase的数据会被缓存,服务层的缓存内存配额配置被各个节点所共享。 如是:如今有一个节点(Node)分配的是2G RAM,那么在加三个节点后,就增长6G RAM来还缓存数据了 ,故一共有8G RAM被分配用来缓存了。
集群能够用多个bucket,bucket用来保存一组特别数据或应用,如一个bucket用来作session,另外一个bucket用来作作副本。bucket RAM quota的策略,对server quota设定是相辅相成的莲藕关系,很大程度影响cache的内存配额。
Memory Size
Replicas
默认bucket副本是3个。 index replica 开启选项 默认的选项,couchbase的策略比较灵活。只有当数据和节点足够多时,才会开始备份。
Flush
禁用或开启(默认禁用),用于清空bucket的数据
Auto-compaction
持久化的数据和view,index,长期会产生碎片,开启功能时,会自动整理硬盘数据碎片
> 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
Number (either integer or floating-point).
Boolean
{'value' : true}
String
"hello world"
Array
[1, 4, 5]
Object
{ 'title' : 'google', 'url' : 'https://www.google.com/' }
内嵌
{ 'author' : 'Matin', 'books' : [ {'title' : 'Refactor' , 'IBSN' : '485-566'},...] }
外部文档,引用其docment id
{ 'author' : 'Matin', 'books' : [ 'AD3D63D6-2FE0-11E2-93F9-898688C79046_book',...] }
与Mongodb相比,Couchbase的存储方式为Key/Value,Value的类型很为单一, 不支持数组。另外也不会自动建立doc id, couchbase须要为每一docment指定一个用于存储的Document Indentifer。
使用惟一的字段作标示符
如在session中,可使用用户的email, username做为惟一标示符
对象与自增策略
单首创建一自增数据(Document Indentifer),如 add('user',0) 每次建立一个用户时,能够自增'user', 而后获得 'user:1233'等
使用uuid
使用couchbase的bucket策略 自定义方式 (加前缀)
实践列举:
1. 网站访问量(PAGE VIW) 若咱们须要用couchbase统计网站PV 那么命名如 'pv:index', 'pv:blog', 'pv:about'。 2. 用户朋友圈 为用户创建一个朋友圈 apend('user#1233','user#444,user#666,')
经常使用来作cache,session,购物车使用,验证码等。ttl经过传入一个数字表示, couchbase会对数字做以下的判断:
小于30天(606024*30)的一秒为单位的数字,如600表示10分钟过时。
大于三十天的数字(秒),采用从公元开始的计数,如1381921696表示16th October 2013。
为0的表示永不过时。
set和add都是原子性操做,是多线程环境安全的操做。
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!"; }
与set不一样的是,若是docid内容存在时会,会更新失败。
$cb->add('message', 'Hello World!'); /*下面语句会失败*/ $cb->add('message', 'I pushed the button, but nothing happened!');
单文档返回
在php中若是docid不存在会返回undef:
$message = $cb->get('message')
多文档返回 (Retrieving in Bulk)
不一样库的多文档返回实现不一样,多文档返回比单独返回要快,由于请求和响应有延迟。 php的会返回一个关联数组:
$ret = $cb->getMulti(array('recipe1','recipe2'));
在set,add后可使用replace更新数据:
$message = $cb->get('message'); $message = $message . " How are you today?"; $cb->replace('message',$message);
在并发环境中,有必要保证并发更新
情景一:
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>'); }
用于页面访问量更新,数据统计等功能:
/*To increment by 1*/ $cb->set('counter',10); $cb->increment('counter'); /*To increment by 10:*/ $cb->set('counter',10); $cb->increment('counter', 10);
向文档首尾追加内容:
$user->set('userlist','martin,'); $user->append('userlist', 'stuart,'); $user->append('userlist', 'sharon,');
当数据存在时,可使用delete删除:
$cb->delete('message');