My Octopress Blog

life and I

Apache Nutch and Solr 初试

| Comments

简介

Apache Nutch 是一个用JAVA语言编写的开源web爬虫项目。通过使用它,我们能够以一种自动化的方式找到web页面上的超链接, 减少了大量的维护工作,例如检查无用的链接或者创建一个所有访问过搜索页面的副本。讲到这里Apache Solr出现, Solr是一个开源的全文检索框架,通过solr我们能搜索Nutch访问过的页面。幸运的是,整合Nutch和Solr是十分简单的,例如下面的讲解。

Apache Nutch 支持Solr拆箱即用,使得Nutch 和solr的整合非常简单。同时也去除了遗留的依赖问题: 不必在Apchce tomcat上运行老版本的Nutch web应用程序,也不必基于Lucene进行搜索

Nutch安装测试

nutch 和 solr 都需要首先安装apache hadoop并设置JAVA_HOME, HADOOP_INSTALL并将其添加进环境变量中 下载nutchDownload的二进制版本,这里面用的是1.6版本 解压到某文件夹内后进入

修改nutch-site.xml

1
2
3
4
<property>
<name>http.agent.name</name>
<value>My Nutch Spider</value>
</property>

创建种子文件

1
2
3
mkdir -p urls
touch urls/seed.txt
echo http://nutch.apache.org/ > urls/seed.txt

修改conf/regex-urlfilter.txt 将

1
2
# accept anything else
+.

替换为

1
+^http://([a-z0-9]*\.)*nutch.apache.org/

创建抓取文件夹

1
2
mkdir mycrawl
chmod 777 mycrawl

运行抓取

1
bin/nutch crawl urls -dir mycrawl -depth 3 -topN 5

Solr安装测试

问题

org.apache.hadoop.mapred.InvalidInputException: Input path does not exist

由于抓取文件夹访问异常造成,需要执行创建mycrawl并赋予777权限

参考

  1. nutch1.4 + solr3.5 上路
  2. NutchTutorial

Using Cppcheck

| Comments

简介

cppcheck 是一个静态代码检查工具,支持c, c++ 代码;作为编译器的一种补充检查,cppcheck对产品的源代码执行严格的逻辑检查。 执行的检查包括

1.  自动变量检查 2.  数组的边界检查 3.  class类检查 4.  过期的函数,废弃函数调用检查 5.  异常内存使用,释放检查 6.  内存泄漏检查,主要是通过内存引用指针 7.  操作系统资源释放检查,中断,文件描述符等 8.  异常STL 函数使用检查 9.  代码格式错误,以及性能因素检查

安装和使用

1
$sudo apt-get install cppcheck

使用

1
cppcheck -j 4 --enable=all  . 2>err.txt

Google Python Style

| Comments

概述

对于Python来说,有其自己的一套语法规范,同时由于python在google里的大量应用,类似于google的c++规范。也有一个类似的python style 下面是一些摘要

摘要

工具

pychecker

1
sudo apt-get install pychecker

使用的话直接运行

1
pychecker test.py

只检测文件自身语法,添加only选项

1
pychecker --only test.py

内容

  • 使用模块的全路径名来导入每个模块
  • 模块或包应该定义自己的特定域的异常基类, 这个基类应该从内建的Exception类继承
  • 避免全局变量
  • 鼓励使用嵌套/本地/内部类或函数
  • lambda适用于单行函数
  • 访问和设置数据成员时, 你通常会使用简单, 轻量级的访问和设置函数. 建议用属性来代替它们
  • 永远不要用==或者!=来比较单件, 比如None. 使用is或者is not.
  • 永远不要用==将一个布尔量与false相比较
  • 对于序列(字符串, 列表, 元组), 要注意空序列是false
  • 注意‘0’(字符串)会被当做true
  • 不要依赖内建类型的原子性
  • 避免使用过于技巧性的特性

参考

Ubuntu Sudo 无密码

| Comments

使得sudo无需密码

需要修改/etc/sudoer 尽量使用

1
sudo visudo

进行修改,保证不会因为出错无法使用sudo

1
%sudo ALL=NOPASSWD: ALL

直接修改/etc/sudoer出错处理

进入recovery模式的root账户,执行

1
2
chmod 666 /dev/null
mount -o remount,rw /

去除只读模式后,修改/etc/sudoer文件 最后

