分布式缓存服务器设计原理

1.数据是如何被分布到多个服务器上的?(一致性哈希算法)

假设有n台服务器,

计算这n台服务器的IP地址的哈希值,

把这些哈希值从小到大按顺时针排列组成一个“服务器节点环”,

客户端需要存储一系列的“键值对”到这些服务器上去,

计算这些“键”的哈希值,

看看这些“键”的哈希值落在“服务器环”的哪些区间,

如下图所示:

根据上图示意,数据将被存储在“顺时针方向上的下一个服务器节点”

读取数据时,也是先根据“键”的哈希值,找到这个服务器节点,

再向这个节点索取数据。

2.数据如何均匀的分布?(虚拟服务器)

假设服务器数量较少,

很可能造成有些服务器存储的数据较多、承担的压力较大,

有些服务器就比较空闲。

这时就要把一台服务器虚拟化成多台服务器,

具体的操作办法:

在计算服务器对应的哈希值时

可以在IP地址字符串加多个“尾缀”

比如:

10.0.0.1#1

10.0.0.1#2

10.0.0.1#3

....

这样,一台物理服务器就被虚拟化成多台服务器,

对应“服务器环”上的多个节点。

3.如何实现数据的热备份?

以顺时针方向看“服务器环”

当有客户端把数据存储在第1台服务器上后,

第1台服务器负责把该数据拷贝一份给第2台服务器

以此类推,

也就是说“服务器环”上的每一个节点,都是上一个节点的热备份节点

同时,一个服务器上存了两类数据,一类是自身的业务数据,一类是上一节点的热备数据。

注意:这里所说的服务器,都是物理服务器,不是虚拟服务器。

如下图所示

4.如何让客户端发现所有服务端?

每个服务器节点都要维护一个对照表

这个对照表中包含所有服务器,(IP地址和IP地址的哈希值对照表)

配置客户端时,只要让客户端知道任意一个服务器的IP地址即可

客户端可以通过获取这个服务器的对照表从而知道所有的服务器

客户端初始化的时候,这个对照表也存储在客户端一份

客户端根据这个对照表来存取数据

注意:这个对照表是有一个版本号的,具体的用途见下面的描述

5.如何应对服务器异常?

假设数据在节点1上读写不成功,

我们就认为这个节点存在异常,要把它从服务器群集中拿掉。

客户端先在节点2(节点1的热备节点)上完成相应的读写工作,这时客户端就可以去做其他工作了。

然后节点2向节点0索取数据(这些数据是本应该备份在节点1上的数据)
然后节点2向节点3推送数据(这些数据是节点1上的数据,现在要备份在节点3上)

然后节点2更新其对照表,把节点1从其对照表中移除,并更新对照表的版本号

当有任何客户端与节点2交互的时候,

就会发现节点2上的对照表的版本号比自己持有的对照表要高

此时,客户端就更新自己的对照表

这些客户端再与其他服务器交互的时候

其他服务器发现客户端携带的对照表版本号比自己持有的要高

此时,其他服务器更新自己的对照表

注意:这是一个“发散式的连锁反应”,不会影响生产。

还可以让节点2告知节点3需要更新对照表

当节点3更新完之后,再让节点3告知节点4....

以此引发“环式的连锁反应”

注意:

当“服务器环”上连续两台服务器同时故障的时候,那么这个系统就崩溃了

可以对数据做两次热备份,以提高安全性,但性能和硬件利用率会有所损耗。

6.如何增加服务器?

首先需要通过配置让这台服务器知道节点环上的任意一台服务器的IP地址(假设是10.0.0.1)

此服务端运行之后,他就会从10.0.0.1上获取对照表,

以此知道自己在节点环中的具体位置,

它首先需要从它的下一个节点中迁移一部分数据(也就是它上一个节点热备份的一部分数据)
然后从上一个节点中索取一部分数据(也就是该自己存储的一部分数据)

然后它把自己加入对照表中,

然后告知10.0.0.1需要更新对照表,以此引发连锁反应

 

 

 

此文最初的想法是一个alexqiu跟我说的,

后来又仔细研究了一致性哈希算

并加入了我自己的想法(热备机制、配置表保存及升级机制)

最终形成此文。

 

 

2014年4月9号:

针对此文做了技术分享,录音文件地址:http://url.cn/KxFQw5

第一个问题:此文利用IP地址(虚拟IP地址)计算哈希值的办法尚待进一步考虑和验证

第二个问题:增减服务器节点均是在"物理节点环"上完成,与“虚拟节点环”没有关系

第三个问题:除了热备,还可以在热备的基础上实现负载均衡

时间: 2024-11-09 02:18:58

分布式缓存服务器设计原理的相关文章

以fourinone为例详细解析分布式协调的设计原理

fourinone 实际上可以单独当做 Zookeeper 用,它使用最少的代码实现了 Zookeeper 的所有功能,并且力图做到功能更强但是使用更简洁.本文以 fourinone 为例详细解析了分布式协调的设计原理. Fourinone(中文名字"四不像")是一个四合一分布式计算框架,在写这个框架之前,我对分布式计算进行了长时间的思考,也看了老外写的其他开源框架.当我们把复杂的 Hadoop 当作一门学科学习时,似乎忘记了我们想解决问题的初衷:我们仅仅是想写个程序把几台甚至更多的机

