memcache本身没有像redis所具备的数据持久化功能,比如RDB和AOF都没有,但是可以通过做集群同步的方式,让各memcache服务器的数据进行同步,
从而实现数据的一致性,即保证各memcache的数据是一样的,即使有任何一台memcache发生故障,只要集群种有一台memcache可用就不会出现数据丢失,
当其他memcache重新加入到集群的时候可以自动从有数据的memcache当中自动获取数据并提供服务。
Memcache借助了操作系统的libevent工具做高效的读写。libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。
即使对服务器的连接数增加,也能发挥高性能。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。
Memcache支持最大的内存存储对象为1M,超过1M的数据可以使用客户端压缩或拆分报包放到多个key中,比较大的数据在进行读取的时候需要消耗的时间比较长,
memcache最适合保存用户的session实现session共享,Memcached存储数据时, Memcached会去申请1MB的内存, 把该块内存称为一个slab, 也称为一个page。
memcached具有多种语言的客户端开发包,包括:Perl/PHP/JAVA/C/Python/Ruby/C#/
分类
Key-value Store
redis、memcached
Document Store
mongodb、CouchDB
Column Store列存数据库,Column-Oriented DB
HBase、Cassandra,大数据领域应用广泛
Graph DB
Neo4j
Time Series 时序数据库
InfluxDB
Memcached只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统。
Memcached功能机制
内存分配机制:应用程序运行需要使用内存存储数据,但对于一个缓存系统来说,申请内存、释放内存将十分频繁,非常容易导致大量内存碎片,最后导致无连续可用内存可用。
Memcached采用了Slab Allocator机制来分配、管理内存。
Page: (slab与page同等)分配给Slab的内存空间,默认为1MB,分配后就得到一个Slab。Slab分配之后内存按照固定字节大小等分成chunk。
Chunk:用于缓存记录kv值的内存空间。Memcached会根据数据大小选择存到哪一个chunk中,假设chunk有128bytes、64bytes,数据只有100bytes存储在128bytes中,存在些浪费。
Chunk最大就是Page的大小,即一个Page中就一个Chunk,也可以在一个Page中分多个Chunk
Slab Class:Slab按照大小分组,就组成不同的Slab Class,Slab之间的差异可以使用Growth Factor控制,默认1.25。-f参数控制。
查看Slab Class (memcached -u memcached -p 11211 -f 2 -vv)
懒过期Lazy Expiration
memcached不会监视数据是否过期,而是在取数据时才看是否过期,过期的把数据有效期限标识为0,并不清除该数据。以后可以覆盖该位置存储其它数据。
LRU
当内存不足时,memcached会使用LRU(Least Recently Used)机制来查找可用空间,分配给新纪录使用。
集群
Memcached集群,称为基于客户端的分布式集群,即由客户端实现集群功能,即Memcached本身不支持集群,Memcached集群内部并不互相通信,
一切都需要客户端连接到Memcached服务器后自行组织这些节点,并决定数据存储的节点。
# 与memcached通信的不同语言的连接器。 libmemcached提供了C库和命令行工具。
[root@localhost7A webapps]# yum list all | grep memcached
memcached.x86_64 1.4.15-10.el7_3.1 @Centos7
libmemcached.i686 1.0.16-5.el7 Centos7
libmemcached.x86_64 1.0.16-5.el7 Centos7
libmemcached-devel.i686 1.0.16-5.el7 Centos7
libmemcached-devel.x86_64 1.0.16-5.el7 Centos7
memcached-devel.i686 1.4.15-10.el7_3.1 Centos7
memcached-devel.x86_64 1.4.15-10.el7_3.1 Centos7
opensips-memcached.x86_64 1.10.5-4.el7 Centos7_epel
php-ZendFramework-Cache-Backend-Libmemcached.noarch
php-pecl-memcached.x86_64 2.2.0-1.el7 Centos7_epel
python-memcached.noarch 1.48-4.el7 Centos7
uwsgi-router-memcached.x86_64 2.0.18-8.el7 Centos7_epel
memcached安装和使用
root@centos7 ~]#yum –y install gcc libevent-devel
[root@centos7 ~]#wget http://memcached.org/files/memcached-1.5.22.tar.gz
[root@centos7 ~]#tar xvf memcached-1.5.22.tar.gz
[root@centos7 ~]#cd memcached-1.5.22/
[root@centos7 ~]#./configure --prefix=/apps/memcached
[root@centos7 ~]#make && make install
[root@centos7 ~]#tree /apps/memcached/
[root@centos7 ~]#echo 'PATH=/apps/memcached/bin:$PATH' > /etc/profile.d/memcached.sh
[root@centos7 ~]#. /etc/profile.d/memcached.sh
[root@centos7 ~]#useradd -r -s /sbin/nologin memcached
[root@centos7 ~]#memcached -u memcached -m 2048 -c 65536 &
[root@centos7 ~]#ss -ntl
安装memcached
# yum install memcached
# rpm -ql memcached
# cat /usr/lib/systemd/system/memcached.service
[Service]
Type=simple
EnvironmentFile=-/etc/sysconfig/memcached
ExecStart=/usr/bin/memcached -u USER -pPORT -m CACHESIZE -cMAXCONN $OPTIONS
# cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024" #连接数
CACHESIZE="64" #内存
OPTIONS=""
前台显示看看效果
# memcached -u memcached -p 11211 -vv
连接
# telnet 127.0.0.1 11211
修改memcached运行参数,可以使用下面的选项修改/etc/sysconfig/memcached文件
-u username memcached运行的用户身份,必须普通用户
-p 绑定的端口,默认11211
-m num 最大内存,单位MB,默认64MB
-c num 最大连接数,缺省1024
-d 守护进程方式运行
-f 增长因子Growth Factor,默认1.25
-v 详细信息,-vv能看到详细信息
-M 内存耗尽,不许LRU
-U 设置UDP监听端口,0表示禁用UDP
-P <file> 将PID写入文件<file>,这样可以使得后边进行快速进程终止, 需要与-d 一起使用
-l <ip_addr> 绑定地址(默认:所有都允许,无论内外网或者本机更换IP,有安全隐患,若设置为127.0.0.1就只能本机访问)
语法:
command <key> <flags> <expiration time> <bytes>
<value>
命令执行最简单的操作。这些命令和操作包括:
set :命令用于向缓存添加新的键值对。如果键已经存在,则之前的值将被替换。(单词 STORED 进行响应)
add :仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对。如果缓存中已经存在键,则之前的值将仍然保持相同,并且您将获得响应 NOT_STORED。
replace :仅当键已经存在时,replace 命令才会替换缓存中的键。如果缓存中不存在键,那么您将从 memcached 服务器接受到一条 NOT_STORED 响应。
get :命令用于检索与之前添加的键值对相关的值。您将使用 get 执行大多数检索操作。
delete :命令用于删除 memcached 中的任何现有值。您将使用一个键调用delete,如果该键存在于缓存中,则删除该值。如果不存在,则返回一条NOT_FOUND 消息。
stats: :统计数据
stats items 显示各个 slab 中 item 的数目和存储时长(最后一次访问距离现在的秒数)。
stats reset 清空统计数据
stats slabs 显示各个slab的信息,包括chunk的大小、数目、使用情况等
stats sizes 输出所有item的大小和个数(第一列是 item 的大小,第二列是 item 的个数)
stats cachedump slabs_id limit_num
slabs_id: 由stats items返回的结果(STAT items后面的数字)决定的
limit_num:返回的记录数,0表示返回所有记录
通过stats items、stats cachedump slab_id limit_num配合get命令可以遍历memcached的记录。
append :将数据追加到当前缓存数据的之后,当缓存数据存在时才存储。
prepend :将数据追加到当前缓存数据的之前,当缓存数据存在时才存储。
flush_all:用于清理缓存中的所有名称/值对。如果您需要将缓存重置到干净的状态,则 flush_all 能提供很大的用处。
参数:
参数 用法
key key 用于查找缓存值
flags 可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time 在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes 在缓存中存储的字节数
value 存储的值(始终位于第二行)
范例:
1.add :仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对。如果缓存中已经存在键,则之前的值将仍然保持相同,并且您将获得响应 NOT_STORED。
add userid 1 0 5
12345
STORED
get userid
VALUE userid 1 5
12345
END
add userid 1 0 6
123456
NOT_STORED #key值不能相同
add user 0 0 5
abcd #字节数少于申明的5个,无法操作。
e
add user 0 0 5
abcdef #字节数多于申明的5个,提示信息。
CLIENT_ERROR bad data chunk
ERROR
2.get:命令用于检索与之前添加的键值对相关的值。您将使用 get 执行大多数检索操作。
add userid 1 0 5
12345
STORED
get userid
VALUE userid 1 5
12345
END
3.set :命令用于向缓存添加新的键值对。如果键已经存在,则之前的值将被替换。(单词 STORED 进行响应)
add userid 1 0 5
set userid 8 0 6
123456
STORED
get userid
VALUE userid 8 6
123456
END
4.replace :仅当键已经存在时,replace 命令才会替换缓存中的键。如果缓存中不存在键,那么您将从 memcached 服务器接受到一条 NOT_STORED 响应。
add userid 1 0 5
replace userid 6 0 5
12345
STORED
get userid
VALUE userid 6 5
12345
END
5.delete :命令用于删除 memcached 中的任何现有值。您将使用一个键调用delete,如果该键存在于缓存中,则删除该值。如果不存在,则返回一条NOT_FOUND 消息。
set userId 0 0 5
98765
STORED
delete userId
DELETED
get userId
END
append 将数据追加到当前缓存数据的之后,当缓存数据存在时才存储。
prepend 将数据追加到当前缓存数据的之前,当缓存数据存在时才存储。
set name 0 0 4
bang
STORED
append name 0 0 4
chen
STORED
get name
VALUE name 0 8
bangchen
END
prepend name 0 0 4
yuan
STORED
get name
VALUE name 0 12
yuanbangchen
END
flush_all:用于清理缓存中的所有名称/值对。如果您需要将缓存重置到干净的状态,则 flush_all 能提供很大的用处。
实例的信息
STAT pid 22459 进程ID
STAT uptime 1027046 服务器运行秒数
STAT time 1273043062 服务器当前unix时间戳
STAT version 1.4.4 服务器版本
STAT pointer_size 64 操作系统字大小(这台服务器是64位的)
STAT rusage_user 0.040000 进程累计用户时间
STAT rusage_system 0.260000 进程累计系统时间
STAT curr_connections 10 当前打开连接数
STAT total_connections 82 曾打开的连接总数
STAT connection_structures 13 服务器分配的连接结构数
STAT cmd_get 54 执行get命令总数
STAT cmd_set 34 执行set命令总数
STAT cmd_flush 3 指向flush_all命令总数
STAT get_hits 9 get命中次数
STAT get_misses 45 get未命中次数
STAT delete_misses 5 delete未命中次数
STAT delete_hits 1 delete命中次数
STAT incr_misses 0 incr未命中次数
STAT incr_hits 0 incr命中次数
STAT decr_misses 0 decr未命中次数
STAT decr_hits 0 decr命中次数
STAT cas_misses 0 cas未命中次数
STAT cas_hits 0 cas命中次数
STAT cas_badval 0 使用擦拭次数
STAT auth_cmds 0 认证命令处理的次数
STAT auth_errors 0 认证失败数目
STAT bytes_read 15785 读取字节总数
STAT bytes_written 15222 写入字节总数
STAT limit_maxbytes 1048576 分配的内存数(字节)
STAT accepting_conns 1 目前接受的链接数
STAT listen_disabled_num 0 失效的监听数
STAT threads 4 线程数
STAT conn_yields 0 连接操作主动放弃数目
STAT bytes 0 存储item字节数
STAT curr_items 0 item个数
STAT total_items 34 item总数
STAT evictions 0 为获取空间删除item的总数
memcached集群部署架构
一、基于magent的部署架构
该部署方式依赖于magent实现高可用,应用端通过负载服务器连接到magent,然后再由magent代理用户应用请
求到memcached处理,底层的memcached为双主结构会自动同步数据,本部署方式存在magent单点问题因此需
要两个magent做高可用。
二、Repcached实现原理:
在 master上可以通过 -X指定 replication port,在 slave上通过 -x/-X找到 master并 connect上去,事实上,如果同时指定了 -x/-X,
repcached一定会尝试连接,但如果连接失败,它就会用 -X参数来自己 listen(成为master);如果 master坏掉, slave侦测到连接断了,它会自动 listen而成为 master;
而如果 slave坏掉,master也会侦测到连接断,它就会重新 listen等待新的 slave加入。从这方案的技术实现来看,其实它是一个单 master单 slave的方案,
但它的 master/slave都是可读写的,而且可以相互同步,所以从功能上看,也可以认为它是双机 master-master方案。
部署repcached:
1.两个都是主节点。视对方为从节点
2.复制双方中内存的K/V值
一.部署repcached:
172.18.200.222 haproxy
172.18.200.106 11211 主节点 memcached+repcached
172.18.200.105 11211 主节点 memcached+repcached
二.安装软件
yum install haproxy
vi /etc/haproxy/haproxy.cfg
listen web_port
bind 0.0.0.0:11211 #有VIP就监听VIP的IP。
mode tcp
balance roundrobin
server web1 172.18.200.106:11211 check inter 3000 fall 2 rise 5
server web2 172.18.200.105:11211 check inter 3000 fall 2 rise 5
三.安装服务器软件
yum install libevent libevent-devel memcached
wget https://sourceforge.net/projects/repcached/files/repcached/2.2.1-1.2.8/memcached-1.2.8-repcached-2.2.1.tar.gz
[root@s6 src]# tar xvf memcached-1.2.8-repcached-2.2.1.tar.gz
[root@s6 src]# cd memcached-1.2.8-repcached-2.2.1
[root@s6 memcached-1.2.8-repcached-2.2.1]# ./configure --prefix=/usr/local/repcached -- enable-replication
[root@s6 memcached-1.2.8-repcached-2.2.1]# make #报错如下
[root@s6 memcached-1.2.8-repcached-2.2.1]# vim memcached.c
56 #ifndef IOV_MAX
57 #if defined(__FreeBSD__) || defined(__APPLE__)
58 # define IOV_MAX 1024
59 #endif
60 #endif
改为如下内容:
55 /* FreeBSD 4.x doesn't have IOV_MAX exposed. */
56 #ifndef IOV_MAX
57 # define IOV_MAX 1024
58 #endif
[root@s6memcached-1.2.8-repcached-2.2.1]# make && make install
/usr/local/repcached/bin/memcached -h
-x <ip_addr> hostname or IP address of peer repcached 对方IP
-X <num:num> TCP port number for replication. <listen:connect> (default: 11212) 对方端口,默认11212.
四.启动
[root@s6 src]# /usr/local/repcached/bin/memcached -d -m 2048 -p 11211 -u root -c 2048 -x 172.18.200.106 -X 16000
[root@s5 src]# /usr/local/repcached/bin/memcached -d -m 2048 -p 11211 -u root -c 2048 -x 172.18.200.105 -X 16000
五.连接到memcache验证数据:
[root@s6 src]# telnet 172.18.200.222 11211
set name 0 0 4 #key 的名为name,且永不超时
jack STORED #符合长度后自动保存
get name
VALUE name 0 4
jack END
[root@s6 src]# telnet 172.18.200.105 11211 #到其中一台memcached服务器验证是否有数据
get name
VALUE name 0 4
jack