缓存的进化之路—Couchbase的分布式架构

标签: 缓存 进化 couchbase | 发表时间:2014-06-30 08:00 | 作者:
出处:http://jolestar.com

本文从缓存的演进,分析了Couchbase分布式缓存的架构

单机时代

单机时代一切都是美好的,缓存只是为了解决磁盘访问速度问题,大多数本地缓存基本上都是个HashMap.存储型应用内部都会内置一个缓存,复杂度一般不在缓存本身,而在于存储型应用提供的访问方式.(比如mysql缓存的复杂在于sql查询转换成缓存的key-value查询). 当单机纵向扩展(Scaling Up)遇到瓶颈时,必须探寻横向扩展(Scaling out)的方案.

多机分片(sharding)

横向扩展最简单的方式就是分片,无论存储还是缓存.分片最简单的方式就是 node=nodes[hash(key)/%nodes.length] n表示机器的节点数.但这样的方式用在缓存上有个问题,当新增加节点或者减少节点的时候,n变化基本上会导致所有的key对应的节点都发生变化,造成缓存震荡.这个大多数应用都是不可接受的. 另外一种分片就是静态key分片,应用配置中给每个节点设置静态hash区间,解决缓存震荡的问题.但这种方式带来的问题是如果某个节点宕机,不能自动摘除,无法实现高可用。 于是有了一致性哈希(Consistent Hashing) 一致性哈希(图片来自网络) 具体参看 一致性哈希 一般的实现方式是(代码仅是示例,做了部分精简):

  //构造hash环,一般用二叉树(java中TreeMap是红黑树)实现,便于便于增删节点
TreeMap<Long, Node> nodeMap = new TreeMap<Long, Node>();
for (Node node : nodes) {
    for (int i = 0; i < numReps; i++) {
        nodeMap.put(hash(node, i), node);
    }
}
//获取节点
Long nodeKey = nodeMap.ceilingKey(hash(key));
Node node = nodeKey == null?nodeMap.firstEntry().value:nodeMap.get(nodeKey);

分片的方式有以下优点: * 机器之间互相独立,运维部署简单(分片方案相对集群的优势) * 一致性哈希避免了减少或者增加节点导致的缓存震荡 * 一致性哈希的漂移机制一定程度上实现了高可用(相对静态分片) 但也存在以下问题: * 如果请求量非常大,宕机后1/n的数据穿透也不可接受 * 下线或者新增节点比较麻烦,需要应用修改配置升级,同时也会导致上面的问题 * 无法动态增减节点

代理方案

通过代理实现高可用也是一种可选方式,具体可参看 Redis HA 方案选型. 不过代理方式存在的问题: * 性能瓶颈 * 增加运维复杂度 * 不能很好解决单点问题(Redis代理一般要依赖Redis的主从复制机制,memcached代理无法实现分组多写)

分组多写方案

为了解决高可用问题,应用发展过程中逐步演化出来的方案. 同一个memcached集群,配置多组,写的时候多写,读的时候随机读或者根据配置规则读.一组中读取不到,则读取另一组. memcached-multi-group 增加新节点的时候,将新节点和旧节点合在一起作为一组(A),全部的旧节点作为另外一组(B),同时启用两组,读取数据的时候先从A读取,如果读取不到则从B读取.写的时候同时写两组.这样新增的节点会逐步热起来,等待合适的时候将B组下线. 这个方案虽然有点笨,但也能解决集群方案尚未成熟的时候的缓存的高可用问题. 这个方案存在以下问题: * 应用层的配置比较复杂,上线下线节点更加麻烦 * 写的时候要多写,对性能有影响 * 纯内存型缓存,如果数据量比较大,内存数据丢失(重启服务等),热缓存的成本比较高

分布式缓存

总结一下,我们期望中的理想缓存: * 自动分片,不需要应用关心
* failover,高可用,无单点问题
* 可动态扩容,可自动迁移数据实现均衡 * 自动复制(Replication),无需应用通过多写解决 * 可持久化 以上需求就是分布式缓存需要解决的问题

Couchbase的实现

要解决自动分片以及动态扩容问题,首先面临的问题就是客户端怎么知道数据存到那个节点上了?因为这个是动态变化的.初步想到的可能是用个中心节点去保存数据和节点的映射关系.这个方式在分布式文件系统中用的多,但用在缓存上明显不合适了,因为缓存的数据都是小数据,这样中心节点就成瓶颈了,但思路可以借鉴.于是Couchbase引入了vBucket的概念. * vBucket vBucket其实就是key的分组,然后配置中心只需维护vBucket到节点的映射关系.复制以及数据迁移都以vBucket为单位,这样降低了复制和数据迁移的成本.原来复制迁移数据,需要将整个节点的数据都迁移完成后才能提供服务,而有了vBucket的概念后,一个vBucket迁移完即可提供对该vBucket下的数据的访问服务. 注:Couchbase中的vBucket和Bucket是不同的概念.Bucket是Couchbase的数据分区,相当于虚拟的数据库集群.二者没有任何关系 * TAP协议 memcached本身没有提供数据同步机制,于是Couchbase引入了TAP协议来实现数据复制. http://www.couchbase.com/wiki/display/couchbase/TAP+Protocol * ep-engine(Eventually Persistent in-memory database) 持久化 https://github.com/membase/ep-engine ep-engine来源于membase,是memcached的持久化插件。 * ns_server 基于Erlang OTP框架实现,承担着集群管理监控协调的任务,提供web界面以及REST管理接口 https://github.com/couchbase/ns_server * smartclient 顾名思义,这个client需要”聪明”一些.client需要将vBucket的映射表缓存起来,访问的时候就不需要从配置中心查询对应的vBucket在哪个节点上.同时需要连接到集群上,监听vBucket映射的变化,动态变更本地的client配置. * moxi Memcached代理,主要提供给不支持smartclient的编程语言应用使用,如:php