1
init 6

Keepalived使用

| Comments

概述

项目中使用redis和自己编写的模块,需要用keepalived进行管理。下面的是相关资料和步骤。

安装

ppa安装

在Ubuntu12.04上进行安装

1
2
sudo apt-get install libssl-dev openssl libpopt-dev
sudo apt-get install keepalived

配置

源码安装

拷贝/usr/loacl/etc/rc.d/keepalived/etc/init.d 修改/etc/init.d/keepalived三处

1
2
#. /etc/rc.d/init.d/functions  
. /lib/lsb/init-functions
1
2
#. /etc/sysconfig/keepalived  
. /usr/etc/sysconfig/keepalived
1
2
3
4
5
6
7
8
start() {
  echo -n $"Starting $prog: "
#daemon keepalived ${KEEPALIVED_OPTIONS}  
      daemon keepalived start
      RETVAL=$?
      echo
      [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
}

创建目录

1
sudo mkdir -p /var/lock/subsys

安装daemon

1
sudo apt-get install daemon

ppa安装

1
sudo apt-get install keepaliaved

配置

日志配置

查看日志需要安装syslog

1
sudo apt-get install sysklogd

修改日志显示配置

1
sudo touch /var/log/keepalived.log

/etc/syslog.conf后添加

1
2
# keepalived
local0.*        /var/log/keepalived.log

重启sysklogd

修改/etc/init.d/keepalived

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/keepalived
DAEMON_OPTS="-f /etc/keepalived/keepalived.conf -d -D -S 0" #属性
NAME=keepalived
DESC=keepalived
CONFIG=/etc/keepalived/keepalived.conf
TMPFILES="/tmp/.vrrp /tmp/.healthcheckers"

#includes lsb functions 
. /lib/lsb/init-functions

test -f $CONFIG || exit 0
test -f $DAEMON || exit 0

case "$1" in
start)
log_daemon_msg "Starting $DESC" "$NAME"
for file in $TMPFILES
do
test -e $file && test ! -L $file && rm $file
done
if start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
     --exec $DAEMON -- $DAEMON_OPTS; then
     log_end_msg 0
     else
     log_end_msg 1
     fi
     ;;

重启keepalived

测试

利用apache2进行测试,首先安装

1
sudo apt-get install apache2

其配置文件在/etc/apache2中,网页文件为/var/www/index.html 根据不同的server修改index.html中的内容

master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
global_defs
{
  notification_email {
      sss@126.com
  }
}

vrrp_script apache2_check {
  script "/etc/keepalived/apach2_check.sh"
      interval 5
      weight -20
}

vrrp_sync_groups vp1
{
  group {
      vi1
  }
}

vrrp_instance vi1
{
  state                   MASTER
      interface               eth0
      virtual_router_id       51
      priority                100
      advert_int              1
      authentication {
          auth_type       PASS
              auth_pass       1111
      }
  track_script {
      apache2_check
  }

  virtual_ipaddress {
      10.10.5.120
  }
}

slave

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
global_defs
{
  notification_email {
      sss@126.com
  }
}

vrrp_script apache2_check {
  script "/etc/keepalived/apach2_check.sh"
      interval 5
      weight -20
}

vrrp_sync_groups vp1
{
  group {
      vi1
  }
}

vrrp_instance vi1
{
  state                   BACKUP
      interface               eth0
      virtual_router_id       51
      priority                95
      advert_int              1
      authentication {
          auth_type       PASS
              auth_pass       1111
      }
  track_script {
      apache2_check
  }

  virtual_ipaddress {
      10.10.5.120
  }
}

脚本文件在/etc/keepalived

1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh

if [ `ps -C apache2 --no-header| wc -l` -eq 0 ]
then
sudo service apache2 start
sleep 3
echo `ps -C apache2 --no-header| wc -l`
if [ `ps -C apache2 --no-header| wc -l` -eq 0 ];then
sudo service keepalived stop
fi
fi

分别启动master和slave,利用下面命令查看当前服务的server

1
curl 10.10.5.120

然后关闭master上面的apache2,仍然用命令查询状态发现已经转移到slave上

配置文件

对于项目中的使用来说,需要同时监测redis和自己写的模块(asio_manager_sh)其配置脚本如下

通用配置

redis需要修改的配置

