memcached+magent实现memcached集群

首先说明下memcached存在如下问题

  本身没有内置分布式功能,无法实现使用多台Memcache服务器来存储不同的数据,最大程度的使用相同的资源;无法同步数据,容易造成单点故障。(memagent代理实现集群)

      在 Memcached中可以保存的item数据量是没有限制的,只要内存足够 。
  Memcached单进程最大使用内存为2G,要使用更多内存,可以分多个端口开启多个Memcached进程 
  最大30天的数据过期时间,设置为永久的也会在这个时间过期,常量REALTIME_MAXDELTA 
  60*60*24*30控制 
  最大键长为250字节,大于该长度无法存储,常量KEY_MAX_LENGTH 250控制 
  单个item最大数据是1MB,超过1MB数据不予存储,常量POWER_BLOCK 1048576进行控制, 
  它是默认的slab大小 
  最大同时连接数是200,通过 conn_init()中的freetotal进行控制,最大软连接数是1024,通过 
  settings.maxconns=1024 进行控制 
  跟空间占用相关的参数:settings.factor=1.25, settings.chunk_size=48, 影响slab的数据占用和步进方式

memcached是一种无阻塞的socket通信方式服务,基于libevent库,由于无阻塞通信,对内存读写速度非常之快。
  memcached分服务器端和客户端,可以配置多个服务器端和客户端,应用于分布式的服务非常广泛。
  memcached作为小规模的数据分布式平台是十分有效果的。

memcached是键值一一对应,key默认最大不能超过128个字 节,value默认大小是1M,也就是一个slabs,如果要存2M的值(连续的),不能用两个slabs,因为两个slabs不是连续的,无法在内存中 存储,故需要修改slabs的大小,多个key和value进行存储时,即使这个slabs没有利用完,那么也不会存放别的数据。

集群配置

由于Memcached服务器与服务器之间没有任何通讯,并且不进行任何数据复制备份,所以当任何服务器节点出现故障时,会出现单点故障,如果需要实现HA,则需要通过另外的方式来解决。

通过Magent缓存代理,防止单点现象,缓存代理也可以做备份,通过客户端连接到缓存代理服务器,缓存代理服务器连接缓存连接服务器,缓存代理服务器可以连接多台Memcached机器可以将每台Memcached机器进行数据同步。如果其中一台缓存服务器down机,系统依然可以继续工作,如果其中一台Memcached机器down掉,数据不会丢失并且可以保证数据的完整性。具体可以参考:http://code.google.com/p/memagent/

memcached的分布式                                                                                                                                                                                                                                                                                                              

Memcached作为集中式Cache,就存在着集中式的致命问题:单点问题,Memcached支持多Instance分布在多台机器上,仅仅只是解决了数据全部丢失的问题,但是当其中一台机器出错以后,还是会导致部分数据的丢失,一个篮子掉在地上还是会把部分的鸡蛋打破。

因此就需要实现一个备份机制,能够保证Memcached在部分失效以后,数据还能够依然使用,当然大家很多时候都用Cache不命中就去数据源获取的策略,但是在SIP的场景中,如果部分信息找不到就去数据库查找,那么要把SIP弄垮真的是很容易,因此SIP对于Memcached中的数据认为是可信的,因此做Cluster也是必要的。

memcached和memcache的安装请看上一篇,这里不做介绍,下面直接安装magent

1、安装magent:

[root@lys2 src]# mkdir magent
[root@lys2 src]# mv magent-0.6.tar.gz magent
[root@lys2 src]# cd magent
[root@lys2 magent]# tar -zxvf magent-0.6.tar.gz
[root@lys2 magent]# /sbin/ldconfig
[root@lys2 magent]# sed -i "s#LIBS = -levent#LIBS = -levent -lm#g" Makefile
[root@lys2 magent]# make (此处遇到几个报错,解决方法请看文章末尾)
[root@lys2 magent]# cp magent /usr/bin/magent

