内核参数的优化

 Linux内核在启动的时候,能接收某些命令行选项或启动时参数。当内核不能识别某些硬件进而不能设置硬件参数或者为了避免内核更改某些参数的值,可以通过这种方式手动将这些参数传递给内核。


如果不使用启动管理器,比如直接从BIOS或者把内核文件用“cp zImage /dev/fd0”等方法直接从设备启动,就不能给内核传递参数或选项--这也许是我们使用引导管理器比如LILO的好处之一吧。


Linux的内核参数是以空格分开的一个字符串列表,通常具有如下形式:


name[=value_1][,value_2]...[,value_10]


“name”是关键字,内核用它来识别应该把“关键字”后面的值传递给谁,也就是如何处理这个值,是传递给处理例程还是作为环境变量或者抛给“init”。值的个数限制为10,你可以通过再次使用该关键字使用超过10个的参数。


首先,内核检查关键字是不是 `root=',`nfsroot=', `nfsaddrs=', `ro', `rw', `debug'或 `init',然后内核在bootsetups数组里搜索于该关键字相关联的已注册的处理函数,如果找到相关的已注册的处理函数,则调用这些函数并把关键字后面的值作为参数传递给这些函数。比如你在启动时设置参数name=a,b,c,d,内核搜索bootsetups数组,如果发现“name”已注册,则调用“name”的设置函数如name_setup(),并把a,b,c,d传递给name_setup()执行。


所有型如“name=value”参数,如果没有被上面所述的设置函数接收,将被解释为系统启动后的环境变量,比如“TERM=vt100”就会被作为一个启动时参数。


所有没有被内核设置函数接收也没又被设置成环境变量的参数都将留给init进程处理,比如“single”。


常用的设备无关启动时参数。


1、init=...


设置内核执行的初始化进程名,如果该项没有设置,内核会按顺序尝试/etc/init,


/bin/init,/sbin/init, /bin/sh,如果所有的都没找到,内核会抛出 kernel panic:的错误。


2、nfsaddrs=...


设置从网络启动时NFS的启动地址,已字符串的形式给出。


3、nfsroot=...


设置网络启动时的NFS根名字,如果该字符串不是以 "/"、","、"."开始,默认指向“/tftp-boot”。


以上2、3在无盘站中很有用处。


4、no387


该选项仅当定义了CONFIG_BUGi386时才能用,某些i387协处理器芯片使用32位的保护模式时会有BUG,比如一些浮点运算,使用这个参数可以让内核忽略387协处理器。


5、no-hlt


该选项仅当定义了CONFIG_BUGi386时才能用,一些早期的i486DX-100芯片在处理“hlt”指令时会有问题,执行该指令后不能可靠的返回操作系统,使用该选项,可以让Linux系统在CPU空闲的时候不要挂起CPU。


6、root=...


该参数告诉内核启动时使用哪个设备作为根文件系统。比如可以指定根文件为hda8:root=/dev/hda8。


7、ro和rw


ro参数告诉内核以只读方式加载根文件系统,以便进行文件系统完整性检查,比如运行fsck;rw参数告诉内核以读写方式加载根文件系统,这是默认值。


8、reserve=...


保留端口号。格式:reserve=iobase,extent[,iobase,extent]...,用来保护一定区域的I/O端口不被设备驱动程序自动探测。在某些机器上,自动探测会失败,或者设备探测错误或者不想让内核初始化设备时会用到该参数;比如: reserve=0x300,32 device=0x300,除device=0x300外所有设备驱动不探测 0x300-0x31f范围的I/O端口。


9、mem=...


限制内核使用的内存数量。早期BIOS设计为只能识别64M以下的内存,如果你的内存数量大于64M,你可以指明,如果你指明的数量超过了实际安装的内存数量,系统崩溃是迟早的事情。如:mem=0x1000000意味着有16M内存,如果是mem=0x6000000,就是96M内存了。


注意:很多机型把部分内存作为BIOS的映射,所以你在指定内存大小的时候一定要预留空间。你也可以在 pentium或者更新的CPU上使用mem=nopentium关闭4M的页表,这要在内核配置时申明。


10、panic=N


默认情况,内核崩溃--kernel panic 后会宕机而不会重启,你可以设置宕机多少秒之后重启机器;也可以在/proc/sys/kernel/panic文件里设置。


11、reboot=[warm|cold][,[bios|hard]]


该选项仅当定义了CONFIG_BUGi386时才能用。2.0.22的内核重启默认为cool reboot,warm reboot 更快,使用"reboot=bios"可以继承bios的设置。


12、nosmp 和 maxcpus=N


仅当定义了 __SMP__,该选项才可用。可以用来禁用多CPU或者指明最多支持的CPU个数。


内核开发和调试的启动时参数


这些参数主要用在内核的开发和调试上,如果你不进行类似的工作,你可以简单的跳过本小节。


1、debug


Linux的日志级别比较多(详细信息可以参看Linux/kernel.h),一般地,日志的守护进程klogd只把比DEBUG级别高的日志写进磁盘;如果使用该选项,klogd也把内核的DEBUG信息写进日志。


2、profile=N


在做内核开发的时候,如果想清楚的知道内核在什么地方耗用了多少CPU的时钟周期,可以使用核心的分析函数设置变量prof_shift为非0值,有两种方式可以实现:一种是在编译时指定,另一种就是通过“profile=”来指定; 他给出了一个相当于最小单位--即时钟周期;系统在执行内核代码的时候, profile[address >;>; prof_shift]的值就会累加,你也可以从 /proc/profile得到关于它的一些信息。


3、swap=N1,N2,N3,N4,N5,N6,N7,N8


设置内核交换算法的八个参数:max_page_age, page_advance, page_decline,page_initial_age, age_cluster_fract, age_cluster_min, pageout_weight,bufferout_weight。


4、buff=N1,N2,N3,N4,N5,N6


设置内核缓冲内存管理的六个参数:max_buff_age, buff_advance, buff_decline,buff_initial_age, bufferout_weight, buffermem_grace。


使用 RAMDISK的参数


(仅当内核配置并编译了 CONFIG_BLK_DEV_RAM)。一般的来说,使用ramdisk并不是一件好事,系统自己会更加有效的使用可用的内存;但是,在启动或者制作启动盘时,使用ramdisk可以很方便的装载软盘等设备上的映象(尤其是安装程序、启动过程中),因为在正真使用物理磁盘之前,必须要加载一些必要的模块,比如文件系统模块,scsi驱动等(可以参见我的initrd-x.x.x.img文件分析-制作安装程序不支持的根文件系统)。


早期的ramdisk(比如1.3.48的核心)是静态分配的,必须以ramdisk=N来指定ramdisk的大小;现在ramdisk可以动态增加。一共有四个参数,两个布尔型,两个整形。


1、load_ramdisk=N


如果N=1,就加载ramdisk;如果N=0,就不加载ramdisk;默认值为0。


2、prompt_ramdisk=N


N=1,提示插入软盘;N=0,不提示插入软盘;默认为1。


3、ramdisk_size=N或者ramdisk=N


设定ramdisk的最大值为N KB,默认为4096KB。


4、ramdisk_start=N


设置ramdisk的开始块号为N,当ramdisk有内核的映象文件是需要这个参数。


5、noinitrd


(仅当内核配置了选项 CONFIG_BLK_DEV_RAM和CONFIG_BLK_DEV_INITRD)现在的内核都可以支持initrd了,引导进程首先装载内核和一个初始化的ramdisk,然后内核将initrd转换成普通的ramdisk,也就是读写模式的根文件系统设备。然后Linuxrc执行,然后装载真正的根文件系统,之后ramdisk被卸载,最后执行启动序列,比如/sbin/init。


选项noinitrd告诉内核不执行上面的步骤,即使内核编译了initrd,而是把initrd的数据写到 /dev/initrd,只是这是一个一次性的设备。

 

 

 

另一:

 

使用ulimit -n命令能够看到单个进程能够打开的最大文档句柄数量(socket连接也算在里面)。系统默认值1024。
vi /etc/security/limits.conf,加入如下内容:
*               hard    nofile          10240
vi /etc/profile,加入如下内容:
ulimit -n 10240
执行:
source /etc/profile
验证:
ulimit -n
返回数值应该是10240
vi /etc/sysctl.conf
加入:
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1

shmmax - 共享内存段的最大字节数,建议设大点,甚至能够大过物理内存的字节数
shmmin - 共享内存段的最小尺寸.
shmmni - 共享内存段的最大数目.
shmseg - 每个进程可分配的最大共享内存段数目.
shmall - 最大的并发共享内存段数目,比SGA还要大.
semmns - 信号灯的最大数量,跟ORACLE的PROCESS数有关.
semmsl - 每个信号灯集合中最多的信号灯数目.
配置Linux内核参数
配置 Linux 内核参数(2种方法),修改后不用重启动更新: /sbin/sysctl -p
第一种:打开/etc/sysctl.conf
kernel.shmmax = 536870912
kernel.shmall = 2097152
kernel.shmmax = 2147483648            2G
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max = 65536
net.ipv4.ip_local_port_range = 1024     65000
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=262144
net.core.wmem_max=262144
第二种:打开终端
cat >> /etc/sysctl.conf
kernel.shmall = 2097152
  *
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
fs.file-max =
net.ipv4.ip_local_port_range = 1024     65000
net.core.rmem_default=262144
net.core.wmem_default=262144
net.core.rmem_max=262144
net.core.wmem_max=262144
EOF
这里,对每个参数值做个简要的解释和说明。
    (1)shmmax:该参数定义了共享内存段的最大尺寸(以字节为单位)。缺省为32M,对于oracle来说,该缺省值太低了,通常将其配置为2G。
    (2)shmmni:这个内核参数用于配置系统范围内共享内存段的最大数量。该参数的默认值是 4096 。通常无需更改。
    (3)shmall:该参数表示系统一次能够使用的共享内存总量(以页为单位)。缺省值就是2097152,通常无需修改。
    (4)sem:该参数表示配置的信号量。
    (5)file-max:该参数表示文档句柄的最大数量。文档句柄配置表示在linux系统中能够打开的文档数量。
    修改好内核以后,执行下面的命令使新的配置生效。
[root @linux1 /root]# /sbin/sysctl -p
以 root 用户身份运行以下命令来验证您的配置:
/sbin/sysctl -a | grep shm
/sbin/sysctl -a | grep sem
/sbin/sysctl -a | grep file-max
/sbin/sysctl -a | grep ip_local_port_range
例如:
# /sbin/sysctl -a | grep shm
kernel.shmmni = 4096
kernel.shmall = 2097152
kernel.shmmax = 2147483648
kernel.shm-use-bigpages = 0
# /sbin/sysctl -a | grep sem
kernel.sem = 250        32000   100     128
# /sbin/sysctl -a | grep file-max
fs.file-max = 65536
# /sbin/sysctl -a | grep ip_local_port_range
net.ipv4.ip_local_port_range = 1024     65000
假如系统的参数配置的比上述参数值小,则编辑 /etc/sysctl.conf 文档,添加或更改这些参数。完成后,运行以下命令激活更改:
/sbin/sysctl -p
对于 SLES 8,在完成以上步骤后运行以下命令。
/sbin/chkconfig boot.sysctl on
(6)
if [ \$USER = "oracle" ]; then 
if [ \$SHELL = "/bin/ksh" ]; then
ulimit -p 16384
ulimit -n 65536
else
ulimit -u 16384 -n 65536
fi
umask 022
fi
EOF
cat >> /etc/csh.login
if ( \$USER == "oracle" ) then
limit maxproc 16384
limit descriptors 65536
umask 022
endif
EOF
为 oracle 用户配置 Shell 限制.Oracle 建议对每个 Linux 帐户能够使用的进程数和打开的文档数配置限制,ROOT登录.(第(6)步骤能够跳过.)
cat >> /etc/profile
[ 此帖最后由Admin在2007-05-16 12:15:21从 Linux技术及应用 转移过来 ]  
在Linux下,我们使用ulimit -n命令能够看到单个进程能够打开的最大文档句柄数量(socket连接也算在里面)。系统默认值1024。
   对于一般的应用来说(象Apache、系统进程)1024完全足够使用。但是怎样象squid、mysql、java等单进程处理大量请求的应用来说就有点捉襟见肘了。假如单个进程打开的文档句柄数量超过了系统定义的值,就会提到“too many files open”的错误提示。怎样知道当前进程打开了多少个文档句柄呢?下面一段小脚本能够帮您查看:lsof -n |awk ’{print $2}’|sort|uniq -c |sort -nr|more  
  在系统访问高峰时间以root用户执行上面的脚本,可能出现的结果如下:# lsof -n|awk ’{print $2}’|sort|uniq -c |sort -nr|more    131 24204   57 24244   57 24231   56 24264
  其中第一行是打开的文档句柄数量,第二行是进程号。得到进程号后,我们能够通过ps命令得到进程的周详内容。ps -aef|grep 24204 mysql  24204 24162 99 16:15 ?    00:24:25 /usr/sbin/mysqld
  哦,原来是mysql进程打开最多文档句柄数量。但是他现在只打开了131个文档句柄数量,远远底于系统默认值1024。
  但是假如系统并发特别大,尤其是squid服务器,很有可能会超过1024。这时候就必须要调整系统参数,以适应应用变化。Linux有硬性限制和软性限制。能够通过ulimit来设定这两个参数。方法如下,以root用户运行以下命令:ulimit -HSn 4096
  以上命令中,H指定了硬性大小,S指定了软性大小,n表示设定单个进程最大的打开文档句柄数量。个人觉得最好不要超过4096,毕竟打开的文档句柄数越多响应时间肯定会越慢。设定句柄数量后,系统重启后,又会恢复默认值。假如想永久保存下来,能够修改.bash_profile文档,能够修改 /etc/profile 把上面命令加到最后。(
异常 1 
java.net.SocketException: Too many open files
    at java.net.PlainSocketImpl.accept(Compiled Code)
    at java.net.ServerSocket.implAccept(Compiled Code)
    at java.net.ServerSocket.accept(Compiled Code)
    at weblogic.t3.srvr.ListenThread.run(Compiled Code) 
异常 2
java.io.IOException:打开的文档过多
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.(UNIXProcess.java:54)
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.(UNIXProcess.java:54)
    at java.lang.Runtime.execInternal(Native Method)
    at java.lang.Runtime.exec(Runtime.java:551)
    at java.lang.Runtime.exec(Runtime.java:477)
    at java.lang.Runtime.exec(Runtime.java:443)
第一个异常在错误影响到基础 TCP 协议时抛出,而第二个异常则在错误影响到 I/O 操作时抛出。
文档打开数过多最坏的情况能够使系统崩溃,到时候只能是重起服务器了。
原因:   
    操作系统的中打开文档的最大句柄数受限所致,常常发生在很多个并发用户访问服务器的时候.因为为了执行每个用户的应用服务器都要加载很多文档(new一个socket就需要一个文档句柄),这就会导致打开文档的句柄的缺乏.
解决:
尽量把类打成jar包,因为一个jar包只消耗一个文档句柄,假如不打包,一个类就消耗一个文档句柄.
java的垃圾回收不能关闭网络连接打开的文档句柄,假如没有执行close()(例如:java.net.Socket.close())则文档句柄将一直存在,而不能被关闭.您也能够考虑配置socket的最大打开数来控制这个问题.
对操作系统做相关的配置,增加最大文档句柄数量。
Linux
在Linux内核2.4.x中需要修改源代码,然后重新编译内核才生效。编辑Linux内核源代码中的 include/linux/fs.h文档,将 NR_FILE 由8192改为65536,将NR_RESERVED_FILES 由10 改为 128。编辑fs/inode.c 文档将MAX_INODE 由16384改为262144。或编辑 /etc/sysctl.conf  文档增加两行 fs.file-max = 65536 和 fs.inode-max = 262144 。一般情况下,系统最大打开文档数比较合理的配置为每4M物理内存256,比如256M.能够用lsof -p 看打开的文档句柄数.
Windows
最大文档句柄是16,384,您在任务管理器的性能这一项中能够看到当前打开的句柄数.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值