linux下free命令查看内存[转]

Linux的内存管理,实际上跟windows的内存管理有很相像的地方,都是用虚拟内存这个的概念,
说到这里不得不骂MS,为什么在很多时候还有很大的物理内存的时候,却还是用到了pagefile.
所以才经常要跟一帮人吵着说Pagefile的大小,以及如何分配这个问题,
在Linux大家就不用再吵什么swap大小的问题,我个人认为,swap设个512M已经足够了,如果你问说512M的SWAP不够用怎么办?
只能说大哥你还是加内存吧,要不就检查你的应用,是不是真的出现了memory leak.
夜也深了,就不再说废话了。
在Linux下查看内存我们一般用free
[root@nonamelinux ~]# free
         total       used       free     shared    buffers     cached
Mem:    386024     377116     8908      0       21280      155468
-/+ buffers/cache: 200368     185656
Swap:    393552        0       393552
下面是对这些数值的解释:
第二行(mem):
total:总计物理内存的大小。
used:已使用多大。
free:可用有多少。
Shared:多个进程共享的内存总额。
Buffers/cached:磁盘缓存的大小。
第三行(-/+ buffers/cached):
used:已使用多大。
free:可用有多少。
第四行就不多解释了。
区别:
第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别。
这两个的区别在于使用的角度来看,第一行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,所以他的可用内存是8908KB,已用内存是377116KB,其中包括,内核(OS)使用+Application(X,oracle,etc)使用的+buffers+cached.
第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。
所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached.
如上例:
185656=8908+21280+15546
接下来解释什么时候内存会被交换,以及按什么方交换。
当可用内存少于额定值的时候,就会开会进行交换.
如何看额定值(RHEL4.0):
#cat /proc/meminfo
交换将通过三个途径来减少系统中使用的物理页面的个数:
1.减少缓冲与页面cache的大小,
2.将系统V类型的内存页面交换出去,
3.换出或者丢弃页面。(Application 占用的内存页,也就是物理内存不足)。
事实上,少量地使用swap是不会影响到系统性能的。

Tokyo Tyrant(TTServer)系列-启动参数和配置[转]

ttserver命令可以启动一个数据库实例。因为数据库已经实现了Tokyo Cabinet的抽象API,所以可以在启动的时候指定数据库的配置类型。

支持的数据库类型有:

    * 内存hash数据库
    * 内存tree数据库
    * hash数据库
    * B+ tree数据库,

  命令通过下面的格式来使用,‘dbname’制定数据库名,如果省略,则被视作内存hash数据库。

ttserver [-host name] [-port num] [-thnumnum] [-tout num] [-dmn] [-pid path] [-log path] [-ld|-le] [-ulog path] [-ulim num] [-uas] [-sidnum] [-mhost name] [-mport num] [-rts path] [-ext path] [-extpc nameperiod] [-mask expr] [dbname]

下面来说这些参数的功能:

      -host name :指明服务器的hostname或者ip地址。默认服务器的所有地址都会被绑定。比如:指定127.0.0.1这样的ip,就只是本地可以访问了。

      -port num : 指定服务启动的端口. 默认1978.如果要启动多个数据库实例,端口需要不一样。

      -thnum num : 指定服务工作的线程数。默认8.

      -tout num : 指定每个会话的超时时间。默认永不超时。

      -dmn : 以守护进程方式运行。

      -pid path : 输出进程IP到指定的文件。

      -log path : 输出日志信息到指定文件。

      -ld : 日志中记录debug信息。

      -le :日志中只记录错误信息。

      -ulog path : 指定存放更新日志(update log)的目录.可以用来备份恢复数据库,主从库之间的同步。

      -ulim num : 指定每个更新日志文件的大小限制.

      -uas :使用异步IO记录更新日志。(使用此项可以减少写入日志的IO开销,但是在服务器意外关机,进程被kill时可能会丢失数据。根据经验,一般可以不使用)。

      -sid num : 指定服务的ID号。主从复制的时候通过不同的ID号来识别。

      -mhost name : 指定主从复制模式下的主服务器的IP或域名。

      -mport num : 指定主从模式下主服务器的端口号.

      -rts path : 指定用于主从复制的时间戳存放文件.

      -ext path : 指定扩展脚本语言文件。

      -extpc name period : 指定被周期调用的函数名和间隔时间.

      -mask expr : 指定被禁止的命令名(比如可以禁止使用清空vanish).

      -unmask expr : 指定被允许的命令名.

