之前听说过高性能的分布式缓存开源工具,但一直没有真正接触过,如今接触的产品中实用到过分布式缓存。所以决定一探到底。memcached是一个优秀的开源的分布式缓存工具。也是眼下比較火热的分布式缓存的解决方式雏形。memcached的服务端产品本身功能简洁,简单易用。可是玩法多种多样。可是其实它是一个“伪分布式”解决方式。它本身并没有实现服务端分布式(服务端的memcached
server之间是不能通信的),所谓的分布式都是依靠client来实现,而眼下市面上提供了client分布式实现的开源工具非常多,在这里我主要以Spymemcached这个client实现为基础讲述一些memcached的原理和应用。


【原理说明】
    之前提到了,memcached产品本身并未实现分布式,所以借助下列两幅网上流行的图片便能够直观的了解memcached的原理以及怎么玩分布式的。

   1、存储(set)
如果memcached server有node1/node2/node3三个节点,如今应用程序须要存储"tokyo"/"test"这样一对键值对。memcachedclient接收应用程序传来的键值对"tokyo"/"test",通过算法(文章尾部会介绍详细的算法细节)从server列表中选中了node1作为目标存储server。接着发送set指令命令node1运行存储任务。

图1 存储数据

    2、获取(get)
如果应用程序如今须要获取键"tokyo"相应的值数据"test",memcachedclient程序接收參数"tokyo",通过相同的算法从server列表中选中node1,接着发送get指令命令node1获取键"tokyo"相应的值数据。

                                                      图2  获取数据

【使用场景】
    在网上也看过一些前辈描写叙述过一些关于使用场景的描写叙述,我简单总结下大致就下面两点
    1、从memcached设计初衷的角度来看,memcached能够降低站点数据库的开销。对于常常须要读取,而又不常常改变的数据全然能够放到memcached中。

    2、分布式应用之间共享数据。举个样例,登陆系统和商品查询系统是独立部署,而且是集群的。用户登陆了登陆系统之后怎样将登录信息与其它的业务系统(商品查询系统)共享信息,这时就能够使用memcached缓存登录信息。商品查询系统便能够从memcached中获取用户的登陆信息。

【client源代码分析】


   
1、client调用
    以Spymemcachedclient实现为例。以下贴一段client的简单应用代码。下载链接memcached client
package com.lvmama.memcached;
import java.net.InetSocketAddress;
import net.spy.memcached.MemcachedClient;
public class TestSpymemcached {
public static void main(String[] args) throws Exception{
MemcachedClient client = new MemcachedClient(new InetSocketAddress("127.0.0.1", 11211)); //创建连接
client.set("name", 10, "tony"); //set数据
Object name = client.get("name"); //get数据
System.out.println("name:" + name);
}
}


   2、余数hash算法
    实现类为ArrayModNodeLocator,将传入的參数k(键)。通过hash算法得出一个整数值,计算下memcached server的个数。拿着參数k的hash值对server节点的个数求余数。余数便是选中的server节点。

  public MemcachedNode getPrimary(String k) {
return nodes[getServerForKey(k)];
} private int getServerForKey(String key) {
int rv = (int) (hashAlg.hash(key) % nodes.length);
assert rv >= 0 : "Returned negative key for key " + key;
assert rv < nodes.length : "Invalid server number " + rv + " for key "
+ key;
return rv;
}

   3、consistent hash算法
    算法原理见下图
    第一步:将memcachedserver节点的hash值映射到一个0~2的32次方的环形数据结构上,存储方式为k(hash值),v(server节点);
    第二步:将要保存的參数k计算hash值,并映射到环形数据结构中;
    第三步:从參数k的hash值顺时针查找已映射的hash值,第一个hash值相应的server节点便是选中的目标存储server。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbG10b255/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

                                                 图 3   consistent hash算法

    实现类为KetamaNodeLocator,代码结构比較简单:将要保存的k计算hash值作为參数传入getNodeForKey()方法,从hash值顺时针查找到剩余的环形数据结构tailMap。假设tailMap不为空则取tailMap中第一个已经映射hash值,假设tailMap为空则取整个环形数据结构ketamaNodes的第一个已经映射的hash值(从0開始),取得hash值便能够找到相应的memcachedserver节点。

  public MemcachedNode getPrimary(final String k) {
MemcachedNode rv = getNodeForKey(hashAlg.hash(k));
assert rv != null : "Found no node for key " + k;
return rv;
} MemcachedNode getNodeForKey(long hash) {
final MemcachedNode rv;
if (!ketamaNodes.containsKey(hash)) {
// Java 1.6 adds a ceilingKey method, but I'm still stuck in 1.5
// in a lot of places, so I'm doing this myself.
SortedMap<Long, MemcachedNode> tailMap = getKetamaNodes().tailMap(hash);
if (tailMap.isEmpty()) {
hash = getKetamaNodes().firstKey();
} else {
hash = tailMap.firstKey();
}
}
rv = getKetamaNodes().get(hash);
return rv;
}

4、算法优劣比較
余数hash算法:当server节点存在添加或者降低时,get数据时求得的余数同set数据时求得的余数非常可能就不是同一个值,这时便大大降低了缓存读取的命中率。
consistent hash算法:当server节点存在添加或者降低时,如图3添加了node5,仅仅有node2~node5之间的hash值会受到影响,由原来存储时命中的node4变成获取数据时命中的node5。其余hash值都不会受到影响。所以命中率较高。
并且有些consistent
hash算法的实现採用了虚拟节点的思想,使用一般的hash函数会使得server节点的映射分布的不均匀。因此能够为每一个物理server节点分配100~200虚拟映射点。这样便可最大限度的降低节点分布不均的情况发生。


