设计和开发可以掌控客户端的分布式服务端程序是件幸事,可以把很多事情交给客户端来做,而且可以做的很优雅。角色决定命运,在互联网架构中,web server必须冲锋在前,注定要在多浏览器版本以及协议兼容性方面呕心沥血。但要是做了web server的backend,就会好很多,可以让服务端程序独善其身,分布式的功能特性都由客户端来支持和实现。memcache就是这样的设计模式。memcache是后台架构必备的利器,关于其原理及源码分析可以直接google之,在此不再多说。最近项目中要考虑冗余和容错的问题,就把memcache redundancy机制分析了一下,仅供大家参考。

why

consistent hash能保证在向现有机器组里加入或移除一台机器时,不会造成hash映射关系大范围的改变。但一台cache机器down了,内容就没有了,缓存需要重建,数据库的压力就会上升,要是cache机器down的太多,就会有cache雪崩,故障在所难免。要是一个key=value可以存储在多台机器上,一台down了还有其它的顶着,岂不甚好,这就是redundancy机制。可惜,memcached不支持这个特性。
It's not! Surprise! Memcached is a caching layer for your application. It is not designed to have any data redundancy.显然memcached自身不想做这个特性,又一次把任务抛给了客户端。有需求就有实现,pecl/memcache在3.0之后已经开始支持这种机制。
If data integrity is of greater importance a real replicating memcached backend such as "repcached" is recommended.可以通过配置memcache来开启这个特性:
memcache.redundancy = # default 1

how

下面就以pecl/memcache 3.0.6的代码分析一下redundancy具体的实现。

  • set

先来看一下set操作的相关代码:
/* schedule the first request */
mmc = mmc_pool_find(pool, key, key_len TSRMLS_CC);
result = mmc_pool_schedule(pool, mmc, request TSRMLS_CC);
/* clone and schedule redundancy-1 additional requests */
for (i=0; i < redundancy-1 && i < pool->num_servers-1; i++) {
mmc_queue_push(&skip_servers, mmc);
mmc = mmc_pool_find_next(pool, key, key_len, &skip_servers, &last_index TSRMLS_CC);
if (mmc_server_valid(mmc TSRMLS_CC)) {
mmc_pool_schedule(pool, mmc, mmc_pool_clone_request(pool, request TSRMLS_CC) TSRMLS_CC);
}
}

可以看出在set了一个key=value之后,还会set redundancy-1个clone。具体key的变换在mmc_pool_find_next函数:
/* find the next server not present in the skip-list */
do {
keytmp_len = sprintf(keytmp, "%s-%d", key, (*last_index)++);
mmc = pool->hash->find_server(pool->hash_state, keytmp, keytmp_len TSRMLS_CC);
} while (mmc_queue_contains(skip_servers, mmc) && *last_index < MEMCACHE_G(max_failover_attempts));

key变换的规则很简单,1变N(key-i) ,进行N次set。

  • get

get的时候当然是要以相同的方式来查找。但只要找到一个valid server就停止查找并返回。
mmc_t *mmc = pool->hash->find_server(pool->hash_state, key, key_len TSRMLS_CC);
/* check validity and try to failover otherwise */
if (!mmc_server_valid(mmc TSRMLS_CC) && MEMCACHE_G(allow_failover)) {
unsigned int last_index = 0;
do {
mmc = mmc_pool_find_next(pool, key, key_len, NULL, &last_index TSRMLS_CC);
} while (!mmc_server_valid(mmc TSRMLS_CC) && last_index < MEMCACHE_G(max_failover_attempts));
}

think
memcache是通过将一个key=value变换成N个key=value来实现redundancy,这样可以和3.0.0之前的接口很好的兼容,但redundancy的key需要变换并随机分散在机器上,每次都要hash查找,也很不好管理。自己想了一种redundancy的设计,就是引入group的概念,在加入机器的时候,配置所属的group id,一个key只hash到一个group id,所有的请求都发到group,group里面的每台机器存储hash(key)到该group的全部内容。这样set/get只需要一次hash操作,同时也可以在group内设计更灵活的实现方式。