redis.conf
1
2
repl-ping-slave-period 3
repl-timeout 10

通用脚本

util.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/sh
KEEPALIVED_LOG=/var/log/keepalived.log
REDIS_BIN=/usr/local/bin
  BAT_DIR=/home/cd/bat/ubuntu
check_process()
{
  name=$1


      pid=`ps -ef | grep -v grep | grep "${name}" | sed -n  '1P' | awk '{print $2}'`;

# echo pid is $pid

  if [ -z $pid ]
      then
          return 1
  else
      return 0
          fi

}

check_redis()
{

  ip=$1
      $REDIS_BIN/redis-cli -h $ip ping

      if [ $? -eq 0 ]

          then
              return 0
      else
          return 1

              fi

}

启动redis脚本

db.sh
1
2
3
4
5
#!/bin/sh

. /home/cd/bat/ubuntu/util.sh

$REDIS_BIN/redis-server /home/cd/bat/ubuntu/redis.conf&

启动asio_manager_sh

run.sh
1
2
3
4
5
#!/bin/sh

. /home/cd/bat/ubuntu/util.sh

$BAT_DIR/asio_manager_sh --LocalServerIp=10.10.5.120 --WatchDogProtoPort=5200 --ClientPrivatePort=5000 --RedisServerIP=10.10.5.120 --RedisServerPort=6379 --LogConfigFile=$BAT_DIR/log4cplus.properties &

启动keepalived脚本

start_keepalived.sh
1
2
3
#!/bin/sh

sudo service keepalived start

停止所有脚本

stop_all.sh
1
2
3
4
5
#!/bin/sh

sudo service keepalived stop
killall asio*
killall redis-server

检测manager脚本

manager_check.sh
1
2
3
4
5
6
7
#!/bin/sh

. /home/cd/bat/ubuntu/util.sh

check_process asio_manager_sh

exit $?

检测redis脚本

redis_check.sh
1
2
3
4
5
6
7
#!/bin/sh

. /home/cd/bat/ubuntu/util.sh

check_redis 127.0.0.1

exit $?

检测redis和manager脚本

both_check.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/sh
. /home/cd/bat/ubuntu/util.sh

check_redis 127.0.0.1

rc_val=$?


check_process asio_manager_sh

mc_val=$?

if [ $rc_val -eq 0 ] && [ $mc_val -eq 0 ]
then
exit 0
else
exit 1
fi

停止keepalived时运行的脚本

to_stop.sh
1
2
3
4
5
6
7
#!/bin/sh

. /home/cd/bat/ubuntu/util.sh

sudo echo "Stop redis and manager....." >> $KEEPALIVED_LOG
sudo killall redis-server
sudo killall asio_manager_sh

链接出错脚本

to_fault.sh
1
2
3
4
5
6
7
#!/bin/sh

. /home/cd/bat/ubuntu/util.sh

sudo echo "fault detect..." >> $KEEPALIVED_LOG

sudo service keepalived stop

master上脚本

成为master脚本

to_master.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/sh

. /home/cd/bat/ubuntu/util.sh

#sudo echo "sync the data from slave..." >> $KEEPALIVED_LOG

$REDIS_BIN/redis-cli -h 127.0.0.1 -p 6379 slaveof 10.10.5.119 6379 >> $KEEPALIVED_LOG 2>&1

sleep 15

$REDIS_BIN/redis-cli -h 127.0.0.1 -p 6379 slaveof no one >> $KEEPALIVED_LOG 2>&1

$BAT_DIR/run.sh

成为backup脚本

to_backup.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/sh

#KEEPALIVED_LOG=/var/log/keepalived.log
#REDIS_BIN=/usr/local/bin

. /home/cd/bat/ubuntu/util.sh

echo "sync data from slave...." >> $KEEPALIVED_LOG
#sudo service keepalived stop

sudo killall asio_manager_sh

sleep 5
$REDIS_BIN/redis-cli -h 127.0.0.1 -p 6379 slaveof 10.10.5.119 6379 >> $KEEPALIVED_LOG 2>&1
sleep 15

keepalived配置文件

keepalived.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
global_defs
{
          notification_email {
                              sss@126.com
                                      }
}

vrrp_script apache2_check {
  script "/etc/keepalived/apach2_check.sh"
  interval 5
  weight 20
}

