深入理解Memcache原理

1.为什么要使用memcache


由于网站的高并发读写需求,传统的关系型数据库开始出现瓶颈,例如:

1)对数据库的高并发读写

关系型数据库本身就是个庞然大物,处理过程非常耗时(如解析SQL语句,事务处理等)。如果对关系型数据库进行高并发读写(每秒上万次的访问),那么它是无法承受的。

2)对海量数据的处理

对于大型的SNS网站,每天有上千万次的苏剧产生(如twitter, 新浪微博)。对于关系型数据库,如果在一个有上亿条数据的数据表种查找某条记录,效率将非常低。

使用memcache能很好的解决以上问题。

在实际使用中,通常把数据库查询的结果保存到Memcache中,下次访问时直接从memcache中读取,而不再进行数据库查询操作,这样就在很大程度上减少了数据库的负担。

保存在memcache中的对象实际放置在内存中,这也是memcache如此高效的原因。

2.memcache的安装和使用

这个网上有太多教程了,不做赘言。

3.基于libevent的事件处理

libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能 封装成统一的接口。即使对服务器的连接数增加,也能发挥O(1)的性能。

memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。

参考:

  • libevent:  http://www.monkey.org/~provos/libevent/

  • The C10K Problem:  http://www.kegel.com/c10k.html

4.memcache使用实例:

<?php$mc = new Memcache();$mc->connect('127.0.0.1', 11211);

$uid = (int)$_GET['uid'];$sql = "select * from users where uid='uid' ";$key = md5($sql);if(!($data = $mc->get($key))) {    $conn = mysql_connect('localhost', 'test', 'test');    mysql_select_db('test');    $result = mysql_fetch_object($result);    while($row = mysql_fetch_object($result)) {          $data[] = $row;    }    $mc->add($key, $datas);}

var_dump($datas);?>

5.memcache如何支持高并发

memcache使用多路复用I/O模型,如(epoll, select等),传统I/O中,系统可能会因为某个用户连接还没做好I/O准备而一直等待,知道这个连接做好I/O准备。这时如果有其他用户连接到服务器,很可能会因为系统阻塞而得不到响应。

而多路复用I/O是一种消息通知模式,用户连接做好I/O准备后,系统会通知我们这个连接可以进行I/O操作,这样就不会阻塞在某个用户连接。因此,memcache才能支持高并发。

此外,memcache使用了多线程机制。可以同时处理多个请求。线程数一般设置为CPU核数,这研报告效率最高。

6.使用Slab分配算法保存数据

slab分配算法的原理是:把固定大小(1MB)的内存分为n小块,如下图所示:

slab分配算法把每1MB大小的内存称为一个slab页,每次向系统申请一个slab页,然后再通过分隔算法把这个slab页分割成若干个小块的chunk(如上图所示),然后把这些chunk分配给用户使用,分割算法如下(在slabs.c文件中):

memset(slabclass, 0, sizeof(slabclass));// 初始化每个slabclass_t的trunk大小和每个slab中trunk数量// slabclass中每个slabclass_t的trunk大小增长为factor倍// 注意 i 从索引 1 开始while (++i < POWER_LARGEST && size <= settings.item_size_max / factor) {/* Make sure items are always n-byte aligned */if (size % CHUNK_ALIGN_BYTES)                             // 内存8字节对齐size += CHUNK_ALIGN_BYTES - (size % CHUNK_ALIGN_BYTES);slabclass[i].size = size;slabclass[i].perslab = settings.item_size_max / slabclass[i].size;size *= factor;if (settings.verbose > 1) {fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",i, slabclass[i].size, slabclass[i].perslab);}}// slabclass中最后一个slabclass_t的trunk大小设置为最大item大小power_largest = i;slabclass[power_largest].size = settings.item_size_max;slabclass[power_largest].perslab = 1;if (settings.verbose > 1) {fprintf(stderr, "slab class %3d: chunk size %9u perslab %7u\n",i, slabclass[i].size, slabclass[i].perslab);}....// 省略
}

上面代码中的slabclass是一个类型为slabclass_t结构的数组,其定义如下:

typedef struct {unsigned int size;      /* sizes of items */unsigned int perslab;   /* how many items per slab */void **slots;           /* list of item ptrs */unsigned int sl_total;  /* size of previous array */unsigned int sl_curr;   /* first free slot */void *end_page_ptr;         /* pointer to next free item at end of page, or 0 */unsigned int end_page_free; /* number of items remaining at end of last alloced page */unsigned int slabs;     /* how many slabs were allocated for this class */void **slab_list;       /* array of slab pointers */unsigned int list_size; /* size of prev array */unsigned int killing;  /* index+1 of dying slab, or zero if none */size_t requested; /* The number of requested bytes */
} slabclass_t;

由分割算法的源代码可知,slab算法按照不同大小的chunk分割slab页,而不同大小的chunk以factor(默认是1.25)倍增大。

使用memcache -vv 命令查看内存分配情况(8字节对齐):