这只是个人的一点儿想法,欢迎大家拍砖指正。

memcache redundancy机制分析及思考的更多相关文章

  1. Memcache存储机制与指令汇总

    1.memcache基本简介 memcached是高性能的分布式内存缓存服务器.一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度.提高可扩展性. Memcach ...

  2. Java 动态代理机制分析及扩展

    Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...

  3. 转:Redis和Memcache的区别分析

    Redis和Memcache的区别分析  原文链接:http://blog.csdn.net/u013474436/article/details/48632665 简单区别: 1. Redis中,并 ...

  4. Java 动态代理机制分析及扩展,第 1 部分

    Java 动态代理机制分析及扩展,第 1 部分 http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 本文通过分析 Java 动态代理的机制和特 ...

  5. Linux mips64r2 PCI中断路由机制分析

    Linux mips64r2 PCI中断路由机制分析 本文主要分析mips64r2 PCI设备中断路由原理和irq号分配实现方法,并尝试回答如下问题: PCI设备驱动中断注册(request_irq) ...

  6. IOS Table中Cell的重用reuse机制分析

    IOS Table中Cell的重用reuse机制分析 技术交流新QQ群:414971585 创建UITableViewController子类的实例后,IDE生成的代码中有如下段落: - (UITab ...

  7. 您还有心跳吗?超时机制分析(java)

    注:本人是原作者,首发于并发编程网(您还有心跳吗?超时机制分析),此文结合那里的留言作了一些修改. 问题描述 在C/S模式中,有时我们会长时间保持一个连接,以避免频繁地建立连接,但同时,一般会有一个超 ...

  8. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  9. Linux信号(signal) 机制分析

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

随机推荐

  1. 懒惰的JY--关于遍历

    先上题: [问题描述] 众所周知,JY的百度搜索算法已经练的炉火纯青,任何搜索题都能0.000ms出解. 不幸的是,JY遇到了一道百度搜索算法解决不了的题目,题目是这样的: 给定N个数A[1] A[2 ...

  2. 【tyvj1860】后缀数组

    描述 我们定义一个字符串的后缀suffix(i)表示从s[i]到s[length(s)]这段子串.后缀数组(Suffix array)SA[i]中存放着一个排列,满足suffix(sa[i])< ...

  3. Core love JavaScript

    Core love JavaScript 前言 在 ASP.NET 团队的 Github 的主页上,有这样一个开源项目叫:"JavaScriptsServices",那么什么是 J ...

  4. 1187: [HNOI2007]神奇游乐园 - BZOJ

    Description 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这是一个游乐场,专为旅途中疲惫的人设计. ...

  5. IntelliJ IDEA14 安装

    一.官网下载 IntelliJ IDEA的官网:https://www.jetbrains.com/idea/ 进入选择Get IntelliJ IDEA Now ,进入下载页:https://www ...

  6. jq获取元素到底部的距离

    // var wh = $(window).height(),//是文档窗口高度 // ot = $("#icoimg").offset().top,//是标签距离顶部高度 // ...

  7. What are the advantages of logistic regression over decision trees?FAQ

    What are the advantages of logistic regression over decision trees?FAQ The answer to "Should I ...

  8. WPF 位置转化和动画

    位置转化 private void DrawScale() { double majorTickUnitValue = this.ScaleSweepLenth / this.MajorDivisio ...

  9. sort-based shuffle的核心:org.apache.spark.util.collection.ExternalSorter

    依据Spark 1.4版 在哪里会用到它 ExternalSorter是Spark的sort形式的shuffle实现的关键.SortShuffleWriter使用它,把RDD分区中的数据写入文件. o ...

  10. ajax返回正个页面