vrrp_script manager_check {
  script "/home/cd/bat/ubuntu/manager_check.sh"
  interval 5
  weight 20
}

vrrp_script redis_check {
  script "/home/cd/bat/ubuntu/redis_check.sh"
  interval 5
  weight 20
}

vrrp_script both_check {
  script "/home/cd/bat/ubuntu/both_check.sh"
  interval 5
  weight -20
}

vrrp_instance vi1
{
  state                   MASTER
      interface               eth0
      virtual_router_id       51
      priority                100
      advert_int              1
      authentication {
          auth_type       PASS
              auth_pass       1111
      }


  track_script {
      both_check
  }


  virtual_ipaddress {
      10.10.5.120
  }

  notify_master /home/cd/bat/ubuntu/to_master.sh
      notify_backup /home/cd/bat/ubuntu/to_backup.sh
      notify_stop   /home/cd/bat/ubuntu/to_stop.sh
#       notify_fault  /home/cd/bat/ubuntu/to_fault.sh
}

backup上脚本

成为master

to_master.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/sh

. /home/cd/bat/ubuntu/util.sh

sudo echo "change to master" >> $KEEPALIVED_LOG
#sleep 15

$REDIS_BIN/redis-cli -h 127.0.0.1 -p 6379 slaveof no one >> $KEEPALIVED_LOG 2>&1

#$REDIS_BIN/redis-cli -h 127.0.0.1 -p 6379 slaveof 10.10.5.88 6379 >> $KEEPALIVED_LOG 2>&1

sleep 10

$BAT_DIR/run.sh

成为backup

to_backup.sh
1
2
3
4
5
6
7
8
9
10
11
#!/bin/sh

. /home/cd/bat/ubuntu/util.sh

echo "sync data from slave...." >> $KEEPALIVED_LOG

sudo killall asio_manager_sh

sleep 15

$REDIS_BIN/redis-cli -h 127.0.0.1 -p 6379 slaveof 10.10.5.88 6379 >> $KEEPALIVED_LOG 2>&1

keepalived配置文件

keepalived.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
global_defs
{
          notification_email {
                              sss@126.com
                                      }
}

vrrp_script apache2_check {
  script "/etc/keepalived/apach2_check.sh"
  interval 5
  weight 20
}

vrrp_script manager_check {
  script "/home/cd/bat/ubuntu/manager_check.sh"
  interval 5
  weight 20
}

vrrp_script redis_check {
  script "/home/cd/bat/ubuntu/redis_check.sh"
  interval 5
  weight -20
}

vrrp_script both_check {
  script "/home/cd/bat/ubuntu/both_check.sh"
  interval 5
  weight -20
}

vrrp_instance vi1
{
  state                   BACKUP
      interface               eth0
      virtual_router_id       51
      priority                90
      advert_int              1
      authentication {
          auth_type       PASS
              auth_pass       1111
      }

  track_script {
      redis_check
  }

  virtual_ipaddress {
      10.10.5.120
  }

  notify_master /home/cd/bat/ubuntu/to_master.sh
      notify_backup /home/cd/bat/ubuntu/to_backup.sh
      notify_stop   /home/cd/bat/ubuntu/to_stop.sh
#       notify_fault  /home/cd/bat/ubuntu/to_fault.sh
}

:

  • 需要首先启动master,然后等待第一次both_check成功后再启动backup

  • 先启动redis再启动keepalived,必要的话可以用chkconfig进行启动配置

问题

参考

  1. 通过Keepalived实现Redis Failover自动故障切换功能
  2. keepalived的log
  3. keepalived安装配置
  4. keealived-vrrp_script

OpenStack Install on Ubuntu

| Comments

概述

对于OpenStack的学习笔记之一,简单记录在Ubuntu 12.04上面安装OpenStack并进行简单 测试。基本步骤按照参考1来进行

步骤

安装依赖

ntp服务

1
sudo apt-get install ntp

将下面的内容添加进/etc/ntp.conf

1
2
3
server ntp.ubuntu.com iburst
server 127.127.1.0
fudge 127.127.1.0 stratum 10

重启ntp服务

1
sudo service ntp restart

tgt

nova-volume需要tgt支持,安装它

1
sudo apt-get install tgt

然后启动服务

1
sudo service tgt start

openiscsi-client

nova-compute需要