这样Couchbase几乎实现了理想中的分布式缓存。

Couchbase的缺点

  1. 逐渐倾向于闭源,社区版本和商业版本之间差距比较大。
  2. 各种组件拼接而成,都是c++实现,导致复杂度过高,遇到奇怪的性能问题排查比较困难。可能这也是Redis的集群采取了一种保守方案的原因吧。

相关 [缓存 进化 couchbase] 推荐:

缓存的进化之路—Couchbase的分布式架构

- - 午夜咖啡
本文从缓存的演进,分析了Couchbase分布式缓存的架构. 单机时代一切都是美好的,缓存只是为了解决磁盘访问速度问题,大多数本地缓存基本上都是个HashMap.存储型应用内部都会内置一个缓存,复杂度一般不在缓存本身,而在于存储型应用提供的访问方式.(比如mysql缓存的复杂在于sql查询转换成缓存的key-value查询).

结合使用 Hadoop 和 Couchbase

- - 博客 - 伯乐在线
来源: IBM Developerworks. 简介: Hadoop 非常适合处理大量数据并将该信息解析为您可查询的较小的信息集. 但是,通过与 Couchbase Server 集成,您可以对信息执行实时查询和报告,同时继续使用 Hadoop 处理大型数据集和数据集的繁重处理工作. Couchbase Server 还使用了一个 MapReduce 查询系统,这使您能够轻松地迁移和集成索引和查询系统,从而有效地提取和操作信息.

Couchbase:更好的Cache系统

- - 博客园_知识库
  在移动互联网时代,我们面对的是更多的客户端,更低的请求延迟,这当然需要对数据做大量的 Cache 以提高读写速度.   现有 Cache 系统的特点.   目前业界使用得最多的 Cache 系统主要是 memcached 和 redis. 这两个 Cache 系统都有都有很大的用户群,可以说是比较成熟的解决方案,也是很多系统当然的选择.

Couchbase Server 2.0 发布,NoSQL 数据库

- - 开源中国社区最新新闻
Couchbase Server 2.0 发布了,主要特性包括:. 增量 Map Reduce. 详细功能描述和下载地址请看:. Couchbase Server (前身是 Membase) 是一个分布式的面向文档的 NoSQL 数据库管理系统,该系统联合了 CouchDB 的简单和可靠以及 Memcached 的高性能以及 Membase 的伸缩性.

CouchDB与Couchbase:区别何在,Membase又将如何?

- - InfoQ cn
去年二月, CouchOne与Membase合并了,合并之后的公司叫做Couchbase. Membase公司有一个名为Membase的产品,它是个键/值、持久化、可伸缩的解决方案,使用了 memcached wire协议. CouchOne支持 CouchDB. CouchDB是个文档数据库,提供了端到端的复制方法,这对于移动与分布在不同位置的数据中心来说是很有用的.

[原]Couchbase之环境搭建与Java小试

- - 上善若水 厚德载物
Couchbase Server 是一个集群化的、基于文档的数据库系统,网上有MongoDB与Couchbase的对比,请参考:. Couchbase主页: http://www.couchbase.com/. 本文的目标是搭建简单的Couchbase环境并用Java语言进行读写测试. 1)下载  Couchbase Server ,本文用到的版本是1.8.1 for win32 ,2.0在我的机器上装不上,内核问题.

文章: 从关系数据库向NoSQL迁移:采访Couchbase的产品管理主管Dipti Borkar

- - InfoQ cn
尽管关系数据库用于存储数据已经有几十年的历史,而且对很多用例而言,这仍然代表着一类可行的方案,但NoSQL正在成为人们当前的选择,尤其是考虑可伸缩性和性能的时候. 本文是对Couchbase的产品管理主管Dipti Borkar的采访,主要谈到了从关系数据库向NoSQL迁移的挑战、收益和过程. QCon北京2013,架构设计,大数据云计算等十八项专题,1月6日前报名7折.

缓存算法

- lostsnow - 小彰
没有人能说清哪种缓存算法由于其他的缓存算法. (以下的几种缓存算法,有的我也理解不好,如果感兴趣,你可以Google一下  ). 大家好,我是 LFU,我会计算为每个缓存对象计算他们被使用的频率. 我是LRU缓存算法,我把最近最少使用的缓存对象给踢走. 我总是需要去了解在什么时候,用了哪个缓存对象.

Hibernate 缓存

- - ITeye博客
1数据缓存:(date caching) 是一种将数据暂时存于内存缓存去中的技术,缓存通常是影响系统性能的关键因素. 2.ORM的数据缓存策略有3中.   1.事务级缓存:  分为 数据库事务和 应用级事务,是基于Session的生命周期的实现,每个session都会在内部维持一个数据缓存, 随session的创建和消亡.