RabbitMQ及HAProxy集群环境搭建

最近项目上要用到RabbitMQ和HAProxy共同组建的集群,在这里记录一下环境搭建过程,便于以后查阅。

项目上的虚拟化环境是基于CentOS 6.7的docker,pull的是官方的centos:centos6.7作为虚拟机。使用的RabbitMQ版本是3.6.1,erlang也是rabbitmq官方提供的下载,具体版本号是7.3 。docker启动时需要指定IP地址。

由于docker拉下来的image本身和普通OS是有一定区别的,有一些必须的包都没有装,所以要先把这些包装全了,主要要装的是ifconfig和scp,logrotate是rabbitmq需要用的,也一并算在这里。命令如下:

yum install iputils
yum install openssh-clients
yum install logrotate

环境安装完毕后,需要从网上下载最新的erlang安装包和rabbitmq安装包,首先安装erlang,其次安装rabbitmq。由于都是rpm,就不多说安装过程了。如果有提示缺少依赖关系的话,自行补上。

接下来安装haproxy。在haproxy的安装过程中,由于linux2.6 kenel的epoll功能可以提高HAProxy的性能,故在编译时要加上TARGET=linux26或TARGET=generic。
# make TARGET=generic
# make install

执行完毕后,haproxy已经安装在系统中,成为系统的一部分了。下面进入具体的集群环境搭建过程。

这次要搭建的是基于rabbitmq的镜像集群,为保证持久化和性能的平衡,主节点是内存节点,从节点是磁盘节点。HAProxy暂时选择最基本的round-robin算法。在集群中,haproxy的作用是分发消息,起到负载均衡的作用。rabbitmq的内存节点负责与haproxy交互传输消息,磁盘节点负责持久化工作,不直接承载消息。

rabbitmq的集群是通过机器名来互相传递消息的,所以需要配置/etc/hosts以及/etc/sysconfit/network的机器名,修改完毕后需要重启docker。docker重启完毕后,需要修改/var/lib/rabbitmq/.erlang.cookie中的cookie值。由于rabbitmq的集群本质上是erlang的集群,所以需要遵从erlang的技术规范,把集群中的机器刷成同样的cookie。由于erlang和rabbitmq的特殊需求,这个文件必须是400权限,需要在修改前改成666,修改好以后还要还原为400,否则集群启动会报错。

安装完毕后,可以在bash下执行rabbitmq-server -detached,确定一下系统安装是否正常,如果输出没有报错,就表示完成了rabbitmq的单点安装。下面需要进入集群配置过程。rabbitmq的节点实际上更类似于一个水平扩容的过程,同一个集群中的节点会共享metadata,例如exchange和queue的定义以及binding的定义,但是不会共享message。这种设计充分说明了MQ的解耦,通过水平扩容,保证每个节点都可以单独提供服务,充分利用每个节点的计算能力,share nothing。

由于rabbitmq的集群设计,使得节点加入集群的方式非常简单,只需要执行

rabbitmqctl join_cluster rabbit@xxxxx

就能加入集群了。rabbitmq会处理完剩下的事情。如果出现报错,请首先检查hostname等配置是否正常,机器之间能否通过机器名互相访问。不要去看rabbitmq无脑吆喝的什么TLS和SSL。

同样,基于上面说的share nothing的集群架构设计,rabbitmq的每个节点都可以随时离线,也可以随时上线。最后一个退出的节点,需要在启动时第一个启动,否则系统会在启动时等待三十秒,等待这个节点上线。同时,加入集群这个操作仅仅表明进行元数据同步,不会自动启动消息服务,需要手工start_app。当然,这些都是bash指令,写一个batch也是可以的。

默认情况下,集群的节点都是disc节点,如果需要修改类型要先stop_app,再执行change_cluster_node_type ram,再执行start_app。反之亦然。在rabbitmq中,镜像等操作被抽象为policy,是通过设置ha policy来完成镜像操作的,没有单独的镜像cli。下面的句子可以将集群中所有节点设为镜像。

