热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Memcached常规应用与分布式部署方案

下面天涯[PHPHA.COM]介绍下Memcached的最常规的应用及分布式部署方案。相关内容参考了凹凸曼写的Memcached使用与实践章节。至于Memcached的安装及基本使用,这里不做介绍,有需要可以借助Google或Baidu。

下面天涯[PHPHA.COM]介绍下Memcached的最常规的应用及分布式部署方案。相关内容参考了凹凸曼写的Memcached使用与实践章节。至于Memcached的安装及基本使用,这里不做介绍,有需要可以借助Google或Baidu。

1、Memcached常规应用
使用Memcached缓存MySQL查询结果减轻数据库压力,下面直接上代码,后面做简单说明。

  1. php
  2. /**
  3. * Memcached常规应用演示
  4. * 天涯PHP博客
  5. * http://blog.phpha.com
  6. */
  7. $mc = new Memcache();
  8. $mc->conncet('127.0.0.1', 11211);
  9. $sql = sprintf("SELECT * FROM users WHERE uid = %d", $_GET['uid']);
  10. $key = md5($sql);
  11. //检测结果是否已经被缓存
  12. if( ! $data = $mc->get($key)){
  13. //没有缓存则直接从数据库读取
  14. mysql_conncet('localhost', 'test', 'test');
  15. mysql_select_db('test');
  16. while($row = mysql_fetch_object(mysql_query($sql))){
  17. $data[] = $row;
  18. }
  19. //并将查询结果缓存
  20. $mc->add($key, $data);
  21. }
  22. var_dump($data);

说明:首先通过md5()将SQL语句转化成一个唯一的KEY,并用此KEY查询Memcached检测是否已经缓存,是的话在直接返回结果,否则先查询数据库再缓存,并返回结果。这样,下次使用此KEY就可以直接返回结果了。另外值得一提的是,看代码中SQL语句的组合部分,用到了sprintf()函数,简单高效,来自白菜指南推荐。

2、Memcached分布式部署方案
通常较小的应用一台Memcached服务器就可以满足需求,但是大中型项目可能就需要多台Memcached服务器了,这就牵涉到一个分布式部署的问题。
对于多台Memcached服务器,怎么确定一个数据应该保存到哪台服务器呢?有两种方案,一是普通Hash分布,二是一致性Hash分布。下面详细说明。

[1]Memcached分布式部署之普通Hash分布
普通Hash分布对于Memcached服务器数量固定的情况推荐使用,比较简单,但是可想而知扩展性不好。

																							
  1. php
  2. /**
  3. * 普通Hash分布
  4. * 天涯PHP博客
  5. * http://blog.phpha.com
  6. */
  7. //Hash函数
  8. function mHash($key){
  9. $md5 = substr(md5($key), 0, 8);
  10. $seed = 31;
  11. $hash = 0;
  12. for($i = 0; $i < 8; $i++){
  13. $hash = $hash * $seed + ord($md5{$i});
  14. $i++;
  15. }
  16. return $hash & 0x7FFFFFFF;
  17. }
  18. //假设有2台Memcached服务器
  19. $servers = array(
  20. array('host' => '192.168.1.1', 'port' => 11211),
  21. array('host' => '192.168.1.1', 'port' => 11211)
  22. );
  23. $key = 'MyBlog';
  24. $value = 'http://blog.phpha.com';
  25. $sc = $servers[mHash($key) % 2];
  26. $memcached = new Memcached($sc);
  27. $memcached->set($key, $value);
  28. ?>

说明:首先通过MD5函数把KEY处理成32位字符串,然后截取前8位,再经过Hash算法处理成一个整数并返回。利用这个整数与Memcached服务器数量取模,决定当前KEY存储于哪台Memcached服务器,就完成了Memcached的分布式部署。可想而知,当要读取KEY的值时,依然是先要通过Hash算法判断存储于哪台服务器。这种方案整体来说比较简单容易理解。

[2]Memcached分布式部署之一致性Hash分布
当Memcached服务器数量固定时,普通Hash分布可以很好的运作。但是当服务器数量发生改变时,问题就出来了。因为同一个KEY经Hash算法处理后,与服务器数量取模,会导致结果与服务器数量未变化时不同,这就导致之前保存的数据丢失。采取一致性Hash分布可以有效的解决这个问题,把丢失的数据减到最小(注意这里并没有说完全不丢失)。
一致性Hash分布算法分4个步骤:
步骤1:将一个32位整数[0 ~ (2^32-1)]想象成一个环,0 作为开头,(2^32-1) 作为结尾,当然这只是想象。
步骤2:通过Hash函数把KEY处理成整数。这样就可以在环上找到一个位置与之对应。
步骤3:把Memcached服务器群映射到环上,使用Hash函数处理服务器对应的IP地址即可。
步骤4:把数据映射到Memcached服务器上。查找一个KEY对应的Memcached服务器位置的方法如下:从当前KEY的位置,沿着圆环顺时针方向出发,查找位置离得最近的一台Memcached服务器,并将KEY对应的数据保存在此服务器上。
说明:这样一来,当添加或移除某一台服务器时,受影响的数据范围变的更小了。具体可以画个图更便于理解,这里我就不画了。