2、测试magent +memcached的强大功能

开5个memcached端口依次执行

[root@lys2 magent]# memcached -m 1 -u root -d -l192.168.144.101 -p 10001
[root@lys2 magent]# memcached -m 1 -u root -d -l192.168.144.101 -p 10002
[root@lys2 magent]# memcached -m 1 -u root -d -l192.168.144.101 -p 10003
[root@lys2 magent]# memcached -m 1 -u root -d -l192.168.144.101 -p 10004
[root@lys2 magent]# memcached -m 1 -u root -d -l192.168.144.101 -p 10005

先看看是否启动监听端口成功

[root@lys2 magent]# netstat -ulpnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 0.0.0.0:60734               0.0.0.0:*                   LISTEN      1313/rpc.statd      
tcp        0      0 127.0.0.1:9000              0.0.0.0:*                   LISTEN      1479/php-fpm        
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      1291/rpcbind        
tcp        0      0 192.168.144.101:10001       0.0.0.0:*                   LISTEN      2004/memcached      
tcp        0      0 192.168.144.101:10002       0.0.0.0:*                   LISTEN      2012/memcached      
tcp        0      0 192.168.144.101:10003       0.0.0.0:*                   LISTEN      2020/memcached      
tcp        0      0 192.168.144.101:10004       0.0.0.0:*                   LISTEN      2028/memcached      
tcp        0      0 192.168.144.101:10005       0.0.0.0:*                   LISTEN      2036/memcached     

接着启动magent 设置启动参数 -u当然是启动账号 -n是最大连接数,-l是magent监听的IP -p是magent监听的端口后面的格式依次是 -s IP:端口 代表是主服务器 然后指定IP:端口的格式

#命令详解
'''
  -h this message
  -u uid
  -g gid
  -p port, default is 11211. (0 to disable tcp support)
  -s ip:port, set memcached server ip and port
  -b ip:port, set backup memcached server ip and port
  -l ip, local bind ip address, default is 0.0.0.0
  -n number, set max connections, default is 4096
  -D do not go to background
  -k use ketama key allocation algorithm
  -f file, unix socket path to listen on. default is off
  -i number, max keep alive connections for one memcached server, default is 20
  -v verbose
'''

这里设置了10001,10002,10003 为主Memcached服务器 10004,10005 为memcached备份服务器 

[root@lys2 magent]# magent -uroot -n 51200 -l 192.168.144.101 -p 12000 -s 192.168.144.101:10001 -s 192.168.144.101:10002 -s 192.168.144.101:10003 -b 192.168.144.101:10004 -b 192.168.144.101:10005

执行命令后 可以先查看是否启动成功

[root@lys2 magent]# ps -ef | grep magent
root       2062      1  0 09:06 ?        00:00:00 magent -uroot -n 51200 -l 192.168.144.101 -p 12000 -s 192.168.144.101:10001 -s 192.168.144.101:10002 -s 192.168.144.101:10003 -b 192.168.144.101:10004 -b 192.168.144.101:10005
root       2067   1881  0 09:07 pts/0    00:00:00 grep magent

3、在XP客户端上测试

直接连接magent 端口 12000 执行stats

说明magent 里面已经负载了3个memcached 端口接着我们继续set

好了 依次设置了3个key ,这里说明下参数 <command name> <key> <flags> <exptime> <bytes>

既然设置了3个key,我们来读取看执行命令get key1 get key2 get key3依次返回了

 到此,一个缓存写入已经存取的过程就完成了

然后我们直接登陆memcached的端口get数据看 它是怎么样保存的

依次telnet 192.168.144.101 10001  192.168.144.101 10002  192.168.144.101 10003 192.168.144.101 10004 192.168.144.101 10005 去获取key值

telnet 192.168.144.101 10001:

telnet 192.168.144.101 10002:

telnet 192.168.144.101 10003:

telnet 192.168.144.101 10004:

