memcached分布式算法

memcached的分布式是依靠客户端的算法来实现,假设键名为$key,服务器数量为N,常规的实现方式有两种:

  • 取模哈希

    • crc32($key)%N,通过这个算法将键名映射到某一台服务器,比如需要存取一个键名为myname的缓存,服务器数量为3,那么通过算法计算:crc32('myname')%3=0,那么这个缓存就落到第1台服务器上面
    • 这种方式虽然简单可行,但是增减服务器的时候,缓存将面临大量的重建,比如上面的例子中,新增了1台服务器,服务器数量变为4台,通过算法计算:crc32('myname')%4=3,从第1台变成第3台了,导致缓存重建;又比如第1台服务器挂了,缓存的存取都会失败,导致短时间内大量的请求涌入mysql
  • 一致性哈希
    • 一致性哈希就是为了解决上面的缓存重建而设计的,取模法不理想的原因就是算法的本质就是根据服务器数量来计算的,缓存跟服务器是一一对应,要想灵活一点就不能是一对一的关系,一致性哈希算法首先创建出一个首( 0 )尾( 2^32-1 )相接的环形的哈希空间,如下图的圆环,然后把服务器通过hash算法映射到环形的某一点,如下图中node1、node2、node3、node4,然后再把缓存的键映射到环形的某一点,获取某个键的内容是从这个键的节点按顺时针方向开始查找服务器节点,找到的第一台服务器就是这个缓存要进行存取的服务器,如此一来当node1服务器挂了,影响到的只是从node3到node1节点之间的缓存数据,这些数据将会去node2中存取,这样可以把缓存重建的代价降低

安装依赖软件

[root@localhost ~]# yum install gcc
[root@localhost ~]# yum install gcc-c++
[root@localhost ~]# yum install autoconf

安装libmemcached

memcached扩展依赖于libmemcached,因此先安装libmemcached

[root@localhost ~]# cd /usr/local/src
[root@localhost src]# wget https://launchpad.net/libmemcached/1.0/1.0.17/+download/libmemcached-1.0.17.tar.gz
[root@localhost src]# tar -zxvf libmemcached-1.0.18.tar.gz
[root@localhost src]# cd libmemcached-1.0.18
[root@localhost libmemcached-1.0.18]# ./configure --prefix=/usr/local/libmemcached --with-memcached
[root@localhost libmemcached-1.0.18]# make && make install

安装php的memcached扩展

[root@localhost ~]# cd /usr/local/src
[root@localhost src]# wget http://pecl.php.net/get/memcached-3.0.3.tgz
[root@localhost src]# cd memcached-3.0.3
[root@localhost memcached-3.0.3]# tar -zxvf memcached-3.0.3.tgz
[root@localhost memcached-3.0.3]# ./configure --prefix=/usr/local/pecl-memcached --with-php-config=/usr/local/php/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached
error: no, sasl.h is not available
[root@localhost memcached-3.0.3]# yum install cyrus-sasl-devel
[root@localhost memcached-3.0.3]# make && make install
#修改php配置,加入memcache扩展
[root@localhost memcached-3.0.3]# vi /usr/local/php/lib/php.ini
extension=memcached.so#重启apache
[root@localhost memcached-3.0.3]# apachectl restart#启动memcached服务器并记录日志
[root@localhost src]# memcached -d -u nobody -p 32054 -vv >> /tmp/memcached.32054.log 2>&1
[root@localhost src]# memcached -d -u nobody -p 32055 -vv >> /tmp/memcached.32055.log 2>&1
[root@localhost src]# memcached -d -u nobody -p 32056 -vv >> /tmp/memcached.32056.log 2>&1

测试一致性哈希