数据库类型
下面我们再来看下数据库类型的详细配置。

    *     数据库名的命名方式被Tokyo Cabinet的抽象API指定。
    *     如果数据库名为"*",表示内存hash数据库。
    *     如果数据库名为"+"表示内存tree数据库。
    *     如果数据库名为".tch",则数据库为hash数据库。
    *     如果数据库名的后缀为".tcb",数据库将为B+ tree数据库。
    *     如果数据库名的后缀为".tcf"。则数据库将为fixed-length数据库。
    *     如果数据库名的后缀为".tct",则数据将为一个table数据库(有表的概念)。

数据库的调整参数通过数据库名的延伸来指定,通过"#"分开,每个参数通过一个参数名和值来指定,用"="隔开。

内存hash数据库支持"bnum", "capnum", 和 "capsiz"

内存tree数据库支持"capnum" 和 "capsiz"

    capnum指定记录的最大容量,capsiz指定最大的内存使用量(在内存数据库中),记录通过存储的顺序移除。

hash数据库支持"mode", "bnum", "apow", "fpow", "opts", "rcnum", 和 "xmsiz".

    rcnum'指定最大的缓存记录数。如果它不大于零,那么缓存记录不可用。默认不可用。
    xmsiz  指定外部内存的大小。如果不大于0,内存不可用。默认是67108864,即64M。
   
bnum’ 指定bucket存储桶的数量。如果指定的数目不大于0,将会使用默认的数值131071.推荐数量应该在所有需要存储的记录总数的0.4-4倍
    apow' 跟一个key关联的记录数,2的N次方表示.  如果不指定,默认2^4=16.
   
fpow’ specifies the maximum number of elements of the free block pool by power of 2.  默认2^10=1024.
    opts' 指定选项,位或:HDBTLARGE’ 指定数据库的大小通过使用64位数组桶能够超过2G。
                          HDBTDEFLATE'  指定每个记录被Deflate encoding压缩。
                         
HDBTBZIP’ 指定每个记录被BZIP2 encoding压缩
                          HDBTTCBS'指定每个记录被 TCBS encoding压缩.

B+ tree数据库支持"mode", "lmemb", "nmemb", "bnum", "apow", "fpow", "opts", "lcnum", "ncnum", 和 "xmsiz".
Fixed-length 数据库 支持 "mode", "width", and "limsiz".
Table 数据库支持 "mode", "bnum", "apow", "fpow", "opts", "rcnum", "lcnum", "ncnum", "xmsiz", 和 "idx"
      "idx"指定表的索引。
    "mode"可以包含 "w" 写, "r" 读, "c" 创建, "t" 截断,"e" 无锁,和"f" 非阻塞锁。默认的的mod为"wc"。

优化性能

    如果使用hash数据库我们可以指定#bnum=xxx来提高性能。xxx大于或等我我们的记录总数。

      如果使用B+ tree数据库我们可以通过指定"#lcnum=xxx#bnum=yyy" 来提高性能.第一个参数指定被缓存的最大叶子节点数,受内存容量限制,第二个参数指定桶的数量,它应该大于总记录数的1/128.

    如果有大量的客户端连接,确保我们的文件描述符够用。系统默认是1024,我们可以用使用“ulimit”来重新设定

  比如下面的单机实例启动脚本(一个正在线上运行的脚本):
#!/bin/sh
ulimit -SHn 51200
ttserver -host 192.168.0.136  -port 11212 -thnum 8 -dmn -pid /data/ttserver/ttserver.pid -log /data/ttserver/ttserver.log -le -ulog /data/ttserver/ -ulim 128m -sid 1 -rts /data/ttserver/ttserver.rts /data/ttserver/database.tch#bnum=10000000#xmsiz=434217728#rcnum=20000
使用hash数据库,最大会缓存20000个记录,最大使用内存434217728bytes(414M),bucket存储桶的数量10000000。

目前的库大小:

-rw-r--r--  1 root root  28G Mar  8 12:19 bbsdatabase.tch

因为使用了64位操作系统,所以文件大小不受2G的限制。

我们再看下读取数据的速度:

当前获取memcache Threads_cdb_threads_tid3565732_displayorder_0 使用时间 0.00054812431335449
以上是程序打印出来的通过memcache协议读取key为memcache Threads_cdb_threads_tid3565732_displayorder_0的数据所花的时间0.00054812431335449(s),可以看到速度还是非常快的。

