memcache

安装memcached
官网下载tar.gz包
解压
yum -y install libevent libevent-devel
./configure --prefix=/usr/local/memcached




memcached依赖于GCC和libevent库





memcache缓存机制:

增加一条数据:
    add key flag expiretime bytes\r\n
    data\r\n

    key:给这个值起一个固定的名字
    flag:标志,是一个整数
    expiretime:有效期,
    length:添加的缓存的长度,以字节bytes\r\n为单位
    data:存放真实数据

    flag的意义:
        memcache基于简单的文本协议,可以理解为字符串存储。flag用来表示不同类型的对象
        
    
常用操作:
        delete key  删除

        replace    key flag expiretime length     替换
        newdata   
        
        append:将数据追加到key对应的value值的末尾,不允许操过限制
        
        get key 返回key的值

        set  修改和设置值,类似于add replace,但是功能不一样。
        set相当于有add replace两者的功能
        set key flag expiretime  length
            

        incr和decr,增加和减少,针对于数字而言。
        incr key 10  给key增加10
        decr key 10  给key减少10

统计命令 stats
STAT pid 1514
STAT uptime 6580
STAT time 1485675604
STAT version 1.4.34
STAT libevent 2.0.21-stable
STAT pointer_size 64            
STAT rusage_user 2.220000
STAT rusage_system 1.776000
STAT curr_connections 10
STAT total_connections 11
STAT connection_structures 11
STAT reserved_fds 20
STAT cmd_get 29
STAT cmd_set 13
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 21            成功的get次数
STAT get_misses 8            失败的get次数        可以计算命中率
STAT get_expired 2
STAT get_flushed 0
STAT delete_misses 0
STAT delete_hits 1
STAT incr_misses 0
STAT incr_hits 1
STAT decr_misses 0
STAT decr_hits 1
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 817
STAT bytes_written 2330
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT malloc_fails 0
STAT log_worker_dropped 0
STAT log_worker_written 0
STAT log_watcher_skipped 0
STAT log_watcher_sent 0
STAT bytes 147
STAT curr_items 2             当前存储2个值
STAT total_items 8                总共存储了多少个值
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 0
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
END


flush_all  清空所有缓存对象




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

内存管理:

1 内存的碎片化
当我们使用C语言或其它语言进行malloc,free等类似命令操作内存的时候
在不断的申请和释放过程中,形成了一些很小的内存储片段,我们无法继续的利用
那这种空闲,无法继续利用内存的情况,我们称之为内存的碎片化。


2 MC管理内存的方法
MC使用slab allocator的机制来管理内存
原理:预告将内存划分为数个slab class的仓库
各个仓库 切分成不同尺寸的小块(chunk),默认大小是64MB
需要存放内容的时候,先判断内容的大小,为其选取合理的仓库存放。


3 如何选择合适的chunk?
MC会根据收到的数据的大小,选择最合适数据大小的chunk组(slab class)
MC中保存着slab class内空闲chunk的列表,根据列表选择空的chunk,然后将数据缓存其中


4 固定大小的chunk带来的内存浪费
由于slab allocate机制中,分配的chunk的大小是固定的,因此,对于特定item,可能更会造成内存的浪费
比如说,将100字节的数据缓存到122字节的chunk中,剩余的22字节就浪费了

对于chunk空间的浪费问题,无法彻底解决,只能缓解该问题


grow factor 增长因子。默认为1.25


---------------------------------------------------------------------------
LRU原理

MC的过期数据惰性删除

1 当某个值过期后,并没有从内存中删除,因此,我们在进行stats统计信息的时候,curr_items有其信息。
2 当某个新值去占用他的位置的时候,当成空chunk来占用
3 当get key值得时候,先判断key是否过期,如果过期,返回空,并且清空,curr_items就减少了

即过期并没有从内存中删除数据,只是我们看不到而已。
所以我们把这个作为lazy expire,即惰性失效
好处是:节省了cpu的时间和惰性成本