rabbitmqctl set_policy -p /  ha-allqueue “^” ‘{“ha-mode”:”all”}’

完成镜像后,需要对数据进行同步,请执行

rabbitmqctl sync_queue ryttest。

如果java client提示类似NOT_ALLOWED – access to vhost ‘/’ refused for user ‘xxx’的话,需要给这个用户加上对vhost的权限,语句如下:

rabbitmqctl  set_permissions -p / xxx ‘.*’ ‘.*’ ‘.*’

 

最后,附上基于1.6.1的haproxy配置文件

haproxy配置文件
#this config needs haproxy-1.6

#logging options
global
log 127.0.0.1 local0 info
maxconn 5120
chroot /usr/local/sbin
uid 99
gid 99
daemon
quiet
nbproc 20
pidfile /var/run/haproxy.pid

defaults
log global
#使用4层代理模式,”mode http”为7层代理模式
mode tcp
#if you set mode to tcp,then you nust change tcplog into httplog
option tcplog
option dontlognull
retries 3
option redispatch
maxconn 2000
contimeout 5s
clitimeout 120s
srvtimeout 120s

#front-end IP for consumers and producters
listen rmqcluster
bind 0.0.0.0:5672
#配置TCP模式
mode tcp
#balance url_param userid
#balance url_param session_id check_post 64
#balance hdr(User-Agent)
#balance hdr(host)
#balance hdr(Host) use_domain_only
#balance rdp-cookie
#balance leastconn
#balance source //ip
#简单的轮询
balance roundrobin
#rabbitmq集群节点配置
server rabbit1 172.17.0.1:5672 check inter 5000 rise 2 fall 2
server rabbit2 172.17.0.2:5672 check inter 5000 rise 2 fall 2

#配置haproxy web监控,查看统计信息
listen stats
bind 192.168.0.94:8100
mode http
option httplog
stats enable
#设置haproxy监控地址为http://localhost:8100/rabbitmq-stats
stats uri /rabbitmq-stats
stats refresh 5s

发表在 Java | 留下评论

火花缤纷

上一次我们搞定了安装,这次我们要干熟么呢?

唔,为了安全,我们搞个集群吧。spark集群安装比较简单,几个脚本搞定。先定好主机和从机,做好存储规划和网络互访。每台机器都要对bin和sbin做755,机器之间可以不做ssh互信,网络通就行了。 

  • 完成以后,去conf把slave文件以及env文件根据模板创建出来,slave里一行一个写上你整个集群的机器名,env上写一些需要的环境变量,把他们export出来就行。忙好以后在主机的sbin执行start master脚本,然后在日志里找到启动以后的集群url,以spark打头的那个。
  • 从机上sbin里执行start slave,参数是上面说的url。
  • 如果成功,log目录里有输出的,默认的8080的web ui上也有输出。
  • 提交任务很简单,spark shell就行了。

然后我想说,任务是跑在单机上的,所以资源要共享,也所以,还是搞个hdfs吧。还有一句,jdk版本高一些好,最好是8。还有,用scala吧。李裕航说过,java api即使是8也蛋疼。

吃饭了。

发表在 CDH, Java, 基础框架搭建 | 留下评论

今天晚上开始看spark了。以后看完会来更新一个简单的memo,毕竟有手机客户端方便很多。

先说今天的,哦不对是昨天的。

spark是个牛轰轰的框架,能够在内存里对数据排序计算,能做做很多事,机器学习数据查询什么的都可以。这里不细说了,介绍网上多的是。目前最新是1.5.2。

推荐的运行环境是Linux和java环境。按照我的习惯,推荐centos6和jdk8,推荐8是因为要写lambda表达式,不然累死也别扭死了。不过呢,测试环境的话,win也是可以的,但是做集群的时候就不行了。同样也没看到小机的情况,先认为不支持吧。

下面说一个我最喜欢也是个人认为最nice的feature。

