couchbase是一个较新的、发展迅速的nosql数据库技术。2014年,viber宣布使用couchbase替换mongodb,以适应10亿级的用户量,目前,couchbase已大量运用于生产环境,国内使用的公司主要有新浪,腾讯等。由于中文资料较少,阅读了官方文档中的部分介绍后,将资料翻译和汇总如下。

概述

couchbase是CouchDB和MemBase的合并。而memBase是基于Memcached的。因此couchbase联合了couchbase的简单可靠和memcached的高性能,以及membase的可扩展性。

灵活的数据模型:couchbase中使用json格式存储对象和对象之间的关系。

Nosql数据库的一个特性是不需要定义数据结构,在couchbase中,数据可以存储为key-value对或者json文档,不需要预先定义严格的格式,由于这种特性,couchbase支持以 scale out(水平扩展)方式扩展数据量,提升io性能,只需要在集群中添加更多的服务器就行了。相反,关系数据库管理系统scale up(纵向扩展),通过加更多的CPU,内存和硬盘以扩展容量。

Couchbase可用于单机环境,也可以和其他服务器一起提供分布式的数据存储。

数据存储:

Couchbase通过使用buckets提供数据管理服务,buckets相当于关系数据库中的库,couchbase中没有表的概念,保存数据时,先建bucket,然后就直接插入数据了。buckets可以供集群中的多个客户端程序访问。couchbase通过Buckets组织,管理和分析数据资源。

couchbase中有两种类型的数据bucket,当启动couchbase服务的时候,可以选择需要的类型。

1)memcached buckets。只将数据存储在内存中。提供了一个分布式的(横向扩展),纯内存的,key-value缓存。Memcached buckets 设计用于关系数据库的缓存,可以缓存经常访问的数据,由此减少web程序中数据库的查询次数。

2)couchbase buckets。存数据在内存和硬盘。提供高可用性和可动态重新配置的分布式数据存储,提供数据持久化和复制服务。couchbase buckets 100% 兼容开源的分布式缓存memcached。

内存配额

Server Quota:

Couchbase服务初始化时会给服务器分配内存限额,表示这个服务器中可用的最大内存,是node级的。初始配置在集群中的第一台服务器(node)上,所有服务器的内存配额都是一样的。例如集群中有10台服务器,服务器内存配额是16G,整个集群中共160G可用内存。如果需要加2个新的服务器,每个新的服务器需要16G的可用内存,集群中可用的内存数将是192G。

Bucket Quota:

Bucket 内存配额是分配给一个bucket的可用内存。配置在每个节点上,是从server quota中分配出去的。例如,如果你创建了一个新的bucket,限额是1GB,在10个节点的集群中,汇总后会有10G。如果添加两个节点,集群中汇总后会有12G的bucket 限额。

 

从图上可以看出,增加新的节点就可以扩展总的可用内存,从而增加存储的数据量。通过bucket限额系统可以判断数据是否应该调出内存。

vBucket

vBucket相当于一个key的子集,保存的是客户端存储对象的key值,vBuckets 用于在集群的节点间分配数据和备份数据。是couchbase 实现 auto sharding,在线动态增减节点的重要基础。不是用户可访问的组件,但是至关重要。

通过vbucket,客户端直接访问保存信息的服务器,不需要通过中间代理或者其他架构,因此可以从数据中抽象出物理拓扑结构。这种方式使couchbase易扩展。

这种架构不同于memcached使用的架构,memcached的做法是用 key 算出一个 hash,得到服务器列表中的对应服务器。这个列表需要动态维护,还需要一个hash算法用于处理集群拓扑结构的变化。

如以下代码所示:

       servers = ['server1:111', 'server2:112', 'server3:113']
server_for_key(key) = servers[hash(key) % servers.length]

这种算法很简单,也很容易理解,但也有几个问题:

1、如果一台服务器失效,会造成该分片的所有 key 失效。

2、如果服务器容量不同,管理非常麻烦。

3、运维、配置非常不方便。

为了把 key 跟服务器解耦,couchbase 引入了 vBucket。每个key都属于一个vbucket,查找对应的value时先用hash函数计算这个key属于哪个vbucket,再从vBucket 与服务器对应表中查找这个vbucket属于哪个服务器,映射表保存vbucket和服务器的对应关系,一个bucket一行,一个服务器可以对应多个vbucket。

1、key hash 对应一个 vBucket,不再直接对应服务器。

2、集群维护一个全局的 vBucket 与服务器对应表。

例如,集群中有3个服务器,客户端要查找 一个key对应的value值,首先计算key属于哪个Vbucket,在这个例子中,hash结果是vB8 ,通过查映射表,客户端确定vB8对应到服务器C,然后get操作直接发送到服务器C。

一段时间后,需要加一个新的服务器D到集群,vbuckets映射表更新为:

