使用memcached加速typecho

安装libmemcached

yum install cyrus-sasl-devel -y
wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz
tar zxf libmemcached-1.0.18.tar.gz
cd libmemcached-1.0.18
./configure --libdir=/usr/lib64
make
make install clean
ldconfig
ll /usr/lib64/libmemcached* -th
-rw-r--r-- 1 root root 212K Jan 14 19:01 /usr/lib64/libmemcachedutil.a
-rw-r--r-- 1 root root 2.9M Jan 14 19:01 /usr/lib64/libmemcached.a
-rwxr-xr-x 1 root root 1.1K Jan 14 19:01 /usr/lib64/libmemcachedutil.la
lrwxrwxrwx 1 root root   25 Jan 14 19:01 /usr/lib64/libmemcachedutil.so -> libmemcachedutil.so.2.0.0
lrwxrwxrwx 1 root root   25 Jan 14 19:01 /usr/lib64/libmemcachedutil.so.2 -> libmemcachedutil.so.2.0.0
-rwxr-xr-x 1 root root 111K Jan 14 19:01 /usr/lib64/libmemcachedutil.so.2.0.0
-rwxr-xr-x 1 root root  974 Jan 14 19:01 /usr/lib64/libmemcached.la
lrwxrwxrwx 1 root root   22 Jan 14 19:01 /usr/lib64/libmemcached.so -> libmemcached.so.11.0.0
lrwxrwxrwx 1 root root   22 Jan 14 19:01 /usr/lib64/libmemcached.so.11 -> libmemcached.so.11.0.0
-rwxr-xr-x 1 root root 1.3M Jan 14 19:01 /usr/lib64/libmemcached.so.11.0.0
lrwxrwxrwx 1 root root   25 Jan 14 18:31 /usr/lib64/libmemcachedutil.so.0 -> libmemcachedutil.so.0.0.0
lrwxrwxrwx 1 root root   21 Jan 14 18:31 /usr/lib64/libmemcached.so.2 -> libmemcached.so.2.0.0
-rwxr-xr-x 1 root root  64K Nov 12  2010 /usr/lib64/libmemcached.so.2.0.0
-rwxr-xr-x 1 root root 6.9K Nov 12  2010 /usr/lib64/libmemcachedutil.so.0.0.0

安装php-memcached

/production/server/php/bin/phpize
./configure --with-php-config=/production/server/php/bin/php-config --enable-memcached --enable-memcached-json
make -j2
make install clean