这货支持独立运行。换句话说,你可以不搞hadoop,完全没问题。而且集群也可以不依赖hadoop,这个就凶猛了。假设我有一批数据,是传统业务产生的,需要处理。我难道要为了传递数据专门去搞hdfs?spark可以直接读取磁盘上的文件,然后生成rdd去处理。

集群方面,spark自身有完备的主从机制和脚本,能搞定一切,同时也有web ui,默认8080端口。主从貌似是7070端口。集群方面如前所说,可以独立运行,也可以基于yarn或者是mesos运行。

下面一步是组建内外网的集群,其实内网来说就是主备各一台。机器应该是够的,我印象里是。今天要去公司的话就装一下。外网就一个单点吧,无所谓的事。毕竟外网考虑到访问便捷,主要是用来测试完备性,内网才是性能等等。

去睡觉了,各位晚安。

发表于钱多多 | 留下评论

基础框架搭建

最近因为项目的原因,一直在网上寻觅优秀的java框架。中间看了很多,比如SpringSide,G4Studio以及他弟弟AOS,AppFuse,Seam等等。也一直唠唠叨叨的说要写个博客,那么就写点东西吧。

这段时间主要看了G4和AOS,感觉这俩是典型的阿里风,虽然作者熊春不是阿里的人。做事雷厉风行,代码质量很高,完成度也很高。但是,用起来会发现很麻烦,原因恰恰就是集成度太高了。浓重的个人气息,带来了强烈的个人习惯。举个例子,AOS的变量名都是下划线结尾,还有w\g\t打头的函数名,很明显的MFC程序员。看后台还好,MyBatis3的代码凑合也能看看,结果看到前台就疯了,居然是AOS自己的js函数。没有文档,没有注释,底层框架不开源,想修改底层功能就只能等作者心情好了。。。

SpringSide的话,太简单了,没有菜单等等功能,不过这样的话也好,可以高度自定义,而且我也熟悉一点。虽然我会继续纠结,但是不出意外,应该就是用这个了。

发表在 基础框架搭建, 日记 | 留下评论

Trouble Shooting 暨 2015新篇

2015年忙到现在,忙的一个字都没写过,哎。。。

一直打算写Trouble Shooting的,但是一直没时间,也觉得不算什么Trouble。后来遇到一些来咨询的,才知道是不是问题要看人的(偷笑)。

先说正题。某友商遇到一个问题,操作系统SUSE10,软件是Java写的,数据库是Oracle。出于安全需要,由base版本开发搞了个系统加固程序,针对Linux的。加固完成,没有报错,但是软件却蹦蹦蹦的刷日志说连不上了。一群人忙着查东查西,但是所有的东西看起来都很正常,于是问题提交到了我这里。

简单问了下,Oracle的lsnrctl start会告诉你already started,但是java那边使劲报连不上数据库,Connection can not be established。

看上去问题比较奇怪,数据库说我是好的,软件说你丫骗人。但是本着没有无缘无故的恨的缘故,我写了如下几条命令让友商执行。

1 到数据库机上,su 到oracle,执行命令

lsnrctl status

2 查看结果是否显示提示监听已启动。如果监听已启动的话,执行命令

ps aux | grep ora

env | grep -i sid

其中第二条命令可能没有返回。如果同时有返回,那么两者应当一致,否则认为数据库启动有问题,建议排查数据库实例是否已启动。如果第二条无返回,那么查看第一条返回的结果集是否完整。其中应当包含全部Oracle的进程。例如ckpt、dbwr、pmon、smon等。

3 如果上述两步都无异常的话,请执行下面的命令。

3.1 在数据库机上,切换到root下,执行netstat -tnlp。查看是否有针对数据库端口的监听。附图如下。

123

3.2 登录应用机,执行telnet ip port。请将ip和port替换为对应的地址和端口。如果显示如下:

[root@li1068-133 ~]# telnet 1.2.3.4 56
Trying 1.2.3.4…