telnet 192.168.144.101 10005:

然后我把主服务器的10001 10002 10003的进程全部kill了

[root@lys2 magent]# netstat -ulpnt | egrep "10001|10002|10003" | grep LISTEN | awk '{print $7}' | awk -F /  '{print $1}' | xargs kill
[root@lys2 magent]# netstat -unlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 0.0.0.0:60734               0.0.0.0:*                   LISTEN      1313/rpc.statd      
tcp        0      0 192.168.144.101:12000       0.0.0.0:*                   LISTEN      16346/magent        
tcp        0      0 127.0.0.1:9000              0.0.0.0:*                   LISTEN      1479/php-fpm        
tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      1291/rpcbind        
tcp        0      0 192.168.144.101:10004       0.0.0.0:*                   LISTEN      16330/memcached     
tcp        0      0 192.168.144.101:10005       0.0.0.0:*                   LISTEN      16338/memcached     

再在magent的端口上get key

并不影响取值。不过如果备用服务器也死了的话,就无力了,

集群搭建到此全部完成!

报错解决:

make

错误1:

    gcc -lrt -Wall -g -O2 -I/usr/local/include -m64 -c -o magent.o magent.c

    magent.c: In function ‘writev_list’:

    magent.c:729: error: ‘SSIZE_MAX’ undeclared (first use in this function)

    magent.c:729: error: (Each undeclared identifier is reported only once

    magent.c:729: error: for each function it appears in.)

    make: *** [magent.o] Error 1

解决办法:

vi ketama.h

在开头加入

   

#ifndef SSIZE_MAX

# define SSIZE_MAX      32767

#endif

错误2:

    gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o magent.o magent.c

    gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o ketama.o ketama.c

    gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o /usr/lib64/libevent.a /usr/lib64/libm.a

    /usr/lib64/libevent.a(event.o): In function `gettime’:

    (.text+0×449): undefined reference to `clock_gettime’

    /usr/lib64/libevent.a(event.o): In function `event_base_new’:

    (.text+0x72a): undefined reference to `clock_gettime’

    collect2: ld returned 1 exit status

    make: *** [magent] Error 1

解决办法

vim Makefile

   

CFLAGS = -Wall -g -O2 -I/usr/local/include $(M64)

改为:   

CFLAGS = -lrt -Wall -g -O2 -I/usr/local/include $(M64)


错误3:centos 6

[root@test magent]# make

gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o magent.o magent.c

gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o ketama.o ketama.c

gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o /usr/lib64/libevent.a /usr/lib64/libm.a

gcc: /usr/lib64/libm.a:没有那个文件或目录

make: *** [magent] 错误 1

解决办法

ln -s /usr/lib64/libm.so /usr/lib64/libm.a

注:有可能还会报错 gcc: /usr/lib64/libevent.a: 没有那个文件或目录

如果有,可执行

vi Makefile

找到 LIBS = /usr/lib64/libevent.a /usr/lib64/libm.a

修改 LIBS = /usr/libevent 的安装路径/libevent.a /usr/lib64/libm.a

例: LIBS = /usr/lib/libevent.a /usr/lib64/libm.a

查看magent是否安装成功

cd usr/bin/magent ./magent

please provide -s "ip:port" argument

 

memcached agent v0.6 Build-Date: Oct 15 2012 16:12:30

Usage:

  -h this message

  -u uid

  -g gid

  -p port, default is 11211. (0 to disable tcp support)

  -s ip:port, set memcached server ip and port

  -b ip:port, set backup memcached server ip and port

  -l ip, local bind ip address, default is 0.0.0.0

  -n number, set max connections, default is 4096

  -D don't go to background

  -k use ketama key allocation algorithm

  -f file, unix socket path to listen on. default is off

  -i number, set max keep alive connections for one memcached server, default is 20

  -v verbose

原文地址:https://www.cnblogs.com/liuyisai/p/5973858.html