memcache原理

作者: mrchen004 | 来源:发表于2018-11-01 22:57 被阅读0次

    早些年,memcache是主流的缓存框架,现在一般不会再用memcache了,redis逐渐代替了memcache。相比memcache,redis有更丰富的数据类型、支持持久化等等优点。redis以后再说,本文主要介绍memcache的一些要点,这些知识点都是网上看了别人的memcache源码分析之后做的总结。想看原始文章可以点击查看memcache源码分析。 

一、内存分配

    memcache启动时,会先申请一块内存(默认64M),然后计算初始chunk大小,以及slab的个数。初始chunk大小=48B+item_size+对齐字节,其中48B可以用启动参数-n配置,item_size是memcache对key-value封装之后的对象大小,固定48B,对齐字节保证最后的大小正好是8的整数倍。所以,初始chunk大小默认是96B。slab个数则和初始chunk大小、增长因子、Page大小有关。增长因子默认是1.25,可以用启动参数-f指定;Page大小默认1M,可以用启动参数-I(这是i/j/k的i的大写,不是L的小写,我曾经掉到这个坑里)指定。slab的个数为:96B、120B、152B...以增长因子(1.25倍)递增直到Page大小(1M),共42个。

    当有数据需要存储时,根据大小找到对应的slab,查看是否有空闲的chunk,如果没有,就去申请一个Page,然后将Page分割为一组chunk,用来存储。

    一种slab可以申请多个Page,每个Page一旦分配就不会被回收或者重新分配。slab下闲置的chunk不会被其他的slab使用。

二、两级哈希

    在客户端会先通过一致性哈希找到key应该被存储到哪个memcache服务器,发送网络请求到对应的服务器之后,服务器是用数组+链表的方式来存储key-value的,所以需要计算key应该存到数组的哪个位置(用key来hash,然后取余)。也就是说,memcache服务器用哈希表来存储所有的key-value。

    memcache服务器不向redis,前者是多线程处理客户端请求的,而后者是单线程的。多线程处理请求,就会导致并发操作数组,memcache用类似JDK7中的ConcurrentHashMap的分段锁来保证线程安全。随着hash扩容,锁的数量不会变多,而是每个锁锁住的元素增多。

    当存入的key-value达到一定条件时(元素个数超过数组长度的1.5倍),会触发hash扩容,扩容时先申请一个2倍的数组,然后就是迁移数据了。迁移数据不是一次全部迁移完成,而是每次迁移一定数量的桶位(默认1个,可配置),多次迁移之后完成扩容。当要操作一个key时,会比较当前迁移到的桶位下标,如果小于,就去操作原数组,否则操作新数组。

三、LRU算法

    memcache对key-value进行封装之后的对象包含如下属性:data、h_next、pre、next、time、expire。其中data是key-value的封装,h_next用来维护冲突链表,time是最后访问时间,expire是到期时间,pre/next则是用来维护LRU队列。

    LRU队列是为了当容量满的时候,淘汰掉其他数据,腾出空间存储新的key-value。memcache中,每一种slab都有一个LRU队列,该队列按节点的time字段由大到小排序。

数据删除的触发时机:

    a、get时判断是否到期,如果到期就删除

    b、set时,如果没有空间分配,找到LRU队列末端节点,清除内存占为己用,把节点放到队头

    c、flush_all时,设置一个全局变量,记录所有数据的过期时间为当前时间

    d、客户端发送命令让服务端启动线程去清除过期数据,可以指定几个线程,清除哪些slab的数据

四、线程模型

    memcache启动的时候,会启动一个主线程来监听连接,同时启动多个工作线程用于处理请求。当有连接到来时,主线程通过求余选择一个工作线程,然后将socket信息封装成CQ_item放入其CQ队列,并通过pipe管道通知工作线程。工作线程从CQ队列中拿到socket信息,创建libevent的读写事件,对读写事件进行解析处理。

    libevent可以理解为c++界的netty,是封装io多路复用的框架,它可以自动判断当前系统所使用的io多路复用模型(windows下的IOCP,Linux下的Epoll,Mac下的KQueue),达到非阻塞处理io操作的目的。

相关文章

  • cache书目录

    memcache memcache是什么 memcache的工作原理 memcache的特点 memcache如何...

  • memcached - linux CLI

    Memcache Linux CLI原理支持Telnet 接口,并且提供了查询接口 连接memcache : 命令...

  • memcache原理

    早些年,memcache是主流的缓存框架,现在一般不会再用memcache了,redis逐渐代替了memcac...

  • 深入理解Memcache原理

    1.为什么要使用memcache 由于网站的高并发读写需求,传统的关系型数据库开始出现瓶颈,例如: 1)对数据库的...

  • PHP如何安装memcache扩展

    安装memcache只是安装memcache的客户端,要让PHP与memcache连接还得在PHP中安装memca...

  • MemCache详细讲解

    1 MemCache讲解 1.1 MemCache是什么 MemCache是一个自由、源码开放、高性能、分布式的分...

  • MemCache 入门极简教程

    MemCache 概述 MemCache虽然被称为”分布式缓存”,但是MemCache本身完全不具备分布式的功能 ...

  • linux使用docker安装memcache

    拉取memcache镜像,(memcache:latest)指最新版本,也可指定版本号拉取(memcache:1....

  • PHP 中如何使用 Memcache

    php version: 5.6.*OS: windows Memcache是什么? Memcache 是一套分...

  • memcache安装及python中使用

    memcache安装及python中使用 1. yum安装 1.1 yum -y install memcache...

网友评论

    本文标题:memcache原理

    本文链接:https://www.haomeiwen.com/subject/hysfxqtx.html