初尝memcached,如有描写叙述有误,欢迎拍砖哈!兴许会写memcached服务端的内存模型。内存管理,源代码分析等文档,欢迎大家一起探讨!



















    

分布式设计《初尝memcached》的更多相关文章

  1. .NET领域驱动设计—初尝(三:穿过迷雾走向光明)

    开篇介绍 在开始这篇富有某种奇妙感觉的文章之旅时我们先短暂的讨论一下关于软件开发方法论的简要: 纵观软件开发方法论,从瀑布模型.螺旋模型.RUP(统一软件开发过程).XP(极限编程).Agile(敏捷 ...

  2. .NET领域驱动设计—初尝(一:疑问、模式、原则、工具、过程、框架、实践)

     .NET领域驱动设计—初尝(一:疑问.模式.原则.工具.过程.框架.实践) 2013-04-07 17:35:27 标签:.NET DDD 驱动设计 原创作品,允许转载,转载时请务必以超链接形式标明 ...

  3. [转] .NET领域驱动设计—初尝(原则、工具、过程、框架)

    阅读目录: 1.原则 1.1.精简聚合 1.2.分离用例与接口功能(设计模式的用武之地) 2.工具.框架.组件 3.过程 1]原则 原则对于任何一项技术实现来说都是至关重要的,在设计某一个系统功能的时 ...

  4. [转] .NET领域驱动设计—初尝(疑问、模式、原则、工具、过程、框架、实践)

    阅读目录: 1.1.疑问 1.1.1.UML何用 1.1.2.领域建模 1.2.模式 1.3.原则 1.5.过程 1.6.框架 1.7.项目演示 最近在研究DDD颇有收获,所以整理出来跟大家分享,共同 ...

  5. 初尝 Perl

    本文将阐述以下几方面内容: 1.什么是Perl 2.Perl有什么用 3.Windows 下的Perl环境搭建 4.Perl 版Hello World 5.Perl 语法梗概 6.一些参考资料 什么是 ...

  6. 初尝Windows 下批处理编程

    本文叫“ 初尝Windows 下批处理编程”是为了延续上一篇“初尝 Perl”,其实对于博主而言批处理以及批处理编程早就接触过了. 本文包括以下内容 1.什么是批处理 2.常用批处理命令 3.简介批处 ...

  7. seajs初尝 加载jquery返回null解决学习日志含示例下载

    原文地址:http://www.tuicool.com/articles/bmuaEb 如需demo示例,请点击下方链接下载: http://yunpan.cn/cVEybKs8nV7CF  提取码 ...

  8. Kafka#4:存储设计 分布式设计 源码分析

    https://sites.google.com/a/mammatustech.com/mammatusmain/kafka-architecture/4-kafka-detailed-archite ...

  9. 初尝微信小程序2-Swiper组件、导航栏标题配置

    swiper 滑块视图容器. 很多网页的首页都会有一个滚动的图片模块,比如天猫超市首页,滚动着很多优惠活动的图片,用来介绍优惠内容,以及供用户点击快速跳转到相应页面. Swiper不仅可以滚动图片,也 ...

随机推荐

  1. Java调用JavaWebService

    1.pom配置 <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId&g ...

  2. BZOJ 4565 状压DP

    思路: f[i][j][S]表示从i到j压成S状态 j-m是k-1的倍数 $f[i][j][S<<1]=max(f[i][j][S<<1],f[i][m-1][S]+f[m][ ...

  3. H265

    H265 h265  一.名词 CTU: 编码树单元 CU: 编码单元 PU: 以CU为根,对CU进行划分,一个预测单元PU包含一个亮度预测块PB和两个色度预测块PB. TU: 以CU为根,变换单元T ...

  4. Windows 下MySQL zip 安装

    主要步骤: 1.下载解压到安装的文件夹 2.配置环境路径 3.配置my.ini文件,设置程序路径和数据存储路径 4.以管理员身份启动Mysqld install(提示sevice安装成功) 5.启动M ...

  5. JavaScript特效之图片特效放大,缩小,旋转

    效果图如下: 效果代码如下: <!doctype html> <html lang="en"> <head> <meta charset= ...

  6. python2打印list中文内容防乱码

    zh_ls = ['人','民'] print str(zh_ls).decode("string_escape")

  7. SLAM: 图像角点检测的Fast算法(OpenCV文档)

    官方链接:http://docs.opencv.org/trunk/doc/py_tutorials/py_feature2d/py_fast/py_fast.html#fast-algorithm- ...

  8. C# 获得剪贴板内容和 richTextBox部分文本设置颜色

    try { MemoryStream vMemoryStream = iData.GetData("Html Format") as MemoryStream; if (vMemo ...

  9. BZOJ 2959: 长跑 LCT_并查集_点双

    真tm恶心...... Code: #include<bits/stdc++.h> #define maxn 1000000 using namespace std; void setIO ...

  10. 【转载】使用JSONObject生成和解析json

    1. json数据类型 类型 描述 Number 数字型 String 字符串型 Boolean 布尔型 Array 数组 Object 对象 null 空值 (1)json中不区分整数.小数等类型, ...