zoukankan      html  css  js  c++  java
  • Memcached基础知识

    主要内容:

      Memcached基本的工作原理

      Memcached的两阶段哈希

      Memcached的数据存储方式

      Memcached新建Item分配内存过程

      Memcached的数据过期方式

      Memcached与Spring集成

    ------------------------------------------------------------------------------------------

    Memcached基本的工作原理

      Memcached是以守候程序的方式运行于一个或者多个服务器中,随时等待客户端的链接请求,通过启动Memcached服务端,配置相应的监听IP、端口等参数,客户端可通过指定的服务器IP 将数据以key-value的方式存储到Memcached实例中。

      如下图所示,有N个Memcached实例部署在一台专门的机器上,应用程序在查询数据时首先去Memcached里面查询,如果有数据则直接返回客户端使用,如果Memcached里面没有需要的数据或者数据过期了,则应用程序先去查询数据库,然后把查询的结果放到Memcached实例里面去,最后返回给客户端。

    Memcached的两阶段哈希

      第一阶段哈希是计算"key-value"存储在哪个Memcached实例上,第二阶段哈希是计算"key-value"是存储存储在Memcached实例的哪个chunk里面。

      客户端存取数据时,首先参考Memcached实例列表计算出key的哈希值(阶段一哈希),进而选中一个Memcached实例;客户端将请求发送给选中的Memcached实例节点,然后该Memcached节点通过内部的哈希算法(阶段二哈希) 进行真正的数据(Item)存取。 Memcached的服务器和客户端通信并不使用复杂的XML等格式,而是使用简单的基于文本行的协议。

      如下图所示:
        比如我们要在Memcached上存储 key为"Hello",value为"World" 的这么一个键值对。
        阶段一哈希: 首先在客户端根据key计算出该"键值对"会存储在哪个Memcached实例中,假如是m2
        阶段二哈希: 在Memcached实例二中 再次根据key计算出该"键值对"在m2实例中存在的位置。

     

    Memcached的数据存储方式

      Memcached的数据存储方式被称为Slab Allocator,其基本方式是:

      (a)先把内存分成很多个Slab,这个大小是预先规定好的,以解决内存碎片问题。

        分配给Slab的内存空间被称为Page,默认是1M。一个Slab下可以有多个Page。

        (如下图:在Memcached实例中先把内存分了n个slab,然后每个slab里面分了n个page)

      (b)然后把一个Page分成很多个chunk块,chunk块是用于缓存记录的空间。Chunk的大小是先有一个基本值,然后根据增长因子来增大。
    Slab Allocation的原理——将分配的内存分割成各种尺寸的块(chunk), 并把尺寸相同的块分成组(chunk的集合),每个chunk集合被称为slab。
      (借用网上一张图来说明:)

     

      (c)slab class:内存区类别(48byte-1M),每个类别有一个slab classId

     

    (d)Memcached里面保存着slab内存空间的chunk列表,当收到要保存的item时,它会根据item的大小去选择一个最适合的slab,然后找到空闲的chunk,把数据存放进去。

    Memcached新建Item分配内存过程

      第一步: 快速定位slab classid,先计算Item长度
        key键长+flag+suffix(16字节)+value值长+结构大小(32字节),比如计算出来有90byte
        如果Item长度计算出来>1M,则无法存储丢弃
        取最小冗余的slab class进行存储,比如有:48、96、120, 存储90就会选96
      第二步:按顺序寻找可用的chunk
        (a) slot : 检查slab回收空间slot里是否有剩余chunk
          delete: delete时标记到slot
          exptime: get时检查的过期对象标记到slot
        (b)end_page_ptr: 检查page中是否有剩余chunk
        (c)memory: 内存还有剩余空间可以用于开辟新的slab
        (d)LRU
      (PS:Memcached的数据存储方式的缺点,由于chunk的大小是预先分配好的特定长度,因此如果数据不能完全填满chunk,那么chunk中剩余的空间就浪费了。)

    Memcached的数据过期方式
      (1)Lazy Expiration(延迟/惰性 过期)
        Memcached不会监控记录是否过期,而是当客户端来获取数据的时候,才会检查记录的时间戳,因此成为Lazy Expiration
      (2)LRU(Least Recently Used 最近最少使用)
        当空间不足的时候,Memcached会优先使用已经过期的数据空间,如果还不够的话,那么就会把最近最少使用的对象的空间释放出来。
        (ps:要特别注意,Memcached的LRU不是全局的,而是针对slab的,可以说是区域性的)
      (3)惰性删除机制
        删除item对象时,不释放内存,作删除标记,指针放入slot回收插槽,下次分配的时候直接使用。

    Memcached与Spring集成

    (1)先把jar包添加到本地仓库中:

      mvn install:install-file -Dfile=java_memcached-release_2.6.6.jar -DgroupId=com.danga -DartifactId=memcached -Dversion=2.6.6 -Dpackaging=jar -DgeneratePom=true

      (ps:注意 -Dfile=java_memcached-release_2.6.6.jar  一定要输入jar包的全路径名 )

    (2)在pom中添加memcached的lib依赖和common-pool的lib依赖:

     1         <dependency>
     2             <groupId>commons-pool</groupId>
     3             <artifactId>commons-pool</artifactId>
     4             <version>1.5.6</version>
     5         </dependency>
     6         <dependency>
     7             <groupId>com.danga</groupId>
     8             <artifactId>memcached</artifactId>
     9             <version>2.6.6</version>
    10         </dependency>

    (3)在spring的applicationContext.xml文件中加入memcached的配置

     1 <bean id="memcachedPool" class="com.danga.MemCached.SockIOPool" factory-method="getInstance"
     2     init-method="initialize" destroy-method="shutDown">
     3         <constructor-arg>
     4             <value>neeaMemcachedPool</value>
     5         </constructor-arg>
     6         <property name="servers">
     7             <list>
     8                 <value>192.168.1.81:3333</value>
     9             </list>
    10         </property>
    11         <property name="weights">
    12             <list>
    13                 <value>1</value>
    14             </list>
    15         </property>
    16         <property name="initConn">
    17             <value>5</value>
    18         </property>
    19         <property name="minConn">
    20             <value>5</value>
    21         </property>
    22         <property name="maxConn">
    23             <value>5</value>
    24         </property>
    25         <property name="maintSleep">
    26             <value>30</value>
    27         </property>
    28         <property name="nagle">
    29             <value>false</value>
    30         </property>
    31         <property name="maxIdle">
    32             <value>6000</value>
    33         </property>
    34         <property name="socketTO">
    35             <value>3000</value>
    36         </property>
    37     </bean>
    38     
    39     <bean id="memCachedClient" class="com.danga.MemCached.MemCachedClient">
    40         <constructor-arg>
    41             <value>neeaMemcachedPool</value>
    42         </constructor-arg>
    43     </bean>

     在程序中就可以通过 MemCachedClient的get、set方法来往Memcached里面获取和设置item了

     

      

  • 相关阅读:
    ffmpeg rtmp推流 视频转码
    java日志发展史 log4j slf4j log4j2 jul jcl 日志和各种桥接包的关系
    nginx stream 流转发,可以转发rtmp、mysql访问流,转发rtmp、jdbc请求
    java web http 转https 通过nginx代理访问
    linux 服务器磁盘挂载
    novnc 通过websockify代理 配置多点访问
    linux 文件服务 minio 安装部署配置
    AOP实现原理,手写aop
    java 泛型
    JAVA反射getGenericSuperclass()用法
  • 原文地址:https://www.cnblogs.com/xinhuaxuan/p/6087387.html
Copyright © 2011-2022 走看看