memcached 是一套内存缓存系统或者软件,用于动态应用系统中缓存数据库数据,减少数据库访问压力,达到性能提升目的
1,一般在企业中用于数据库的cache
2,作为集群架构节点应用服务器之间session数据共享的存储
memcached 是通过预分配指定内存空间来存储数据,java ,php 应用并发超不过1000 单台mysql200-300 已经很大了
memcached(不能持久化),redis(可持久化缓存) 后端数据库的缓存,动态数据。博文,bbs
nginx ,squid,varnish 前端web应用的缓存 静态数据缓存,图片,附件,js,css,html
需要事先分配一块内存,通过api方式存取,读取内存中的缓存数据,每条数据是以key-value形式存放
当程序更新,删除数据库中已有的数据时候,客户端会同时发送请求通知memcached已经缓存过的同一ID内容的旧数据失效,从而保证memecached中的数据和数据库中的
数据一致
如果是高并发场合,除了通知memcached过期的缓存失效外,还会通过相关机制使用户访问新数据前,通过程序预先把更新的数据推送到memcached中缓存起来,然后再
访问,这样可以减少数据的访问压力,,这样的效率非常高
缺点:
1,如果memcached 重启(断电),缓存丢失,可能造成数据雪崩
如何处理??
先把前端代理设置禁止对外访问,通过程序做初始化,把mysql数据缓存好,缓存到memcached中,然后慢慢挂载好服务器,然后让前端找缓存
当memcached内存空间用完之后,memecached自身会使用(LRU least recently used 最近最少使用)加到期权失效策略,失效的数据首先被替换掉,然后是最近未使用
的数据被替换掉
几乎所有网站,当访问量很大的时候,最先出现的是数据库角色服务器,以及存储角色服务器出现瓶颈,我们设计的时候应该靠前原则
千万级pv/ip规模高性能并发网站架构
http://oldboy.blog.51cto.com/2561410/736710
memcached 【分布式应用1】
memcached支持分布式,我们在应用服务器程序上改造,就可以好的支持,例如我们的key可以适当进行有规律的
封装,比如以用户为主的网站来说,每个用户都有userid,那么可以按照固定的ID来进行提取和存取,比如1-100w开头的用户保存在第一台memcached服务器上,,以
100-200w开头的保存在第二台服务器上,存取数据都先按照userID来进行相应的转换存储。
但是这个有缺点,就是需要对userID 进行判断,如果业务不一致,或者其他类型的应用,肯定不是那么合适,根据自己业务判断.
memcached【分布式应用2】
在应用服务器通过程序URL_HASH,抑制性哈希算法访问memcached服务, 所有memcached服务器地址池可以简单的每个程序配置文件里
memcached【分布式应用3】
门户 百度。会通过一个中间件代理负责请求后端的cache服务,然后连接web
memcached【分布式应用4】
可以用常见的LVS haproxy做cache的负载均衡. 重点是调度算法, cache一般选择url_hash以及一致性hash算法,会牺牲LVS的性能
memcahed 服务应用优化案例
数据库负责很高 load 20-30
登录数据库
show processlist;
show full processlist ;
mysql -u -p -e "show full processlist | grep -vi sleep"
结果显示like "***" 类似语句很多
优化思路:
1,从业务上实现用户登录后在搜索,可以减少搜索次数,从而减轻数据库压力
2,如果有大量平凡的搜索,一般是爬虫在爬你们网站,ip封掉
3,配置主从同步,程序实现读写分离,最好案吧like的语句去从库查询,减轻主库压力
4,一般像like的语句,一般很难在mysql里面优化,可以通过搜索服务sphinx实现搜索
5.在数据库前端加memcached服务器
memcached 特性:
memcached 作为高并发,高性能的缓存服务,具有以下特征:
协议简单
memcached 的协议实现比较简单,使用基本的文本协议,能通过telent之间操作memcached服务器存取数据
基于libevent的事件处理
内置的内存管理方式 (slab allocation)
这个内置管理方式很高效,所有数据都保存在memecache中,当存入的数据占满空间时候,memcached使用URL算法自动删除不适用的缓存数据,就,即重用过期数据的内
存空间.但是容易丢失数据,可以会用sina开发的memcaceDB 持久性内存缓存系统,当然还有redis,mongodb
memcached服务器之间不通信,都是独立存储数据,不共享任何信息,通过对客户端的设计,让memcached具有分布式,支持海量数据的大规模应用
.
memcached软件工作原理:
memcached是一个C/S架构软件,在服务端启动服务守护进程,可以为memcached服务器指定监听IP地址,端口号,并发连接数,以及分配多少内存来处理客户端的请求参
数
采用异步的I/O,应用程序通过指定服务器的IP地址,和端口,就可以连接memcached服务相互通信
需要被缓存的数据以key/value键值对的形式保存在服务器端分配的内存中,每个被缓存的数据有唯一的标示key,操作memcached中的数据通过这个唯一标示key进行,
缓存到memcached的数据都被放在被分配放的内存中,而不是被分配到磁盘中,因此读书速递非常快
注意事项,要考虑重新启动丢失数据带来的影响和高并发场合丢失数据
memcached删除机制
memcached不会释放已分配的内存空间,(除非添加数据时候设定过期或者内存满了的时候)
lazy expiration策略,自己不会监控存入的key/value对是否过期,而是获取key值查看记录时间戳检查key/value对空间是否过期,这种策略不会再过期检查上浪费CPU
资源
LRU算法来分配空间,删除最近最少使用的key/value对,如果内存足够大,不想使用LRU算法,那么可以再启动时候加上-M 参数,这样memcached会在内存耗尽时候返回
一个错误
安装memcached
1,wget http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz [root@localhost ~]# tar xvf libevent-1.4.13-stable.tar.gz [root@localhost ~]# cd libevent-1.4.13-stable [root@localhost libevent-1.4.13-stable]# make make install 2,memcached
分为客户端和服务端
memcached-2.2.5.tgz ---client memcached-1.4.15.tar --server wget http://memcached.googlecode.com/memcached-1.4.13.tar.gz cd memcached-1.4.15 1004 ./configure && make && make install 1010 ls /usr/local/lib/ 1011 echo "/usr/local/lib" >> /etc/ld.so.conf 1012 ldconfig 1013 which memcached /usr/local/bin/memcached memcached 1.4.15 -p <num> TCP port number to listen on (default: 11211) -U <num> UDP port number to listen on (default: 11211, 0 is off) -l <addr> interface to listen on (default: INADDR_ANY, all addresses) <addr> may be specified as host:port. If you don't specify a port number, the value you specified with -p or -U is used. You may specify multiple addresses separated by comma or by using -l multiple times -d run as a daemon -r maximize core file limit -u <username> assume identity of <username> (only when run as root) -m <num> max memory to use for items in megabytes (default: 64 MB) -M return error on memory exhausted (rather than removing items) -c <num> max simultaneous connections (default: 1024) 并发 -P <file> save PID in <file>, only used with -d option [root@localhost ~]# memcached -p 11211 -u root -m 16m -c 10240 -d [root@localhost ~]# lsof -i:11211 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME memcached 20124 root 26u IPv4 139731 0t0 TCP *:memcache (LISTEN) memcached 20124 root 27u IPv6 139732 0t0 TCP *:memcache (LISTEN) memcached 20124 root 28u IPv4 139735 0t0 UDP *:memcache memcached 20124 root 29u IPv6 139736 0t0 UDP *:memcache 启动memcached 多实例 各个实例之间是相对独立的 memcached -p 11212 -u root -m 16m -c 10240 -d /etc/rc.local
(4)写入数据检查结果
向memcached中添加数据
1,通过nc写入 [root@localhost ~]# printf "set key007 0 0 10\r\noldboy0987\r\n"|nc 127.0.0.1 11211 STORED ----命令的字节是10,那么后面就是10个字符,否则添加不成功 [root@localhost ~]# printf "get key007\r\n" | nc 127.0.0.1 11211 VALUE key007 0 10 oldboy0987 END [root@localhost ~]# printf "set key001 0 0 10\r\noldboy0098\r\n"|nc 127.0.0.1 11211 STORED 删除: [root@localhost ~]# printf "delete key001\r\n" | nc 127.0.0.1 11211 DELETED [root@localhost ~]# printf "get key001\r\n" | nc 127.0.0.1 11211 END telent 127.0.0.1 11211 stats ---查看memcached的服务状态 STAT pid 20124 STAT uptime 10911 STAT time 1437183342 STAT version 1.4.15 STAT libevent 1.4.13-stable STAT pointer_size 64 STAT rusage_user 0.146977 STAT rusage_system 0.469928 STAT curr_connections 10 STAT total_connections 54 STAT connection_structures 12 STAT reserved_fds 20 STAT cmd_get 28 STAT cmd_set 4 STAT cmd_flush 0 STAT cmd_touch 0 STAT get_hits 12 ---------命中率 ,每次get 便会递增1 STAT get_misses 16 ---------丢失率 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 3888 STAT bytes_written 2571 STAT limit_maxbytes 16777216 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 bytes 161 STAT curr_items 2 STAT total_items 3 新增一个,此值会递增 STAT expired_unfetched 0 STAT evicted_unfetched 0 STAT evictions 0 STAT reclaimed 0 END
重启memcached ,数据丢失
[root@localhost ~]# printf "get key\r\n"|nc 127.0.0.1 11211 VALUE key 0 10 wybwyb END [root@localhost ~]# ps -ef | grep memcached root 20124 1 0 06:33 ? 00:00:00 memcached -p 11211 -u root -m 16m -c 10240 -d root 22920 22899 0 09:47 pts/1 00:00:00 grep memcached [root@localhost ~]# kill -9 20124 [root@localhost ~]# ps -ef | grep memcached root 22922 22899 0 09:48 pts/1 00:00:00 grep memcached [root@localhost ~]# memcached -p 11211 -u root -m 16m -c 10240 -d [root@localhost ~]# ps -ef | grep memcached root 22924 1 0 09:49 ? 00:00:00 memcached -p 11211 -u root -m 16m -c 10240 -d root 22931 22899 0 09:49 pts/1 00:00:00 grep memcached [root@localhost ~]# printf "get key\r\n"|nc 127.0.0.1 11211 END
memcached命令语法
set key 0 0 10
<command name> <key> <flags> <exptime> <bytes>\r\n
command name 是set get add replace
获取数据
key 是接下来的客户端所要求储存的数据的键值
集群中的session共享存储
http://oldboy.blog.51cto.com/2561410/1331316
用memcached来存储session特点:
优点:
1)读写速度上会比普通files时快很多。
2)可以解决多个服务器共用session的难题。
缺点:
1)session数据都保存在memory中,持久化方面有所欠缺,但对session数据来说不是问题。
2)单点,部署多台,也无法数据同步。通过hash算法分配依然有sesson丢失的问题。
大规模企业解决思路:
2)可以用其他的持久化系统存储sessons,例如:redis,ttserver,替代memcached。
3)高性能高并发场景,cookies效率比session要好很多,因此,大网站都会用cookies解决会话共享问题。
4)有初级运维网友通过牺牲LB的负载均衡的策略实现,例如:lvs -p,nginx ip_hash等,这些不是好的方法。
如何解决session不共享的问题呢
http://oldboy.blog.51cto.com/2561410/1331316
http://oldboy.blog.51cto.com/2561410/1323468
1,在服务端启动一个memcache实例,把这个实例作为共享 memcached -p 11211 -u root -m 16m -c 10240 -d
真正配置的开始
修改配置文件,在php.ini中全局设置:
###################web集群session共享存储设置:
1,让所有的web服务器把session保存在相同路径的缓存里面(/tmp)
可以做共享nfs ,把/tmp共享,(A-B服务器),但是nfs高访问下,响应不够及时,所以都存放到memcached中
php.ini
session.save_path = "/tmp"
2,使用memcached
把所有web站点的php.ini改成同一memcached的ip+port
默认php.ini中session的类型和配置路径:
#session.save_handler = files
#session.save_path = "/tmp"
修改成如下配置:
session.save_handler = memcache
session.save_path = "tcp://10.0.0.18:11211" ---
提示:
1)10.0.0.18:11211 为memcached数据库缓存的IP及端口。
2)上述适合LNMP,LAMP环境。
3)memcached服务器也可以是多台通过hash调度。
##################针对memcached单点故障出现的问题解决方案:(也不太完美,没有解决master挂掉,再次开启数据无法恢复问题)
1,针对memcached做高可用
http://blog.snsgou.com/post-800.html
2,使用新浪的memcachedDB,对原有客户端来讲还是memcached,但在服务端他是可以持久化存储。
3,日本人开发的Tokyo tyrant+Tokyo Cabinet
#################memcached的管理方式
1,通过telent + port +ip
2, 通过nc ---printf "get key008\r\n" | nc 127.0.0.1 11211
###############memcached 监控管理工具
memadmin-1.0.12.tar.gz -----放到php站点目录下----(lamporonmp 最好是源码编译)
tar xvf memamin
www.etiantian.com/memcache
通过memadmin工具,可以看到memcached的状态,连接次数,当前的并发数,通过这些信息可以
分析出,当前memcached的换入换出手否比较厉害,容量是否足够