分类 运维 下的文章

50个最常用的Unix/Linux命令

这篇文章翻译自http://www.thegeekstuff.com/2010/11/50-linux-commands/这些都是一些很常用的命令,这篇文章中每个命令都有一些简单的示例说明它的用法,对于想学习Unix/Linux的人,这些命令基本上都是需要掌握的:

tar    grep    find    ssh    sed    awk    vim    diff    sort    export
args    ls    pwd    cd    gzip    bzip2    unzip    shutdown    ftp    crontab
service    ps    free    top    df    kill    rm    cp    mv    cat
mount    chmod    chown    passwd    mkdir    ifconfig    uname    whereis    whatis    locate
man    tail    less    su    mysql    yum    rpm    ping    date    wget
  1. tar
    创建一个新的tar文件
    $ tar cvf archive_name.tar dirname/
    解压tar文件
    $ tar xvf archive_name.tar
    查看tar文件
    $ tar tvf archive_name.tar
  2. grep
    在文件中查找字符串(不区分大小写)
    $ grep -i "the" demo_file
    输出成功匹配的行,以及该行之后的三行
    $ grep -A 3 -i "example" demo_text
    在一个文件夹中递归查询包含指定字符串的文件
    $ grep -r "ramesh" *
  3. find
    查找指定文件名的文件(不区分大小写)
    $ find -iname "MyProgram.c"
    对找到的文件执行某个命令
    $ find -iname "MyProgram.c" -exec md5sum {} ;
    查找home目录下的所有空文件
    $ find ~ -empty
  4. ssh
    登录到远程主机
    $ ssh -l jsmith remotehost.example.com
    调试ssh客户端
    $ ssh -v -l jsmith remotehost.example.com
    显示ssh客户端版本
    $ ssh -V
  5. sed
    当你将Dos系统中的文件复制到Unix/Linux后,这个文件每行都会以rn结尾,sed可以轻易将其转换为Unix格式的文件,使用n结尾的文件
    $ sed 's/.$//' filename
    反转文件内容并输出
    $ sed -n '1!G; h; p' filename
    为非空行添加行号
    $ sed '/./=' thegeekstuff.txt | sed 'N; s/n/ /'
  6. awk
    删除重复行
    $ awk '!($0 in array) { array[$0]; print}' temp
    打印/etc/passwd中所有包含同样的uid和gid的行
    $ awk -F ':' '$3=$4' /etc/passwd
    打印文件中的指定部分的字段
    $ awk '{print $2,$5;}' employee.txt
  7. vim
    打开文件并跳到第10行
    $ vim +10 filename.txt
    打开文件跳到第一个匹配的行
    $ vim +/search-term filename.txt
    以只读模式打开文件
    $ vim -R /etc/passwd
  8. diff
    比较的时候忽略空白符
    $ diff -w name_list.txt name_list_new.txt
  9. sort
    以升序对文件内容排序
    $ sort names.txt
    以降序对文件内容排序
    $ sort -r names.txt
    以第三个字段对/etc/passwd的内容排序
    $ sort -t: -k 3n /etc/passwd | more
  10. export
    输出跟字符串oracle匹配的环境变量
    $ export | grep ORCALE
    declare -x ORACLE_BASE="/u01/app/oracle"
    declare -x ORACLE_HOME="/u01/app/oracle/product/10.2.0"
    declare -x ORACLE_SID="med"
    declare -x ORACLE_TERM="xterm"

设置全局环境变量

$ export ORACLE_HOME=/u01/app/oracle/product/10.2.0
  1. xargs
    将所有图片文件拷贝到外部驱动器

    $ ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory

    将系统中所有jpd文件压缩打包

    $ find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz

    下载文件中列出的所有url对应的页面

    $ cat url-list.txt | xargs wget –c
  2. ls
    以易读的方式显示文件大小(显示为MB,GB...)

    $ ls -lh
    -rw-r----- 1 ramesh team-dev 8.9M Jun 12 15:27 arch-linux.txt.gz

    以最后修改时间升序列出文件

    $ ls -ltr

    在文件名后面显示文件类型

    $ ls -F
  3. pwd
    输出当前工作目录
  4. cd
  5. -可以在最近工作的两个目录间切换

使用shopt -s cdspell可以设置自动对cd命令进行拼写检查

  1. gzip
    创建一个*.gz的压缩文件
    $ gzip test.txt
    解压*.gz文件
    $ gzip -d test.txt.gz
    显示压缩的比率
    $ gzip -l *.gz

     compressed        uncompressed  ratio uncompressed_name
          23709               97975  75.8% asp-patch-rpms.txt
  2. bzip2
    创建*.bz2压缩文件
    $ bzip2 test.txt
    解压*.bz2文件
    bzip2 -d test.txt.bz2
  3. uzip
    解压*.zip文件
    $ unzip test.zip
    查看*.zip文件的内容
    $ unzip -l jasper.zip
    Archive: jasper.zip
    Length Date Time Name
    -------- ---- ---- ----
    40995 11-30-98 23:50 META-INF/MANIFEST.MF
    32169 08-25-98 21:07 classes_
    15964 08-25-98 21:07 classes_names
    10542 08-25-98 21:07 classes_ncomp
  4. shutdown
    关闭系统并立即关机
    $ shutdown -h now
    10分钟后关机

$ shutdown -h +10
重启

$ shutdown -r now

重启期间强制进行系统检查