九爷带你了解 深入理解 Memcache 原理相关推荐

  1. 我不是九爷 带你了解 ansible

      <我不是九爷> Ansible 1. 了解什么是ansible ansible是个什么东西呢?官方的title是"Ansible is Simple IT Automatio ...

  2. 我不是九爷 带了解 Unity3D与VR虚拟现实

    对于大多数人来说,可能不知道Unity3D是什么,但是却知道VR虚拟现实是什么,更不会把VR虚拟现实和Unity3D联系在一起,外行的人根本不知道这两者之间有什么关系.那么,今天来给你讲解一下Unit ...

  3. 九爷 带你了解 nginx优化与防盗链

    Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为"engine X",是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP  ...

  4. 九爷带你了解 nginx 日志配置指令详解

    nginx日志配置指令详解 日志对于统计排错来说非常有利的. 本文总结了nginx日志相关的配置如 access_log.log_format.open_log_file_cache.log_not_ ...

  5. 深入理解Memcache原理

    1.为什么要使用memcache 由于网站的高并发读写需求,传统的关系型数据库开始出现瓶颈,例如: 1)对数据库的高并发读写: 关系型数据库本身就是个庞然大物,处理过程非常耗时(如解析SQL语句,事务 ...

  6. 防劝退!数据结构和算法难理解?可视化动画带你轻松透彻理解!

    大家好,我是 Rocky0429,一个连数据结构和算法都不会的蒟蒻- 学过数据结构和算法的都知道这玩意儿不好学,没学过的经常听到这样的说法还没学就觉得难,其实难吗?真难! 难在哪呢?当年我还是个小蒟蒻 ...

  7. 深入理解浏览器原理和架构|硬核

    本文用47张图带你了解「浏览器的发展史」.「浏览器的架构」.「浏览器的基本原理」以及 「浏览器的其它小知识」 ???? 正文开始 浏览器的主要功能就是向服务器发出请求,在浏览器窗口中展示HTML文档. ...

  8. 龙书啃不动?老司机带你从零入门编译原理,开发编译器

    计算机只认识二进制的,但是我们平常开发中根本不会使用二进制进行开发,我们使用的都是 Java.C.Python 这类的高级语言.每种语言都会经过一系列的转换才能被计算机识别,那么到底是谁做的这项工作呢 ...

  9. 全局最优和局部最优 世俗理解以及原理解释

    引言 今天逛知乎看到这样一个问题和回答,让我瞬间理解局部最优和全局最优 在诸如算法导论等书是这样解释的:全局最优是在全局选取一个最佳值,而局部最优是在某一部分选取一个最佳值.每一部分都选取最佳值(即局 ...

  10. C++实现爬虫,深入理解爬虫原理(最详细,最简单的教程)

    前言: 我目前主要学习方向是c++,看到网上基本上都是用python写的爬虫,我也试过,确实非常方便,几行代码就能解决,但却就是因为python封装的太好,过于简单,使得很多人包括我最开始的时候,都很 ...

最新文章

  1. mysql userstat_mysql 中记录用户登录错误日志方法小结
  2. Matplotlib pyplot中title() xlabel() ylabel()无法显示中文(即显示方框乱码)的解决办法...
  3. Python其他数据结构collection模块-namtuple defaultdict deque Queue Counter OrderDict arrary
  4. docker核心网络原理详解
  5. 编程之美之控制cpu线
  6. BZOJ 1609 [Usaco2008 Feb]Eating Together麻烦的聚餐:LIS LDS (nlogn)
  7. highcharts php 动态数据,php动态传数据到highcharts的方法
  8. DataFrame.apply()
  9. 刘鹏教授为江苏移动大数据和网络部门作报告
  10. Vue项目中的文件/文件夹命名规范
  11. 基本 SQL 之增删改查
  12. snownlp中文文本情感分析
  13. 计算机桌面图标往左进去只能看见一半,win7系统桌面图标只显示一半另外一半显示别的程序的解决方法...
  14. 当面试官说 “你还有什么问题想问的”,你该如何回答?
  15. Kaggle共享单车需求项目详解
  16. “槑囧圐圙”您认得这些汉字吗?
  17. 使用Termux把Android手机变成SSH服务器
  18. 华为云CDN加速,真正的六边形战士
  19. 获取表单 input框中输入的值
  20. 后端 绘制有向无环图(DAG图)

热门文章

  1. 姿态估计1-08:FSA-Net(头部姿态估算)-源码无死角讲解(3)-Fine-grained 以及Scoring function
  2. Log binomial 回归详解
  3. BFM:总线功能模型 zz
  4. Unity内置Shader解读1——Bumped Diffuse
  5. 下厨房怎么显示服务器错误,4s只有一个下厨房app显示网络连接失败
  6. 如何使用C#把数据写到EXCEL文档中
  7. 为什么神经网络有偏置? 神经网络中的偏置(bias)究竟有这么用
  8. lua菜鸟教程_lua经典学习教程.pdf
  9. 用 Python 制作商品历史价格查询
  10. 微信小程序页面跳转方式