1
sudo apt-get install open-iscsi open-iscsi-utils

network

需要配置网络,如果没有使用NetworkManager,编辑/etc/network/interfaces,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
auto lo
iface lo inet loopback

auto eth0 
iface eth0 inet static
address 10.42.0.6
network 10.42.0.0
netmask 255.255.255.0
broadcast 10.42.0.255
gateway 10.42.0.1

auto eth1
iface eth1 inet static
address 192.168.22.1
network 192.168.22.0
netmask 255.255.255.0
broadcast 192.168.22.255

bridge-utils

1
2
sudo apt-get install bridge-utils
sudo /etc/init.d/networking restart

AMQP

1
sudo apt-get install rabbitmq-server memcached python-memcache

kvm

1
sudo apt-get install kvm libvirt-bin

配置MySQL

1
sudo apt-get install -y mysql-server python-mysqldb

修改/etc/mysql/my.cnf

1
bind-address = 0.0.0.0

重启mysql

1
sudo serivce mysql restart

配置数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql -u root <<EOF
CREATE DATABASE nova;
GRANT ALL PRIVILEGES ON nova.* TO 'novadbadmin'@'%' 
  IDENTIFIED BY '123456';
EOF

mysql -u root <<EOF
CREATE DATABASE glance;
GRANT ALL PRIVILEGES ON glance.* TO 'glancedbadmin'@'%' 
  IDENTIFIED BY '123456';
EOF

mysql -u root <<EOF
  CREATE DATABASE keystone;
  GRANT ALL PRIVILEGES ON keystone.* TO 'keystonedbadmin'@'%'
    IDENTIFIED BY '123456';
EOF

安装配置Keystone

1
sudo apt-get install keystone python-keystone python-mysqldb python-keystoneclient

编辑/etc/keystone/keystone.conf

1
2
3
[sql]
connection = mysql://keystonedbadmin:123456@10.10.5.41/keystone
idle_timeout = 200

重启并同步数据库

1
2
sudo service keystone restart
sudo keystone-manage db_sync

下载keystone_data.sh_.txtendpoints.sh_.txt 修改keystone_data.sh_.txt

1
2
ADMIN_PASSWORD=${ADMIN_PASSWORD:-123456}
export SERVICE_TOKEN="ADMIN"

运行

1
./endpoints.sh -m 10.10.5.41 -u keystonedbadmin -D keystone -p 123456 -K 10.10.5.41 -R RegionOne -E "http://localhost:35357/v2.0" -S 10.10.5.41 -T ADMIN

安装配置Glance

1
sudo apt-get install glance glance-api glance-client glance-common glance-registry python-glance

编辑/ect/glance/glance-api-paste.ini/etc/glance/glance-registry-paste.ini

1
2
3
admin_tenant_name = service
admin_user = glance
admin_password = 123456

编辑/ect/glance/glance-registry.conf

1
sql_connection = mysql://glancedbadmin:123456@10.10.5.41/glance

/etc/glance/glance-registry.conf/etc/glance/glance-api.conf末尾添加

1
2
[paste_deploy]
flavor = keystone

运行

1
2
sudo glance-manage version_control 0
sudo glance-manage db_sync

重启

1
sudo service glance-api restart && service glance-registry restart

下载img

1
wget http://uec-images.ubuntu.com/releases/12.04/release/ubuntu-12.04-server-cloudimg-amd64-disk1.img

安装配置Nova

第一个VM

Dashboard

参考

  1. Installing OpenStack Essex (2012.1) on Ubuntu 12.04

Install Hadoop on Ubuntu

| Comments

概述

Hadoop 由 Apache Software Foundation 公司于 2005 年秋天作为 Lucene 的子项目 Nutch 的一部分正式引入。它受到最先由 Google Lab 开发的 MapReduce 和 Google File System 的启发。2006 年 3 月份,MapReduce 和 Nutch Distributed File System (NDFS) 分别被纳入称为 Hadoop 的项目中。 Hadoop 是最受欢迎的在 Internet 上对搜索关键字进行内容分类的工具,但它也可以解决许多要求极大伸缩性的问题

安装

软件

软件版本分别为

  • java: jdk-7u9-linux-x64
  • hadooop: hadoop-1.1.1.tar.gz
  • eclipse: eclipse-java-juno-SR1-linux-gtk-x86_64