[3]一致性Hash分布算法实例

																																																				
  1. php
  2. /**
  3. * 一致性Hash分布
  4. * 天涯PHP博客
  5. * http://blog.phpha.com
  6. */
  7. class FlexiHash{
  8. //服务器列表
  9. private $serverList = array();
  10. //记录是否已经排序
  11. private $isSorted = FALSE;
  12. //添加一台服务器
  13. public function addServer($server){
  14. $hash = $this->mHash($server);
  15. if(!isset($this->serverList[$hash])){
  16. $this->serverList[$hash] = $server;
  17. }
  18. //需要重新排序
  19. $this->isSorted = FALSE;
  20. return TRUE;
  21. }
  22. //移除一台服务器
  23. public function removeServer($server){
  24. $hash = $this->mHash($server);
  25. if(isset($this->serverList[$hash])){
  26. unset($this->serverList[$hash]);
  27. }
  28. //需要重新排序
  29. $this->isSorted = FALSE;
  30. return TRUE;
  31. }
  32. //在当前服务器列表查找合适的服务器
  33. public function lookup($key){
  34. $hash = $this->mHash($key);
  35. //先进行倒序排序操作
  36. if(!$this->isSorted){
  37. krsort($this->serverList, SORT_NUMERIC);
  38. $this->isSorted = TRUE;
  39. }
  40. //圆环上顺时针方向查找当前KEY紧邻的一台服务器
  41. foreach($this->serverList as $pos => $server){
  42. if($hash >= $pos) return $server;
  43. }
  44. //没有找到则返回顺时针方向最后一台服务器
  45. return $this->serverList[count($this->serverList) - 1];
  46. }
  47. //Hash函数
  48. private function mHash($key){
  49. $md5 = substr(md5($key), 0, 8);
  50. $seed = 31;
  51. $hash = 0;
  52. for($i = 0; $i < 8; $i++){
  53. $hash = $hash * $seed + ord($md5{$i});
  54. $i++;
  55. }
  56. return $hash & 0x7FFFFFFF;
  57. }
  58. }
  59. ?>

说明:其整体查找思路,已经在前面的一致性Hash分布部分进行了介绍,需要补充的是每次添加或移除服务器后需要对服务器列表这个序列就行一次排序。
下面是对上面的一致性Hash分布实例的相关测试代码:

																																																																																																																
  1. php
  2. /**
  3. * 一致性Hash分布测试代码
  4. * 天涯PHP博客
  5. * http://blog.phpha.com
  6. */
  7. $hserver = new FlexiHash();
  8. //初始5台服务器
  9. $hserver->addServer("192.168.1.1");
  10. $hserver->addServer("192.168.1.2");
  11. $hserver->addServer("192.168.1.3");
  12. $hserver->addServer("192.168.1.4");
  13. $hserver->addServer("192.168.1.5");
  14. echo "save key1 in server: ", $hserver->lookup('key1'), "
    "
    ;
  15. echo "save key2 in server: ", $hserver->lookup('key2'), "
    "
    ;
  16. echo '===============================================
    '
    ;
  17. //移除1台服务器
  18. $hserver->removeServer("192.168.1.4");
  19. echo "save key1 in server: ", $hserver->lookup('key1'), "
    "
    ;
  20. echo "save key2 in server: ", $hserver->lookup('key2'), "
    "
    ;
  21. echo '===============================================
    '
    ;
  22. //添加1台服务器
  23. $hserver->addServer('192.168.1.6');
  24. echo "save key1 in server: ", $hserver->lookup('key1'), "
    "
    ;
  25. echo "save key2 in server: ", $hserver->lookup('key2');
  26. ?>
  27. //测试结果如下:
  28. save key1 in server: 192.168.1.4
  29. save key2 in server: 192.168.1.2
  30. ==================================
  31. save key1 in server: 192.168.1.3
  32. save key2 in server: 192.168.1.2
  33. ==================================
  34. save key1 in server: 192.168.1.3
  35. save key2 in server: 192.168.1.2