然而并不出结果的话,就说明网络不通,端口无法访问。不是所有机器都有telnet,实在不行可以在windows里搞,命令一样。

456

 

那么这个时候高度怀疑是网络防火墙的问题。检测步骤如下

iptables -L

如果没有看到ACCEPT 端口的话,请去找开发。。。

发表在 Java, oracle, 未分类 | 留下评论

CDH最佳实践 简单说说Hadoop发行版

前面几篇说了些关于Hadoop基础的东西,包括Hadoop是什么,Hadoop常见组件之类的。下面我们来讨论一个问题。假设我们需要做一个项目,里面需要用到Hadoop,HDFS,Spark,Hive,HBase这些组件,还要用一个类SQL查询的工具。那么,我们要如何满足这个需求呢?

当然,最直接的做法,飞奔去各大网站,下各个组件,各种配置,慢慢调整,恭喜发财,祝您胃口好。如果你能够在配置一次以后,形成自己的安装包,做一键启动,那您更有才了,真犀利啊!

当然,如果你又做了一个WEB的图形化界面,哇塞,好厉害好漂漂哦~不过那个类SQL的工具您也自己做了的话。。。

那你来看我文章干毛线?

我是个懒人,从来不造轮子,除非轮子不好用。另一方面,世上每一个能生财的地方一定有人去做,比如Hadoop的整体打包再发布。我们能想到,别人也能想到,于是世界上有了一个叫CDH的东西,也有个叫Hortonworks的东西。他们都是经过第三方机构整合、挑选并包装和增强的Hadoop发行版套装。两家对Hadoop都有所增强,并有部分收费支持的项目。

那么问题来了,我们要选哪个呢?我选CDH。要问我为啥,我会告诉你Intel这么大的财力物力人力都不继续开发自己的IDH了,转投CDH了么?无论为啥,Intel的选择就是对的。如果CDH不是真的好,Intel怎么可能投入这么大的精力去做这个事呢,对不对呢?

回答一下一位同学的疑问。Spark是不是只有CDH才有?答案是,不,Spark属于全人类。只不过CDH让我们有了不必太关注底层安装细节的特权。安装CDH,你不用知道Hadoop装在64位平台上要编译jar包这种事,也不用去管Spark和Hadoop整合的细节问题。你只要有一个高速的网络就行了。又或者,你看完tarball安装指南,照着做一次也就可以了。

感谢懒惰的人类,让世界更美好。。。

发表在 CDH, 写给中级技术人员的书 | 留下评论

CDH最佳实践 Hadoop周边生态圈

上一篇简单描述了一下这个系列的愿景。现在开始进入正题,由浅入深的介绍一下CDH的最佳实践。这一篇的主题,是Hadoop周边生态圈。

首先Hadoop有两个含义,一个是广义相对论,一个是狭义相对论。狭义的就是指Hadoop这个分布式任务平台,不包括其他含义。如果从广相的角度来说,Hadoop不仅仅指的是这个分布式任务平台,还包括建立在Hadoop平台上的一系列软件,比如HDFS,Hive,HBase等等。这里面还有个特别的地方,HDFS从目前来看,已经超出了组件的概念,可以认为是等同于Hadoop平台存在的一个框架了。基本上只要涉及到大数据和云计算的,都离不开HDFS。

HDFS是一个分布式的文件系统,实现了分布式计算框架里最重要的一环,资源的跨物理机分布。任何分布式系统都需要解决一个问题,就是资源如何分布式存放。这里面涉及到高效的读写,多副本复制的安全措施,CRC校验等等确保文件不出错,还要考虑到节点之间的高可用等等问题。最后,还要尽可能的透明,尽可能的简单易用。整体来说,还是个很复杂的工程。HDFS以实践的方式证明了自己的高效和易用,以至于在喜欢出同类项的开源世界都没有同类项目存在。可以负责任的说,肯定有人也想做出类似于HDFS一样的东西来,但是出于种种原因,不管是技术难度还是时间问题,都没有能够匹敌的项目。

