memcached基础总结

    xiaoxiao2021-03-26  56

    概述

    memecached内存缓存软件,协议简单,基于libevent事件处理,内置内存存储方式,采用不互相通信的分布式;

    安装memcached

    yum -y install libevent libevent-devel安装libevent libevent-devel wget http://memcached.org/files/memcached-1.4.33.tar.gz tar cd memcached-1.x.x ./configure --prefix=/usr/local/memcached make && make test && make install

    安装memcache扩展

    wget http://pecl.php.net/get/memcache-2.2.7.tgz tar -zxvf memcache-2.2.7.tgz /usr/local/php/bin/phpize ./configure --with-php-config=/usr/local/php/bin/php-config make && make install

    启动和参数说明

    /usr/local/memcached/bin/memcached -p port:监听端口tcp port number,TCP端口 -m num:单个数据项最大可用内存,MB为单位,默认64M;(占用机器内存) -u num:udp port端口udp端口监听。 -a <mask>:支持mask 0700 -d start :告诉memcached启动 -d restart:告诉启动memcached重启 -d stop|shutdown:启动memcached关闭 -d install:安装memcached服务; -d uninstall:取消安装memcached服务 -r :最大核心文件限制 -u <username>:用什么身份启动 -c <num>:最大的连接数。 -v :输出错误信息; -vv:输出所有的信息。 -vvv:超详细的所有信息 -h:打印帮助和退出。 -i:打印memcached和libevent license; -p <file>:保存pid到文件。 -f <factor>:增长因子,默认1.25; -n <bytes>:最小的空间分配给key-value,默认48; -l <ip_addr> 监听的IP地址。(默认:INADDR_ANY,所有地址)

    连接

    memcache客户端与服务器通信比较简单,使用基于文本的协议,而不是二进制协议; 可以通过telnet与memcached做交互; telnet 127.0.0.1 11211 ctrl+]

    命令

    hash哈希:碰撞要低。 某个范围内,随机出一个hash值,放到相关的内存地址; 取出数据的时候,根据hash值来获取数据的内存地址取得地址;
    新增add
    add key flag expire length 回车 add name 1 30 3 lin STORED get name VALUE name 1 3 lin END key:唯一键值;flag:标志,要求一个正整数。 expire:有效期;length:缓存长度字节单位; flag:标志:标识存储数据的格式类型;比如:1-字符串,2-反转成数组,3,反序列对象等。 expire:设置秒数;时间戳(到某个点);设为0不失效; 默认memcache最长常量为30天。可能等不到30天,数据也可能会被挤出去; 老数据有可能被踢
    读取数据get
    get key:返回某个key值
    删除delete
    delete key 删除指定的key;
    替换replace
    replace key flag expire length 参数和add一样,修改某个key的值; 只能对已经存在的键进行修改 replace age 0 0 9 linjunbin STORED get age VALUE age 0 9 linjunbin END
    设置和修改值set
    参数和add,replace一样,功能有所区别,如果key存在则修改,不存在则添加。
    incr,decr命令:增加/减少值的大小
    incr/decr key num

    注意:incr,decr操作是把32位无符号来+-操作,值在0-2的32次方范围内。 秒杀场景。每进来一个用户就新增1,直到进来达到限制数其他的直接拒绝静态页。

    统计stats
    stats STAT pid 15992 :进程号 STAT uptime 3289 :运行的时间 STAT time 1485095107 :当前时间戳 STAT version 1.4.13 :当前版本 STAT libevent 2.0.21-stable STAT pointer_size 64 STAT curr_connections 11 :当前有几个连接 STAT total_connections 13 :总共连接几个 STAT connection_structures 12 STAT reserved_fds 20 STAT cmd_get 10 :查询次数 STAT cmd_set 7 : STAT cmd_flush 0 STAT cmd_touch 0 STAT get_hits 8 :获取成功次数 STAT get_misses 2 :失败的次数,获取不到值;可以计算缓存命中率 STAT delete_misses 0 STAT delete_hits 1 STAT incr_misses 0 STAT incr_hits 0 STAT decr_misses 0 STAT decr_hits 0 STAT cas_misses 0 STAT cas_hits 0 STAT cas_badval 0 STAT touch_hits 0 STAT touch_misses 0 STAT auth_cmds 0 STAT auth_errors 0 STAT bytes_read 541 STAT bytes_written 667 STAT limit_maxbytes 268435456 STAT accepting_conns 1 STAT listen_disabled_num 0 STAT threads 4 STAT conn_yields 0 STAT hash_power_level 16 STAT hash_bytes 524288 STAT hash_is_expanding 0 STAT expired_unfetched 0 STAT evicted_unfetched 0 STAT bytes 222 STAT curr_items 3 :当前几个key值 STAT total_items 6 :自动启动起来存储的几个值 STAT evictions 0 STAT reclaimed 1 END
    flush_all清空所有的存储对象
    flush_all

    memcached内存管理和删除机制

    C语言:使用malloc,free来向操作系统申请和释放内存。

    内存碎片化:在不断的申请和释放过程中,形成了一些很小的内存片段,无法再利用

    slab allocator缓存内存碎片化

    memcached用slab allocator机制来管理内存。

    slab allocator原理:预告把内存划分成数个slab class仓库(每个slab clas大小1M)各个仓库切分成不同尺寸的小块(chunk);需要存内容的时候,判断内容大小,为其选择合理的仓库;

    1M slab class = 4 byte (chunk) * 1000 * 250;

    将尺寸相同的chunk放在同一组class;

    关联参数:增长因子,表示chunk之间间隔倍数1.25默认。这个参数可以调整
    系统选择合适的chunk

    数据存储:chunk为固定大小,造成浪费这个问题,不能克服,只能缓解;根据要存入数据的大小来选择不同空闲chunk来存储。

    注意:如果有100byte的内容要存,可是122大小的仓库中没有空闲的chunk满了, 是不会寻找更大规格chunk来存(144),而是把122byte仓库的旧数据踢掉。 LRU:删除机制less recently use 过期机制与删除机制
    固定大小chunk带来的内存浪费

    比如存储100byte数据到122chunk中,无疑浪费了22byte就浪费了,无法彻底解决,只能缓解问题。

    注意:开发者可以对网站缓存中的item长度进行统计,并制定合理的slab class中的chunk大小。通过增长因子调整。 -m 64 -p 11211 -vvv -f 增长因子
    grow factor调优
    默认值1.25倍数。使用-f参数进行调整。 注意:当f=1.25时,从输出结果来看,某些相邻slab class大小比值并非1.25,这些误差为了保持字节数对齐而故意调整的。

    memcached的过期数据惰性删除

    当某个值过期后,并没有从内存删除,因此,stats统计时,curr_item有其信息; 当某个新值去占用她的位置时,当成空chunk来占用。 当get值时,判断是否过期,如果过期返回空,并且清空,curr_item就减少了。 惰性删除:减少cpu时间和检测成本;

    memcached此处用的LRU删除机制

    如果122byte大小的chunk都满了,要插入新的值120byte,会挤掉122bytechunk里面的值; memcached用的LRU删除机制,最近最少使用;least recently used; 当某个单元被请求时,维护一个计数器,通过计数器来判断最近谁最少被使用。

    注意:即使key设置了永久有效也会被踢出;

    memcached中的一些参数限制

    key长度:250 btye(二进制协议支持65535个字节) value的限制1M,一般都是存储一些文本, 内存的限制:32位下最大设置2G

    如果有30G数据要缓存,一般不会单实例装30G,一般建议开启多个实例,不同服务器端口,或者不同机器;

    深入理解memcache

    支持高并发

    memcached使用多路复用I/O模型epoll,select等。多路复用I/O是一种消息通知模式。 用户连接好I/O准备后,系统会通知我们这个连接可以进行I/O操作,不会阻塞在某个用户连接。 所以,memcached能支持高并发; -t:参数表示支持线程数,并非线程数越多越好,一般设置为CPU核数,这样效率最高。 线程数越多系统需要县城调度时间就越多,而把线程数设置成CPU核数,系统需要的线程调度时间最少。
    使用slab分配算法保存数据
    memecache默认只能存储不大于1M的数据(修改源码可以存多1m,把power_block宏设置更大数) 使用Slab分配算法,把固定大小1M内存块分成N小块; (具体后续查看分析源码)
    删除过期item
    memcache为每个item设置一个过期时间,并非过期就删除,而是访问时过期数据才删除。懒删除机制;
    memcached多线程模型
    memcached是一个多线程缓存服务器程序,线程分为: 1、主线程:接收客户端连接,并把连接分配给工作线程处理。 2、工作线程:worker thread,处理客户端连接请求。 主线程accept函数接收到来的连接,把连接push工作线程的CQ队列中,并向工作线程发送一个信号,通知工作线程有新的客户端连接需要处理。 当工作线程接收到主线程信号,便会把CQ队列上的客户端连接注册到libevent进行侦听, libevent会侦听客户端连接的读写时间,并调用相关的回调函数drive_machine进行处理。
    示例-小试牛刀
    <?php $mc = new Memcache(); $mc->connect('127.0.0.1', '11211');//连接mamcache服务器 $val = $mc->get('name'); if(empty($val)) { $mc->set('name', 'linjunbin', 0, 10);//缓存数据 }else{ $mc->delete('name');//删除数据 } $mc->close();//断开连接

    PHP扩展访问memecached服务器

    connect():返回bool类型连接单个服务器 host:服务器域名或者IP port:服务器TCP端口,默认11211 timeout:连接持续超时时间,默认值1s,过长的连续持续时间可能导致失去所有的缓存优势。 addServer():用于向对象添加一个服务器;

    注意:addserver()没有连接到服务器动作,所以在memcached进程没有启动时候,执行addserver成功也会返回true;

    bool Memcache:addServer( host,int port[,bool persistent,int weight, int timeout,int retry_interval, bool status,callback failure_callback])

    persistent:是否使用常连接,默认为true; weight:权重,在多个服务器设置中占得比例; timeout:连接memcached服务器失效的秒数 retry_interval:服务器连接失败的重试平率,默认是15S一次,设置-1为自动重试 status:控制服务器是否被标记为online, fail_callback:失败时候的回调函数,函数的两个参数失败服务器hostname和port //示例 foreach ((array) $hosts as $i => $host) { $port = isset($ports[$i]) ? $ports[$i] : $ports[0]; $this->options['timeout'] > 0 ?$this->handler->addServer($host, $port, $this->options['persistent'], 1, $this->options['timeout']) :$this->handler->addServer($host, $port, $this->options['persistent'], 1); } memcache:getServerStatus:用于获取一个服务器在线或者离线状态。 int Memcache::getServerStatus(string $host, int $port); 0:表示服务器离线,非0:表示服务器在线; getStats:用于获取服务器的统计信息。返回一个关联数组统计信息; array Memcache::getStats(string $type, int $slabid, int $limit) type:期望统计的信息类型,reset,malloc,maps等。 slabid:与type参数联合指定slab分块拷贝数据; limit:从服务器获取的实体条数;
    转载请注明原文地址: https://ju.6miu.com/read-649995.html

    最新回复(0)