MC的LRU删除机制:
假如我们以122字节大小的chunk举例,122的chunk都满了,又有新的值(长度也为122)要加入,那么要挤掉谁?

这时就运用了LRU删除机制


注:操作系统常用的内存管理,经常使用的算法是FIFO,LRU算法

LRU:least recently used 最近最少使用
fifo:first in first out 先进先出

LRU:原理,当某个单元被请求的时候,维护一个计数器,通过计数器来判断最近谁最少使用,那就把谁踢出去
注:即使某个key值被设置永久有效,也会被踢出来,这个就是永久数据被踢的现象



key的长度:250字节(二进制协议支持65536个字节)
value的限制:1M,我们一般存储一些文本,足够

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

缓存雪崩现象?
一般是由某个缓存节点失效导致其它节点的缓存命中率下降,缓存中缺失的数据
去数据库查询短时间内,造成数据库服务器崩溃

重启DB,短期内又被压垮,但缓存数据多一些
DB反复多次重启,缓存重建完毕,DB才能稳定运行

或者,是由于缓存周期性的失效,比如每8小时失效一次,那么8小时将有一个请求峰值
严重者会导致数据库崩溃






生产环境:
例如,缓存数据设置为每8小时失效一次,导致最终结果是没8小时数据库压力会变大一次,
每8小时我们的数据库就会迎来一次请求高峰,因为之前设置的缓存已经失效

解决方案?

缓存失效后,通过加锁或者队列来控制数据库写缓存的线程数量。
比如对某个key只允许一个线程查询数据和写缓存,其它线程等待。
不同的key设置不同的过期时间,让缓存失效的时间点尽量均匀。


做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2
A1缓存失效时间设置为短期,A2则为长期。




--------------------------------------------------------------------------
multiget是什么?

是指从memcache(或其它分布式缓存)一次性获得多个键值,一般有memcached client自行实现。


multiget hole是什么?
该问题是由facebook的工作人员提出的,facebook在2010年左右,memcached节点就已经达到3000个缓存数千G的内容,
他们发现了一个问题,memcached连接频率,效率下降了。然后再增加memcached节点,但是问题仍然存在,称之为“multiget hole现象”

问题原因?
我们使用multiget一次性获取100各键值对应的数据。
系统最初只有一台memcached服务器,随着访问量的增加,系统负载增加,然后又增加一台memcached服务器,数据散列到两台服务器上
开始那100各键在两台服务器上各有50各。
问题在于:原本只要访问一台服务器就能获取的数据,现在要访问两台服务器才能获取,服务器增加的越多,需要访问的服务器就越多
所以问题不会改善,甚至还会恶化


请求是并行的还是串行的?
请求多台服务器并不是问题的症结,真正的原因在于客户端请求多台服务器时是并行的还是串行的
问题是很多客户端,包括libmemcached在内,在处理multiget多台服务器请求时,使用的是串行方式
也就是说,先请求一台服务器,然后等待其相应结果,接着请求另外一台,结果导致客户端操作时间累加。请求堆积性能下降。

解决的方法:
保证multiget中的键key只出现在一个节点上即可。
把某一组key,按照其共同前缀来分布
比如user-133-age,user-133-name,user-133-height折三个key
在使用分布式算法请求其节点时,应该以"user-133"来计算
这样三个关于个人信息的key都在一个节点上,访问时只需要请求一台主机。



---------------------------------------------------------------------
永久数据丢失现象的原因?
1 如果slab里的很多chunk已经过期,但多期后没有被get过,系统不知道他们已经过期。
2 永久数据很久没get,不活跃,如果新增item,则永久数据被踢
3 当然如果那些非永久数据被get过,也会被标识为expire,从而不会再踢掉永久数据

解决方案:
永久数据和非永久数据分开放











    
    
    
    
    
    
    
    
    
    
   

posted @ 2017-02-19 22:13  hehe88  阅读(201)  评论(0)    收藏  举报