在Hadoop和HDFS的基础上,最常用的两个组件分别是Hive和HBase。可以简单的认为,Hive是离线分析引擎,使用类似SQL的DSL来操作数据。Hive最擅长的是大数据分析,类似于Oracle的OLAP。HBase是一个面向高并发事务处理的框架,类似于OLTP。由于HBase是列式存储,在做部分运算时效率要远超Oracle。现在陆陆续续有人在基于HBase开发一些使用SQL做DSL的应用,比如说CDH的Impala。这部分框架还不是很成熟,对SQL92的支持也不是很完备。不过根据一些路线图来看,在不远的将来,会有完整支持SQL92的版本出现的。毕竟支持SQL92只是时间问题,并没有技术鸿沟。

接下来,我们来聊聊任务处理和调度部分的框架。最早也最原始的,是大名鼎鼎的三驾马车之一的MapReduce框架。MR从HDFS上读取文件作为数据来源,在经过map和(或)reduce阶段后,把计算结果提交给用户。MR的中间结果,会以文件的方式存放在HDFS上,简称落盘。这种处理方式,可想而知的,处理效率不会很好。毕竟分布式磁盘读写的效率取决于每一块磁盘的效率,还要扣除软件的消耗,整体效率不会很好。

正是由于这一系列原因,伯克利的高人们揭竿而起,创造了Spark内存处理框架。Spark和MR最大的不同,在于Spark的处理过程数据是不落盘的,全部在内存输出。此外,Spark不但可以按照传统的方式接受数据,还可以读取HBase上的数据,以及MQ里的数据。虽然说MR也可以做,但是自己做和原生自带的契合度,是不可同日而语的。

Spark对大数据贡献最大的部分,是他真正实现了流计算,Streaming。举个例子,我们需要进行实时数据分析,一旦有超速车辆,立刻扣分。如果不使用流计算,那么大致上我们需要不断扫描接口或者MQ,在触发以后生成MR任务或者Spark任务,计算完毕以后再关闭。好麻烦。

但是有了Streaming就不一样了,我们可以把数据丢进Kafka队列,Spark会帮我们做好剩下的事情。

Spark还有机器学习包MLLib,还有SQL实现,未来还会有更多更多的东西。好吧我是Spark粉。只是最近事情太多,一直没完整的时间来做这个。

发表在 CDH | 留下评论

CDH最佳实践 序

最近和勇华聊天的时候,说到写点投资未来的事情,感觉有必要写点文章积淀一下自己。那么说干就干吧。最近业余时间在研究Hadoop相关的东西,大致算一下也有个小半年时间了。回首当时对大数据一无所知的时候,真心不知道撞了多少南墙也不知道走了多少弯路,最后才跌跌撞撞的摸索出一条基本可行的路来。
上面说的这条路呢,我是指以最简单最方便的方法,构建出一个可用的大数据环境来。首先,我们是学习用的,而且是初学者,所以不应该也不可以去关注太多的细节,那样会累死自己的。其次,我们也需要这个环境尽可能的稳定,简单易上手。最后,这个环境最好是很容易就能搭建,并且不需要太多的复杂配置就能跑起来。
多说一句,我这本书不是Hadoop技术书籍,不会过多的涉及Hadoop、MR、YARN等等的技术细节,而是偏重使用层面的东西。目标读者是系统架构师、系统设计人员、数据分析人员等偏向架构设计方面的技术人员,而不是大数据相关代码的开发人员,亦或是还处在学习阶段的同学们。我会假设你实际参与过2-3个大型项目的开发,有一定的项目开发、设计经验,能够闭着眼睛随口说出在页面上点击按钮查询数据的整体前后台交互过程。语言不做太多要求,不过Hadoop系列是Java写的,跑在Linux上,所以你最好具备Java和Linux使用经验。此外,你如果能熟练使用SQL语言,那就更好了。
下面我们来罗列一下提纲吧。首先会简单介绍一下Hadoop的相关组件,以及相关功能和适用范围。然后介绍一下大数据和RDBMS的区别,后面介绍一下手工搭建和发行版的区别,再介绍一下CDH和Hortonworks,然后介绍一下CDH的组件和构成。这些写完以后,应该来说,我会选一两个主题深入的讲一下,要怎么用,怎么设计之类的。
这么估算了一下,就算集结成册,也不会太厚,挺好。看到那种厚厚一大本的东西,看到就头疼。随身的小册子其实很好。