分布式文件系统FastDFS设计原理

  原文地址: http://blog.chinaunix.net/uid-20196318-id-4058561.html FastDFS是一个开源的轻量级分布式文件系统,由跟踪服务器(tracker server).存储服务器(storage server)和客户端(client)三个部分组成,主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务.   Storage server Storage server(后简称st

mysql 与缓存服务器集成的介绍(memcache+redis)

Memcached和Redis作为两种Inmemory的key-value数据库,在设计和思想方面有着很多共通的地方,功能和应用方面在很多场合下(作为分布式缓存服务器使用等) 也很相似,在这里把两者放在一起做一下对比的介绍    基本架构和思想 首先简单介绍一下两者的架构和设计思路   Memcached Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric为首开发的高性能分布式内存缓存服务器.其本质上就是一个内存key-value

OEA中的缓存模块设计

  项目组目前开发的基于OEA框架的GIX4项目,本次功能已经完成得差不多了,本次迭代的目标主要是提升产品的性能.由于GIX4是C/S结构的应用程序,所以决定实现缓存模块来提升高繁数据访问的缓存.     本篇文章主要介绍了OEA框架中的缓存模块设计与一般的缓存有什么不同,如何在OEA框架中实现缓存模块.分为以下几个小节: 一般缓存介绍 OEA缓存目标 概要设计 通用缓存框架的详细设计 OEA中集成Cache的详细设计 小结 一般缓存介绍     网上介绍缓存的文章比较多,在这里我就挑点重点说一

关于.Net开发下的分布式缓存设计

最近拜读了代振军同学写的关于.net开发下的Discuz!NT的缓存设计的一篇文 章Discuz!NT 缓存设计简析 [原创],颇有些想法,姑且写在这里让大家拍砖吧 .;) 缓存真是个好东西,在大型的系统中可以有效地提升系统的速度,此乃废话 就不多说了,在.Net 平台下面我把缓存从功用大致分为两类,数据对象缓存和 页面输出缓存. 对于数据缓存来讲是由System.Web.Caching.Cache这个类来实现 ,可以从上下文对象Context.Cache 来获取这个对象的引用.而页面/控件输出

Memcached 分布式缓存实现原理简介_Linux

摘要 在高并发环境下,大量的读.写请求涌向数据库,此时磁盘IO将成为瓶颈,从而导致过高的响应延迟,因此缓存应运而生.无论是单机缓存还是分布式缓存都有其适应场景和优缺点,当今存在的缓存产品也是数不胜数,最常见的有redis和memcached等,既然是分布式,那么他们是怎么实现分布式的呢?本文主要介绍分布式缓存服务mencached的分布式实现原理. 缓存本质 计算机体系缓存 什么是缓存,我们先看看计算机体系结构中的存储体系,根据冯·诺依曼计算机体系结构模型,计算机分为五大部分:运算器.控制器.存

一起谈.NET技术,.Net下的分布式缓存--从Discuz!NT的缓存设计谈起

最近拜读了代振军同学写的关于Discuz!NT的缓存设计的一篇文章<Discuz!NT 缓存设计简析 [原创]>,颇有些想法,姑且写在这里让大家拍砖吧. 缓存真是个好东西,在大型的系统中可以有效地提升系统的速度,此乃废话就不多说了,在.Net 平台下面我把缓存从功用大致分为两类,数据对象缓存和页面输出缓存. 对于数据缓存来讲是由System.Web.Caching.Cache这个类来实现,可以从上下文对象Context.Cache 来获取这个对象的引用.而页面/控件输出缓存则是由.Net环境在

高性能服务器架构(三):分布式缓存

原文链接:http://mp.weixin.qq.com/s/BxQB44DQZhDQr1dYU3qTIA 在分布式程序架构中,如果我们需要整个体系有更高的稳定性,能够对进程容灾或者动态扩容提供支持,那么最难解决的问题,就是每个进程中的内存状态.因为进程一旦毁灭,内存中的状态会消失,这就很难不影响提供的服务.所以我们需要一种方法,让进程的内存状态,不太影响整体服务,甚至最好能变成"无状态"的服务.当然"状态"如果不写入磁盘,始终还是需要某些进程来承载的.在现在流行的

.Net下的分布式缓存--从Discuz!NT的缓存设计谈起

最近拜读了代振军同学写的关于Discuz!NT的缓存设计的一篇文章<Discuz!NT 缓存设计简析 [原创]>,颇有些想法,姑且写在这里让大家拍砖吧. 缓存真是个好东西,在大型的系统中可以有效地提升系统的速度,此乃废话就不多说了,在.Net 平台下面我把缓存从功用大致分为两类,数据对象缓存和页面输出缓存. 对于数据缓存来讲是由System.Web.Caching.Cache这个类来实现,可以从上下文对象Context.Cache 来获取这个对象的引用.而页面/控件输出缓存则是由.Net环境在