$ shutdown -Fr now
  1. ftp
    ftp命令和sftp命令的用法基本相似连接ftp服务器并下载多个文件

    $ ftp IP/hostname
    ftp> mget *.html
    

显示远程主机上文件列表

ftp> mls *.html -
/ftptest/features.html
/ftptest/index.html
/ftptest/othertools.html
/ftptest/samplereport.html
/ftptest/usage.html
  1. crontab
    查看某个用户的crontab入口

    $ crontab -u john -l

    设置一个每十分钟执行一次的计划任务

    */10 * * * * /home/ramesh/check-disk-space
  2. service
    service命令用于运行System V init脚本,这些脚本一般位于/etc/init.d文件下,这个命令可以直接运行这个文件夹里面的脚本,而不用加上路径

查看服务状态

$ service ssh status

查看所有服务状态

$ service --status-all

重启服务

$ service ssh restart
  1. ps
    ps命令用于显示正在运行中的进程的信息,ps命令有很多选项,这里只列出了几个

查看当前正在运行的所有进程

$ ps -ef | more

以树状结构显示当前正在运行的进程,H选项表示显示进程的层次结构

$ ps -efH | more
  1. free
    这个命令用于显示系统当前内存的使用情况,包括已用内存、可用内存和交换内存的情况

默认情况下free会以字节为单位输出内存的使用量

$ free
             total       used       free     shared    buffers     cached
Mem:       3566408    1580220    1986188          0     203988     902960
-/+ buffers/cache:     473272    3093136
Swap:      4000176          0    4000176

如果你想以其他单位输出内存的使用量,需要加一个选项,-g为GB,-m为MB,-k为KB,-b为字节

$ free -g
             total       used       free     shared    buffers     cached
Mem:             3          1          1          0          0          0
-/+ buffers/cache:          0          2
Swap:            3          0          3

如果你想查看所有内存的汇总,请使用-t选项,使用这个选项会在输出中加一个汇总行

ramesh@ramesh-laptop:~$ free -t
             total       used       free     shared    buffers     cached
Mem:       3566408    1592148    1974260          0     204260     912556
-/+ buffers/cache:     475332    3091076
Swap:      4000176          0    4000176
Total:     7566584    1592148    5974436
  1. top
    top命令会显示当前系统中占用资源最多的一些进程(默认以CPU占用率排序)如果你想改变排序方式,可以在结果列表中点击O(大写字母O)会显示所有可用于排序的列,这个时候你就可以选择你想排序的列

    Current Sort Field:  P  for window 1:Def
    Select sort field via field letter, type any other key to return
    
      a: PID        = Process Id              v: nDRT       = Dirty Pages count
      d: UID        = User Id                 y: WCHAN      = Sleeping in Function
      e: USER       = User Name               z: Flags      = Task Flags
      ........
    

如果只想显示某个特定用户的进程,可以使用-u选项

$ top -u oracle
  1. df
    显示文件系统的磁盘使用情况,默认情况下df -k 将以字节为单位输出磁盘的使用量

    $ df -k
    Filesystem           1K-blocks      Used Available Use% Mounted on
    /dev/sda1             29530400   3233104  24797232  12% /
    /dev/sda2            120367992  50171596  64082060  44% /home
    

使用-h选项可以以更符合阅读习惯的方式显示磁盘使用量

$ df -h
Filesystem                  Size   Used  Avail Capacity  iused      ifree %iused  Mounted on
/dev/disk0s2               232Gi   84Gi  148Gi    37% 21998562   38864868   36%   /
devfs                      187Ki  187Ki    0Bi   100%      648          0  100%   /dev
map -hosts                   0Bi    0Bi    0Bi   100%        0          0  100%   /net
map auto_home                0Bi    0Bi    0Bi   100%        0          0  100%   /home
/dev/disk0s4               466Gi   45Gi  421Gi    10%   112774  440997174    0%   /Volumes/BOOTCAMP
//app@izenesoft.cn/public  2.7Ti  1.3Ti  1.4Ti    48%        0 18446744073709551615    0%   /Volumes/public

使用-T选项显示文件系统类型

$ df -T
Filesystem    Type   1K-blocks      Used Available Use% Mounted on
/dev/sda1     ext4    29530400   3233120  24797216  12% /
/dev/sda2     ext4   120367992  50171596  64082060  44% /home
  1. kill
    kill用于终止一个进程。一般我们会先用ps -ef查找某个进程得到它的进程号,然后再使用kill -9 进程号终止该进程。你还可以使用killall、pkill、xkill来终止进程
    $ ps -ef | grep vim
    ramesh 7243 7222 9 22:43 pts/2 00:00:00 vim
    $ kill -9 724
  2. rm
    删除文件前先确认
    $ rm -i filename.txt
    在文件名中使用shell的元字符会非常有用。删除文件前先打印文件名并进行确认
    $ rm -i file*
    递归删除文件夹下所有文件,并删除该文件夹
    $ rm -r example
  3. cp
    拷贝文件1到文件2,并保持文件的权限、属主和时间戳
    $ cp -p file1 file2

拷贝file1到file2,如果file2存在会提示是否覆盖

$ cp -i file1 file2
  1. mv
    将文件名file1重命名为file2,如果file2存在则提示是否覆盖

    $ mv -i file1 file2
    

注意如果使用-f选项则不会进行提示
-v会输出重命名的过程,当文件名中包含通配符时,这个选项会非常方便