步骤

JAVA

解压jdk-7u9-linux-x64.tar.gz/usr/lib/jvm

运行

1
2
3
4
5
6
7
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.7.0/bin/java" 1
sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.7.0/bin/javac" 1
sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.7.0/bin/javaws" 1

sudo update-alternatives --config java
sudo update-alternatives --config javac
sudo update-alternatives --config javaws

选择对应的版本

类似配置javac, javaws

完成后判断java以及javac版本

1
2
java -version
javac -version

/etc/profile中添加

1
2
3
4
export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_09/
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH

完成后需要重启

Hadoop

创建用户组以及用户hadoop

1
2
sudo addgroup hadoop
sudo adduser --ingroup hadoop hadoop

将hadoop用户组添加进sudoer中,在/etc/sudoers中添加如下内容

1
%hadoop ALL=(ALL) ALL

修改不用密码执行sudo

1
sudo visudo

修改下面的项

1
%sudo    ALL=NOPASSWD: ALL

重启后以hadoop用户登录

配置ssh

安装opensssh-server

1
sudo apt-get install openssh-server

配置密码

1
2
ssh-keygen -t rsa -P ""
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

测试

1
ssh localhost

可以不用密码登录

禁用ipv6 可能出现问题:在ubuntu上使用IPV6会有一个问题,就是不同的网络环境配置hadoop会导致hadoop与IPV6地址绑定

/etc/sysctl.conf中添加

1
2
3
4
#disable ipv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

完成后重启

测试是否有效

1
cat /proc/sys/net/ipv6/conf/all/disable_ipv6

0表示没有成功,1表示设置成功

配置hadoop

以single node为例,hadoop版本为1.1.1

解压到某个文件夹内,比如/opt 在~/.bashrc中添加

1
2
export HADOOP_INSTALL=/opt
export PATH=$PATH:$HADOOP_INSTALL/bin

设置conf/hadoop-env.sh,添加

1
export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_09/

根据不同的启动方式配置相关文件,一共有三种启动方式:本地模式,伪分布式,完全分布式

格式化hdfs

1
hadoop namenode -format

查看日志

Eclipse

参考

  1. How do I install Oracle Java JDK 7?

C10k 相关

| Comments

简介

网络服务在处理数以万计的客户端连接时,往往出现效率低下甚至完全瘫痪,这被称为 C10K问题。随着互联网的迅速发展,越来越多的网络服务开始面临C10K问题.这个问题在2001年被c10k提出

经典的多线程模式和select模式都不再适用。 应当抛弃它们,采用epoll/kqueue/dev_poll来捕获I/O事件C10K问题, c10k翻译

c10k问题

C10K问题的最大特点是:设计不够良好的程序,其性能和连接数及机器性能的关系往往 是非线性的。举个例子:如果没有考虑过C10K问题,一个经典的基于select的程序能在 旧服务器上很好处理1000并发的吞吐量,它在2倍性能新服务器上往往处理不了并发 2000的吞吐量

常用框架模式

Serve many clients with each thread, and use nonblocking I/O and level-triggered readiness notification

把网络句柄设置为非阻塞模型,然后使用select()或poll()来告知哪个句柄已有数据在等待 处理。 此模型是最传统的,在此模型下,由内核告知你某个文件描述符是否准备好,是否已经完成你的任务

Serve many clients with each thread, and use nonblocking I/O and readiness change notification

Readiness change notification(或边缘触发就绪通知)的意思就是当你给内核一个文件描述 符,一段时间后, 如果该文件描述符从没有就绪到已经准备就绪,那么内核就会发出通知,告知 该文件描述符已经就绪, 并且不会再对该描述符发出类似的就绪通知直到你在描述符上进行一些 操作使得该描述符不再就绪 (如直到在send,recv或者accept等调用上遇到EWOULDBLOCK错误,或 者发送/接收了少于需要的字节数)。

当使用Readiness change notification时,必须准备好处理乱真事件,因为最常见的实现是只 要接收到任何数据包都发出就绪信号, 而不管文件描述符是否准备就绪

Serve many clients with each server thread, and use asynchronous I/O

IO使用的是边缘触发的完成时通知,例如,当一个操作完成时信号就被加入队列

Serve one client with each server thread