Installing shared extensions:     /production/server/php/lib/php/extensions/no-debug-non-zts-20131226/
find . -name *.gcno -o -name *.gcda | xargs rm -f
find . -name *.lo -o -name *.o | xargs rm -f
find . -name *.la -o -name *.a | xargs rm -f
find . -name *.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
rm -f libphp.la       modules/* libs/*

打开

vim php/etc/php.ini

# 添加以下配置
[memcached]
extension=memcached.so

sbin/php-fpm -t
[14-Jan-2018 19:13:55] NOTICE: configuration file /production/server/php/etc/php-fpm.conf test is successful
service php-fpm reload
/production/server/php/bin/php -m | grep memcached
memcached

安装配置memcached

yum install memcached -y
diff /etc/sysconfig/memcached /etc/sysconfig/memcached.ori
5c5
< OPTIONS="-l 127.0.0.1"
---
> OPTIONS=""

安装扩展

git clone https://github.com/phpgao/TpCache.git

CentOS6.x安装memcached-1.5.x

一、系统及安装说明

系统:CentOS6.x_x64,memcached-1.5.3。memcached官方下载地址 http://www.memcached.org/files/memcached-1.5.3.tar.gz。libevent 库:https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz

二、开始安装

1>首先yum安装gcc

yum install -y wget gcc

2>安装源码libevent库

#wget https://github.com/downloads/libevent/libevent/libevent-2.0.21-stable.tar.gz
#tar zxvf libevent-2.0.21-stable.tar.gz
#./configure --prefix=/usr/local/libevent
#make && make install

检查是否安装成功

#输入: ls -al /usr/local/libevent/lib | grep libevent
#如果输出为下所示则表示安装成功
lrwxrwxrwx 1 root root      21 Dec  4 18:08 libevent-2.0.so.5 -> libevent-2.0.so.5.1.9
-rwxr-xr-x 1 root root  968442 Dec  4 18:08 libevent-2.0.so.5.1.9
-rw-r--r-- 1 root root 1571130 Dec  4 18:08 libevent.a
lrwxrwxrwx 1 root root      26 Dec  4 18:08 libevent_core-2.0.so.5 -> libevent_core-2.0.so.5.1.9
-rwxr-xr-x 1 root root  585057 Dec  4 18:08 libevent_core-2.0.so.5.1.9
-rw-r--r-- 1 root root  977914 Dec  4 18:08 libevent_core.a
-rwxr-xr-x 1 root root     985 Dec  4 18:08 libevent_core.la
lrwxrwxrwx 1 root root      26 Dec  4 18:08 libevent_core.so -> libevent_core-2.0.so.5.1.9
lrwxrwxrwx 1 root root      27 Dec  4 18:08 libevent_extra-2.0.so.5 -> libevent_extra-2.0.so.5.1.9
-rwxr-xr-x 1 root root  404772 Dec  4 18:08 libevent_extra-2.0.so.5.1.9
-rw-r--r-- 1 root root  593288 Dec  4 18:08 libevent_extra.a
-rwxr-xr-x 1 root root     992 Dec  4 18:08 libevent_extra.la
lrwxrwxrwx 1 root root      27 Dec  4 18:08 libevent_extra.so -> libevent_extra-2.0.so.5.1.9
-rwxr-xr-x 1 root root     950 Dec  4 18:08 libevent.la
lrwxrwxrwx 1 root root      29 Dec  4 18:08 libevent_openssl-2.0.so.5 -> libevent_openssl-2.0.so.5.1.9
-rwxr-xr-x 1 root root   94209 Dec  4 18:08 libevent_openssl-2.0.so.5.1.9
-rw-r--r-- 1 root root  131836 Dec  4 18:08 libevent_openssl.a
-rwxr-xr-x 1 root root    1021 Dec  4 18:08 libevent_openssl.la
lrwxrwxrwx 1 root root      29 Dec  4 18:08 libevent_openssl.so -> libevent_openssl-2.0.so.5.1.9
lrwxrwxrwx 1 root root      30 Dec  4 18:08 libevent_pthreads-2.0.so.5 -> libevent_pthreads-2.0.so.5.1.9
-rwxr-xr-x 1 root root   18462 Dec  4 18:08 libevent_pthreads-2.0.so.5.1.9
-rw-r--r-- 1 root root   18702 Dec  4 18:08 libevent_pthreads.a
-rwxr-xr-x 1 root root    1013 Dec  4 18:08 libevent_pthreads.la
lrwxrwxrwx 1 root root      30 Dec  4 18:08 libevent_pthreads.so -> libevent_pthreads-2.0.so.5.1.9
lrwxrwxrwx 1 root root      21 Dec  4 18:08 libevent.so -> libevent-2.0.so.5.1.9

3>下载安装memcached

#wget 
#tar -zxvf  memcached-1.5.3.tar.gz
#./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent
#make && make install
#ln -s /usr/local/memcached/bin/memcached /usr/local/bin   #建立软连接

三、编辑脚本加入启动项

1>脚本

vim cat /etc/init.d/memcached
#!/bin/sh
#
# memcached:    MemCached Daemon
#
# chkconfig:    - 90 25
# description:  MemCached Daemon
# Source function library.
# Author: pkey san 2015/12/07
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network
prog=memcached
pidfile=${PIDFILE-/var/run/memcached.pid}
start()
{
        echo -n $"Starting memcached: "
        daemon --pidfile=${pidfile} /usr/local/bin/memcached -u daemon -d -m 512 -l 127.0.0.1 -c 4096 -p 11211
        echo `ps aux |grep memcached |grep 11211 |grep -v grep |awk '{print $2}'` >$pidfile
        echo
}
stop()
{
        echo -n $"Shutting down memcached: "
        killproc  $prog
        echo
}
rh_status(){
status -p ${pidfile} $prog
}
[ -f /usr/local/bin/memcached ] || exit 0
# See how we were called.
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        rh_status
        ;;
  restart|reload)
        stop
        start
        ;;
  *)
        echo $"Usage: $0 {start|stop|status|restart|reload|}"
        exit 1
esac
exit 0

2>解释说明

daemon --pidfile=${pidfile} /usr/local/bin/memcached -u daemon -d -m 512 -l 127.0.0.1 -c 4096 -p 11211     

-p memcached监听的TCP端口
-l 监听的ip地址,127.0.0.1是本机,当然也可以写上你的服务器IP,如:10.0.0.10,这是我服务器的IP地址,如果你需要多个服务器都能够读取这台memcached的缓存数据,那么就必须设定这个ip
-d 以daemon方式运行,将程序放入后台
-u memcached的运行用户
-P memcached的pid文件路径
-m memcached可以使用的最大内存数量
-c memcached同时可以接受的最大的连接数
如果你希望以socket方式来访问memcached,那么在启动的时候就必须去掉 -l和-p参数,并加上-s参数:
-s memcached的socket文件路径

3>添加开机启动

#chmod +x /etc/init.d/memcached
#chkconfig --add memcached
#chkconfig memcached on
#service memcached start|stop|restart|reload|status

四、编译配置(第二种启动方式)

#安装好之后
ln -s /usr/local/memcached/bin/memcached /usr/bin/memcached
/bin/cp scripts/memcached.sysv /etc/init.d/memcached
sed -i 's@^USER=.*@USER=root@' /etc/init.d/memcached
sed -i 's@chown@#chown@' /etc/init.d/memcached
sed -i 's@/var/run/memcached/memcached.pid@/var/run/memcached.pid@' /etc/init.d/memcached
sed -i 's@^prog=.*@prog="/usr/local/memcached/bin/memcached"@' /etc/init.d/memcached #前面有软链接,这里可以省略
chmod +x /etc/init.d/memcached
chkconfig --add memcached
chkconfig memcached on

此种方式也可以加到启动项里。

配置Memcached禁止公网访问

1. 修改memcached配置文件,添加OPTIONS的-l 127.0.0.1参数

    [root@iZbp include]# vim /etc/init.d/memcached
     11 PORT=11211
     12 USER=memcached
     13 MAXCONN=1024
     14 CACHESIZE=984
     15 OPTIONS="-l 127.0.0.1"
     16 DAEMON=/usr/local/memcached/bin/memcached

重启memcached服务

    [root@iZbp include]# service memcached restart
    Stopping memcached:                                        [  OK  ]
    Starting memcached:                                        [  OK  ]

2. 配置防火规则,仅仅允许本机的tcp、udp访问memcached的11211端口,拦截外部访问

accept规则

    # iptables -A INPUT -p tcp -s 127.0.0.1 --dport 11211 -j ACCEPT
    # iptables -A INPUT -p udp -s 127.0.0.1 --dport 11211 -j ACCEPT

drop规则

    # iptables -I INPUT -p tcp --dport 11211 -j DROP
    # iptables -I INPUT -p udp --dport 11211 -j DROP

保存规则并重启 iptables

    # service iptables save
    # service iptables restart

3. 办公电脑本机cmd命令行测试是否可以远程访问:

    telnet x.x.x.x 11211

提示11211端口连接失败,则表示配置成功,Server禁止远程访问memcached。

MEMCACHED的时间设置

1、过期时间限制

memcached的过期时间并不能随便设置,有一个最大时限就是30天,若超过30天后,存储时返回true,但是在取数据的时候取不到。(在取数据的时候才去做验证,看看数据是否失效)
说到这个过期时间了,就不得不说说memcached的缓存失效策略:
memcached的缓存失效策略是LRU(最近最少使用)加上到期失效策略。当向memcached存储数据时,你可能会设置一个过期时间,可以是永久也可以是一段时间,但是如果一旦给memcached分配的内存使用完毕,则首先会替换掉已失效的数据,其次是最近最少使用的数据。

2、存储限制

键被限制在 250 字符之内。数据项不能超过 1M (这个值由其内存分配机制决定的),因为这是最大的块( slab )值。如果对数据超过1M的值进行set,则会返回FALSE。
memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题.

3、访问限制

最大同时连接数200.

linux服务器下如何查看memcached的运行情况

查看memcached的运行情况有两种办法:

方法一、登录服务器通过命令查询

通过SSL登录服务器,在命令行输入:

echo stats | nc 127.0.0.1 11211

能看到如下内容:

未分类

重点关注两行数据即可:

STAT get_hits xxxx

命中了多少次缓存,也就是从 Memcached 缓存中成功获取数据的次数

STAT get_misses xxxx

没有命中的次数

方法二、使用memcached官方的探针

具体方法参见: https://www.liangshare.com/linux/8340.html

安装探针之后,访问探针页面,能看到如下信息:

未分类

其中右边长方形的柱形图,绿色表示命中率,橘色表示未命中率。

Redis与Memcached的区别

传统MySQL+ Memcached架构遇到的问题
  
实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:

  1. MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。
      
  2. Memcached与MySQL数据库数据一致性问题。
      
  3. Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。
      
  4. 跨机房cache同步问题。

众多NoSQL百花齐放,如何选择
  
最近几年,业界不断涌现出很多各种各样的NoSQL产品,那么如何才能正确地使用好这些产品,最大化地发挥其长处,是我们需要深入研究和思考的问题,实际归根结底最重要的是了解这些产品的定位,并且了解到每款产品的tradeoffs,在实际应用中做到扬长避短,总体上这些NoSQL主要用于解决以下几种问题

  1. 少量数据存储,高速读写访问。此类产品通过数据全部in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。
      
  2. 海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。
      
  3. 这方面最具代表性的是dynamo和bigtable 2篇论文所阐述的思路。前者是一个完全无中心的设计,节点之间通过gossip方式传递集群信息,数据保证最终一致性,后者是一个中心化的方案设计,通过类似一个分布式锁服务来保证强一致性,数据写入先写内存和redo log,然后定期compat归并到磁盘上,将随机写优化为顺序写,提高写入性能。
      
  4. Schema free,auto-sharding等。比如目前常见的一些文档数据库都是支持schema-free的,直接存储json格式数据,并且支持auto-sharding等功能,比如mongodb。

面对这些不同类型的NoSQL产品,我们需要根据我们的业务场景选择最合适的产品。
  
Redis适用场景,如何正确的使用
  
前面已经分析过,Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?

如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:

  1. Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

  2. Redis支持数据的备份,即master-slave模式的数据备份。

  3. Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

抛开这些,可以深入到Redis内部构造去观察更加本质的区别,理解Redis的设计。

在Redis中,并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别。Redis只会缓存所有的 key的信息,如果Redis发现内存的使用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计 算出哪些key对应的value需要swap到磁盘。然后再将这些key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得Redis可以 保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的key,毕竟这些数据是不会进行swap操作的。同时由于Redis将内存 中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以如果更新需要swap的数据,Redis将阻塞这个 操作,直到子线程完成swap操作后才可以进行修改。

使用Redis特有内存模型前后的情况对比:

VM off: 300k keys, 4096 bytes values: 1.3G used
VM on:  300k keys, 4096 bytes values: 73M used
VM off: 1 million keys, 256 bytes values: 430.12M used
VM on:  1 million keys, 256 bytes values: 160.09M used
VM on:  1 million keys, values as large as you want, still: 160.09M used

当 从Redis中读取数据的时候,如果读取的key对应的value不在内存中,那么Redis就需要从swap文件中加载相应数据,然后再返回给请求方。 这里就存在一个I/O线程池的问题。在默认的情况下,Redis会出现阻塞,即完成所有的swap文件加载后才会相应。这种策略在客户端的数量较小,进行 批量操作的时候比较合适。但是如果将Redis应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。所以Redis运行我们设置I/O线程 池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。

如果希望在海量数据的环境中使用好Redis,我相信理解Redis的内存设计和阻塞的情况是不可缺少的。

Linux – 将memcached注册为服务

1、编写脚本

编写脚本文件如下(memcached):

#!/bin/sh
#
# memcached: Start/Stop/Restart memcached
# chkconfig: 35 33 84
# description: memcached server
MEMCACHED=/usr/local/bin/memcached
# memcached 分配的内存大小,单位M
MEMSIZE=128
USER=nobody

# memcached使用的端口
PORT01=11211
# 每个memcache 提供的最大连接数
MAXCONN=1024
# 每个memcache 的进程ID
PID01=/var/run/memcached/memcached$PORT01.pid
RETVAL=0
prog="memcached"

start() {
         echo -n $"Starting $prog: "
         $MEMCACHED -d -m $MEMSIZE -u $USER -p $PORT01 -c $MAXCONN -P $PID01
     if [ $? -eq 0 ];then
            echo "memcacheds$PORT01 servers is start ok..."
         else
            echo "memcacheds$PORT01 server not runing......"
         fi

        }

stop() {

      for i in $PID01
      do 
       kill `cat $i`
       rm -f $i
           echo  $"Stopping $prog: "
      done

     }

# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|restart}"
;;
esac
exit $RETVAL

2、将其放入/etc/init.d/目录下

3、为文件赋予被执行的权限

chmod /etc/init.d/memcached

4、将memcached加入chkconfig管理列表

执行命令:

chkconfig --add memcached

chkconfig memcached on

5、启动memcached服务

service memcached start

阿里云centos7.3编译安装NGINX+PHP7+MariaDB+MEMCACHED

一、安装前准备

  • 修改默认主机名称
[root@iZuf60c5bxd15kr9gycvv6Z ~]# hostnamectl set-hostname centos7
[root@iZuf60c5bxd15kr9gycvv6Z ~]# reboot
[root@iZuf60c5bxd15kr9gycvv6Z ~]# yum update
  • 安装依赖库
[root@centos7 ~]# yum -y install libaio libaio-devel bison bison-devel zlib-devel openssl openssl-devel ncurses ncurses-devel libcurl-devel libarchive-devel boost boost-devel lsof wget gcc gcc-c++ make cmake perl kernel-headers kernel-devel pcre-devel

二、删除系统默认数据库配置文件

  • 查询
[root@centos7 ~]# find -H /etc/ | grep my.c
/etc/my.cnf
/etc/my.cnf.d
/etc/my.cnf.d/mysql-clients.cnf
/etc/pki/tls/certs/renew-dummy-cert
/etc/pki/tls/certs/make-dummy-cert
  • 删除
[root@centos7 ~]# rm -rf /etc/my.cnf /etc/my.cnf.d /etc/my.cnf.d/mysql-clients.cnf
  • 确认
[root@centos7 ~]# find -H /etc/ | grep my.c
/etc/pki/tls/certs/renew-dummy-cert
/etc/pki/tls/certs/make-dummy-cert

三、卸载系统自带mariadb-libs

  • 查询
[root@centos7 ~]# rpm -qa|grep mariadb-libs
mariadb-libs-5.5.52-1.el7.x86_64
  • 删除
[root@centos7 ~]# rpm -e mariadb-libs-5.5.52-1.el7.x86_64 --nodeps

四、安装MariaDB数据库

  • 下载安装包
[root@centos7 ~]# cd /usr/local/src
[root@centos7 src]# wget https://downloads.mariadb.org/interstitial/mariadb-10.2.8/source/mariadb-10.2.8.tar.gz 
  • 解压
[root@centos7 src]# tar -zxvf mariadb-10.2.8.tar.gz
  • 创建数据库安装目录,数据存放目录,以及用户组、用户
# 创建mysql用户组
[root@centos7 mariadb-10.2.8]# groupadd -r mysql
# 创建mysql用户
[root@centos7 mariadb-10.2.8]# useradd -r -g mysql -s /sbin/nologin -d /usr/local/mysql -M mysql
# 创建安装目录
[root@centos7 mariadb-10.2.8]# mkdir -p /usr/local/mysql
# 创建数据存放目录
[root@centos7 mariadb-10.2.8]# mkdir -p /data/mysql
# 赋以mysql用户读写权限
[root@centos7 mariadb-10.2.8]# chown -R mysql:mysql /data/mysql
  • 编译安装
[root@centos7 mariadb-10.2.8]# cd /usr/local/src/mariadb-10.2.8
# 输入以下编译参数
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql 
-DMYSQL_DATADIR=/data/mysql 
-DSYSCONFDIR=/etc 
-DWITHOUT_TOKUDB=1 
-DWITH_INNOBASE_STORAGE_ENGINE=1 
-DWITH_ARCHIVE_STPRAGE_ENGINE=1 
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 
-DWIYH_READLINE=1 
-DWIYH_SSL=system 
-DVITH_ZLIB=system 
-DWITH_LOBWRAP=0 
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock 
-DDEFAULT_CHARSET=utf8 
-DDEFAULT_COLLATION=utf8_general_ci

# 如果编译失败请删除CMakeCache.txt
[root@centos7 mariadb-10.2.8]# rm -f CMakeCache.txt
# 让指令重新执行,否则每次读取这个文件,命令修改正确也是报错
# cmake没问题,可以编译并且安装了

# 开始安装,这个过程比较久,跟据电脑配制不同可能会有10-30分钟
[root@centos7 mariadb-10.2.8]# make && make install
  • 导入mysql系统表
[root@centos7 mariadb-10.2.8]# cd /usr/local/mysql/
[root@localhost mysql]# scripts/mysql_install_db --user=mysql --datadir=/data/mysql
  • 复制配制文件
[root@localhost ~]# cd /usr/local/mysql/
[root@localhost mysql]# cp support-files/my-large.cnf /etc/my.cnf
  • 编写快捷启动脚本
[root@centos7 mysql]# vi /lib/systemd/system/mysql.service
# --------------------------------------------------------------------------
# 输入以下代码
# --------------------------------------------------------------------------
[Unit]
Description=MySQL Community Server
After=network.target

[Service]
User=mysql
Group=mysql
Type=forking
PermissionsStartOnly=true
PIDFile=/data/mysql/centos7.pid
ExecStart=/usr/local/mysql/support-files/mysql.server start
ExecReload=/usr/local/mysql/support-files/mysql.server restart
ExecStop=/usr/local/mysql/support-files/mysql.server stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target
  • 设置开机启动
[root@centos7 mysql]# systemctl enable mysql.service
  • 其它命令说明
# 启动mysql
[root@centos7 mysql]# systemctl start mysql.service
# 停止mysql
[root@centos7 mysql]# systemctl stop mysql.service
# 重启mysql
[root@centos7 mysql]# systemctl restart mysql.service
# 如果提示:Job for mysql.service failed because the control process exited with error code. See "systemctl status mysql.service" and "journalctl -xe" for details.
# 请选结束mysql进程后再尝试执行上面的快捷操作
[root@centos7 mysql]# pkill -9 mysql
  • 配置环境变量(以便在任何目录下输入mysql命令)
# 创建独立环境变量文件
[root@localhost mysql]# touch /etc/profile.d/mysql.sh
# 写入变量值
[root@localhost mysql]# echo 'export PATH=$PATH:/usr/local/mysql/bin/' > /etc/profile.d/mysql.sh 
# 赋以执行权限
[root@localhost mysql]# chmod 0777 /etc/profile.d/mysql.sh 
# 刷新生效
[root@localhost mysql]# source /etc/profile.d/mysql.sh
  • 初始化MariaDB
# 运行MariaDB初始化脚本
[root@localhost mysql]# ./bin/mysql_secure_installation

# --------------------------------------------------------------------------
# 根据相关提示进行操作
# 以下提示:
# --------------------------------------------------------------------------
Enter current password for root (enter for none):    输入当前root密码(没有输入)
Set root password? [Y/n]                             设置root密码?(是/否)
New password:                                        输入新root密码
Re-enter new password:                               确认输入root密码
Password updated successfully!                       密码更新成功
Remove anonymous users? [Y/n]                        删除匿名用户?(是/否)
Disallow root login remotely? [Y/n]                  不允许root登录远程?(是/否)
Reload privilege tables now? [Y/n]                   现在重新加载权限表(是/否)

#全部完成!如果你已经完成了以上步骤,MariaDB安装现在应该安装完成。
  • 创建外部管理员帐号(根据需要,请尽量保证密码的复杂性避免数据库外泄)
[root@localhost mysql] mysql -uroot -p
# 根据提示输入密码
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;

五、安装NGINX

  • 下载安装包并解压
[root@localhost mysql]# cd /usr/local/src
[root@localhost src]# wget http://nginx.org/download/nginx-1.12.1.tar.gz
[root@localhost src]# tar -zxvf nginx-1.12.1.tar.gz
  • 创建NGINX安装目录,WEB存放目录,以及用户组、用户
# 创建nginx用户组
[root@centos7 src]# groupadd -r www
# 创建nginx用户
[root@centos7 src]# useradd -r -g www -s /sbin/nologin -d /usr/local/nginx -M www
# 创建安装目录
[root@centos7 src]# mkdir -p /usr/local/nginx
# 创建数据存放目录
[root@centos7 src]# mkdir -p /data/web
# 赋以mysql用户读写权限
[root@centos7 src]# chown -R www:www /data/web
  • 编译安装
[root@localhost src]# cd nginx-1.12.1
# 输入以下参数
./configure 
--prefix=/usr/local/nginx 
--without-http_memcached_module 
--user=www  
--group=www 
--with-http_stub_status_module 
--with-http_ssl_module 
--with-http_gzip_static_module

# 如果看到以下说明则编译成功
Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

# 开始安装
[root@localhost nginx-1.12.1]# make && make install
  • 尝试启动
[root@centos7 nginx-1.12.1]# /usr/local/nginx/sbin/nginx
# 如果未提示错误即代表安装成功
  • 编写快捷启动脚本
[root@centos7 nginx-1.12.1]# vi /lib/systemd/system/nginx.service
# --------------------------------------------------------------------------
# 输入以下代码
# --------------------------------------------------------------------------
[Unit]
Description=nginx
After=network.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true

[Install]
WantedBy=multi-user.target
  • 设置开机启动
[root@centos7 nginx-1.12.1]# systemctl enable nginx.service
  • 其它命令说明
# 启动nginx
[root@centos7 nginx-1.12.1]# systemctl start nginx.service
# 停止nginx
[root@centos7 nginx-1.12.1]# systemctl stop nginx.service
# 重启nginx
[root@centos7 nginx-1.12.1]# systemctl restart nginx.service
# 如果提示:Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
# 请选结束nginx进程后再尝试执行上面的快捷操作
[root@centos7 nginx-1.12.1]# pkill -9 nginx
  • 修改配NGINX配制文件
[root@centos7 php-7.1.9]# cd /usr/local/nginx/conf
[root@centos7 conf]# vi nginx.conf
# 修改如下代码
# --------------------------------------------------------------------------
#user  nobody;去除前面#号,并将用户改为www www
user www www;
# --------------------------------------------------------------------------
#pid        logs/nginx.pid; 去除前面的#号 
pid        logs/nginx.pid;
# --------------------------------------------------------------------------
去除前面的#号 如下
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
# --------------------------------------------------------------------------
# gzip  on;去除前面的#号并加上隐藏版号代码 
server_tokens off;
# --------------------------------------------------------------------------
index  index.html index.htm;后面加上index.php 默认页
index  index.html index.htm index.php;
# --------------------------------------------------------------------------
去下以下前面的#号并做如下修改
location ~ .php$ {
    root           html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    #fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
}
  • 最后张节介绍虚拟主机配制,以及memcache配制

七、安装PHP7

  • 下载安装包并解压
[root@centos7 nginx-1.12.1]# cd /usr/local/src
[root@centos7 src]# wget http://cn.php.net/distributions/php-7.1.9.tar.gz
[root@centos7 src]# tar -zxvf php-7.1.9.tar.gz
  • 安装必要的相关扩展
[root@centos7 src]# yum install libxml2 libxml2-devel openssl openssl-devel bzip2 bzip2-devel libcurl libcurl-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel gmp gmp-devel libmcrypt libmcrypt-devel readline readline-devel libxslt libxslt-devel
  • 编译安装
[root@localhost src]# cd php-7.1.9
# 输入以下参数
./configure 
--prefix=/usr/local/php 
--with-config-file-path=/usr/local/php/etc 
--enable-fpm 
--with-fpm-user=www  
--with-fpm-group=www 
--enable-inline-optimization 
--disable-debug 
--disable-rpath 
--enable-shared  
--enable-soap 
--with-libxml-dir 
--with-xmlrpc 
--with-openssl 
--with-mcrypt 
--with-mhash 
--with-pcre-regex 
--with-zlib 
--enable-bcmath 
--with-iconv 
--with-bz2 
--enable-calendar 
--with-curl 
--with-cdb 
--enable-dom 
--enable-exif 
--enable-fileinfo 
--enable-filter 
--with-pcre-dir 
--enable-ftp 
--with-gd 
--with-openssl-dir 
--with-jpeg-dir 
--with-png-dir 
--with-zlib-dir  
--with-freetype-dir 
--enable-gd-native-ttf 
--enable-gd-jis-conv 
--with-gettext 
--with-gmp 
--with-mhash 
--enable-json 
--enable-mbstring 
--enable-mbregex 
--enable-mbregex-backtrack 
--with-libmbfl 
--with-onig 
--enable-pdo 
--with-mysqli=mysqlnd 
--with-pdo-mysql=mysqlnd 
--with-zlib-dir 
--with-pdo-sqlite 
--with-readline 
--enable-session 
--enable-shmop 
--enable-simplexml 
--enable-sockets  
--enable-sysvmsg 
--enable-sysvsem 
--enable-sysvshm 
--enable-wddx 
--with-libxml-dir 
--with-xsl 
--enable-zip 
--enable-mysqlnd-compression-support 
--with-pear 
--enable-opcache

# 开始安装
[root@localhost php-7.1.9]# make && make install
  • 配置环境变量(以便在任何目录下输入php命令)
# 创建独立环境变量文件
[root@localhost php-7.1.9]# touch /etc/profile.d/php.sh
# 写入变量值
[root@localhost php-7.1.9]# echo 'export PATH=$PATH:/usr/local/php/bin/' > /etc/profile.d/php.sh 
# 赋以执行权限
[root@localhost php-7.1.9]# chmod 0777 /etc/profile.d/php.sh 
# 刷新生效
[root@localhost php-7.1.9]# source /etc/profile.d/php.sh
  • 配制php.ini
[root@centos7 php-7.1.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@centos7 php-7.1.9]# vi /usr/local/php/etc/php.ini
# 做以下修改(时区,不显示版本号,开启opcache缓存加速PHP)
# --------------------------------------------------------------------------
1.找到:;date.timezone =                               修改为:date.timezone = PRC
2.找到:expose_php = On                                   修改为:expose_php = Off
3.找到:opcache.enable=0                              修改为:opcache.enable=1
4.在 Dynamic Extensions 代码块中添加 zend_extension=opcache.so
  • 配置php-fpm
[root@centos7 php-7.1.9]# cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
[root@centos7 php-7.1.9]# cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf
[root@centos7 php-7.1.9]# cp sapi/fpm/init.d.php-fpm /usr/local/php/bin/php-fpm
[root@centos7 php-7.1.9]# chmod 0777 /usr/local/php/bin/php-fpm
  • 尝试启动
[root@centos7 php-7.1.9]# /usr/local/php/bin/php-fpm start
Starting php-fpm  done
# 如提示以上即表示安装成功
  • 编写快捷启动脚本
[root@centos7 php-7.1.9]# vi /lib/systemd/system/php-fpm.service
# --------------------------------------------------------------------------
# 输入以下代码
# --------------------------------------------------------------------------
[Unit]
Description=php-fpm
After=network.target

[Service]
Type=forking
PIDFile=/usr/local/php/var/run/php-fpm.pid
ExecStart=/usr/local/php/bin/php-fpm start
ExecReload=/usr/local/php/bin/php-fpm restart
ExecStop=/usr/local/php/bin/php-fpm stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target
  • 设置开机启动
[root@centos7 php-7.1.9]# systemctl enable php-fpm.service
  • 其它命令说明
# 启动php-fpm
[root@centos7 php-7.1.9]# systemctl start php-fpm.service
# 停止php-fpm
[root@centos7 php-7.1.9]# systemctl stop php-fpm.service
# 重启php-fpm
[root@centos7 php-7.1.9]# systemctl restart php-fpm.service
# 如果提示:Job for php-fpm.service failed because the control process exited with error code. See "systemctl status php-fpm.service" and "journalctl -xe" for details.
# 请选结束php-fpm进程后再尝试执行上面的快捷操作
[root@centos7 php-7.1.9]# pkill -9 php-fpm

八、NGINX虚拟主机配制

  • 打开配制文件
[root@centos7 php-7.1.9]# vi /usr/local/nginx/conf/nginx.conf
  • 在http{}节点尾加入以下代码
    ##############################################
    #LIANGZHI
    ##############################################
    server {
        listen          80;
        server_name     *.demo.com;
        root            /data/web/demo/www;
        access_log      /data/web/demo/log/access.log  main;
        error_log       /data/web/demo/log/error.log error;
        index           index.php;

        #THINKPHP伪静态
        location / {
            if (!-e $request_filename) {
                rewrite ^(.*)$ /index.php?s=$1 last;
                break;
            }
        }

        #解析PHP代码
        location ~ .php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

        #静态资源缓存1天
        location ~ .*.(gif|jpg|jpeg|png|bmp|ico|swf|js|css)$ {
            expires     1d;
            access_log  off;
        }

        #字体文件跨域问题
        location ~ .*.(eof|ttf|ttc|otf|eof|woff|woff2|svg)(.*){
            add_header Access-Control-Allow-Origin *;
        }
    }

九、安装PHP支持插件Memcache

[root@centos7 www]# cd /usr/local/src
[root@centos7 src]# wget http://memcached.org/files/memcached-1.5.1.tar.gz
[root@centos7 src]# tar -zxvf memcached-1.5.1.tar.gz
[root@centos7 src]# cd memcached-1.5.1
[root@centos7 memcached-1.5.1]# yum install libevent*
[root@centos7 memcached-1.5.1]# ./configure --prefix=/usr/local/memcached
[root@centos7 memcached-1.5.1]# make && make install
  • 编写快捷启动脚本
[root@centos7 memcached-1.5.1]# vi /usr/local/memcached/memcached
# 输入以下代码(启动参数请在下面的脚本中修改,如端口,最大内存)
#! /bin/sh
#
# chkconfig: - 55 45
# description:  The memcached daemon is a network memory cache service.
# processname: memcached
# config: /etc/sysconfig/memcached

# Source function library.
. /etc/rc.d/init.d/functions

PORT=11211
USER=root 
MAXCONN=1024
CACHESIZE=64
OPTIONS=""

if [ -f /etc/sysconfig/memcached ];then
    . /etc/sysconfig/memcached
fi

# Check that networking is up.
if [ "$NETWORKING" = "no" ]
then
    exit 0
fi

RETVAL=0

start () {
    echo "Starting memcached ..."
    # insure that /var/run/memcached has proper permissions
    chown $USER /usr/local/memcached/bin/memcached
    /usr/local/memcached/bin/memcached -d -p $PORT -u $USER -m $CACHESIZE -c $MAXCONN -P /var/run/memcached.pid $OPTIONS
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/memcached
}
stop () {
    echo "Stopping memcached ..."
    killproc memcached
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ] ; then
        rm -f /var/lock/subsys/memcached
        rm -f /var/run/memcached.pid
    fi
}

restart () {
    stop
    start
}

# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
    stop
    ;;
    status)
    status memcached
    ;;
    restart|reload)
    restart
    ;;
    condrestart)
    [ -f /var/lock/subsys/memcached ] && restart || :
    ;;
    *)
    echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}"
    exit 1
esac
  • 脚本执行权限
[root@localhost memcached-1.5.1]# chmod 0777 /usr/local/memcached/memcached
编写服务启动脚本
[root@centos7 memcached-1.5.1]# vi /lib/systemd/system/memcached.service
# --------------------------------------------------------------------------
# 输入以下代码
# --------------------------------------------------------------------------
[Unit]
Description=memcached
After=network.target

[Service]
Type=forking
PIDFile=/var/run/memcached.pid
ExecStart=/usr/local/memcached/memcached start
ExecReload=/usr/local/memcached/memcached restart
ExecStop=/usr/local/memcached/memcached stop
PrivateTmp=true

[Install]
WantedBy=multi-user.target
  • 设置开机启动
[root@centos7 memcached-1.5.1]# systemctl enable memcached.service
  • 其它命令说明
# 启动memcached
[root@centos7 memcached-1.5.1]# systemctl start memcached.service
# 停止memcached
[root@centos7 memcached-1.5.1]# systemctl stop memcached.service
# 重启memcached
[root@centos7 memcached-1.5.1]# systemctl restart memcached.service
# 如果提示:Job for memcached.service failed because the control process exited with error code. See "systemctl status memcached.service" and "journalctl -xe" for details.
# 请选结束memcached进程后再尝试执行上面的快捷操作
[root@centos7 memcached-1.5.1]# pkill -9 memcached
  • 为PHP增加memcache支持(官司网memcache-3.0.8暂时不支持PHP的编译)

官网memcache-3.0.8在编译的时候出现“php-smart_str.h”没有找到的错误!
但是我们可以在github里面找到pecl-memcache支持PHP7的分支,请按以下操作即可完成memcache中扩展安装

[root@centos7 memcached]# cd /usr/local/src/php-7.1.9/ext
# 如果已经安装git忽略yun install git
[root@centos7 memcached]# yum install git
[root@centos7 ext]# git clone https://github.com/websupport-sk/pecl-memcache memcache
[root@centos7 ext]# cd memcache
[root@centos7 ext]# yum install autoconf
[root@centos7 ext]# /usr/local/php/bin/phpize
[root@centos7 ext]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@centos7 ext]# make && make install
  • 修改php.ini
[root@centos7 ext]# vi /usr/local/php/etc/php.ini
# 在 Dynamic Extensions 代码块中添加如下扩展
extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20160303/memcache.so
  • 重启linux完成安装(或重启nginx php-fpm)
[root@centos7 ext]# reboot

启用memcached动态缓存加速wordpress

概述

扉启博客正在使用的是基于nginx的fastcgi纯静态缓存,这是将所有的动态HTML页面都缓存到硬盘文件,nginx针对http请求只处理静态内容,因此对服务器的开销很小,速度快。对于动态内容不多的站点,用这个方法能极大缓解cpu的负担,由nginx来高效地处理并发。

另一种缓存方式是基于memcached缓存动态内容,将数据库的数据缓存在内存中,下次需要的时候直接从内存中取数据,减少MySQL的访问次数,也加速了wordpress对网页的处理。这种方式直接从内存中存取数据,理论上比静态缓存的IO开销更小,但是由于memcached需要占用一定php资源,因此会对CPU带来一些额外的压力。

本文记述了在另一个站点上安装部署memcached的过程,最后测试这种方式的缓存的响应速度和并发处理能力。

未分类

安装memcached服务

网上有一些文章提供了memcached服务的安装方法,有的手动下载源码编译安装,这里采用军哥lnmp一键包插件安装简单的方法。在lnmp源代码目录下,运行addon.sh脚本安装memcached服务

./addons.sh install memcached

在随后出现的选项里选择2,也就是php-memcached的带d的版本,这个相对不带d的版本更新,性能更好。

编译安装完成以后,检查一下memcached的服务是否已经运行。

systemctl status memcached
memcached.service - LSB: memcached - Memory caching daemon
   Loaded: loaded (/etc/rc.d/init.d/memcached; bad; vendor preset: disabled)
   Active: active (running) since Fri 2017-08-18 14:38:00 CST; 1 weeks 0 days ago

然后检查php的memcached模块是否已经加载

php -m | grep memcached

可以新建一个php文件测一下缓存功能,将下面的代码保存为test.php文件。

<?php
$m = new Memcached();
$m->addServer( '127.0.0.1', 11211 );
$m->set( 'foo', 100 );
echo $m->get( 'foo' ) . "n";

运行php -f test.php,如果结果是100的话表明memcached正常运行。
都没问题的话,就可以进行下一步安装wordpress插件

安装wordpress的memcached插件

访问github项目下载插件文件object-cache.php

将下载好的文件放入wordpress网站目录的wp-content/下,此时wordpress已自动利用memcached缓存功能。

缓存HTML页面到内存

到前面这一步已经完成了数据库查询的动态缓存,如果想要进一步提高性能,还可以类似与wp supercache或fastcgi缓存一下将网站的页面静态化,只不过存储在memcached分配的内存中,而不是硬盘上的文件。

这里要用到的插件叫做batcache,代码的readme文件里解释了这个名称的由来。bat并不表示真的和蝙蝠有什么联系,而是正好发布前夕wp-supercache已经发布,为了不和其他缓存插件冲突而用了这个名字。

首先下载官方插件项目的代码包batcache,解压缩后得到了advanced-cache.php文件,将其放入wordpress网站目录的wp-content/下。

然后在wordpress站点根目录下,在wp-config.php文件内加入一行

define('WP_CACHE', true);

batcache相关的配置在advanced-cache.php中的batcache类中,查找下面这几行

var $max_age =  3600; // Expire batcache items aged this many seconds (zero to disable batcache)
var $remote  =    0; // Zero disables sending buffers to remote datacenters (req/sec is never sent)
var $times   =    2; // Only batcache a page after it is accessed this many times... (two or more)
var $seconds =  120; // ...in this many seconds (zero to ignore this and use batcache immediately)

在此将缓存有效期设为3600秒,也就是过1小时后缓存将重新生成。在120秒内,连续访问该页面2次将生成缓存。具体数字可以根据实际情况修改。

测试一下,将网站的某个页面刷新几次,在Chrome的开发者工具源码页,注意查看body元素的footer里面,包含了下面一段,表明当前页面是由memached缓存生成的。

<!--
    generated in 0.349 seconds
    28088 bytes batcached for 300 seconds
-->

并发测试

经过几次测试,发现通过这种缓存方案,托管于linode的站点大概最多能承担每秒150个并发请求,再多就超过error rate的阈值了。

未分类

  • 平均响应时间170ms
  • 平均每秒并发数量170个
  • error rate为0.8%
  • 服务器的CPU使用率开始最高90%,后来稳定在50%左右

总结

针对博客类型的小站,最好还是使用fastcgi的方案实现全静态化。如果动态类型较多,可以采用memcached缓存方案,但是并发处理能力没有fastcgi的好。

Memsniff:一款开源的memcached流量分析工具

背景介绍

在知名在线资源存储网站Box上,我们看到云服务已经经历了从一小撮应用服务器和数据库到高规格、高性能协作平台的转变。像大多数大型网络公司一样,Box也依赖于使用分布式缓存层来缓存经常访问的数据。

Box使用memcached(一个高性能的分布式内存对象缓存系统)每天为经常使用的数据对象提供数十万亿请求。然而,我们偶尔也会碰到某些数据对象的访问频率突然变得很高的现象(即出现热键,hot key),热键问题的诱因有很多,有可能是因为后台任务造成的,也有可能是因为应用程序处理不当,又或者是因为用户频繁的活动。

在下图中,我们可以看到几个memcached服务器其中一个网络带宽突然激增的现象(棕色曲线部分表示出现了热键问题)。这种现象会导致数据服务器带宽负载过重,影响缓存服务器提供高性能的服务。

未分类

在此次事件中,很难确定是哪些数据导致了这一问题。因为与数据库不同的是,许多缓存系统为了高效地处理请求,几乎不提供日志,所以很难进行判定。这时就需要一种不同的方法来识别热键。

如今,Box正式推出了memsniff——一款强大的memcached开源流量分析工具。它通过检查memcached服务器上的网络数据包,来分析数据键并提供各个数据键的实时统计信息,包括数据大小、请求速率以及占用的带宽。如此一来,就可以在不影响memcached服务器的情况下识别热键。

Memsniff操作步骤

作为一款强大的、高效和可扩展的开源工具,memsniff的灵感来自于Etsy的mctop和Tumblr的memkeys。它可以在大量流量负载的情况下处理几乎所有的网络数据包(超过99.99%)。此外,它使用golang的简单多线程原语,并在不占用太多CPU或内存的情况下发挥高性能,具体参见下图:

未分类

安装memsniff

memsniff使用了标准的 golang工具链(toolchain),这使得安装过程变得更为便捷。如果你已经安装了golang工具链,并设置了GOPATH环境变量,那么可以通过如下的命令来构建memsniff:

$ go get github.com/box/memsniff

$ go build github.com/box/memsniff

使用memsniff

memsniff需要超级用户权限来捕获大多数操作系统上的网络数据包,-i 参数是必备的,需要用它来指定网卡接口。使用示例:

$ sudo memsniff -i eth0

memsniff还具有从tcpdump的数据包转储文件中读取数据的能力。

$ sudo memsniff -r eth0.pcap

参见memsniff的GitHub主页,了解其他更多的命令行选项。

memsniff的工作原理

未分类

  • 使用 GoPacket 从 libpcap 主线程上捕获原始数据包;

  • 批量的原始数据包被发送到解析工具中,随后,工作人员开始对原始数据包中的memcached协议部分进行解析,来寻找GET请求的响应消息。从中提取返回值的数据键和数据项大小;

  • 提取出来的响应概要被发送给分析工具,然后,根据数据键进行哈希分区,并发送给工作线程。每一个工作线程持有一个分区;

  • 响应来自UI的定期请求,分析工具将各个工作线程的报告合并到单个排序的列表中,并将其展示给UI用户。

memsniff的性能

在一台运行Intel Xeon E5-2470处理器的服务器上,每秒钟可以处理约35万个memcached请求,具体数据如下:

  • 使用了4-5个核(约20个线程,每个CPU使用率约为20%);

  • 100%的数据包处理;

  • 展示99.99%的数据包,表明启动时丢弃了一小部分数据包;

  • 在发生热键问题,网络接口(NIC)出现饱和时,仍然可以处理99.9%的数据包;

  • 使用40MB左右的堆内存(heap);

  • 100MB左右的RSS(可通过GOGC调节);

  • 平均GC停顿:0.6毫秒;

  • 最大GC停顿:2.0毫秒;

memsniff愿景/路线图

我们期待memsniff将以下面的方式进一步发展:

深化功能

  • TCP stream重组:get-miss跟踪、支持二进制协议,支持redis;

  • 触发器(例如,当热键出现时发出警报);

  • 当满足指定条件时自动记录日志到磁盘(例如集成或单个数据键的流量超过阈值);

  • 能够将数据收集限制为与过滤器匹配的数据键;

  • 跟踪单个请求/响应周期;

  • 根据客户端IP限制流量;

改进功能

  • 支持非默认memcached服务器端口;

  • 支持其他替代的排序方式;

  • 支持同时监听多个服务器端口的流量;

  • 支持GET以外的其他操作;

  • 视图过滤;

  • 创建稳定的报告格式,并输出到磁盘;

  • 为其他格式的包(如deb、rpm等)提供构建支持;