$ mv -v file1 file2
  1. cat
    你可以一次查看多个文件的内容,下面的命令会先打印file1的内容,然后打印file2的内容

$ cat file1 file2
-n命令可以在每行的前面加上行号

$ cat -n /etc/logrotate.conf
    1    /var/log/btmp {
    2        missingok
    3        monthly
    4        create 0660 root utmp
    5        rotate 1
    6    }
  1. mount
    如果要挂载一个文件系统,需要先创建一个目录,然后将这个文件系统挂载到这个目录上

    # mkdir /u01
    # mount /dev/sdb1 /u01

    也可以把它添加到fstab中进行自动挂载,这样任何时候系统重启的时候,文件系统都会被加载

    /dev/sdb1 /u01 ext2 defaults 0 2
  2. chmod
    chmod用于改变文件和目录的权限

给指定文件的属主和属组所有权限(包括读、写、执行)

$ chmod ug+rwx file.txt

删除指定文件的属组的所有权限

$ chmod g-rwx file.txt

修改目录的权限,以及递归修改目录下面所有文件和子目录的权限

$ chmod -R ug+rwx file.txt
  1. chown
    chown用于改变文件属主和属组

同时将某个文件的属主改为oracle,属组改为db

$ chown oracle:dba dbora.sh

使用-R选项对目录和目录下的文件进行递归修改

$ chown -R oracle:dba /home/oracle
  1. passwd
    passwd用于在命令行修改密码,使用这个命令会要求你先输入旧密码,然后输入新密码

    $ passwd

    超级用户可以用这个命令修改其他用户的密码,这个时候不需要输入用户的密码

    # passwd USERNAME

    passwd还可以删除某个用户的密码,这个命令只有root用户才能操作,删除密码后,这个用户不需要输入密码就可以登录到系统

    # passwd -d USERNAME
  2. mkdir
    在home目录下创建一个名为temp的目录

    $ mkdir ~/temp

    使用-p选项可以创建一个路径上所有不存在的目录

    $ mkdir -p dir1/dir2/dir3/dir4/
  3. ifconfig
    ifconfig用于查看和配置Linux系统的网络接口

查看所有网络接口及其状态

$ ifconfig -a

使用up和down命令启动或停止某个接口

$ ifconfig eth0 up
$ ifconfig eth0 down
  1. uname
    uname可以显示一些重要的系统信息,例如内核名称、主机名、内核版本号、处理器类型之类的信息

    $ uname -a
    Linux john-laptop 2.6.32-24-generic #41-Ubuntu SMP Thu Aug 19 01:12:52 UTC 2010 i686 GNU/Linux
    
  2. whereis
    当你不知道某个命令的位置时可以使用whereis命令,下面使用whereis查找ls的位置

    $ whereis ls
    ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/man1p/ls.1p.gz
    

当你想查找某个可执行程序的位置,但这个程序又不在whereis的默认目录下,你可以使用-B选项,并指定目录作为这个选项的参数。下面的命令在/tmp目录下查找lsmk命令

$ whereis -u -B /tmp -f lsmk
lsmk: /tmp/lsmk
  1. whatis
    wathis显示某个命令的描述信息
    $ whatis ls
    ls(1) - list directory contents
    $ whatis ifconfig
    ifconfig (8) - configure a network interface
  2. locate
    locate命名可以显示某个指定文件(或一组文件)的路径,它会使用由updatedb创建的数据库

下面的命令会显示系统中所有包含crontab字符串的文件

$ locate crontab
/etc/anacrontab
/etc/crontab
/usr/bin/crontab
/usr/share/doc/cron/examples/crontab2english.pl.gz
/usr/share/man/man1/crontab.1.gz
/usr/share/man/man5/anacrontab.5.gz
/usr/share/man/man5/crontab.5.gz
/usr/share/vim/vim72/syntax/crontab.vim
  1. man
    显示某个命令的man页面

$ man crontab
有些命令可能会有多个man页面,每个man页面对应一种命令类型

$ man SECTION-NUMBER commandname

man页面一般可以分为8种命令类型

用户命令
系统调用
c库函数
设备与网络接口
文件格式
游戏与屏保
环境、表、宏
系统管理员命令和后台运行命令
例如,我们执行whatis crontab,你可以看到crontab有两个命令类型1和5,所以我们可以通过下面的命令查看命令类型5的man页面

$ whatis crontab
crontab (1)  - maintain crontab files for individual users (V3)
crontab (5)  - tables for driving cron
$ man 5 crontab
  1. tail
    tail命令默认显示文件最后的10行文本

    $ tail filename.txt

    你可以使用-n选项指定要显示的行数

    $ tail -n N filename.txt

    你也可以使用-f选项进行实时查看,这个命令执行后会等待,如果有新行添加到文件尾部,它会继续输出新的行,在查看日志时这个选项会非常有用。你可以通过CTRL-C终止命令的执行

    $ tail -f log-fileTerminal
  2. less
    这个命名可以在不加载整个文件的前提下显示文件内容,在查看大型日志文件的时候这个命令会非常有用

    $ less huge-log-file.log

    当你用less命令打开某个文件时,下面两个按键会给你带来很多帮助,他们用于向前和向后滚屏

    CTRL+F – forward one window
    CTRL+B – backward one window
    
  3. su
    su命令用于切换用户账号,超级用户使用这个命令可以切换到任何其他用户而不用输入密码

$ su - USERNAME
用另外一个用户名执行一个命令下面的示例中用户john使用raj用户名执行ls命令,执行完后返回john的账号