让read()和write()阻塞. 这样不好的地方在于需要为每个客户端使用一个完整的栈,从而比较浪费内存。 许多操作系统仍在处理数百个线程时存在一定的问题

Build the server code into the kernel

Novell和Microsoft都宣称已经在不同时期完成了该工作,至少NFS的实现完成了该工作。 khttpd在Linux下为静态web页面完成了该工作, Ingo Molnar完成了”TUX” (Threaded linUX webserver) ,这是一个Linux下的快速的可扩展的内核空间的HTTP服务器

在Linux内核的邮件列表上讨论了该方法的好处和缺点,多数人认为不应该把web服务器放进内核中, 相 反内核加入最小的钩子hooks来提高web服务器的性能,这样对其它形式的服务器就有益

影响服务器性能方面

高性能服务器架构(High-Performance Server Architecture)里面论述了影响服务器架构性能的若干方面

数据拷贝(Data Copies)

有一种可以避免数据拷贝的方法是使用buffer的描述符(或者buffer chains的描述符)来取代直接使用buffer指针, 每个buffer描述符应该由以下元素组成: - 一个指向buffer的指针和整个buffer的长度 - 一个指向buffer中真实数据的指针和真实数据的长度,或者长度的偏移 - 以双向链表的形式提供指向其它buffer的指针 - 一个引用计数

我不建议在任何情况下都使用这种技术,因为当你想在链上搜索你想要的一个块时,就不得不遍历一遍描述符链,这甚至比数据拷贝更糟糕。 最适用这种技术地方是在程序中大的数据块上,这些大数据块应该按照上面所说的那样独立的分配描述符,以避免发生拷贝, 也能避免影响服务器其它部分的工作

关于数据拷贝最后要指出的是:在避免数据拷贝时不要走极端

上下文切换(Context Switches)

在我的经验里,比起数据拷贝,上下文切换是让高负载应用彻底完蛋的真正杀手。系统更多的时间都花费在线程切换上, 而不是花在真正做有用工作的线程上

引起环境切换的第一个原因往往是活跃线程数比CPU个数多。随着活跃线程数相对于CPU个数的增加,上下文切换的次数也在增加, 如果你够幸运,这种增长是线性的,但更常见是指数增长

一个有适量线程的程序首先要考虑的事情是规划出如何创建一个线程去管理多连接c10k

引起环境切换的第二个原因是把对请求的处理从一个线程转移到另一个线程

限制激活线程的数量:

根据cpu个数限制线程个数?

最简单同时也是最有效的方法之一是:用一个老式的带计数的信号量,每一个线程执行的时候就先持有信号量。如果信号量已经到了最大值,那 些处于监听模式的线程被唤醒的时候可能会有一次额外的环境切换,(监听线程被唤醒是因为有连接请求到来, 此时监听线程持有信号量时发现 信号量已满,所以即刻休眠), 接着它就会被阻塞在这个信号量上,一旦所有监听模式的线程都这样阻塞住了,那么它们就不会再竞争资源了, 直到其中一个线程释放信号量,这样环境切换对系统的影响就可以忽略不计

一旦处理请求的过程被分成两个阶段(监听和工作),那么更进一步,这些处理过程在将来被分成更多的阶段(更多的线程)

应该注意到在这种模式下,对阶段的排队是在一个线程内完成的,而不是经由两个线程中完成。这样避免不断把请求放在下一阶段的队列里,紧接着又从该队列取出这个请求来执行。这种经由很多活动队列和锁的阶段很没必要

内存分配(Memory Allocator)

  • 使用预分配
  • 使用一个内存释放分配的lookaside list(监视列表或者后备列表)
  • 第三条建议与我们还没有讨论的锁有关系

锁竞争(Lock Contention)

高效率的锁是非常难规划的, 以至于我把它称作卡律布狄斯和斯库拉(参见附录)。一方面, 锁的简单化(粗粒度锁)会导致并行处理的串行化, 因而降低了并发的效率和系统可伸缩性; 另一方面, 锁的复杂化(细粒度锁)在空间占用上和操作时的时间消耗上都可能产生对性能的侵蚀。 偏向于粗粒度锁会有死锁发生,而偏向于细粒度锁则会产生竞争

首要的事情是为你程序中的锁形成一张图表,有两个轴

  • 纵轴表示代码。如果你正在应用剔出了分支的阶段架构
  • 水平轴表示数据集。在请求的每个阶段都应该有属于该阶段需要的数据集