发表在 CDH, 写给中级技术人员的书 | 留下评论

当JPA遇上MySQL表名全大写

最近在搞一个HRMS,功能不算复杂,先按下不表。这里说一个魂淡的小问题,很纠结,也很烦人。

公司之前有项目是用MySQL的,是我管的。这次这个项目也不大,就继续用那个MySQL吧。我一直知道MySQL在Linux上有字段名表名等的大小写问题,于是为了避免这个问题,选择了全大写的字段名和表名,心说虽然咱用的是JPA,只要使用注解写清楚表名和字段名是大写的,不也没事么。
实际上证明,想象比生活丰富的多,亲们。我用JPA实现登陆的时候,报错说表不存在,表名是全小写的。接下来,折腾才刚刚开始。此时是上午十点多。
解决这个问题,第一步肯定是改MySQL的cnf,改成不区分大小写,心说这就解决问题了吧。事实证明,图样图森破。。。改成大小写不敏感以后,这个表干脆怎么都访问不了了,不管是大写还是小写,show tables可以看到,但是select的时候怎么折腾都不出来。
无奈,只能改回去。但是表结构我没备份过啊,再装个Oracle又麻烦,怎么办呢?既然MySQL那边解决起来麻烦,我们在Java这想想办法吧。简单的分析一下过程,浏览器点按钮,发起请求到后台,Controller接到请求后通过service找到对应的dao,dao又通过Spring Data找到Hibernate实现的JPA规范,再转化成SQL语句发送给数据库执行。只要能在发送前把表名改成大写就能解决问题了。
那么这个把表名改成大写或者小写,是在哪里执行的呢?不知道同学们还记不记得,JPA对字段有一个转换,a_b会转换成aB。这个当然不是Java内核实现的,这个是Hibernate的JPA实现做的。具体到代码,这个东西是org.hibernate.cfg.ImprovedNamingStrategy,命名规则类。Hibernate实现的这个,就是转换驼峰规则的功能。我注解里表名写的是大写,但是输出的sql语句里是小写,毫无疑问,这里有转换成小写的代码。那么我只要实现一个转换成大写表名的方法就对了。

public class MySQLUpperCaseStrategy extends ImprovedNamingStrategy {

private static final long serialVersionUID = 1383021413247872469L;

@Override
public String tableName(String tableName) {
return tableName.toUpperCase();
}
}

简单又好用,不必改原来的数据库任何配置了。

发表在 Java, MySQL | 留下评论

Titan专题 Titan简介

简单介绍一下titan.
Titan是一个图算法库,热推的是它的并行图计算功能。当然,大家都能理解的,实际上他并不能真的实现图算法的并行,只是利用了多线程的并行。可以理解为有限度的并行,或者是部分任务的分拆。
Titan里面的一些概念还是传统的概念,比如点,边,属性,出度入度,弧等等。我们可以自己构建算法模型,来实现自己的业务,Titan能帮你做的,是高效而准确的实现图算法,别无其他。
举个例子,我们要寻找一些顶点的共同父节点,那么就可以构建一幅图,然后找出这些点,再找出它们向上的路径,并寻找交集。
Titan自己是Apache的项目,文档相当的魂淡,几乎无法阅读,东一榔头西一棒。而且没有中文版的,要看就看英文版,目前最新版本是0.4.4,还凑合吧。我用下来的感受是,一般化,谈不上好,但是也不赖。

发表在 Titan | 留下评论