[john@dev-server]$ su - raj -c 'ls'

[john@dev-server]$
用指定用户登录,并且使用指定的shell程序,而不用默认的

$ su -s 'SHELLNAME' USERNAME
  1. mysql
    mysql可能是Linux上使用最广泛的数据库,即使你没有在你的服务器上安装mysql,你也可以使用mysql客户端连接到远程的mysql服务器

连接一个远程数据库,需要输入密码

$ mysql -u root -p -h 192.168.1.2

连接本地数据库

$ mysql -u root -p

你也可以在命令行中输入数据库密码,只需要在-p后面加上密码作为参数,可以直接写在p后面而不用加空格

  1. yum
    使用yum安装apache

    $ yum install httpd

    更新apache

    $ yum update httpd

    卸载/删除apache

    $ yum remove httpd
  2. rpm
    使用rpm安装apache

    # rpm -ivh httpd-2.2.3-22.0.1.el5.i386.rpm

    更新apache

    # rpm -uvh httpd-2.2.3-22.0.1.el5.i386.rpm

    卸载/删除apache

    # rpm -ev httpd
  3. ping
    ping一个远程主机,只发5个数据包

    $ ping -c 5 gmail.com
  4. date
    设置系统日期

    # date -s "01/31/2010 23:59:53"

    当你修改了系统时间,你需要同步硬件时间和系统时间

    # hwclock –systohc
    # hwclock --systohc –utc
  5. wget
    使用wget从网上下载软件、音乐、视频

    $ wget http://prdownloads.sourceforge.net/sourceforge/nagios/nagios-3.2.1.tar.gz

    下载文件并以指定的文件名保存文件

    $ wget -O taglist.zip http://www.vim.org/scripts/download_script.php?src_id=7701
    

Redis和Memcached的区别

说到redis就会联想到memcached,反之亦然。了解过两者的同学有那么个大致的印象:redis与memcached相比,比仅支持简单的key-value数据类型,同时还提供list,set,zset,hash等数据结构的存储;redis支持数据的备份,即master-slave模式的数据备份;redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用等等,这似乎看起来redis比memcached更加牛逼一些,那么事实上是不是这样的呢?存在即合理,我们来根据几个不同点来一一比较一下。

网络IO模型
memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe传递给worker线程,进行读写IO,网络层使用libevent封装的事件库,多线程模型可以发挥多核作用,但是引入了cache coherency和锁的问题,比如:memcached最常用的stats命令,实际memcached所有操作都要对这个全局变量加锁,进行技术等工作,带来了性能损耗。

redis使用单线程的IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll, kqueue和select,对于单存只有IO操作来说,单线程可以将速度优势发挥到最大,但是redis也提供了一些简单的计算功能,比如排序、聚合等,对于这些操作,单线程模型施加会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞的。

数据支持类型
memcached使用key-value形式存储和访问数据,在内存中维护一张巨大的HashTable,使得对数据查询的时间复杂度降低到O(1),保证了对数据的高性能访问。

正如开篇所说:redis与memcached相比,比仅支持简单的key-value数据类型,同时还提供list,set,zset,hash等数据结构的存储;详细可以翻阅《Redis内存使用优化与存储》

内存管理机制
对于像Redis和Memcached这种基于内存的数据库系统来说,内存管理的效率高低是影响系统性能的关键因素。传统C语言中的malloc/free函数是最常用的分配和释放内存的方法,但是这种方法存在着很大的缺陷:首先,对于开发人员来说不匹配的malloc和free容易造成内存泄露;其次频繁调用会造成大量内存碎片无法回收重新利用,降低内存利用率;最后作为系统调用,其系统开销远远大于一般函数调用。所以,为了提高内存的管理效率,高效的内存管理方案都不会直接使用malloc/free调用。Redis和Memcached均使用了自身设计的内存管理机制,但是实现方法存在很大的差异,下面将会对两者的内存管理机制分别进行介绍。

Memcached默认使用Slab Allocation机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完全解决内存碎片问题。Slab Allocation机制只为存储外部数据而设计,也就是说所有的key-value数据都存储在Slab Allocation系统里,而Memcached的其它内存请求则通过普通的malloc/free来申请,因为这些请求的数量和频率决定了它们不会对整个系统的性能造成影响Slab Allocation的原理相当简单。 如图所示,它首先从操作系统申请一大块内存,并将其分割成各种尺寸的块Chunk,并把尺寸相同的块分成组Slab Class。其中,Chunk就是用来存储key-value数据的最小单位。每个Slab Class的大小,可以在Memcached启动的时候通过制定Growth Factor来控制。假定图中Growth Factor的取值为1.25,如果第一组Chunk的大小为88个字节,第二组Chunk的大小就为112个字节,依此类推。

当Memcached接收到客户端发送过来的数据时首先会根据收到数据的大小选择一个最合适的Slab Class,然后通过查询Memcached保存着的该Slab Class内空闲Chunk的列表就可以找到一个可用于存储数据的Chunk。当一条数据库过期或者丢弃时,该记录所占用的Chunk就可以回收,重新添加到空闲列表中。从以上过程我们可以看出Memcached的内存管理制效率高,而且不会造成内存碎片,但是它最大的缺点就是会导致空间浪费。因为每个Chunk都分配了特定长度的内存空间,所以变长数据无法充分利用这些空间。如图 所示,将100个字节的数据缓存到128个字节的Chunk中,剩余的28个字节就浪费掉了。

