对于Linux的学习,一直都是需要才学习,基本上命令都忘记的差不多了。
因为之前的一个部署在服务器上的系统一直出现数据库连接过多,需要频繁的重启服务器,通过分析请求日志,发现一天的请求在2M-3M之间。
听从建议,从三方面入手:1.缓存;2.连接池;3.SQL语句优化
缓存
缓存采用Memcached
具体做法:
[root@***** src]# lsb_release -a
LSB Version: :core-3.1-amd64:core-3.1-ia32:core-3.1-noarch:graphics-3.1-amd64:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: RedHatEnterpriseServer
Description: Red Hat Enterprise Linux Server release 5.5 (Tikanga)
Release: 5.5
Codename: Tikanga
确定是:Red Hat Enterprise Linux Server release 5.5
安装libevent
由于memcached是基于libevent的,因此需要安装libevent,libevent-devel
[root@***** src]# ls -al /usr/lib | grep libevent
结果显示没有安装libevent,那还说是, 安装呗。
[root@***** src]# yum install libevent libevent-devel -y
Loaded plugins: rhnplugin, security
This system is not registered with RHN.
RHN support will be disabled.
Setting up Install Process
Package libevent-1.4.13-1.x86_64 already installed and latest version
Resolving Dependencies
--> Running transaction check
---> Package libevent.i386 0:1.4.13-1 set to be updated
---> Package libevent-devel.i386 0:1.4.13-1 set to be updated
---> Package libevent-devel.x86_64 0:1.4.13-1 set to be updated
--> Finished Dependency Resolution
……此处省略一堆
Installed:
libevent.i386 0:1.4.13-1 libevent-devel.i386 0:1.4.13-1 libevent-devel.x86_64 0:1.4.13-1
Complete!
再次查看,显示已经安装完毕。
# ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root root 21 07-12 10:53 libevent-1.4.so.2 -> libevent-1.4.so.2.1.3
-rwxr-xr-x 1 root root 104804 2009-12-16 libevent-1.4.so.2.1.3
-rw-r--r-- 1 root root 130350 2009-12-16 libevent.a
lrwxrwxrwx 1 root root 26 07-12 10:53 libevent_core-1.4.so.2 -> libevent_core-1.4.so.2.1.3
-rwxr-xr-x 1 root root 34820 2009-12-16 libevent_core-1.4.so.2.1.3
-rw-r--r-- 1 root root 44868 2009-12-16 libevent_core.a
lrwxrwxrwx 1 root root 26 07-12 10:53 libevent_core.so -> libevent_core-1.4.so.2.1.3
lrwxrwxrwx 1 root root 27 07-12 10:53 libevent_extra-1.4.so.2 -> libevent_extra-1.4.so.2.1.3
-rwxr-xr-x 1 root root 84180 2009-12-16 libevent_extra-1.4.so.2.1.3
-rw-r--r-- 1 root root 102266 2009-12-16 libevent_extra.a
lrwxrwxrwx 1 root root 27 07-12 10:53 libevent_extra.so -> libevent_extra-1.4.so.2.1.3
lrwxrwxrwx 1 root root 21 07-12 10:53 libevent.so -> libevent-1.4.so.2.1.3
安装Memcached
下载并解压memcached-1.4.5
cd /root
wget http://memcached.googlecode.com/files/memcached-1.4.15.tar.gz
tar -xvzf memcached-1.4.5.tar.gz
编译安装memcached-1.4.5
cd memcached-1.4.5
./configure --prefix=/etc/memcached
make
make install
配置环境变量
进入用户宿主目录,编辑.bash_profile,为系统环境变量LD_LIBRARY_PATH增加新的目录,需要增加的内容如下:
vi .bash_profile
MEMCACHED_HOME=/etc/memcached
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$MEMCACHED_HOME/lib
刷新用户环境变量:
source .bash_profile
vi memcached,脚本内容如下:
#!/bin/sh
#
# Startup script for the server of memcached
#
# processname: memcached
# pidfile: /etc/memcached/memcached.pid
# logfile: /etc/memcached/memcached_log.txt
# memcached_home: /etc/memcached
# chkconfig: 35 21 79
# description: Start and stop memcached Service
# Source function library
. /etc/rc.d/init.d/functions
RETVAL=0
prog="memcached"
basedir=/etc/memcached
cmd=${basedir}/bin/memcached
pidfile="$basedir/${prog}.pid"
#logfile="$basedir/memcached_log.txt"
# 设置memcached启动参数
ipaddr="***.***.***.***" # 绑定侦听的IP地址
port="port" # 服务端口
username="root" # 运行程序的用户身份
max_memory=64 # default: 64M | 最大使用内存
max_simul_conn=1024 # default: 1024 | 最大同时连接数
#maxcon=51200
#growth_factor=1.3 # default: 1.25 | 块大小增长因子
#thread_num=6 # default: 4
#verbose="-vv" # 查看详细启动信息
#bind_protocol=binary # ascii, binary, or auto (default)
start() {
echo -n $"Starting service: $prog"
$cmd -d -m $max_memory -u $username -l $ipaddr -p $port -c $max_simul_conn -P $pidfile
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
}
stop() {
echo -n $"Stopping service: $prog "
run_user=`whoami`
pidlist=`ps -ef | grep $run_user | grep memcached | grep -v grep | awk '{print($2)}'`
for pid in $pidlist
do
# echo "pid=$pid"
kill -9 $pid
if [ $? -ne 0 ]; then
return 1
fi
done
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
#reload)
# reload
# ;;
restart)
stop
start
;;
#condrestart)
# if [ -f /var/lock/subsys/$prog ]; then
# stop
# start
# fi
# ;;
status)
status memcached
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac
exit $RETVAL
设置脚本可被执行:
chmod +x memcached
设置memcached随系统启动
chkconfig --add memcached
chkconfig --level 35 memcached on
启动memcached
service memcached start
//启动的时候实际上是调用了下面的这个命令,以守护进程的方式来启动memcached
/etc/memcached/bin/memcached -d -m 64 -u root -l 192.168.1.201
\-p 11211 -c 1024 -P /etc/memcached/memcached.pid
查看memcached是否启动
[root@****** init.d]# ps -ef | grep memcached
root 19347 1 0 11:42 ? 00:00:00 /etc/memcached/bin/memcached -d -m 64 -u root -l ***.***.***.*** -p 11211 -c 1024 -P /etc/memcached/memcached.pid
root 24854 1 0 14:09 ? 00:00:00 /etc/memcached/bin/memcached -d -m 64 -u root -p 11211 -c 1024 -P /etc/memcached/memcached.pid
root 24938 8274 0 14:09 pts/2 00:00:00 grep memcached
memcached命令参数解释
参数 | 参数解释及说明 |
-p <num> | 监听的端口 |
-l <ip_addr> | 连接的IP地址,,默认是本机。-l选项可以不使用,此时表示在所有网络接口地址上监听。建议是-l <ip_addr>指定一个内部网络IP地址,以避免成为外部网络攻击的对象 |
-d start | 启动memcached 服务 |
-d restart | 重起memcached 服务 |
-d stop|shutdown | 关闭正在运行的memcached 服务 |
-d install | 安装memcached 服务 |
-d uninstall | 卸载memcached 服务 |
-u <username> | 以<username>的身份运行 (仅在以root运行的时候有效) |
-m <num> | 最大内存使用,单位MB。默认64MB |
-M | 内存耗尽时返回错误,而不是删除项 |
-c <num> | 最大同时连接数,默认是1024 |
-f <factor> | 块大小增长因子,默认是1.25 |
-n <bytes> | 最小分配空间,key+value+flags默认是48 |
-h | 显示帮助 |
Memcache统计数据
Memcached有个stats命令,通过它可以查看Memcached服务的许多状态信息。使用方法如下:先在命令行直接输入telnet 主机名端口号,连接到memcached服务器,然后再连接成功后,输入stats 命令,即可显示当前memcached服务的状态信息。
比如在我本机测试如下:
stats
STAT pid 1552
STAT uptime 3792
STAT time 1262517674
STAT version 1.2.6
STAT pointer_size 32
STAT curr_items 1
STAT total_items 2
STAT bytes 593
STAT curr_connections 2
STAT total_connections 28
STAT connection_structures 9
STAT cmd_get 3
STAT cmd_set 2
STAT get_hits 2
STAT get_misses 1
STAT evictions 0
STAT bytes_read 1284
STAT bytes_written 5362
STAT limit_maxbytes 67108864
STAT threads 1
END
这里显示了很多状态信息,下边详细解释每个状态项:
1. pid: memcached服务进程的进程ID
2. uptime: memcached服务从启动到当前所经过的时间,单位是秒。
3. time: memcached服务器所在主机当前系统的时间,单位是秒。
4. version: memcached组件的版本。这里是我当前使用的1.2.6。
5. pointer_size:服务器所在主机操作系统的指针大小,一般为32或64.
6. curr_items:表示当前缓存中存放的所有缓存对象的数量。不包括目前已经从缓存中删除的对象。
7. total_items:表示从memcached服务启动到当前时间,系统存储过的所有对象的数量,包括目前已经从缓存中删除的对象。
8. bytes:表示系统存储缓存对象所使用的存储空间,单位为字节。
9. curr_connections:表示当前系统打开的连接数。
10. total_connections:表示从memcached服务启动到当前时间,系统打开过的连接的总数。
11. connection_structures:表示从memcached服务启动到当前时间,被服务器分配的连接结构的数量。
12. cmd_get:累积获取数据的数量,这里是3,因为我测试过3次,第一次因为没有序列化对象,所以获取数据失败,是null,后边有2次是我用不同对象测试了2次。
13. cmd_set:累积保存数据的树立数量,这里是2.虽然我存储了3次,但是第一次因为没有序列化,所以没有保存到缓存,也就没有记录。
14. get_hits:表示获取数据成功的次数。
15. get_misses:表示获取数据失败的次数。
16. evictions:为了给新的数据项目释放空间,从缓存移除的缓存对象的数目。比如超过缓存大小时根据LRU算法移除的对象,以及过期的对象。
17. bytes_read:memcached服务器从网络读取的总的字节数。
18. bytes_written:memcached服务器发送到网络的总的字节数。
19. limit_maxbytes:memcached服务缓存允许使用的最大字节数。这里为67108864字节,也就是是64M.与我们启动memcached服务设置的大小一致。
20. threads:被请求的工作线程的总数量。
如何在Java开发中使用Memcache
在Java开发中使用Memcache,一般要用到以下几个程序:1)Memcached
该程序用来在Linux或Windows服务器上建立和管理缓存。其项目网址为:http://danga.com/memcached/。
2)Magent
Magent是一款开源的Memcached代理服务器软件,使用它可以搭建高可用性的集群应用的Memcached服务,其项目网址为:http://code.google.com/p/memagent/。3)Memcached客户端程序
至于Memcached的客户端程序,一般推荐用memcached client for java,为什么推荐用这种客户端,后面会讲到具体的原因,其项目的网址为:http://github.com/gwhalin/Memcached-Java-Client/。需要引入四个jar包。
commons-pool-1.5.6.jar
java_memcached-release_2.6.6.jar
slf4j-api-1.6.1.jar
slf4j-simple-1.6.1.jar
package client;
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
public class CacheClientTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 初始化SockIOPool,管理memcached的连接池
*/
String[] servers = {"ip:port"};
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(servers);
pool.setFailover(true);
pool.setInitConn(10);
pool.setMinConn(5);
pool.setMaxConn(250);
pool.setMaintSleep(30);
pool.setNagle(false);
pool.setSocketTO(3000);
pool.setAliveCheck(true);
pool.initialize();
/**
* 建立MemcachedClient实例
*/
MemCachedClient mcclient = new MemCachedClient();
for(int i=0;i<1000;i++)
{
boolean success = mcclient.set(""+i, "Hello!");
String result = (String)mcclient.get(""+i);
System.out.println(String.format("set( %d ): %s", i, success));
System.out.println(String.format("get( %d ): %s", i, result));
}
}
}
4)其它程序
i. Libevent
在Linux环境下应用Memcache时,Memcache用到了libevent这个库,用于Socket的处理,所以还需要安装libevent。libevent的最新版本是libevent-1.4.13。(如果你的系统已经安装了libevent,可以不用安装)。
官网:http://www.monkey.org/~provos/libevent/
下载:http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz
MemCachedClient与Spring整合
参考文献:
- JAVA MemCache 史无前例的详细讲解!看完包精通MEMCACHE!
- Memcached - 统计与监控
- spring与memcached整合
- memcache过期时间的一点小小的分析
- Linux服务器性能评估(cpu,内存,磁盘IO)