最重要的规则:两个请求不应该产生竞争,除非它们在同一个阶段需要同样的数据集

你定义出了上面那个网格图,在你的系统中的每种类型的锁就都可以被标识出来了。 你的下一个目标是确保这些标识出来的锁尽可能在两个轴之间均匀的分布, 这部分工作是和具体应用相关的

  • 如果你能对请求按顺序编号,或者能对请求进行哈希,或者能把请求和事物ID关联起来,那么根据这些编号或者ID就能对数据更好的进行分隔。
  • 有时,基于数据集的资源最大化利用,把请求动态的分配给数据,相对于依据请求的固有属性来分配会更有优势。就好像现代CPU的多个整数运算单元知道把请求分离一样
  • 确定每个阶段指定的数据集是不一样的是非常有用的,以便保证一个阶段争夺的数据在另外阶段不会争夺

其他方面

  • 你的存储子系统在大数据读写和小数据读写,随即读写和顺序读写方面是如何进行?在预读和延迟写入方面做得怎样?
  • 你使用的网络协议效率如何?是否可以通过修改参数改善性能?是否有类似于TCP_CORK, MSG_PUSH,Nagle-toggling算法的手段来避免小消息产生?
  • 你的系统是否支持Scatter-Gather I/O(例如readv/writev)? 使用这些能够改善性能,也能避免使用缓冲链(见第一节数据拷贝的相关叙述)带来的麻烦
  • 你的系统的页大小是多少?高速缓存大小是多少?向这些大小边界进行对起是否有用?系统调用和上下文切换花的代价是多少?
  • 你是否知道锁原语的饥饿现象?你的事件机制有没有”惊群”问题?你的唤醒/睡眠机制是否有这样糟糕的行为: 当X唤醒了Y, 环境立刻切换到了Y,但是X还有没完成的工作?

c500k c1000k

从 C10K 到 C500K讨论了 Urban Airship c500k的实现,基于Java + Pure NIO.参考文档A Million-user Comet Application with Mochiweb, Part 1 另外涉及内核调优的方法Linux Kernel Tuning for C500k

网络编程之C10K、C500K、C1000K问题中说明

Select和Poll在连接数增加时,性能急剧下降的原因

  • 首先操作系统面对每次的select/poll操作,都需要重新建立一个当前线程的关心事件列表,并把线程挂在这个复杂的等待队列上,这是相当耗时的
  • 其次,应用软件在select/poll返回后也需要对传入的句柄列表做一次扫描来dispatch,这也是很耗时的。这两件事都是和并发数相关,而I/O事件的密度也和并发数相关,导致CPU占用率和并发数近似成O(n2)

Linux 2.6.35 Kernel Google捐赠了的两项新特性可以在系统的多个CPU之间分配网络处理负载,改进网络处理的性能

C1000K高性能服务器构建技术讨论了淘宝构建高性能服务器的经验

参考

Nginx 参考

| Comments

简介

Nginx是当前最流行的HTTP Server之一,根据W3Techs的统计,目前世界排名 (根据Alexa)前100万的网站中,Nginx的占有率为6.8%。与Apache相比, Nginx在高并发情况下具有巨大的性能优势。 Nginx属于典型的微内核设计,其内核非常简洁和优雅,同时具有非常高的可扩展性。 Nginx最初仅仅主要被用于做反向代理,后来随着HTTP核心的成熟和各种HTTP扩展模块的丰富, Nginx越来越多被用来取代Apache而单独承担HTTP Server的责任,例如目前淘宝内各个部门正越来越多使用Nginx取代Apache, 据笔者了解,在腾讯和新浪等公司也存在类似情况

源码

  1. Nginx
  2. Nginx 内存池
  3. 分析blog 1
  4. osc blog 1
  5. csdn blog 1
  6. Nginx开发从入门到精通

模块化

  1. Nginx模块开发入门
  2. Emiller’s Guide To Nginx Module Development
  3. Emiller’s Advanced Topics In Nginx Module Development
  4. subrequest blog
  5. 开发nginx模块之Hello World篇
  6. Nginx开发从入门到精通
  7. lua with nginx
  8. Nginx+Lua+Redis整合实现高性能API接口

其他

  1. pagefault blog
  2. csdn blog 2