Redis的内存管理主要通过源码中zmalloc.h和zmalloc.c两个文件来实现的。Redis为了方便内存的管理,在分配一块内存之后,会将这块内存的大小存入内存块的头部。如图所示,real_ptr是redis调用malloc后返回的指针。redis将内存块的大小size存入头部,size所占据的内存大小是已知的,为size_t类型的长度,然后返回ret_ptr。当需要释放内存的时候,ret_ptr被传给内存管理程序。通过ret_ptr,程序可以很容易的算出real_ptr的值,然后将real_ptr传给free释放内存。

Redis通过定义一个数组来记录所有的内存分配情况,这个数组的长度为ZMALLOC_MAX_ALLOC_STAT。数组的每一个元素代表当前程序所分配的内存块的个数,且内存块的大小为该元素的下标。在源码中,这个数组为zmalloc_allocations。zmalloc_allocations[16]代表已经分配的长度为16bytes的内存块的个数。zmalloc.c中有一个静态变量used_memory用来记录当前分配的内存总大小。所以,总的来看,Redis采用的是包装的mallc/free,相较于Memcached的内存管理方法来说,要简单很多。

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

Memcached使用预分配的内存池的方式,使用slab和大小不同的chunk来管理内存,Item根据大小选择合适的chunk存储,内存池的方式可以省去申请/释放内存的开销,并且能减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数据也可能会被剔除,原因可以参考Timyang的文章:https://timyang.net/data/Memcached-lru-evictions/

Redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎片,Redis跟据存储命令参数,会把带过期时间的数据单独存放在一起,并把它们称为临时数据,非临时数据是永远不会被剔除的,即便物理内存不够,导致swap也不会剔除任何非临时数据(但会尝试剔除部分临时数据),这点上Redis更适合作为存储而不是cache。

数据存储及持久化
memcached不支持内存数据的持久化操作,所有的数据都以in-memory的形式存储。
redis支持持久化操作。redis提供了两种不同的持久化方法来讲数据存储到硬盘里面,一种是快照(snapshotting),它可以将存在于某一时刻的所有数据都写入硬盘里面。另一种方法叫只追加文件(append-only file, AOF),它会在执行写命令时,将被执行的写命令复制到硬盘里面。

数据一致性问题
Memcached提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。 Redis没有提供cas 命令,并不能保证这点,不过Redis提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断。

集群管理不同
Memcached是全内存的数据缓冲系统,Redis虽然支持数据的持久化,但是全内存毕竟才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小就是系统能够容纳的最大数据量。如果需要处理的数据量超过了单台机器的物理内存大小,就需要构建分布式集群来扩展存储能力。

Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。下图给出了Memcached的分布式存储实现架构。当客户端向Memcached集群发送数据之前,首先会通过内置的分布式算法计算出该条数据的目标节点,然后数据会直接发送到该节点上存储。但客户端查询数据时,同样要计算出查询数据所在的节点,然后直接向该节点发送查询请求以获取数据。

相较于Memcached只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。最新版本的Redis已经支持了分布式存储功能。Redis Cluster是一个实现了分布式且允许单点故障的Redis高级版本,它没有中心节点,具有线性可伸缩的功能。Redis Cluster的分布式存储架构,节点与节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信。在数据的放置策略上,Redis Cluster将整个key的数值域分成4096个哈希槽,每个节点上可以存储一个或多个哈希槽,也就是说当前Redis Cluster支持的最大节点数就是4096。Redis Cluster使用的分布式算法也很简单:crc16( key ) % HASH_SLOTS_NUMBER。

为了保证单点故障下的数据可用性,Redis Cluster引入了Master节点和Slave节点。在Redis Cluster中,每个Master节点都会有对应的两个用于冗余的Slave节点。这样在整个集群中,任意两个节点的宕机都不会导致数据的不可用。当Master节点退出后,集群会自动选择一个Slave节点成为新的Master节点。

wget参数用法详解

wget 是一个从网络上自动下载文件的自由工具。它支持HTTP,HTTPS和FTP协议,可以使用HTTP代理。

所谓的自动下载是指,wget可以在用户退出系统的之后在后台执行。这意味这你可以登录系统,启动一个wget下载任务,然后退出系统,wget将在后台执行直到任务完成,相对于其它大部分浏览器在下载大量数据时需要用户一直的参与,这省去了极大的麻烦。

wget可以跟踪HTML页面上的链接依次下载来创建远程服务器的本地版本,完全重建原始站点的目录结构。这又常被称作”递归下载”。在递归下载的时候,wget 遵循Robot Exclusion标准(/robots.txt). wget可以在下载的同时,将链接转换成指向本地文件,以方便离线浏览。

wget 非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性.如果是由于网络的原因下载失败,wget会不断的尝试,直到整个文件下载完毕。如果是服务 器打断下载过程,它会再次联到服务器上从停止的地方继续下载。这对从那些限定了链接时间的服务器上下载大文件非常有用。

wget的常见用法:

wget不但功能强大,而且使用起来比较简单,
基本的语法是:wget [参数列表] “URL” 用””引起来可以避免因URL中有特殊字符造成的下载出错。
下面就结合具体的例子来说明一下wget的用法。

1、下载整个https或者ftp站点。

wget https://place.your.url/here

这个命令可以将https://place.your.url/here 首页下载下来。使用-x会强制建立服务器上一模一样的目录,如果使用-nd参数,那么服务器上下载的所有内容都会加到本地当前目录。