$m = new Memcached();
$m->setOptions(array(Memcached::OPT_DISTRIBUTION=>Memcached::DISTRIBUTION_CONSISTENT,Memcached::OPT_LIBKETAMA_COMPATIBLE=>true,Memcached::OPT_REMOVE_FAILED_SERVERS=>true,
));$m->addServers(array( array('localhost', 32054), array('localhost', 32055), array('localhost', 32056), //array('localhost', 32057), )); $m->set('key1', 1); $m->set('key2', 'abc'); $m->set('key3', array('foo', 'bar')); $m->set('key4', new stdClass); $m->set('key5', 'pigfly'); $m->set('key6', 999); var_dump($m->get('key1'), $m->get('key2'), $m->get('key3'), $m->get('key4'), $m->get('key5'), $m->get('key6')); 

运行这段php代码,我们再查看日志:


#memcached.32054.log
36 STORED
36 STORED
36 sending key key2
>36 END
36 sending key key3
>36 END  #memcached.32055.log <36 new auto-negotiating client connection 36: Client using the ascii protocol <36 set key1 1 0 1 >36 STORED <36 set key4 4 0 19 >36 STORED <36 get key1 >36 sending key key1 >36 END <36 get key4 >36 sending key key4 >36 END <36 quit <36 connection closed.  #memcached.32056.log <36 new auto-negotiating client connection 36: Client using the ascii protocol <36 set key5 0 0 6 >36 STORED <36 set key6 1 0 3 >36 STORED <36 get key5 >36 sending key key5 >36 END <36 get key6 >36 sending key key6 >36 END <36 quit <36 connection closed. 

缓存的分布情况:

host key
32054 key2,key3
32055 key1,key4
32056 key5,key6

现在我们加一台32057的memcached试试:

[root@localhost src]# memcached -d -u nobody -p 32057 -vv >> /tmp/memcached.32057.log 2>&1

取消php代码第13行的注释,运行php,查看日志文件:


#memcached.32054.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key3 4 0 34
>36 STORED
<36 get key3
>36 sending key key3 >36 END <36 quit  #memcached.32055.log <36 new auto-negotiating client connection 36: Client using the ascii protocol <36 set key1 1 0 1 >36 STORED <36 set key4 4 0 19 >36 STORED <36 get key1 >36 sending key key1 >36 END <36 get key4 >36 sending key key4 >36 END <36 quit <36 connection closed.  #memcached.32056.log <36 new auto-negotiating client connection 36: Client using the ascii protocol <36 set key5 0 0 6 >36 STORED <36 set key6 1 0 3 >36 STORED <36 get key5 >36 sending key key5 >36 END <36 get key6 >36 sending key key6 >36 END <36 quit <36 connection closed.  #memcached.32057.log <36 new auto-negotiating client connection 36: Client using the ascii protocol <36 set key2 0 0 3 >36 STORED <36 get key2 >36 sending key key2 >36 END <36 quit <36 connection closed. 

缓存的分布情况:

host key
32054 key3
32055 key1,key4
32056 key5,key6
32057 key2

我们发现32054的key2跑到32057去了,32055和32056的key都没有受到影响,说明一致性哈希起作用了,我们再来模拟一下有一台memcached服务器宕机的情况

[root@local htdocs]# ps -aux | grep memcached
nobody    7621  0.0  0.3 415860  3440 ?        Ssl  16:16   0:00 memcached -d -u nobody -p 32054 -vv
nobody    7632  0.0  0.4 414832  4432 ?        Ssl  16:16   0:00 memcached -d -u nobody -p 32055 -vv
nobody    7643  0.0  0.8 414832  8532 ?        Ssl  16:17   0:00 memcached -d -u nobody -p 32056 -vv
nobody    7659  0.0  0.4 414832  4432 ?        Ssl  16:26   0:00 memcached -d -u nobody -p 32057 -vv
[root@local htdocs]# kill 7621 #杀掉32054

运行php代码,查看日志:


#memcached.32055.log
<36 new auto-negotiating client connection
36: Client using the ascii protocol
<36 set key1 1 0 1
>36 STORED
<36 set key3 4 0 34
>36 STORED <36 set key4 4 0 19 >36 STORED <36 get key1 >36 sending key key1 >36 END <36 get key3 >36 sending key key3 >36 END <36 get key4 >36 sending key key4 >36 END <36 quit <36 connection closed.  #memcached.32056.log <36 new auto-negotiating client connection 36: Client using the ascii protocol <36 set key5 0 0 6 >36 STORED <36 set key6 1 0 3 >36 STORED <36 get key5 >36 sending key key5 >36 END <36 get key6 >36 sending key key6 >36 END <36 quit <36 connection closed.  #memcached.32057.log <36 new auto-negotiating client connection 36: Client using the ascii protocol <36 set key2 0 0 3 >36 STORED <36 get key2 >36 sending key key2 >36 END <36 quit <36 connection closed. 

缓存的分布情况:

host key
32055 key1,key3,key4
32056 key5,key6
32057 key2

由于32054挂了,我们看到32054的key3跑到32055去了,其他端口的缓存没有受到影响,这样就把缓存的重建代价降低了

转载于:https://www.cnblogs.com/jasonLiu2018/articles/10706014.html

memcached一致性哈希及php客户端实现相关推荐

  1. Memcached 一致性哈希算法PHP实现

    <?php// 一致性哈希算法 class ConsistentHashing {protected $nodes = [];protected $position = [];protected ...

  2. Go -- 一致性哈希算法

    一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用 ...

  3. 一致性哈希算法及其在分布式系统中的应用

    摘要 本文将会从实际应用场景出发,介绍一致性哈希算法(Consistent Hashing)及其在分布式系统中的应用.首先本文会描述一个在日常开发中经常会遇到的问题场景,借此介绍一致性哈希算法以及这个 ...

  4. 一致性哈希算法——算法解决的核心问题是当slot数发生变化时,能够尽量少的移动数据...

    一致性哈希算法 摘自:http://blog.codinglabs.org/articles/consistent-hashing.html 算法简述 一致性哈希算法(Consistent Hashi ...

  5. 分布式一致性哈希算法

    一致性哈希算法及其在分布式系统中的应用 作者 张洋 | 发布于 2011-10-18 分布式 一致性哈希 摘要 本文将会从实际应用场景出发,介绍一致性哈希算法(Consistent Hashing)及 ...

  6. 面试必会系列 - 3.1 Redis知识点大汇总(数据类型,内存模型,持久化,缓存击穿,集群,一致性哈希等等)

    本文已收录至 Github(MD-Notes),若博客中图片模糊或打不开,可以来我的 Github 仓库,包含了完整图文:https://github.com/HanquanHq/MD-Notes,涵 ...

  7. 算法高级(24)-一致性哈希算法在分布式系统中的使用场景

    本文将会从实际应用场景出发,介绍一致性哈希算法(Consistent Hashing)及其在分布式系统中的应用. 一.一致性Hash算法背景 一致性哈希算法在1997年由麻省理工学院的Karger等人 ...

  8. 的一致性哈希_五分钟看懂一致性哈希算法

    作者简介: 华哥 10年+后端开发工作经验, 主要分享:关于java体系的知识,如:java基础知识/数据结算/算法,Spring/MyBatis/Netty源码分析,高并发/高性能/分布式/微服务架 ...

  9. 一致性哈希算法及其应用

    一致性哈希 普通的哈希算法使用取余操作:hash(o) mod n,其中 n 代表机器的数量.如果在集群中新增加一个节点时,计算公式会变为:hash(o) mod (n+1):在集群中删除一个机器时, ...

最新文章

  1. 数据结构与算法---稀疏数组
  2. grpc中监听端口添加及绑定
  3. python实现Linux命令wget
  4. html页面手机端console,GitHub - MobileHTML5/vConsole: 一个针对手机网页的前端 console 调试面板。...
  5. day011_步入百万年薪的第十一天
  6. HTTP1.0、HTTP1.1和HTTP2.0的区别
  7. 一文说通C#中的异步迭代器
  8. [Leedcode][JAVA][第560题][和为K的子数组][Hashmap][数组]
  9. SQL版DNN的安装心得
  10. ora-01189故障解决办法
  11. sp3 win xp 符号表_[转载]Windows XP with SP3 各版本全搞定(附序列
  12. 关于画法几何和机械制图有感
  13. 奥斯汀页眉怎么设置_wps怎么只删除本页的页眉_Word页眉的设置和删除,这些问题你有遇到过吗?...
  14. 【索引分类】位图索引
  15. Oracle 19C RAC 静默(silent)安装on RHEL7.x
  16. 如何把项目上传到码云平台?
  17. 简单易用,基于js或vue项目实现一次批量文件下载功能
  18. BUUCTFweb题刷题记录(2020.09.14-2020.09.19)
  19. docker 下声卡无法连接
  20. 科大讯飞考试系统怎么监考_科大讯飞的考试平台后台能检测出哪些内容?

热门文章

  1. ios 添加条纹背景
  2. TreeView 之间节点拖动 /移动
  3. Linux操作系统的常用基本指令
  4. java两人猜数字游戏,三人背后猜数字游戏
  5. 最符合的多载方法有一些無效的引數_SMT小批量贴片加工厂的贴片加工的首件测试方法...
  6. python系统信息_Python获得操作系统信息
  7. python画圆填色橙色_基于TPC-C基准的Python ORM的性能测试详解
  8. 2021了,你还不能玩转js正则表达式?
  9. 前端开发那些不常见但十分有效的小玩意
  10. 零基础学习前端开发,怎么自学javascript?