这时,客户端再想取key对应的value值,hash算法结果仍为vB8,但是新的映射表会将vB8映射到服务器D。

由于 vBucket 把 key 跟服务器的静态对应关系解耦合,基于 vBucket 可以实现一些非常强大有趣的功能,例如:

Replica,以 vBucket 为单位的主从备份。如果某个节点失效,只需要更新 vBucket 映射表,马上启用备份数据。

动态扩容。新增加一个节点后,可以把部分 vBucket 转移到新节点上,并更新 vBucket 映射表。

缓存层

Couchbase自动管理缓存层,确保有足够的内存空间以维持性能。couchbase后台有个进程,专门把一定时间没有被访问的数据移出内存,这个进程的扫描时间和数据的最大无活动时间都是可以设置的。couchbase在对数据进行增删时会先体现在内存中,而不会立刻体现在硬盘上,从内存的修改到硬盘的修改这一步骤是由couchbase自动完成,等待执行的硬盘操作会以write queue的形式排队等待执行,也正是通过这个方法,硬盘的I/O效率在write   queue满之前是不会影响couchbase的吞吐效率的,而write queue的长度是可以设置的。通过write queue执行大量写数据库操作时用户可能会感受到很短时间的内存飙升,但是异步特性和queue的使用使读写速度都非常快。

对于所有文档couchbase都会建立一个额外的56byte的metadata,这个metadata功能之一就是表明数据状态是否活动在内存中。同时文档的id也作为标识符和metadata一起长期活动在内存中。这表示对文档id不存在的情况服务器可以直接返回‘文档id不存在。couchbase官方建议bucket申请的内存中,metadata和key所占用的内存不应超过一半,否则couchbase的性能会显著下降。为了保证这个条件,当有效数据占用超过一定内存时就需要把超额数据移除了。

这里有低水位和高水位的概念,也就是说当移除数据过多以至于内存中有效数据占用内存低于低水位的时候,couchbase会随机挑一些文件到内存中以达到低水位。当有效数据内存占用超过高水位时,couchbase就会移除数据。高低水位都是可以设置的。

随着内存数据越来越多,会逐渐到达低水位,这时候,系统不会做任何处理。当数据量持续增加,到达高水位时,系统会启动一个job任务移除数据,当到达低水位时任务停止。如何进入数据的速度大于移除数据的速度,系统会返回空间不足的错误提示,直到有足够的内存为止。

如果只使用memcached buckets,服务器只提供数据缓存,不会持久化到硬盘。如果服务器内存空间不足,系统会使用LRU算法从内存中Eviction 数据,Eviction表示服务器会移除一个数据项的key,metadata和所有其他信息。Eviction后,数据将无法恢复。

硬盘存储

考虑到性能,couchbase服务主要使用缓存为客户端保存和返回信息,同时会逐渐将数据保存到硬盘以维持高可靠性。如果有节点fail了可以直接从硬盘恢复数据,数据是逐渐持久化到硬盘的,同时保存到缓存层和硬盘write queue,不会阻塞客户线程。当客户端访问一个不在内存的数据时,持有load queue的进程会将数据读到内存,在数据返回之前客户端需要等待。

多线程读写:之前的couchbase版本,读写硬盘的线程只有一个。为了提高读写硬盘的速度和提高缓存命中率,现在couchbase提供了多线程读写。

多线程读写需要考虑线程之间的同步问题以避免冲突。为了维持性能和避免冲突,couchbase对每个线程访问的资源进行了静态分配,同时使用了资源锁。当创建多个读写线程时,服务器为每个线程单独分配了不同的vbuckets。通过这种静态协调方式,可以保证同一个vbuckets只有一个读线程和一个写线程可以访问。上图表示6个线程和两个数据vbucket。每个线程有预先分配的可读写范围。

Rebalancing

Couchbase 服务器上数据的分配方式是通过vbucket结构实现的,如果想增加或减少集群中的机器,vbuckets中存储的数据都需要重新分配,vBucket map(映射表)也需要更新以适应新的集群结构。

Rebalancing 是集群结构发生变化时的数据调整,需要手动操作,这个过程改变vbuckets到服务器的分配,需要在服务器节点之间迁移数据以适应新的结构。

Rebalancing过程可以发生在集群运行和提供服务时,客户端使用现有架构读写数据,同时后端在节点之间迁移数据。一旦这个过程完成, 更新vBucket map表,并通知smart clients和代理服务(MOxi).

Rebalancing后数据在集群中重新分配,因此数据被均匀分配到整个数据库,这个过程需要考虑数据和数据的副本。

总结

数据存储:nosql,易水平扩展。

缓存层:低水位和高水位设置,文档metadata。

vBucket:使系统易于动态管理,自动分片,reblancing。

多线程持久化:预分配每个线程的访问范围,保证性能和可靠性。