wget -r https://place.your.url/here

这个命令会按照递归的方法,下载服务器上所有的目录和文件,实质就是下载整个网站。这个命令一定要小心使用,因为在下载的时候,被下载网站指向的所有地址 同样会被下载,因此,如果这个网站引用了其他网站,那么被引用的网站也会被下载下来!基于这个原因,这个参数不常用。可以用-l number参数来指定下载的层次。例如只下载两层,那么使用-l 2。

要是您想制作镜像站点,那么可以使用-m参数,例如:
wget -m https://place.your.url/here
这时wget会自动判断合适的参数来制作镜像站点。此时,wget会登录到服务器上,读入robots.txt并按robots.txt的规定来执行。

2、断点续传。

当文件特别大或者网络特别慢的时候,往往一个文件还没有下载完,连接就已经被切断,此时就需要断点续传。wget的断点续传是自动的,只需要使用-c参数,例如:
wget -c https://the.url.of/incomplete/file

使用断点续传要求服务器支持断点续传。-t参数表示重试次数,例如需要重试100次,那么就写-t 100,如果设成-t 0,那么表示无穷次重试,直到连接成功。-T参数表示超时等待时间,例如-T 120,表示等待120秒连接不上就算超时。

3、批量下载。

如果有多个文件需要下载,那么可以生成一个文件,把每个文件的URL写一行,例如生成文件download.txt,然后用命令:wget -i download.txt
这样就会把download.txt里面列出的每个URL都下载下来。(如果列的是文件就下载文件,如果列的是网站,那么下载首页)

4、选择性的下载。

可以指定让wget只下载一类文件,或者不下载什么文件。例如:
wget -m –reject=gif https://target.web.site/subdirectory
表示下载https://target.web.site/subdirectory,但是忽略gif文件。–accept=LIST 可以接受的文件类型,–reject=LIST拒绝接受的文件类型。

5、密码和认证。

wget只能处理利用用户名/密码方式限制访问的网站,可以利用两个参数:
–https-user=USER设置HTTP用户
–https-passwd=PASS设置HTTP密码
对于需要证书做认证的网站,就只能利用其他下载工具了,例如curl。

6、利用代理服务器进行下载。

如果用户的网络需要经过代理服务器,那么可以让wget通过代理服务器进行文件的下载。此时需要在当前用户的目录下创建一个.wgetrc文件。文件中可以设置代理服务器:
https-proxy = 111.111.111.111:8080
ftp-proxy = 111.111.111.111:8080
分别表示https的代理服务器和ftp的代理服务器。如果代理服务器需要密码则使用:
–proxy-user=USER设置代理用户
–proxy-passwd=PASS设置代理密码
这两个参数。
使用参数–proxy=on/off 使用或者关闭代理。
wget还有很多有用的功能,需要用户去挖掘。

wget的使用格式

Usage: wget [OPTION]… [URL]…

  • 用wget做站点镜像:
  1. -r -p -np -k https://dsec.pku.edu.cn/~usr_name/

或者wget -m https://dsec.pku.edu.cn/~usr_name/

  • 在不稳定的网络上下载一个部分下载的文件,以及在空闲时段下载
  1. -t 0 -w 31 -c https://dsec.pku.edu.cn/BBC.avi -o down.log &

或者从filelist读入要下载的文件列表

wget -t 0 -w 31 -c -B ftp://dsec.pku.edu.cn/linuxsoft -i filelist.txt -o down.log &
上面的代码还可以用来在网络比较空闲的时段进行下载。我的用法是:在mozilla中将不方便当时下载的URL链接拷贝到内存中然后粘贴到文件 filelist.txt中,在晚上要出去系统前执行上面代码的第二条。

  • 使用代理下载
  1. -Y on -p -k httpss://sourceforge.net/projects/wvware/

代理可以在环境变量或wgetrc文件中设定

在环境变量中设定代理

export PROXY=https://211.90.168.94:8080/

在~/.wgetrc中设定代理

https_proxy = https://proxy.yoyodyne.com:18023/
ftp_proxy = https://proxy.yoyodyne.com:18023/

wget各种选项分类列表

  • 启动
    -V, –version 显示wget的版本后退出