启动实例

个人推荐通过修改ttservctl来实现启动。下面我们举几个简单的启动例子。

单机启动例子,下面是ttservctl文件的部分:

#! /bin/sh

#----------------------------------------------------------------
# Startup script for the server of Tokyo Tyrant
#----------------------------------------------------------------

# configuration variables
prog="ttservctl"
cmd="ttserver"
basedir="/var/ttserver" #数据库存放的路径,比如改为"/data/mydata"
port="1978" #启动的端口
pidfile="$basedir/pid"
logfile="$basedir/log"
ulogdir="$basedir/ulog"
ulimsiz="256m"
sid=1
dbname="$basedir/casket.tch#bnum=1000000" #上面讲的数据库类型配置
maxcon="65536"
retval=0

双机互为主辅模式,比如两台机器的Ip分别为192.168.1.176和192.168.1.1.177,以下为ttservctl文件的一部分。

176的配置:

#! /bin/sh

#----------------------------------------------------------------
# Startup script for the server of Tokyo Tyrant
#----------------------------------------------------------------

# configuration variables
prog="ttservctl"
cmd="ttserver"
basedir="/data/data/data1"
port="11211"
pidfile="$basedir/pid"
logfile="$basedir/log"
ulogdir="$basedir/"
mhost="192.168.1.177" #主ip即另外机器的ip
ulimsiz="256m"
sid=6#注意要每台机器不一样
dbname="$basedir/casket.tch#bnum=100000000#xmsiz=104857600#rcnum=1000000"
rts="$basedir/ttserver.rts" #在ttservctl基础上增加
maxcon="65536"
retval=0

# locale clear
LANG=C
LC_ALL=C
export LANG LC_ALL

# start the server
start(){
  printf 'Starting the server of Tokyo Tyrant\n'
  ulimit -n "$maxcon"
  mkdir -p "$basedir"
  if [ -f "$pidfile" ] ; then
    pid=
cat "$pidfile"
    printf 'Existing process: %d\n' "$pid"
    retval=1
  else
    $cmd \
      -port "$port" \
      -dmn \
      -pid "$pidfile" \
      -log "$logfile" \
      -ulog "$ulogdir" \
      -ulim "$ulimsiz" \
      -sid "$sid" \
      -mhost "$mhost" \#在ttservctl基础上增加
      -mport "$port" \#在ttservctl基础上增加
      -rts "$rts" \#在ttservctl基础上增加
      "$dbname"
    if [ "$?" -eq 0 ] ; then
      printf 'Done\n'
    else
      printf 'The server could not started\n'
      retval=1
    fi
  fi
}

177的配置:
#! /bin/sh

#----------------------------------------------------------------
# Startup script for the server of Tokyo Tyrant
#----------------------------------------------------------------

# configuration variables
prog="ttservctl"
cmd="ttserver"
basedir="/data/data/data1"
port="11211"
pidfile="$basedir/pid"
logfile="$basedir/log"
ulogdir="$basedir/"
mhost="192.168.1.176" #主ip即另外机器的ip
ulimsiz="256m"
sid=7#注意要每台机器不一样
dbname="$basedir/casket.tch#bnum=100000000#xmsiz=104857600#rcnum=1000000"
rts="$basedir/ttserver.rts" #在ttservctl基础上增加
maxcon="65536"
retval=0

# locale clear
LANG=C
LC_ALL=C
export LANG LC_ALL

# start the server
start(){
  printf 'Starting the server of Tokyo Tyrant\n'
  ulimit -n "$maxcon"
  mkdir -p "$basedir"
  if [ -f "$pidfile" ] ; then
    pid=
cat "$pidfile"`
    printf ‘Existing process: %d\n’ "$pid"
    retval=1
  else
    $cmd \
      -port "$port" \
      -dmn \
      -pid "$pidfile" \
      -log "$logfile" \
      -ulog "$ulogdir" \
      -ulim "$ulimsiz" \
      -sid "$sid" \
      -mhost "$mhost" \#在ttservctl基础上增加
      -mport "$port" \#在ttservctl基础上增加
      -rts "$rts" \#在ttservctl基础上增加
      "$dbname"
    if [ "$?" -eq 0 ] ; then
      printf ‘Done\n’
    else
      printf ‘The server could not started\n’
      retval=1
    fi
  fi
}

原文:http://www.pin5i.com/showtopic.aspx?topicid=23307&page=end