补充:本篇写于无聊的5天元旦假期期间。说是5天,其实是2个周末的调休,元旦实际还是1天,这种坑爹的放假方式意味着4号开始要一下上8天班。另外推荐下凹凸曼的这本书吧,《PHP核心技术与最佳实践》。其中对Memcached的源码也有说明,不过都是C的,没有耐着心思去看,以后再说吧。另外还有对Redis的相关章节,其中仍然有一部分源码分析,依然略过。总之,Redis更强大吧,我以后会多关注下,在项目中取代Memcached吧。还有PHP扩展部分,看了一半,待续。
这本书我终于看了一遍了,500多页,其实也就是几个周末加几个晚上。因此,时间还特么就是海绵中的水,想挤还是有的。另外说个感悟吧,有时候感觉技术上升遇到瓶颈,不妨去认真挑本书吧,看完必有收获,毕竟是作者的心血。对于一本书的价值,我想说:大家好才是真的好,那是好迪。自己好才是真的好,这才是书籍。一本书的价值不在于别人说它有多么好,而在于你从中学到了什么。


推荐阅读
  • 本文介绍了数据库体系的基础知识,涵盖关系型数据库(如MySQL)和非关系型数据库(如MongoDB)的基本操作及高级功能。通过三个阶段的学习路径——基础、优化和部署,帮助读者全面掌握数据库的使用和管理。 ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • 在分布式系统中,当多个服务器共同提供服务时,如何高效地将请求路由到正确的服务器是一个关键问题。传统的方法如简单哈希取模在服务器数量变化时会导致大量数据迁移。本文探讨了一致性哈希算法如何有效解决这一问题,确保系统的稳定性和高效性。 ... [详细]
  • 成为一名高效的Java架构师不仅需要掌握高级Java编程技巧,还需深入理解JVM的工作原理及其优化方法。此外,对池技术(包括对象池、连接池和线程池)的应用、多线程处理、集合对象的内部机制、以及常用的数据结构和算法的精通也是必不可少的。同时,熟悉Linux操作系统、TCP/IP协议栈、HTTP协议等基础知识,对于构建高效稳定的系统同样重要。 ... [详细]
  • 远程过程调用(RPC)是一种允许客户端通过网络请求服务器执行特定功能的技术。它简化了分布式系统的交互,使开发者可以像调用本地函数一样调用远程服务,并获得返回结果。本文将深入探讨RPC的工作原理、发展历程及其在现代技术中的应用。 ... [详细]
  • 前言无论是对于刚入行工作还是已经工作几年的java开发者来说,面试求职始终是你需要直面的一件事情。首先梳理自己的知识体系,针对性准备,会有事半功倍的效果。我们往往会把重点放在技术上 ... [详细]
  • 本文探讨了Web开发与游戏开发之间的主要区别,旨在帮助开发者更好地理解两种开发领域的特性和需求。文章基于作者的实际经验和网络资料整理而成。 ... [详细]
  • 本文将详细介绍如何在ThinkPHP6框架中实现多数据库的部署,包括读写分离的策略,以及如何通过负载均衡和MySQL同步技术优化数据库性能。 ... [详细]
  • Spring Cloud因其强大的功能和灵活性,被誉为开发分布式系统的‘一站式’解决方案。它不仅简化了分布式系统中的常见模式实现,还被广泛应用于企业级生产环境中。本书内容详实,覆盖了从微服务基础到Spring Cloud的高级应用,适合各层次的开发者。 ... [详细]
  • 本文深入探讨了分布式文件系统的核心概念及其在现代数据存储解决方案中的应用,特别是针对大规模数据处理的需求。文章不仅介绍了多种流行的分布式文件系统和NoSQL数据库,还提供了选择合适系统的指导原则。 ... [详细]
  • 云计算的优势与应用场景
    本文详细探讨了云计算为企业和个人带来的多种优势,包括成本节约、安全性提升、灵活性增强等。同时介绍了云计算的五大核心特点,并结合实际案例进行分析。 ... [详细]
  • 深入解析Spring Cloud微服务架构与分布式系统实战
    本文详细介绍了Spring Cloud在微服务架构和分布式系统中的应用,结合实际案例和最新技术,帮助读者全面掌握微服务的实现与优化。 ... [详细]
  • 本文探讨了大型服务端开发过程中常见的几个误区,包括异步任务处理不当、日志同步模式使用、网络操作未设置超时、缓存命中率及响应时间未统计、单一缓存模式、分布式缓存加锁不当以及团队管理上的误区,旨在帮助开发者避免这些常见错误。 ... [详细]
  • 本文提供了一套实用的方法论,旨在帮助开发者构建能够应对高并发请求且易于扩展的Web服务。内容涵盖了服务器架构、数据库管理、缓存策略以及异步处理等多个方面。 ... [详细]
  • magent是一款开源的Memcached代理服务器软件,其项目网址为:  http:code.google.compmemagent  一、安装步骤& ... [详细]
author-avatar
dasda
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有