-h, –help 打印语法帮助
-b, –background 启动后转入后台执行
-e, –execute=COMMAND 执行`.wgetrc’格式的命令,wgetrc格式参见/etc/wgetrc或~/.wgetrc

  • 记录和输入文件
    -o, –output-file=FILE 把记录写到FILE文件中

-a, –append-output=FILE 把记录追加到FILE文件中
-d, –debug 打印调试输出
-q, –quiet 安静模式(没有输出)
-v, –verbose 冗长模式(这是缺省设置)
-nv, –non-verbose 关掉冗长模式,但不是安静模式
-i, –input-file=FILE 下载在FILE文件中出现的URLs
-F, –force-html 把输入文件当作HTML格式文件对待
-B, –base=URL 将URL作为在-F -i参数指定的文件中出现的相对链接的前缀
–sslcertfile=FILE 可选客户端证书
–sslcertkey=KEYFILE 可选客户端证书的KEYFILE
–egd-file=FILE 指定EGD socket的文件名

  • 下载
    –bind-address=ADDRESS 指定本地使用地址(主机名或IP,当本地有多个IP或名字时使用)

-t, –tries=NUMBER 设定最大尝试链接次数(0 表示无限制).
-O –output-document=FILE 把文档写到FILE文件中
-nc, –no-clobber 不要覆盖存在的文件或使用.#前缀
-c, –continue 接着下载没下载完的文件
–progress=TYPE 设定进程条标记
-N, –timestamping 不要重新下载文件除非比本地文件新
-S, –server-response 打印服务器的回应
–spider 不下载任何东西
-T, –timeout=SECONDS 设定响应超时的秒数
-w, –wait=SECONDS 两次尝试之间间隔SECONDS秒
–waitretry=SECONDS 在重新链接之间等待1…SECONDS秒
–random-wait 在下载之间等待0…2*WAIT秒
-Y, –proxy=on/off 打开或关闭代理
-Q, –quota=NUMBER 设置下载的容量限制
–limit-rate=RATE 限定下载输率

  • 目录
    -nd –no-directories 不创建目录

-x, –force-directories 强制创建目录
-nH, –no-host-directories 不创建主机目录
-P, –directory-prefix=PREFIX 将文件保存到目录 PREFIX/…
–cut-dirs=NUMBER 忽略 NUMBER层远程目录

  • HTTP 选项
    –https-user=USER 设定HTTP用户名为 USER.

–https-passwd=PASS 设定https密码为 PASS.
-C, –cache=on/off 允许/不允许服务器端的数据缓存 (一般情况下允许).
-E, –html-extension 将所有text/html文档以.html扩展名保存
–ignore-length 忽略 `Content-Length’头域
–header=STRING 在headers中插入字符串 STRING
–proxy-user=USER 设定代理的用户名为 USER
–proxy-passwd=PASS 设定代理的密码为 PASS
–referer=URL 在HTTP请求中包含 `Referer: URL’头
-s, –save-headers 保存HTTP头到文件
-U, –user-agent=AGENT 设定代理的名称为 AGENT而不是 Wget/VERSION.
–no-https-keep-alive 关闭 HTTP活动链接 (永远链接).
–cookies=off 不使用 cookies.
–load-cookies=FILE 在开始会话前从文件 FILE中加载cookie
–save-cookies=FILE 在会话结束后将 cookies保存到 FILE文件中

  • FTP 选项
    -nr, –dont-remove-listing 不移走 `.listing’文件

-g, –glob=on/off 打开或关闭文件名的 globbing机制
–passive-ftp 使用被动传输模式 (缺省值).
–active-ftp 使用主动传输模式
–retr-symlinks 在递归的时候,将链接指向文件(而不是目录)

  • 递归下载
    -r, –recursive 递归下载--慎用!

-l, –level=NUMBER 最大递归深度 (inf 或 0 代表无穷).
–delete-after 在现在完毕后局部删除文件
-k, –convert-links 转换非相对链接为相对链接
-K, –backup-converted 在转换文件X之前,将之备份为 X.orig
-m, –mirror 等价于 -r -N -l inf -nr.
-p, –page-requisites 下载显示HTML文件的所有图片

  • 递归下载中的包含和不包含(accept/reject)
    -A, –accept=LIST 分号分隔的被接受扩展名的列表

-R, –reject=LIST 分号分隔的不被接受的扩展名的列表
-D, –domains=LIST 分号分隔的被接受域的列表
–exclude-domains=LIST 分号分隔的不被接受的域的列表
–follow-ftp 跟踪HTML文档中的FTP链接
–follow-tags=LIST 分号分隔的被跟踪的HTML标签的列表
-G, –ignore-tags=LIST 分号分隔的被忽略的HTML标签的列表
-H, –span-hosts 当递归时转到外部主机
-L, –relative 仅仅跟踪相对链接
-I, –include-directories=LIST 允许目录的列表
-X, –exclude-directories=LIST 不被包含目录的列表
-np, –no-parent 不要追溯到父目录
wget -S –spider url 不下载只显示过程

Crontab定时执行PHP脚本

首先说说cron,它是一个linux下的定时执行工具。根用户以外的用户可以使用 crontab 工具来配置 cron 任务。所有用户定义的 crontab 都被保存在/var/spool/cron 目录中,并使用创建它们的用户身份来执行。要以某用户身份创建一个 crontab 项目,登录为该用户,然后键入 crontab -e 命令来编辑该用户的 crontab。该文件使用的格式和 /etc/crontab 相同。当对 crontab 所做的改变被保存后,该 crontab 文件就会根据该用户名被保存,并写入文件 /var/spool/cron/username 中。cron 守护进程每分钟都检查 /etc/crontab 文件、etc/cron.d/ 目录、以及 /var/spool/cron 目录中的改变。如果发现了改变,它们就会被载入内存。这样,当某个 crontab 文件改变后就不必重新启动守护进程了。

安装crontab:

yum install crontabs

说明:

/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置

查看crontab服务状态:service crond status

手动启动crontab服务:service crond start

查看crontab服务是否已设置为开机启动,执行命令:ntsysv

加入开机自动启动:

chkconfig –level 35 crond on

每一小时执行myscript.php如下:

# crontab -e
00 * * * * /usr/local/bin/php /home/john/myscript.php

如果你的PHP脚本可以通过URL触发,你可以使用lynx或curl或wget来配置你的Crontab。
下面的例子是使用Lynx文本浏览器访问URL来每小时执行PHP脚本。Lynx文本浏览器默认使用对话方式打开URL。但是,像下面的,我们在lynx命令行中使用-dump选项来把URL的输出转换来标准输出。

00 * * * * lynx -dump https://www.jb51.net/myscript.php