CouchBase数据库-一个较新的、发展迅速的nosql数据库技术的更多相关文章

  1. SSDB 一个高性能的支持丰富数据结构的 NoSQL 数据库, 用于替代 Redis.

    SSDB 一个高性能的支持丰富数据结构的 NoSQL 数据库, 用于替代 Redis. 特性 替代 Redis 数据库, Redis 的 100 倍容量 LevelDB 网络支持, 使用 C/C++ ...

  2. 【DB宝46】NoSQL数据库之CouchBase简介、集群搭建、XDCR同步及备份恢复

    目录 一. CouchBase概述 1.1.简述 1.2.CouchDB和CouchBase比对 1.2.1.CouchDB和CouchBase的相同之处 1.2.2.CouchDB和CouchBas ...

  3. NoSQL数据库 Couchbase Server - 分布式缓存

    Couchbase Server (前身是 Membase) 是一个分布式的面向文档的 NoSQL 数据库管理系统,该系统联合了 CouchDB 的简单和可靠以及 Memcached 的高性能以及 M ...

  4. 10个出色的NoSQL数据库

    http://www.infoq.com/research/nosql-databases?utm_source=infoqresearch&utm_campaign=lr-homepage ...

  5. 10个出色的NoSQL数据库(转)

    随着大数据的不断发展,非关系型的数据库现在成了一个极其热门的新领域,非关系数据库产品的发展非常迅速.现今的计算机体系结构在数据存储方面要有庞大的水平扩展性,而NoSQL也正是致力于改变这一现状.目前G ...

  6. 28个MongoDB NoSQL数据库的面试问答

    MongoDB是目前最好的面向文档的免费开源NoSQL数据库.如果你正准备参加MongoDB NoSQL数据库的技术面试,你最好看看下面的MongoDB NoSQL面试问答.这些MongoDB NoS ...

  7. 关于 NoSQL 数据库你应该了解的 10 件事

    四分之一个世纪以来,关系型数据库(RDBMS)一直是主流数据库模型.但是现在非关系型数据库,“云”或者“NoSQL”数据库,正在作为一种替代数据库模型获得越来越多的占有率.本文中我们将关注非关系型 N ...

  8. 各NoSQL数据库管理系统与模型比较

    提供:ZStack云计算 内容简介 NoSQL数据库的存在意义在于提供传统关系数据库管理系统所不具备的特定功能.无论是负责承载简单的键-值对存储以实现短期缓存,抑或是处理传统数据库及结构化查询语言(简 ...

  9. NoSQL数据库的四大分类的分析

    分类 Examples举例 典型应用场景 数据模型 优点 缺点 键值(key-value) Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB 内容缓 ...

随机推荐

  1. visual c++如何显示行号

    工具 -> 选项 -> 文本编辑器

  2. java的坦克大战

    一个渣渣写坦克大战的步骤: 1.首先创造好一个坦克和一个GAME框架,并且坦克能够跟着键盘键位移动 案例:在我的博客文件中保存,它的名字是:tankwar0100.rar 主要解决了:1.坦克背景框 ...

  3. CenOS 更换yum源

    说明: 更换CentOS yum源既是修改配置文件/etc/yum.repos.d/CentOS-Base.repo. 目前有很多公司都提供yum源文件的下载,所以我们可以不需要去修改这个文件,直接从 ...

  4. python调用c++ DLL

    python DLL = ctypes.cdll.LoadLibrary("./dll_file.so") #引入dllDLL.func(mat.ctypes.data // (1 ...

  5. oracle数据库实例启动与关闭

    区分数据库与实例:实例是指各种内存结构和服务进程,数据库是指基于磁盘存储的数据文件.控制文件.参数文件.日志文件和归档日志文件组成的物里文件集合. 数据库实例启动: startup [nomount ...

  6. java版数据结构与算法 (1综述)

    很大部分转载自 https://blog.csdn.net/singit/article/details/54898316 数据的逻辑结构:反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系指数据元 ...

  7. SpringBoot统一异常处理

    /** * 异常处理器 */ @RestControllerAdvice // public class BDExceptionHandler { private Logger logger = Lo ...

  8. 【Python】*args和**kwargs的区别

    1.*args表示将参数作为元组传给函数 通过一个函数的定义来理解’*args’的含义 修改函数的定义: >>> def fun(*args): ... print args ... ...

  9. 清理maven本地库中的lastUpdated文件

    通过CMD命令窗口进入响应的文件夹下 输入指令 for /r %i in (*.lastUpdated) do del %i

  10. [C# 基础知识系列]专题五:当点击按钮时触发Click事件背后发生的事情 (转载)

    当我们在点击窗口中的Button控件VS会帮我们自动生成一些代码,我们只需要在Click方法中写一些自己的代码就可以实现触发Click事件后我们Click方法中代码就会执行,然而我一直有一个疑问的—— ...