zoukankan      html  css  js  c++  java
  • memcached

      许多Web应用都将数据保存到RDBMS中,应用服务器从中读取数据并在浏览器中显示。但随着数据量的增大、访问的集中,就会出现RDBMS的负担加重、数据库响应恶化、网站显示延迟等重大影响。memcached通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。

      

      第一次访问:从关系型数据库(RDBMS)中取得数据保存到memcached中;

      之后的访问:从memcached中去的数据显示页面。

    Memcached作为高速运行的分布式缓存服务器具有以下特点:

    1.协议简单

      memcached的服务器客户端通信并不使用复杂的MXL等格式,而是使用简单的基于文本的协议。

    2.基于libevent的事件处理

      libevent是个程序库,他将Linux 的epoll、BSD类操作系统的kqueue等时间处理功能封装成统一的接口。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。

    3.内置内存存储方式

      为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached,重启操作系统会导致全部数据消失。另外,内容容量达到指定的值之后memcached回自动删除不适用的缓存。

    4.Memcached不互通信的分布式

      memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。他的分布式主要是通过客户端实现的。

     Slab Allocation机制

      最近的memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。 在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。 但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下, 会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。

       

      Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块, 以完全解决内存碎片问题。Slab Allocation的原理相当简单。 将分配的内存分割成各种尺寸的块(chunk), 并把尺寸相同的块分成组(chunk的集合)。但是分成组由于分配的是特定长度的内存,因此无法有效利用分配的内存。

      例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了(如下图)。

       就是说,如果预先知道客户端发送的数据的公用大小,或者仅缓存大小相同的数据的情况下,只要使用适合数据大小的组的列表,就可以减少浪费。

    数据过期方式

    1.Lazy expiration

      memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术被称为lazy(惰性)expiration。假如我们所存储的数据项相当多的时候,在这时候进行监控的话,花费的代价是相当大的,所以memcached不会在过期监视上耗费过多的CPU时间,从而在性能方面也起到一定的优化作用。

    2.LRU

      memcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为 Least Recently Used(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当memcached的内存空间不足时(无法从slab class 获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。

    基于客户端的memcached分布式

      memcached的分布式,通过键值进行hash计算,获得一个hash值,然后,通过通过该hash值对已有的服务器台数进行求余,把该需缓存对象存到相应的服务器上,不过该方式也存在严重的问题,接下来再讨论,先从简单的谈起。

      

      假设memcached服务器中有node1-node3三台服务器,应用程序要保存键名为“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的数据.

    1.准备

      首先向memcached中添加“tokyo”。将“tokyo”传给客户端程序库后, 客户端实现的算法就会根据“键”来决定保存数据的memcached服务器。 服务器选定后,即命令它保存“tokyo”及其值。

    2.添加时

    “kanagawa”“chiba”“saitama”“gunma”都是先选择服务器再保存。接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。 函数库通过与数据保存时相同的算法,根据“键”选择服务器。 使用的算法相同,就能选中与保存时相同的服务器,然后发送get命令。 只要数据没有因为某些原因被删除,就能获得保存的值。

    3.获取时

      讲不通的键保存在不同的服务器上,就实现了memcached的分布式,memcached服务器增多,键就会分散,即使一台服务器发生故障无法使用,也不会影响其他的缓存,系统可以继续运行下去。

      

       实现了memcached的分布式,但是对于服务器端的分布式还是没有实现,当考虑到一个问题,如果新增或者是移除服务器的话,会导致一个严重的问题,就是缓存的命中率严重下降,以为算法中的余数计算没有考虑到服务器数量的变动,如果服务器数量保持不变,那肯定是个不错的选择,但是在实际中,我们的系统在不断增强,所需要的缓存的数据量不断提高,面对这种情况,出现宕机或者是服务器数量的变动问题是正常的,所以我们需要想一个合适的办法去解决这个问题,把损失降到最小,不能因服务器的变动而导致缓存命中率严重下降,这样的话就失去了使用memcached的意义了。

      所以需要结合一致性哈希算法来分析,关于一致性哈希算法的细节,在另外一篇博客中详细介绍了。在此不再赘述。

  • 相关阅读:
    HDU 1261 字串数(排列组合)
    Codeforces 488C Fight the Monster
    HDU 1237 简单计算器
    POJ 2240 Arbitrage
    POJ 3660 Cow Contest
    POJ 1052 MPI Maelstrom
    POJ 3259 Wormholes
    POJ 3268 Silver Cow Party
    Codesforces 485D Maximum Value
    POJ 2253 Frogger(最短路)
  • 原文地址:https://www.cnblogs.com/Mr24/p/6709357.html
Copyright © 2011-2022 走看看