通知设置 新通知
老男孩OpenStack企业私有云实战培训教程
学习资源 空心菜 发表了文章 0 个评论 3656 次浏览 2015-09-13 10:05
本次分享的是老男孩企业私有云培训的教学视频,正在学习openstack的同学可以下载视频学习参考。
视频下载地址:http://pan.baidu.com/s/1jGLCmkY
...查看全部
HDFS高可用方案之QJM
大数据 OpenSkill 发表了文章 0 个评论 3550 次浏览 2015-09-12 20:18
喜欢一个人,可以为TA做任何事,得到不接受却依然心甘情愿鞍前马后,苦苦等候那一线希望。对,这就是备胎,挂在汽车背后,可能一辈子也用不到的那个圆圈状的玩意儿,大部分情况下,它都会默默地挂在那里,等待几千分之一的机会,有个倒霉的轮子兄弟出事了,于是它就能派上用场了 ...查看全部
喜欢一个人,可以为TA做任何事,得到不接受却依然心甘情愿鞍前马后,苦苦等候那一线希望。对,这就是备胎,挂在汽车背后,可能一辈子也用不到的那个圆圈状的玩意儿,大部分情况下,它都会默默地挂在那里,等待几千分之一的机会,有个倒霉的轮子兄弟出事了,于是它就能派上用场了……(摘自豆瓣)
在Hadoop的分布式文件系统HDFS中,NameNode用来保存文件系统的元数据(包含目录结构/数据块位置等),如果NameNode上的数据丢失,HDFS上对应的文件数据就无法找回来了。Hadoop在2.0.0之前的版本,使用SecondaryNameNode备份NameNode的数据,但SecondaryNameNode无法转成NameNode,如果NameNode挂了,整个HDFS就会挂掉,无法实现真正的failover。这篇博文总结了5种Hadoop HA(High Available,高可用)方案,Hadoop2之后官方引入了QJM(Quorum Journal Manager)和NFS用于NameNode的备份和切换。本方将介绍的是QJM方案,它使用第二个NameNode实时同步当前NameNode的数据,相比于SecondaryNameNode,他可以随时切换成为真正的NameNode(一个可转正的高级备胎)。
先看看没有HA的HDFS的系统架构(用draw.io画的,尼马这么好的网站也被墙了):
然后有HA方案的系统架构:
以下的实验基于4个节点的Hadoop集群。其中每个节点的运行的进程列表如下:
实验环境中,所有节点的运行环境基本相同:
手动方式
上面的NameNode默认以standby的状态启动,这时因为没有active的NameNode,所以是不能在HDFS读写文件,需要将其中的一个转成active状态。比如将nn1(对应前面的配置)转成Active:
转成standby的命令是:
bin/hdfs haadmin -transitionToStandby nn1
自动切换
在当前NameNode不能使用时自动切换到第二个NameNode上,需要借助于ZooKeeper[url=ZK]/url。
ZK的安装过程和Hadoop差不多,就是下载文件、修改配置、复制到所有机器、启动。具体步骤在这里。
配置文件conf/zoo.conf:
然后要在hdfs-site.xml上添加配置:
测试
在当前NameNode运行jps看NameNode的进程ID,然后kill掉。通过Web页面( http://hdx:50070 ),可以看到standby的NameNode几乎在kill的同时转成active了。
转载地址:原文地址
在Hadoop的分布式文件系统HDFS中,NameNode用来保存文件系统的元数据(包含目录结构/数据块位置等),如果NameNode上的数据丢失,HDFS上对应的文件数据就无法找回来了。Hadoop在2.0.0之前的版本,使用SecondaryNameNode备份NameNode的数据,但SecondaryNameNode无法转成NameNode,如果NameNode挂了,整个HDFS就会挂掉,无法实现真正的failover。这篇博文总结了5种Hadoop HA(High Available,高可用)方案,Hadoop2之后官方引入了QJM(Quorum Journal Manager)和NFS用于NameNode的备份和切换。本方将介绍的是QJM方案,它使用第二个NameNode实时同步当前NameNode的数据,相比于SecondaryNameNode,他可以随时切换成为真正的NameNode(一个可转正的高级备胎)。
先看看没有HA的HDFS的系统架构(用draw.io画的,尼马这么好的网站也被墙了):
然后有HA方案的系统架构:
以下的实验基于4个节点的Hadoop集群。其中每个节点的运行的进程列表如下:
实验环境中,所有节点的运行环境基本相同:
- []Ubuntu14.04 X64[/][]4G内存[/][]OpenJDK-1.7.0[/][]100Mbps以太网[/]
严格按照单节点搭建和集群搭建两个步骤,系统建起来完全没压力。我遇到的问题是刚开始在配置文件(salves和core-site.xml等文件)中使用的是ip地址而非主机名,然后在log文件里看到各种无法连接。解决方案是修改主机名并在hosts文件里建立映射关系。[list=1]
安装Hadoop系统
hostname {new_hostname} # 修改主机名,只有当前Session有效sudo vi /etc/hostname # 永久修改主机名的方法另外,对于64位的系统,最好重新编译源码。
hdfs-site.xml文件:[list=1]
修改配置文件
dfs.namenode.name.dir /data/hadoop/namenode dfs.datanode.data.dir /data/hadoop/datanode dfs.replication 2 dfs.nameservices mycluster dfs.ha.namenodes.mycluster nn1,nn2 dfs.namenode.rpc-address.mycluster.nn1 hd1:8020 dfs.namenode.rpc-address.mycluster.nn2 hd3:8020 dfs.namenode.http-address.mycluster.nn1 hd1:50070 dfs.namenode.http-address.mycluster.nn2 hd3:50070 dfs.namenode.shared.edits.dir qjournal://hd1:8485;hd2:8485;hd4:8485/mycluster dfs.client.failover.proxy.provider.mycluster org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider dfs.ha.fencing.methods sshfence dfs.ha.fencing.ssh.private-key-files /home/hduser/.ssh/id_rsa dfs.journalnode.edits.dir /data/hadoop/journalnode
- []其中nameservices是集群的命名空间,即使有多个集群,可以共用配置文件,但是要注意某些配置项的顺序。[/][]dfs.ha.namenodes.mycluster中的mycluster是可以任取的,但是要和dfs.nameservices对应。[/][]dfs.namenode.rpc-address.mycluster.nn1参考上一条。[/][]dfs.namenode.shared.edits.dir值的格式是"qjournal://host1:port1;host2:port2;host3:port3/journalId",用来指定对应的JN节点,journalId建议使用和nameservices相同的名称。[/][]dfs.client.failover.proxy.provider.mycluster指定激活NameNode的Java类,目前Hadoop内置的只有上面那个。[/][]dfs.ha.fencing.methods是来用来隔离失效的NameNode的方法,有sshfence和Shell两种方式。sshfence需要配置dfs.ha.fencing.ssh.private-key-files私钥文件,以便交互的过程不需要输入密码。[/][]dfs.journalnode.edits.dir是JN保存数据的文件。[/]
fs.defaultFS hdfs://mycluster
- []注意mycluster要和dhfs-site.xml中的dfs.nameservices对应。fs.defaultFS不用端口号。[/]
改好配置文件好,就要将配置文件同步到所有的机器上了。可以用rsync将文件同步到多台机器上。rsync是一个增量同步工具,需要先安装。下面的rsync.sh的功能是将当前目录的所有文件发送到文件或参数对应的机器上。[list=1]
部署
$ cat rsync.sh #! /bin/bashdir=`pwd`pdir=`dirname $dir`send(){ echo "Sending to $2:$1" rsync -avez -e ssh $1 $2:$3}mul_send(){ while read host do send $dir $host $pdir done < $1}[ -f $1 ] && mul_send $1 || send $dir $1 $pdir
将rsync.sh放在etc/hadoop目录下,进入目录运行chmod +x rsync.sh./rsync.sh slaves# or ./rsync.sh hostname发送完文件之后,就是启动系统。步骤如下: 启动JNs.在所有JournalNode上运行
sbin/hadoop-daemon.sh --script hdfs start journalnode启动NameNode. 在原NameNode上运行
bin/hadoop --script hdfs start namenode # NameNode需要已经format。[url=使用上面的rsync.sh文件]/code[/url]将原NameNode(nn1)上的数据复制到第二个NameNode(nn2)。然后在nn2上运行:[code]bin/hdfs namenode -bootstrapStandby启动其他节点在NameNode上运行
sbin/start-dfs.sh
[list=1]
切换NameNode
手动方式
上面的NameNode默认以standby的状态启动,这时因为没有active的NameNode,所以是不能在HDFS读写文件,需要将其中的一个转成active状态。比如将nn1(对应前面的配置)转成Active:
bin/hdfs haadmin -transitionToActive nn1然后在NameNode的web页面上部的括号里的standby变成active。
转成standby的命令是:
bin/hdfs haadmin -transitionToStandby nn1
自动切换
在当前NameNode不能使用时自动切换到第二个NameNode上,需要借助于ZooKeeper[url=ZK]/url。
ZK的安装过程和Hadoop差不多,就是下载文件、修改配置、复制到所有机器、启动。具体步骤在这里。
配置文件conf/zoo.conf:
tickTime=2000hd2,hd3,hd4是主机名,至少需要三台,这个在一台机挂了整个系统还能用,ZK的数量一般是奇数,为什么为奇数可以参考这里。
dataDir=/data/hadoop/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=hd2:2888:3888
server.2=hd3:2888:3888
server.3=hd4:2888:3888
然后要在hdfs-site.xml上添加配置:
然后就是在NameNode的机器上初始化NameNode在ZK的状态了:
dfs.ha.automatic-failover.enabled
true
ha.zookeeper.quorum
hd2:2181,hd3:2181,hd4:2181
bin/hdfs zkfc -formatZK重启HDFS或手动启动DFSZKFailoverController(ZKFC):
sbin/stop-dfs.sh # 重启hdfs在该HA方案中,每一个NameNode都有一个对应的ZKFC。ZKFC会随NameNode启动。
sbin/start-dfs.sh
sbin/hadoop-daemon.sh start zkfc # 启动ZKFC
测试
在当前NameNode运行jps看NameNode的进程ID,然后kill掉。通过Web页面( http://hdx:50070 ),可以看到standby的NameNode几乎在kill的同时转成active了。
转载地址:原文地址
Apache无法解析PHP代码问题分析
运维 Ansible 发表了文章 0 个评论 4610 次浏览 2015-09-11 21:19
源码安装Apache 和PHP, Apache的版本是httpd-2.2.12.tar.gz,PHP的版本是php-5.3.6.tar.gz
Apache编译参数如下:./configure --prefix=/usr/local/apache2 ...查看全部
源码安装Apache 和PHP, Apache的版本是httpd-2.2.12.tar.gz,PHP的版本是php-5.3.6.tar.gz
Apache编译参数如下:
安装完成后配置Apache,写个php的info页面test.php:
在Apache中的配置文件httpd.conf中添加AddType application/x-httpd-php .php,重启APACHE,还是出现同样的错误。
而且Apache的配置文件已经加载了PHP的模块LoadModule php5_module modules/libphp5.so。最后发现是由于Apache的配置文件缺少如下的配置:
Apache编译参数如下:
./configure --prefix=/usr/local/apache2 --disable-authn-file --disable-authn-default --disable-authz-groupfile --disable-authz-user --disable-authz-default --disable-auth-basic --disable-include --enable-so --with-mpm=preforkPHP编译参数如下:
./configure --prefix=/usr/local/php5.3.6 --with-apxs2=/usr/local/apache2/bin/apxs --enable-mbstring --with-curl --with-openssl --with-zlib --enable-sockets --enable-ftp --with-mysql --with-openssl --with-gd --with-png-dir --with-jpeg-dir --with-freetype-dir --enable-sockets --enable-pcntl --with-mhash --with-mcrypt --enable-bcmath --with-gettext --enable-zip --with-pdo-mysql安装完PHP后将安装源文件中的 cp php.ini-dist /usr/local/php5.3.6/lib/php.ini
安装完成后配置Apache,写个php的info页面test.php:
phpinfo();然后用浏览器访问test.php,页面出现的是test.php文件中的内容,并不是php的info信息。
?>
在Apache中的配置文件httpd.conf中添加AddType application/x-httpd-php .php,重启APACHE,还是出现同样的错误。
而且Apache的配置文件已经加载了PHP的模块LoadModule php5_module modules/libphp5.so。最后发现是由于Apache的配置文件缺少如下的配置:
AddType application/x-httpd-php .php然后重启Apache,代码可以正常解析了!
AddType application/x-httpd-php .php .phtml .php3
AddType application/x-httpd-php-source .phps
云帆大数据Hadoop从入门到上手企业开发视频
学习资源 空心菜 发表了文章 0 个评论 2758 次浏览 2015-09-10 11:52
这次分享的是Hadoop入门开发视频,学习hadoop技术的同学,可以学习参考
视频下载地址:http://pan.baidu.com/s/1o6sxHDS
开源技术社区QQ群号:37247608 ...查看全部
Python编写HDFS Datanode监控进程并自动恢复
运维 OpenSkill 发表了文章 0 个评论 3174 次浏览 2015-09-10 01:17
因为hadoop集群中datanode是大量存在的,那么多机器,什么事都可能发生,最通常的大概就是进程挂掉了。所以为了省事,参考别人的代码写了这个监控进程的daemon。当然,稍加修改就可以用来监控别的必须常驻的进程。只需start,不用后面跟&或者前 ...查看全部
因为hadoop集群中datanode是大量存在的,那么多机器,什么事都可能发生,最通常的大概就是进程挂掉了。所以为了省事,参考别人的代码写了这个监控进程的daemon。当然,稍加修改就可以用来监控别的必须常驻的进程。只需start,不用后面跟&或者前面加nohup。
其实很多人都对进程挂掉很头疼,没事半夜得爬起来上服务器启动进程是一件非常痛苦的事情。
每2秒监测一次进程,发现进程消失就重启进程。主要原理是fork出子进程,然后将子进程挂起,并退出父进程。其程序本身作为被监控进程的外壳程序存在。
转载原文地址:原文地址
其实很多人都对进程挂掉很头疼,没事半夜得爬起来上服务器启动进程是一件非常痛苦的事情。
每2秒监测一次进程,发现进程消失就重启进程。主要原理是fork出子进程,然后将子进程挂起,并退出父进程。其程序本身作为被监控进程的外壳程序存在。
#!/usr/bin/env python实际使用中还是比较好用的,把该程序加入到启动文件中,重启服务器,服务器重启后会自动启动其所监控的进程。用到的都是python的基本模块,不会存在依赖缺失问题。
import sys, os, time, atexit, string
from signal import SIGTERM
class Daemon:
def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
#需要获取调试信息,改为stdin='/dev/stdin', stdout='/dev/stdout', stderr='/dev/stderr',以root身份运行。
self.stdin = stdin
self.stdout = stdout
self.stderr = stderr
self.pidfile = pidfile
def _daemonize(self):
try:
pid = os.fork()
if pid > 0:
#退出主进程
sys.exit(0)
except OSError, e:
sys.stderr.write('fork #1 failed: %d (%s)\n' % (e.errno, e.strerror))
sys.exit(1)
os.chdir("/")
os.setsid()
os.umask(0)
#创建子进程
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError, e:
sys.stderr.write('fork #2 failed: %d (%s)\n' % (e.errno, e.strerror))
sys.exit(1)
#重定向文件描述符
sys.stdout.flush()
sys.stderr.flush()
si = file(self.stdin, 'r')
so = file(self.stdout, 'a+')
se = file(self.stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
#创建processid文件
atexit.register(self.delpid)
pid = str(os.getpid())
file(self.pidfile,'w+').write('%s\n' % pid)
def delpid(self):
os.remove(self.pidfile)
def start(self):
#检查pid文件是否存在以探测是否存在进程
try:
pf = file(self.pidfile,'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if pid:
message = 'pidfile %s already exist. Daemon already running?\n'
sys.stderr.write(message % self.pidfile)
sys.exit(1)
#启动监控
self._daemonize()
self._run()
def stop(self):
#从pid文件中获取pid
try:
pf = file(self.pidfile,'r')
pid = int(pf.read().strip())
pf.close()
except IOError:
pid = None
if not pid:
message = 'pidfile %s does not exist. Daemon not running?\n'
sys.stderr.write(message % self.pidfile)
return #重启不报错
#杀进程
try:
while 1:
os.kill(pid, SIGTERM)
time.sleep(0.1)
os.system('/opt/modules/hadoop/hadoop-0.20.203.0/bin/hadoop-daemon.sh stop datanode')
os.system('/opt/modules/hadoop/hadoop-0.20.203.0/bin/hadoop-daemon.sh stop tasktracker')
except OSError, err:
err = str(err)
if err.find('No such process') > 0:
if os.path.exists(self.pidfile):
os.remove(self.pidfile)
else:
print str(err)
sys.exit(1)
def restart(self):
self.stop()
self.start()
def _run(self):
while True:
datanode = os.popen('ps -fe | grep "java" | grep "datanode" | grep -v "grep" | wc -l').read().strip()
tasktracker = os.popen('ps -fe | grep "java" | grep "tasktracker" | grep -v "grep" | wc -l').read().strip()
#选出进程中含有java且含有datanode|tasktracker且不含有grep,计算出现行数。修改上面的进程监控语句以适应其他应用需求
if datanode == '0':
os.system('/opt/modules/hadoop/hadoop-0.20.203.0/bin/hadoop-daemon.sh start datanode')
#修改这里的启动命令
if tasktracker == '0':
os.system('/opt/modules/hadoop/hadoop-0.20.203.0/bin/hadoop-daemon.sh start tasktracker')
#修改这里的启动命令
time.sleep(2)
#修改这里的停留时间
if __name__ == '__main__':
daemon = Daemon('/tmp/watch_process.pid')
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
else:
print 'Unknown command'
sys.exit(2)
sys.exit(0)
else:
print 'usage: %s start|stop|restart' % sys.argv[0]
sys.exit(2)
#/bin/sh
while true;
do
count=`ps -fe | grep "java" | grep "datanode" | grep -v "grep"`
if [ "$?" != "0" ]; then
/opt/modules/hadoop/hadoop-0.20.203.0/bin/hadoop-daemon.sh start datanode
fi
sleep 2
done
#/bin/sh其实作用是一样的,只是一个前台,一个后台。一个利用bash,一个利用python。
while true;
do
count=`ps -fe | grep "java" | grep "tasktracker" | grep -v "grep"`
if [ "$?" != "0" ]; then
/opt/modules/hadoop/hadoop-0.20.203.0/bin/hadoop-daemon.sh start tasktracker
fi
sleep 2
done
转载原文地址:原文地址