Linux的overcommit配置
Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做Overcommit。
当内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。
Overcommit和下面两个vm的配置有关系。
vm.overcommit_ratio
vm.overcommit_memory
Linux对大部分申请内存的请求都回复"yes",以便能跑更多更大的程序。因为申请内存后,并不会马上使用内存。这种技术叫做Overcommit。
当内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便释放内存。
Overcommit和下面两个vm的配置有关系。
vm.overcommit_ratio
vm.overcommit_memory
前言: 原文《Linux System and Performance Monitoring》,本文尝试翻译文章中的CPU篇,并且省略了一些地方,也在一些地方加了自己的理解。
转载请注明出处: http://www.firefoxbug.com/?p=2760
The utilization of a CPU is largely dependent on what resource is attempting to access it. The kernel has a scheduler that is responsible for scheduling two kinds of resources: threads (single or multi) and interrupts. The scheduler gives different priorities to the different resources. The following list outlines the priorities from highest to lowest:
- Interrupts – Devices tell the kernel that they are done processing. For example, a NIC delivers a packet or a hard drive provides an IO request
- Kernel (System) Processes – All kernel processing is handled at this level of priority.
- User Processes – This space is often referred to as “userland”. All software applications run in the user space. This space has the lowest priority in the kernel scheduling mechanism.
In order to understand how the kernel manages these different resources, a few key concepts need to be introduced. The following sections introduce context switches, run queues, and utilization.
1.打开内核的forward功能
# sysctl -A | grep 'net.ipv4.ip_forward' net.ipv4.ip_forward = 0 如果为0,需要改成1 # vim /etc/sysctl.conf net.ipv4.ip_forward = 1 要使其失效做如下操作 # sysctl -p
volume的配置就是在 hdfs-site.xml 下
<property>
<name>dfs.datanode.data.dir</name>
<value>/sda1,/sda/disk1</value>
</property>
我今早是新加了一个volume,就是(所有机器都是)
drwx------ 4 hadoop hadoop 4096 Apr 2 13:33 /sda1 drwx------ 4 admin admin 4096 Apr 2 13:33 /sda/disk1
用subprocess的时候,怎么获取stdout和stderr?下面是一种方式
import subprocess p = subprocess.Popen(['tail','-10','/tmp/hosts.txt'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=False) stdout,stderr = p.communicate() print 'stdout : ',stdout print 'stderr : ',stder
项目中经常需要解析配置文件,最简单的就是有很多个section,然后每个section里面都是很多option,每一项option的组成都是key=value,怎么解析这个配置文件?python有内置的库可以解决,比如下面是一个配置文件的demo
#WatchDir 配置文件 #配置的value的时候除了第一项就先别加单引号或者双引号了 [monitor] #监控路径 WatchPath='/var/log/' #数据写到本地磁盘cache时间间隔,单位:S Interval=10 #是否以守护进程方式运行 Daemon=False #mysql配置 [mysql] mysql_host = 127.0.0.1 mysql_username = root mysql_password = 12345678 mysql_port = 3306 mysql_dbname = db_a mysql_table = tb_b
先看看这个
#!/bin/bash function a() { while read var do echo $var done < 1.txt echo $var } a
ganglia有一种工作模式是组播,顾名思义,以组播的形式发出自己采集到的信息。这时候集群内所有配置成组播的都可以接收数据,也就是说在组播的情形下,集群内的数据都是共享并且一致的(和路由协议很像),gmetad的功能就是从采集集群内所有系统状态信息,在组播的工作模式下,gmetad可以从任一台gmond上采集集群信息。但是组播的局限性就是在于集群要在一个网段内,并且网络负载提高。 ganglia还有一种工作模式是单播,每个agent上的gmond采集好各自的信息,然后通过udp汇总到一台gmond上,然后这台gmond汇总所有来自其他gmond的信息并且联合本机信息也发送给ganglia,单播的模式就是push,gmetad等待从gmond中心节点上过来的信息。 gmetad会把从gmond收集到的信息写入rrdtool里面,rrdtool是一个环形数据库,用来存储集群信息,然后在ganglia-web可以去读取rrdtool,并且绘图呈现给前端。
问题一:
/etc/hosts 192.168.1.1 www.firefoxbug.net $ awk '{print $1}' /etc/hosts ==>> 打印IP $ awk "{print $1}" /etc/hosts ==>> 打印整行
$ echo $1 $ awk "{print }" /etc/hosts
问题二:
echo '\'' ==>> 等待输入 echo "\"" ==>> 输出"
reslov.conf中的search主要是用来补全hostname的,有时候域名太长,可以做一个短域名做主机名字,但是DNS解析需要的是FQDN,而在resolv.conf中设置search能进行补全。
vim /etc/hosts 42.120.7.71 www
vim /etc/resolv.conf search firefoxbug.net nameserver 114.114.114.114
Server: 114.114.114.114 Address: 114.114.114.114#53 Non-authoritative answer: Name: www.firefoxbug.net Address: 42.120.7.71
正确的域名解析顺序是:
1. 查找/etc/hosts
2. 根据nameserver查找域名
3. 如果在nameserver查找不到域名就进行search补全,重新走1~2步
#!/bin/bash echo "shell定义字典" #必须先声明 declare -A dic dic=([key1]="value1" [key2]="value2" [key3]="value3") #打印指定key的value echo ${dic["key1"]} #打印所有key值 echo ${!dic[*]} #打印所有value echo ${dic[*]} #遍历key值 for key in $(echo ${!dic[*]}) do echo "$key : ${dic[$key]}" done echo "shell定义数组" #数组 list=("value1" "value2" "value3") #打印指定下标 echo ${list[1]} #打印所有下标 echo ${!list[*]} #打印数组下标 echo ${list[*]} #数组增加一个元素 list=("${list[@]}" "value3")
之前Linux read函数浅析-高速缓存说到Linux下读写文件都是通过高速缓存区实现的,应用程序要和底层的设备打交道,首先是通过高速缓存区,要是所要读的数据不存在,高速缓存区会帮应用程序代理去“拿”数据,高速缓存区的处理程序会向设备的驱动程序发出读请求,等待数据返回,这里就说说高速缓存区怎么实现和底层设备驱动函数交互。
最近重新开始看操作系统,看得我云里雾里,经典的操作系统书又很难,看不大懂。学校的操作系统课,说实在的,真的好难和自己真正编程结合起来,里面的概念很多,而且很多都是很老的,历史总是这么蛋疼。没办法,只能硬着头皮去看。这次先讲讲系统调用,因为没看过里面的具体源码,但是尽可能让文章偏向实际编程中的应用。
这一节讲下git的分支功能,分支功能是什么呢?其实这才是真正的软件版本管理核心,比如你的项目想添加一个的功能,但是这个版本是测试的,不一定上线,再或者想开发一个2.0版本专门用于某个场合。传统的做法就是把原来的项目代码,全部都复制一份。然后还傻乎乎地为了区别,把文件夹的名字分成1.0版本和2.0版本,别笑华哥,我之前开发OpenCDN就是这样的。到后来以至于我根本搞不清楚各个版本了,而且还浪费磁盘空间。总之看起来就是很不爽,但是用git可以解决版本控制的问题。
git通过增加分支的方法来实现,git默认的主分支就是master,可以用下面的命令查看。
git branch #查看分支 git branch new_branch #创建一个新的分支 git checkout new_branch #切换到新的分支 git checkout -d new_branch #删除分支
之前的logstash都是单机模式,把几个组件都安装在一台机器上,这一次把每个组件都安装到独立的server上,下面是架构图。
日志通过syslog-ng传输到logstash的agent端,agent主要就是负责接收日志,然后把日志放到redis,redis在这里的作用就是一个队列,主要是日志的缓存,redis是以内存做缓存的,一段时间存到磁盘上。在redis另一端是logstash index,这端主要是从redis取出日志,然后进行filter和output,filter就是对日志进行切割,匹配,过滤,logstash index这里可以是集群的,都从redis拿就行。取出来之后output可以到elasticsearch,elasticsearch也可以是集群,专门做索引。在最前端就是kibana3,再js里面配置从elasticsearch的端口读取数据,呈现到前端。
按照之前logstash+kibana3 GeoIP地理位置那样配置出来的geo地理位置里有经度和纬度,但是是独立开来的。在官网的demo上可以有coordinates的字段,只要是以数组的形式显示经纬度。下面是logstash的配置,在kibana3上呈现坐标形式。
filter { geoip { source => "source_ip" type => "linux-syslog" add_tag => [ "geoip" ] add_field => [ "[geoip][coordinates]", "%{[geoip][longitude]}" ] add_field => [ "[geoip][coordinates]", "%{[geoip][latitude]}" ] } mutate { convert => [ "[geoip][coordinates]", "float" ] }
首先安装python redis扩展模块 yum install python-redis
#!/usr/bin/env python2.6 #-*- coding: utf-8 -*- # Author : firefoxbug # E-Mail : wanghuafire@gmail.com # Blog : www.firefoxbug.net # Function : put or get log dictionary from redis-server import redis global redis_q class RedisQueue(object): """Simple Queue with Redis Backend""" def __init__(self,**redis_kwargs): """The default connection parameters are: host='localhost', port=6379, db=0""" self.__db= redis.Redis(**redis_kwargs) # self.key = '%s:%s' %(namespace, name) def qsize(self,key): """Return the approximate size of the queue.""" return self.__db.llen(key) def empty(self): """Return True if the queue is empty, False otherwise.""" return self.qsize() == 0 def put(self,key,item): """Put item into the queue.""" self.__db.rpush(key, item) def get(self,key,block=True, timeout=None): """Remove and return an item from the queue. If optional args block is true and timeout is None (the default), block if necessary until an item is available.""" if block: item = self.__db.blpop(key, timeout=timeout) else: item = self.__db.lpop(key) if item: item = item[1] return item def get_nowait(self): """Equivalent to get(False).""" return self.get(False) def connect2redis(host='127.0.0.1'): global redis_q redis_q = RedisQueue() if __name__ == '__main__': redis_q = RedisQueue(host='127.0.0.1') i = 0 while True: redis_q.put('test2','hello world') print redis_q.get('test2')
在使用redis2.4和redis2.6过程中,发现一个问题,在redis-cli里输入 keys * 参看键值的时候,2.4版本会卡住,应该是阻塞的,2.6就不是,留个笔记吧。。。
#!/bin/bash wget http://download.redis.io/releases/redis-2.6.16.tar.gz tar zxvf redis-2.6.16.tar.gz cur_dir=$(pwd) cd redis-2.6.16 make cp src/redis-server /usr/sbin/ cp src/redis-cli /usr/bin/ cp utils/redis_init_script /etc/init.d/redis curl -L https://bitbucket.org/ptylr/public-stuff/raw/41d5c8e87ce6adb34aa16cd571c3f04fb4d5e7ac/etc/init.d/redis > /etc/init.d/redis mkdir -p /etc/redis mkdir -p /var/redis mkdir -p /var/lib/redis mv ${cur_dir}/redis.conf /etc/ redis-server /etc/redis.conf
redis.conf配置文件在附件redis