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
2
3
4
5
6
7
8
9
|
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
|
分为客户端和服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
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 ,数据丢失
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[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的换入换出手否比较厉害,容量是否足够
本文转自crazy_charles 51CTO博客,原文链接:http://blog.51cto.com/douya/1677869,如需转载请自行联系原作者