下面的例子是使用CURL访问URL来每5分执行PHP脚本。Curl默认在标准输出显示输出。使用”curl -o”选项,你也可以把脚本的输出转储到临时文件。

*/5 * * * * /usr/bin/curl -o temp.txt https://www.jb51.net/myscript.php

下面的例子是使用WGET访问URL来每10分执行PHP脚本。-q选项表示安静模式。”-O temp.txt”表示输出会发送到临时文件。

*/10 * * * * /usr/bin/wget -q -O temp.txt https://www.jb51.net/myscript.php

参  数:
-e  编辑该用户的计时器设置。
-l  列出该用户的计时器设置。
-r  删除该用户的计时器设置。
-u<用户名称>  指定要设定计时器的用户名称。

crontab 格式

基本格式 :

分钟   小时   日   月   星期   命令
 *     *     *    *    *     *

第1列表示分钟1~59 每分钟用或者 /1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列 表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令

记住几个特殊符号的含义:
“*”代表取值范围内的数字,
“/”代表”每”,
“-”代表从某个数字到某个数字,
“,”分开几个离散的数字

crontab文件的一些例子:

30 21 * * * /usr/local/etc/rc.d/lighttpsd restart 
上面的例子表示每晚的21:30重启apache。 
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpsd restart 
上面的例子表示每月1、10、22日的4 : 45重启apache。 
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpsd restart 
上面的例子表示每周六、周日的1 : 10重启apache。 
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpsd restart 
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。 
0 23 * * 6 /usr/local/etc/rc.d/lighttpsd restart 
上面的例子表示每星期六的11 : 00 pm重启apache。 
0 */1 * * * /usr/local/etc/rc.d/lighttpsd restart 
每一小时重启apache 
0 23-7/1 * * * /usr/local/etc/rc.d/lighttpsd restart 
晚上11点到早上7点之间,每隔一小时重启apache 
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpsd restart 
每月的4号与每周一到周三的11点重启apache 
0 4 1 jan * /usr/local/etc/rc.d/lighttpsd restart 

Linux Top命令详细记录

最近服务器经常出问题,所以用命令 top 分析其性能,在这里对其做个记录,便于以后查看。top 是常用的性能分析命令,基本和 windows 的任务管理器类似,下面详细介绍使用方法。

> top
top - 10:36:26 up 72 days, 22:21,  1 user,  load average: 0.00, 0.01, 0.05
Tasks:  81 total,   1 running,  80 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1883844 total,    99960 free,   375164 used,  1408720 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  1306676 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
    1 root      20   0   43276   2556   1348 S  0.0  0.1   4:19.02 systemd
    2 root      20   0       0      0      0 S  0.0  0.0   0:00.02 kthreadd
    3 root      20   0       0      0      0 S  0.0  0.0   1:20.24 ksoftirqd/0
    5 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0H
    7 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 migration/0
    8 root      20   0       0      0      0 S  0.0  0.0   0:00.00 rcu_bh
    9 root      20   0       0      0      0 S  0.0  0.0   9:45.47 rcu_sched
   10 root      rt   0       0      0      0 S  0.0  0.0   0:18.19 watchdog/0
下面将其参数做下详细的说明:

top - 10:36:26 up 72 days, 22:21,  1 user,  load average: 0.00, 0.01, 0.05
10:36:26:当前系统时间
up 72 days, 22:21:表示系统开机到现在的运行时间
1 user:当前登录系统的用户个数
load average:分别是1分钟、5分钟、15分钟的系统负载情况,
load average 数据是每隔5秒钟检查一次活跃的进程数,然后按特定算法计算出的数值。如果这个数除以逻辑CPU的数量,结果高于5的时候就表明系统在超负荷运转了。

 Tasks:  81 total,   1 running,  80 sleeping,   0 stopped,   0 zombie
可以根据其字面意思得到:系统现在共有 80 个进程,其中处于运行中的有 1 个,80 个在休眠(sleep),stoped 状态的有 0 个,zombie 状态(僵尸)的有 0 个。

%Cpu(s):  0.3 us,  0.3 sy,  0.0 ni, 99.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
CPU 的运转情况,后面值依次意思为:
用户空间占用CPU的百分比 ,内核空间占用CPU的百分比,改变过优先级的进程占用CPU的百分比,空闲CPU百分比,IO等待占用CPU的百分比,#,#

KiB Mem :  1883844 total,    99960 free,   375164 used,  1408720 buff/cache
内存的使用情况:1883844 总内存,99960 可使用内存,375164 已使用,1408720 缓存内存

KiB Swap:        0 total,        0 free,        0 used.  1306676 avail Mem
swap交换分区信息:0 total 总量,0 free 未使用,0 used 已使用

下面就是详细的进程信息:

PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                      
  1 root      20   0   43276   2556   1348 S  0.0  0.1   4:19.02 systemd
PID:进程ID
USER:进程所有者
PR:优先级,数值越大,优先级越高
NI:nice值。负值表示高优先级,正值表示低优先级
VIRT: 进程使用的虚拟内存总量,单位kb。VIRT = SWAP+RES
RES:进程使用的、未被换出的物理内存大小,单位kb。RES = CODE + DATA
SHR:共享内存大小,单位kb
S:进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
%CPU:上次更新到现在的CPU时间占用百分比
%MEM:进程使用的物理内存百分比
TIME+:进程使用的CPU时间总计,单位1/100秒
COMMAND:进程名称(命令名/命令行)