Introduction To Problem Solving & Programming

http://www.youtube.com/view_play_list?p=94CA590D7781A9B9

 

 

Linux 的 Out-of-Memory (OOM) Killer

转载自http://www.dbanotes.net/database/linux_outofmemory_oom_killer.html 

同事在 Linux 服务器上遇到点小问题,我也上去折腾半天。这还是第一次注意到 Linux 这个多年来就存在的特性:OOM Killer 。说白了 OOM Killer 就是一层保护机制,用于避免 Linux 在内存不足的时候不至于出太严重的问题,把无关紧要的进程杀掉,有些壮士断腕的意思。

先要学习点老知识,在 32 位CPU 架构下寻址是有限制的。Linux 内核定义了三个区域:

# DMA: 0x00000000 -  0x00999999 (0 - 16 MB) 
# LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB
# HighMem: 0x038000000 - <硬件特定>

LowMem 区 (也叫 NORMAL ZONE ) 一共 880 MB,而且不能改变(除非用 hugemem 内核)。对于高负载的系统,就可能因为 LowMem 利用不好而引发 OOM Killer 。一个可能原因是 LowFree 太少了,另外一个原因是 LowMem 里都是碎片,请求不到连续的内存区域【根据我遇到的一个案例,一个猜想是 有些应用一次性请求比较大的内存,恰恰又是 880M 之内的,空闲的(LowFree)不够大,就会触发 OOM Killer 出来干活】。检查当前 LowFree 的值:

# cat /proc/meminfo |grep LowFree 

检查LowMem内存碎片:

# cat /proc/buddyinfo

上面这条命令要在 2.6 Kernel 环境下有效。据说使用 SysRq 的方式更好,不过 Hang 的时候再用吧。参见 Metalink Note:228203.1 。

根据一些文档描述,OOM Killer 在 2.4 与 2.6 上表现是不一样的。2.4 的版本中是把新进来(新申请内存)的进程杀掉。而 2.6 上是杀掉占用内存最厉害的进程(这是很危险的,很容易导致系统应用瘫痪)。

对于 RHEL 4 ,新增了一个参数: vm.lower_zone_protection 。这个参数默认的单位为 MB,默认 0 的时候,LowMem 为 16MB。建议设置 vm.lower_zone_protection = 200 甚至更大以避免 LowMem 区域的碎片,是绝对能解决这个问题的(这参数就是解决这个问题出来的)。

而对于 RHEL 3 (Kernel 2.4) 似乎没什么好办法,一个是用 Hugemem 内核(天知道会不会引入新的毛病),一个是升级到 2.4.21-47 并且使用新的核心参数 vm.vm-defragment 控制碎片的数量。再就是使用 RHEL 4 (Kernel 2.6),这又绕回去了。说白了,如果遇到 OOM Killer ,基本上是低版本 Kernel 设计上有点缺陷。

其它,如果去查询 RedHat 的 Bug 库,会发现不少 Kernel 版本也有 Bug 的。尤其在使用 NFS 的场景。

Tip: OOM Killer 的关闭与激活方式:

# echo "0" > /proc/sys/vm/oom-kill 
# echo "1" > /proc/sys/vm/oom-kill

更多参考信息:



围棋自动提子的算法

可以仿照迷宫的算法来编制,假设是白棋提黑子:
1、以白棋当前下的点为例,遍历此白子的四个邻接子(上下左右)

2、如果此邻接子为黑子则分别向它的四个临接点做遍历;如果为白子则返回第1步取下一个邻接子
3、如果遇到白棋,则此个方向的遍历结束,此方向黑棋无气;
4、如果遇到棋盘边界,则此个方向的遍历结束,此方向黑棋无气;
5、如果遇到空(临界点处无棋子),则整个遍历结束,黑棋还有气;
6、如果遇到黑棋,则又向它的三个临接点遍历(去除掉来路的那个临接点),继续执行3-6部,直到遇到结束条件返回;

7、如果4个邻接子都遍历完则结束否则返回第1步,去下一个邻接子。

在整个遍历过程中要记住所有黑棋的位置,在整个遍历结束后,如果不是因为第四种情况结束的,则所有的黑棋将被删除。

UNIX编程的艺术

 

花了3天的时间略读了一下UNIX编程艺术这本书,对某些概念有了了解,对某些方法有了认识。
1、软件模块之间的正交性,模块之间要做到相互无影响,也就是要尽量解耦
2、软件的透明性,我的理解就是代码的层次很清晰,层次尽量少,尽量薄
3、软件的紧凑性,按照作者的说法,就是要围绕一个中心来组织代码,比如一个强大的算法
4、程序之间的通信协议尽量采用文本数据而不是二进制数据,这样有几个好处,容易理解、扩展方便、调试方便。如果认为效率较低占用更多带宽,可以压缩。
5、 尽量避免使用多线程的方法。UNIX的工程哲学是采用多个进程,多个进程间通过管道、文本协议、标准输入输出来相互协作完成工作,就好像一条流水线。在单个进程内,可以利用select、poll这类多路复用技术避免多线程(还有就是nonblock操作)。
6、脚本语言的妙用,perl、python、ruby,可以在c/c++不擅长的领域发挥作用,有效提高生产率,还可以作为领域语言发挥作用
7、 数据驱动编程的模型。采用文本数据+领域语言+基础模块来完成工作。文本数据描述复杂任务本身,领域语言(由脚本语言编写)构成逻辑层用来解释文本数据并 将复杂任务分解为多个基础任务并调用负责完成基础任务的模块(由c/c++语言编写)。当领域逻辑较简单时也可以省略逻辑层。
8、遵循简单但不能太简单(不能简单到无法完成任务)的原则,尤其是由多个简单的模块而不是由一个复杂的模块来完成任务。
9、复杂度的分类,偶然复杂度--由开发人员的素质决定,比如偶然犯的错误,不好的编程习惯等;选择复杂度--由开发人员所选择的编程语言、建模方法、设计方法所决定;本质复杂度--由任务自身的数据结构、功能需求决定。
10、使用yacc和lex(gnu版本bison、flex)来根据BNF做解析器,对于设计标准协议、解析标准协议十分有效。
11、好好利用emacs的强大功能(今天才知道emacs可以很好的结合cvs使用)。

python如何支持并发

原文见A followup on Concurrency within Python

  1. 安全线程,去掉了GIL。Adopt/move forward with a version of CPython based on the work/concepts offered in Adam Olsen's Safe/Without GIL Threading work. Adopt the monitor and deadlock work for all of CPython, but leave the GIL removal as a compile-time option (python3.0 and python3.0-mt binaries).
  2. 新增 pyProcessing, pprocess, or Parallel-Python 模块to the standard library for those who want to use vanilla cpython, and to whom the fork method works. Which module is added should use existing Python semantics, but be powerful enough for advance/distributed usage. Note, I have started work on a PEP to get the pyProcessing module into the stdlib.
  3. Add an Actor - or Actor-Like module to the functools module, in keeping with the concepts of the current implementations. Python's implementation would be obviously leaky. (Note, I am not a functional programmer by any stretch, I like my OOP, suggestions welcome). This could easily take advantage of both the Safe Threading work.
  4. Add a lightweight (not XML) messaging system to couple with the Actor implementation . (no, I have no suggestions here)
  5. 作者没说,我想当然是stackless python

关于查询存储服务的思考

看来接入服务器内部,确实需要一个事务的处理机了,要把这个概念抽象出来,并实现之。主要用于历史文件的多点查询、批量升级、群呼等操作。否则现在出现了大量虽不尽相同,但处理流程相似的雷同代码。