代码未动,文档先行

现在估计是不可能的了,互联网项目,你说等文档写好了,那促销打折啥的活动早就凉凉了!但是,文档还是要有的,是事后补,还是前期写好,都行,重要的是要养成写文档的好习惯。

非常庆幸自己帝都经历过的几家公司,对文档要求都很严格,让我收益很多。软件研发过程中,要写的文档种类很多,需求规格说明书,软件详细设计说明书,测试报告,上线报告,产品手册,接口文档,数据库设计文档等等,自己都写过,通过写这些文档,让我对于软件研发整个生命周期的理解更加透彻。软件研发过程中,通过各种形式的文档,严格限制了需求和设计的边界,让参与研发的各个角色对于软件的理解,更加一致统一,并且保证了软件的维护质量和效率。

我们先来看看在研发一个传统企业级软件的时候,需要哪些形式的文档。


图一 软件文档控制

可以看出,软件研发的控制过程,从需求到产品发布,以及管理,在细化一下。


图二 软件文档控制

规范和文档模板,评审和周报,以及原型和需求,到手册以及部署文档等等,很全面的保障了软件交付质量。《人月神话》看了三遍,不如所有文档写一遍来的痛快和扎实。

需求规格说明书

这份文档的主要作用是理解软件的作用和约束需求(就是让客户不能随便发散),其重点不是罗列出各种功能性需求,而是设置好需求的边界,以及各种非功能性需求和与其他系统的交互规范。把功能性需求描述清楚,是基本要求,包括每个功能点的业务描述(注意要描述业务的特定上下文),详细操作步骤以及功能点的前置和后置条件,这些基本的功能表达清楚了,才能让研发和测试,以及客户都明白要做什么。可以通过UML图,表格,以及用例图等形式来表达。
现在很多互联网公司,多了一个产品经理的角色,其主要工作就是产品的需求和原型的确定,严格上来说他们都不会在写这种规格说明书了,而是通过原型来直接表达,即画出原型后,在原型页面上直接用文字标注各个关键元素的业务逻辑,很直观的表达方式,但是我觉得,一份完备的需求规格说明书还是很有必要的。


图三 软件需求规格说明书


图四 软件需求规格说明书-用例图

软件详细设计说明书

这份文档的主要目的是研发的规约设计,对于软件的主要模块如何设计,如何定义都有详细的说明。这个阶段一般需要写两份文档,概要设计和详细设计,但是很多公司已经就只要一份详细设计了,有重复的地方。
主要通过概述,业务逻辑,服务接口,数据层接口设计这几个方面来阐述一个系统的详细设计,并通过UML图来完整表达设计。依据此份文档,程序员就可以开始编码了。

模块概述:模块的业务描述,注意,同样需要说清楚这个业务模块的上下文和边界;关键流程的表达,一般通过UML中的状态图的方式来展现
业务逻辑:从界面,到业务功能,到异常处理,到特殊需求处理等都需要描述清楚
服务接口:主要是该模块和其他模块或者其他系统之间的接口描述,包括技术和业务描述
数据层接口:详细描述该模块对应的数据表结构的设计


图五 软件详细设计说明书


图六 软件详细设计说明书-类图

数据库模型设计

主要是pdm文件,以前通常用PowerDesigner来设计整个系统的数据模型,这里设计时需要根据公司具体的数据库设计规范,现在在线工具很多,形成最终的数据模型就行,保证团队内部都认可。在设计时,必须清晰的表达清楚,数据库的编码,版本,以及表的存储引擎,和每个字段的含义,索引,以及表之间的关系等等。


图七 数据模型

软件测试报告

测试是软件交付和上线前最关键的一个环节,一般有测试计划和测试报告两个文档,测试计划详细列举了对软件进行测试的环境、资源以及测试资源和测试方案,其中测试范围列出了本次测试的所有测试用例列表。

测试分为功能性测试和性能测试,测试计划中,主要内容是详细列出每个测试用例的测试详情,包括目的,角色和测试准备等。另外,测试会产生bug,通常bug会由统一的bug管理工具进行管理,无需通过文档形式列出。


图八 测试计划


图九 测试计划-测试用例详情

测试报告是对于软件测试的结果进行的总结性报告,即测试计划中的测试用例测试结果。功能性测试和性能测试可以根据不同的测试工具来进行。


图十 软件测试报告


图十一 软件测试报告-功能测试


图十二 软件测试报告-压力测试

软件产品发布

软件产品发布或者上线,会通过用户手册方式交给用户使用。包括某某系统安装配置手册,和某某系统用户手册。


图十三 安装配置手册


图十四 产品发布-配置说明

项目管理约束文档

在整个产品研发周期中,都会有各种评审和会议,都需要严格记录下来每次会议和评审的结果。列举如下。


图十五 项目管理-周报


图十六 项目管理-评审报告

2020/3/21

再聊说话上下文

GitHub上面有个项目,提问的技巧,关于提问的事情,很多年前,台湾黑客coolfire的经典8篇里面,就有关于提问的技巧,关键点在于问题抛出后,让人知道问题的上下文是什么?边界是什么?

在写邮件时(当然,现在大家都不写邮件了),也是要表述清楚你的问题和想法,而对于接受者,要理解你问题的上下文和边界,一次说不清楚,反反复复来来回回,沟通效率低下,或者干脆不回邮件。

当面沟通时,如果不理解上下文,就是人为的导致信息不对称,无法推进交流和协作,你看不管是微软小冰,还是Amazon的echo,甚至小度,都在努力解决自然语言处理中上下文的问题。

当你说一个事情的时候,如果对方原来不清楚这个事情的原委,那就一定要先把事情的上下文先描述一下,大家同步到同一个上下文之后,在进行进一步的沟通,这样效果会更好。如果遇到嘴里经常只冒一个单词的,无非是这人嘴拙,懒的说话,或者表达不出来,表达不出来就算了,那是语文没有学好,体育老师教的,但是懒说话这种,就很难原谅了,只会增加双方的沟通成本和降低效率。

有时候说和一个人好沟通,其实质就是两个人都在同一个上下文中,而且,更有默契的是,有时候一个字对方就明白你要表达的是什么,通常就是我们说的在一个频道上了。

上下文,就像我们写一个方案或者学术文章的时候,首先要做的就是名字解释,这个名词解释就是上下文,保证大家的理解在一个层面上,希望以后与人交流多做名词解释。

2020/3/19

说说这两年的经历,让大家开心下

2018-2019这2年时间,和人合伙弄了个小公司,想着做点生意,能发点小财什么的,总比打工强吧!殊不知,结局很凄惨,现在还在擦屁股!

凡事要总结,往后不要再犯同样的错误就好。

  • 找到合适的合伙人

完美的合伙人不存在的,但是基于公司发展愿景,每个合伙人各有什么特长和资源,一定要弄的明明白白,不得半点马虎,每个人负责哪块,都必须能够独当一面,否则对不起拿的股份啊!
合伙人不宜过多,看各自的资源,而且要有一个人说话算数,有拍板权,对,就是那个能够做出合理决定的人来拍板,不要什么事情都商量,特别是小事情,效率低下。
合伙人,责权利要清晰,清晰再清晰,要有退出机制,一定要有。每个合伙人的能力和性格要清晰,不然不要合作!不要合作!不要合作!重要的事情说三遍。怎么看合伙人能力?直接看看以前这个人做过的那些项目和从业经验就基本知道了。还有一点就是,看看这个人是否有独立思考能力,看看朋友圈发的内容就知道了,天天转发 的就算了,不要合作了。

  • 要有明确的目标

做外包,也要有目标,不是说人多,就公司能赚钱!你指望我,我指望你,到最后谁都指望不上;公司产品是什么,市场在哪里,怎么跑,有没有资源可以利用,竞品分析过没有,有数据支撑吗?如果没有想好,就不要合伙,不要合伙。

  • 节约为王

初期,都是成本,没有现金流的情况下,花的都是股东的真金白银,一定要节约,门面是要,但是看大小和客户类型。能节约就不要装B,重点是服务和产品做好,特别是做IT行业的。动不动没钱就思考贷款这种,算了,散了吧!

  • 项目评估

接触客户,拿项目,难免有预支费用的问题,但是,好的销售会把控,项目不明朗的情况下,要控制支出,不是吃一顿饭喝一次酒,项目就归你的。要能判断,有个底线,不能判断的销售就是有问题!
项目估价要考虑诸多因素,各种成本都要考虑进去,不要寄希望于这次项目完成后,后面还有,有没有甲方自己都不一定知道。首付比例很关键,要考虑尾款收不回来的情况,十有八九会扯皮尾款,这些考虑不到,不是合格的销售。

  • 项目过程管理

软件项目,每个环节不弄清楚就是大问题,软件项目有软件项目特色,需求不明确,功能不把关,测试不到位,每个环节不做好,交付的时候都会出问题。尽量不要外包,质量很难把控,交付的时候也会一起死掉。扯皮的事情太多,所以有条件就不要外包。
软件项目把控,有多种方式,文档和代码必须把控到位,有依据,有反馈,有记录。

  • 招聘

多招人,多聊,样本大了,就会找到合适的人,或者性价比合适的人,要多聊几次,聊透,真的,我们招到过一个神经病,是真的神经病!
尽量挖人,熟人挖,大海捞针,浪费时间,内部推荐都可以。

两年时间,时间成本,机会成本,学到一点,后面不要再犯了,踏实工作!

希望鼠年疫情早点过去,春天再见!

2020/2/9

期货量化交易数据平台浅谈

量化交易介绍

量化交易是用数学模型替代人为的主观判断,利用计算机技术从庞大的历史数据中海选能带来超额收益的多种“大概率”事件以制定策略,主要就是用计算机来代替人类做主观判断;这里我们主要讨论普通商品期货。

数学模型

多因子线性模型(目前都是基于Tick数据进行预测)

X: 影响收益率的因素 - 因子
A: 每个因素的权重 - 系数

因子计算基于历史行情的价格数据和成交量数据得出,如下公式:

系数计算基于历史行情数据进行训练,也就是进行尝试,即代入不同的预先设定系数值进行计算,计算结果越接近观测值,视为最优解。

数据平台

数据量

15个节点,每天接收1G左右数据,2010-2017年总数据量大概1T左右,2010-2017年hbase数据总量1亿条左右

行情网关实现要点

500毫秒一个tick数据

多线程异步写入kafka

数据清洗和过滤逻辑,时间戳补齐,品种名称统一等等

hbase的表名和kafka的Topic名称依据期货品种名称设计,key设计依据数据毫秒时间戳,利于业务数据操作

数据的批量导入

历史批量数据导入,使用BulkLoad快速导入HBase中,其原理是直接将生产的特定文件格式直接导入到hdfs中,符合HBase底层数据文件格式,然后通过工具BulkLoad直接挂接到HBase下即可,会通过mapreduce批量执行任务,这样大大提高记录逐行导入至HBase的效率。

kafka

topic的partiton个数需要根据consumer并行度设置,即在consumer group中有几个consumer实例,就设置几个partion,其目的是为了最大化topic的并行消费能力。

mapreduce

Mapper中执行程序找不到hbase相关的jar,cp到hadoop目录下的lib也不行,使用assemble把依赖的包全部打成一个jar;

集群上运行mapreduce程序,需要读取hbase相关,可能找不到hbase配置文件的问题

hadoop-env.sh
export HADOOP_CLASSPATH="$HADOOP_CLASSPATH:$HBASE_HOME/lib/*"

HBase

开启thrift服务,用于python访问

linux系统最大文件打开数设置,否则出现Premature EOF from inputStream异常

增加压缩存储功能snappy,否则hdfs空间占用太大

日志

平台在生产过程中,产生大量日志,其中zookeeper的日志较多,通过脚本或者命令清理。

echo “”>zookeeper.out

ls | xargs truncate -s 0

pandas

监控

Ambari来监控所有硬件资源和软件服务,较好的ui方便数据平台的管理。

计算平台Spark

总计算节点的总核数决定了并发执行的task数;

多线程、进程增加多作业执行,增加并行度;配置在作业之间轮询调度;

conf.set("spark.scheduler.mode", "FAIR")

尽量把数据分成等份的task进行并行计算,不让每个task计算时间过长,对数据进行partition,需要不断调试,找到合适的值;

对于pair类型的rdd,尽量把key进行细化,在拆分,这样数据集粒度更细,并行度更好;

当rdd后续需要进行各种join等连接操作时,特别是对于pair rdd,就需要进行分区;并且如果此rdd被反复多次使用,就需要cache操作;

做join的时候,尽量用小RDD去join大RDD,用大RDD去join超大的RDD;

RDD如果后面使用迭代,建议cache,但是一定要估计好数据的大小,避免比cache设定的内存还要大,如果大过内存就会删除之前存储的cache,可能导致计算错误,如果想要完全的存储可以设置如下

persist(MEMORY_AND_DISK)

因子和权重系数计算使用spark计算平台,10个节点,从21分钟优化到2.7分钟;

2019/2/17

日常沟通和上下文

“那个合同已经签了!”
“什么?”
“?”
“我说那个合同签了?有好几个合同目前。”
“就是某某的合同!”

“给开发一个某某功能的接口吧?”
“给分配一个git上面的权限吧?”
“做好了吗?”

这种IM工具上面的对话一天来几次的话,如果不疯也会怀疑人生的!对于IM工具进行沟通,基本的礼貌应该是:

你是谁
谁的事情
事情什么状态了
你的问题是什么
需要我做什么

小学我们学语文的时候,就知道句子的组成基本的是主谓宾,定语可以不要,但是基本的主谓宾要有吧!这种无效的沟通实在是让人怀疑世界的美好!这种低效沟通不管是当面交流还是IM工具,还是邮件,都不会有任何区别,只能增加大家心理负担。

写程序里面有个术语叫做上下文,在一个线性执行逻辑里面,如果自始至终没有一个上下文贯穿的话,就无法实现该线性逻辑中各个步骤之间的相互作用,也就是说后面逻辑不理解前面的逻辑,日常沟通一样,没有上下文的沟通非常低效,为了弄清楚大家在说什么,反复重复询问,这种低效除了说明思维懒惰之外,不知道还能说明什么!

在工作十余年之后,发现经历过的大大小小公司里面,优秀的人总会有一些共同特征,写得好;一句话能讲清楚的事情,绝不会用两句话来讲;凡事必有回应;工作稳扎稳打,结果都不会太坏!

2018/9/1

数据平台笔记-数据不一致问题排查

对于突然停电导致系统shutdown,最受伤的就是hbase的数据,完全重启后,会发现hbase的表出问题,要么表不存在,要么存在但是根本写不进去数据。大部分是由于zookeeper中保存的数据和hbase不一致,所以需要从源头进行排查,就是hbase的存储hdfs。

检查hdfs

进入hadoop的管理页面http://ibdp-00:50070,会显示错误的blocks信息,如果没有说明hdfs文件没有问题。

如果存在问题,就扫描hdfs,根据错误提示删除掉坏的block

hadoop fsck /  a
hadoop fs  -rm /xxxxx

检查HBase

这个时候在写hbase看看,能否写入,如果还是有问题,先查看hbase日志,如果出现下面所示异常,说明hbase集群状态不一致。

表有问题是,hbase客户端连接时,会不停的重试,默认是35次,可以修改小一点的值(主配置文件hbase.client.retries.number),减少重试次数。

删除zookeeper中的hbase目录,然后重启habse,在zk中自动重新建立目录。

hbase zkcli
rmr /hbase
hbase-start.sh

如果还是出现错误,那就对hbase进行状态检查和修复,先查看hbase的管理页面,查看表状态,根据所在节点,在继续查看regin server的log日志。

如上图中的hdfs中没有对应的文件,而habse meta中有数据,不一致,那么使用如下命令先检查一致性,在进行修复,修复后需要重启hbase。

hbase hbck -details
hbase hbck -fixMeta -fixAssignments

出现问题,应该先检查日志,根据日志进行判断,而不是瞎猜,浪费时间。

2018/3/3

Ambari安装笔记

通过Ambari安装hadoop是很多人的选择,但是由于各种环境问题,通常安装不顺利,而且hadoop系统最好是手动安装部署,这样维护起来也比较清晰明了,我想使用的Ambari对服务器硬件资源的监控,hadoop服务组件的监控,可以通过后期修改配置文件的方式,集成进Ambari中。

精简安装

只安装必要的组件即可,先把服务器资源监控起来。

前戏

在所在集群中设定一台安装ambari-server,非hadoop的master概念,其他被监控机器安装ambari-agent,非hadoop的slave概念;集群所有机器为centos7,所需软件从看这里下载(不同ambar版本可以自己修改链接中的版本号),请不要在线安装,很慢;找到你的OS版本,找到Tarball对应的链接地址,下载所需的全部安装文件。

以下操作没有特别说明,都在所有机器上执行。

下载文件中包含对应版本的centos的软件源地址文件,文件名为ambari.repo,拷贝到/etc/yum.repos.d/下即可,这样yum有时候需要在线安装源就不会有问题。将所有文件拷贝到集群服务器上面。另外,安装hadoop的服务器设置默认都已经做了,比如从ambari-server机器免密ssh登录到ambari-agent机器上,hosts配置等等,这里不再说了。

修改认证相关的系统配置,文件位于/etc/python/cert-verification.cfg,设置为disable。

安装

先安装ambari-server,使用如下命令直接安装server程序

yum localinstall -y ambari-server-2.5.0.3-7.x86_64.rpm

这里会将默认的依赖库postgresql安装,因为ambari默认使用postgresql存储。安装完毕后,执行如下命令进行数据库设置等初始化,默认即可

ambari-server setup

如果此过程中,发生反复,数据库需要还原,请执行如下命令

ambari-server reset

然后启动ambari server,如下命令。启动成功后,可通过http://ip:8080访问

ambari-server start

下面开始安装agent,请不要通过web页面提供的ssh安装,我们手动在各个被监控服务器上安装agent,以及其他所需的包,执行命令

yum localinstall -y ambari-agent-2.5.0.3-7.x86_64.rpm
yum localinstall -y ambari-metrics-hadoop-sink-2.5.0.3-7.x86_64.rpm
yum localinstall -y ambari-metrics-monitor-2.5.0.3-7.x86_64.rpm
yum localinstall -y smartsense-hst-1.4.0.2.5.0.3-7.x86_64.rpm

以上几个是每个被监控服务器上必须有的,手动安装好后,设置agent连接的服务器,我们这里是server所在的机器ip地址,设置文件为/etc/ambari-agent/conf/ambari-agent.ini,修改hostname为server端ip。然后启动agent服务。

ambari-agent start

然后我们访问web端正式开始安装,选择amdin下的manager ambari开始,具体根据web提示进行安装即可,因为server端会安装其他组件,如果安装过程中失败,根据log日志,直接安装下载包中的软件即可。另外,在组件选择上只选择zookeeper和ambari-metrics即可,最小化安装,其他组件暂时不需要。会要求输入一些服务的密码,请记录保存,在后期使用zeppelin等服务时会用到。

这里zookeeper也是搭建一个集群,选择3台服务器,系统也是要求最小3台机器。如图安装过程:

安装成功后,所有服务启动时,ambari-metrics服务有问题,根本问题是Metrics Collector服务启动失败,它用于收集所有被监控机器的数据,有2个原因导致:

  1. ambari-metrics服务需要使用hbase,hbase启动时默认使用自带的zookeeper,请使用前面我们安装的zookeeper集群,既然有了我们就不在使用其他zk服务了,后面hadoop组件同样也使用这一个zk集群,找到zk服务的client端口设置,在页面中找到Ambari Metrics服务的config选项卡,设置hbase.zookeeper.property.clientPort属性和hbase.zookeeper.quorum属性。

  2. hbase启动过程中,提示找不到ClassNotFoundException: org.apache.commons.httpclient.methods.RequestEntity,问题在于缺少依赖包commons-httpclient-3.1.jar,下载一个放在hbase所在目录lib包下,位于/usr/lib/ams-hbase/lib

所有服务启动成功后,如下图:

某一台服务器监控如下图所示,可以在Hosts菜单中增加新的服务器,过程同安装agent一样,新安装的机器,监控数据要等会儿才能看见,页面会自动刷新。

服务自定义

很难实现

服务的清除

安装这种分布式系统,难免来来回回几次,那么我们需要清除组件,ambari给我们提供了清除脚本很方便。

停止所有服务

停止server和agent的服务

ambari-server stop
ambar-agent stop

执行清除脚本

sudo python /usr/lib/python2.6/site-packages/ambari_agent/HostCleanup.py --silent --skip=users -o cleanup.log

手动删除相关

yum erase -y ambari-*
rm -rf /usr/lib/ambari-server
rm -rf /usr/lib/python2.6/site-packages/ambari_agent
rm -rf /usr/lib/python2.6/site-packages/指向ambari目录的软连接
rm -rf /usr/lib/python2.6/site-packages/ambari* /usr/lib/python2.6/site-packages/resource-management
yum erase -y postgresql-*
rm -rf /var/lib/pgsql*
yum clean all
rm -f /etc/yum.repos.d/ambari.repo
rm -rf /usr/iop/  
rm -rf /hadoop 
rm -rf /etc/hadoop/ /etc/hive /etc/hbase/ /etc/oozie/ /etc/zookeeper/ /tmp/spark
2018/2/9

数据平台笔记-Hadoop搭建

基本的硬件组装完成后,需要安装hadoop,目前有好几个版本可供选择,我选择的是较低的一个版本,而且是手动安装,具体下载链接请去官网寻找。在安装之前,先做好hadoop平台规划,那个节点是主节点,那个是从节点,机器名统一,做到见名知意。

服务器环境准备

ssh免密码登录

在主从节点通信时,通过ssh时需要验证密码,我们需要设置免密码的方式进行通讯。包括master到所有slave免密码,master到master自身需要免密码,具体设置方式请看以前的一篇文章。另外,在所有节点的hosts中配置好所有节点和机器名的对应关系。

关闭防火墙和selinux

systemctl status  firewalld.service
systemctl stop firewalld.service
systemctl disable firewalld.service

设置selinux为disable    /et/selinux/config

配置ntp服务

所有节点需要同步时间,保证软件的工作正常,安装ntp服务

yum -y install ntp
systemctl enable ntpd
systemctl start ntpd
timedatectl set-timezone Asia/Shanghai
timedatectl set-ntp yes
systemctl restart ntpd
ntpq -p

linux文件打开数目

在使用hbase时会打开很多文件,所有节点需要设置linux系统本身支持的文件打开数,同时还要设置hadoop组件的进程数目。

* soft nofile 1000000
* hard nofile 1000000
hdfs - nofile 32768
mapred - nofile 32768
hbase - nofile 32768
hive - nproc 32768
yarn - nproc 32768
storm - nproc 32768

文件压缩配置

hbase或者hadoop存储数据时支持多种压缩,可以使用命令hadoop checknative -a 来检查支持的压缩方式。其中使用snappy压缩时,需要os支持,所以要先在os中安装好snappy功能。具体的linux安装snappy和配置过程还是比较麻烦的,参考这里这里

linux环境变量

在系统的环境配置文件(/etc/profile)中设置好所有hadoop的环境变量,包括java环境变量,供各个组件使用

export JAVA_HOME=/usr/java/jdk1.8.0_121
export HADOOP_HOME=/opt/hadoop-2.5.2
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_YARN_HOME=$HADOOP_HOME
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export HBASE_HOME=/opt/hbase-0.98.9-hadoop2
export CLASSPATH=.:$JAVA_HOME/lib:$HADOOP_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HBASE_HOME/bin:$PATH
export SPARK_HOME=/opt/spark-1.6.3
export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin

hadoop

下载的hadoop以及其他软件都放在/opt目录下,然后进入目录/opt/hadoop-2.5.2/etc下,配置相关文件

slaves
填写所有的从节点机器名

core-site.xml
填写hdfs协议的地址和端口hdfs://ibdp-00:9000,属性名为fs.defaultFS;还有压缩项的配置io.compression.codecs

<configuration>
  <property>
  <name>fs.defaultFS</name>
  <value>hdfs://ibdp-00:9000</value>
  </property>
  <property>
  <name>io.compression.codecs</name>
  <value>
  org.apache.hadoop.io.compress.GzipCodec,
  org.apache.hadoop.io.compress.DefaultCodec,
  org.apache.hadoop.io.compress.BZip2Codec,
  org.apache.hadoop.io.compress.SnappyCodec
  </value>
  </property>
</configuration>

hdfs-site.xml
配置好hdfs的备份份数和namenode和datanode的存储目录,以及开启webhdfs功能

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:/home/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:/home/dfs/data</value>
    </property>
    <property>
        <name>dfs.webhdfs.enabled</name>
        <value>true</value>
    </property>
    <!-- Specifies the maximum number of threads to use for transferring data in and out of the DN. -->
    <property>
      <name>dfs.datanode.max.transfer.threads</name>
      <value>8192</value>
    </property>
</configuration>

yarn-env.sh
主要是配置好java_home这个环境变量,其他不动

export JAVA_HOME=/usr/java/jdk1.8.0_121

yarn-site.xml
主要配置资源管理器yarn主节点相关

<property>
    <name>yarn.resourcemanager.address</name>
    <value>ibdp-00:8032</value>
</property>
<property>
    <name>yarn.resourcemanager.scheduler.address</name>
    <value>ibdp-00:8030</value>
</property>
<property>
    <name>yarn.resourcemanager.resource-tracker.address</name>
    <value>ibdp-00:8031</value>
</property>
<property>
    <name>yarn.resourcemanager.admin.address</name>
    <value>ibdp-00:8033</value>
</property>
<property>
    <name>yarn.resourcemanager.webapp.address</name>
    <value>ibdp-00:8088</value>
</property>

hadoop-env.sh
主要配置java_home

export JAVA_HOME=/usr/java/jdk1.8.0_121

配置好后,拷贝目录到所有slave的相同目录下即可,然后开始第一次格式化所有节点的hdfs

cd /opt/hadoop/bin/ 
./hdfs  namenode -format        

在安装过程中可能会反复这个步骤,那就需要清空hdfs的数据,如下

清空配置的namenode和datanode目录下所有数据
清空/tmp下hadoop目录中的临时数据
清空zookeeper中/opt/zookeeper-data/version-2目录下所有数据,该目录存储了zookeeper的数据

启动hadoop命令比较简单,在master上直接执行一条命令即可,会启动所有slave节点的hadoop组件

./opt/hadoop-2.5.2/sbin/start-all.sh

通过命令jps可以查看hadoop的组件是否已经安装完成

slave:
6176 NodeManager
5339 DataNode
master:
5603 SecondaryNameNode
5174 NameNode
5820 ResourceManager

在hadoop维护过程中,会需要重启单个节点的服务,比如namenode服务挂掉,或者datanode服务挂掉

./opt/hadoop-2.5.2/sbin/yarn-daemon.sh start nodemanager
./opt/hadoop-2.5.2/sbin/hadoop-daemon.sh start datanode          

zookeeper

虽然hadoop本身是不需要zookeeper支持的,但是后面我们数据存储选择了hbase,hbase自身携带的zk服务我们不需要,所以需要一个统一的zk服务,支持集群,以保证整个大数据平台的zk服务的稳定性。zk集群需要奇数位的节点,我们选择3个节点部署zk集群。

同样,zookeeper下载后,统一放在/opt目录下,然后进行配置,主要配置文件为zoo.cfg,配置通信节点和数据保存目录。

server.1=ibdp-01:2888:3888
server.2=ibdp-02:2888:3888
server.3=ibdp-03:2888:3888

dataDir=/opt/zookeeper-data
clientPort=2181

/opt/zookeeper-data/目录下增加文件myid, 内容为zk节点值,即server.后面的数值。然后拷贝到其他两个节点,每个节点分别启动,命令如下

./opt/zookeeper-3.4.9/bin/zkServer.sh start

zk服务决定了整个集群的数据一致性,特别对于hbase的数据,其中region数据等等的一致性都是通过zk来保存的,如果一旦hbase出现问题,请先清空zk中的hbase目录数据,重新启动hbase即可重新写入zk。日常维护zk,使用命令行即可。

./opt/zookeeper-3.4.9/bin/zkCli.sh -server 192.168.3.201:2181,192.168.3.202:2181,192.168.3.203:2181

另外zk的日志很大,需要定时清理,如果手动清理的话,可以使用命令保留最近几日的数据。通过jps可以查看到zk服务的进程QuorumPeerMain

./bin/zkCleanup.sh -n 5

hbase

hbase我们使用zk集群提供服务,并且hbase是依赖hdfs的,配置位于/opt/hbase-0.98.9-hadoop2/conf下。对于hbase和zookeeper服务紧密结合在一起的,所有的表和region信息都存储在zk中,如果hbase出现一致性问题,请先删除zk中的相应目录数据,参考上面部分如何删除。

hbase-site.xml
配置依赖的hdfs地址和zk服务

<property>
  <name>hbase.rootdir</name>
  <value>hdfs://ibdp-00:9000/hbase</value>
</property>

<property>
  <name>hbase.cluster.distributed</name>
  <value>true</value>
</property>

<property>
  <name>hbase.zookeeper.property.clientPort</name>
  <value>2181</value>
</property>

<property>
  <name>hbase.zookeeper.property.dataDir</name>
  <value>/opt/zookeeper-data</value>
</property>

<property>
  <name>hbase.zookeeper.quorum</name>
  <value>ibdp-01,ibdp-02,ibdp-03</value>
</property>

hbase-env.sh
配置是否需要使用自带的zk服务和java_home

export HBASE_MANAGES_ZK=false
export JAVA_HOME=/usr/java/jdk1.8.0_121

hbase正常使用前提是,指定了zk服务和压缩功能的设置,以及os的文件数目设置,前文中已经提及snappy的配置,请自行参考。启动hbase通过master即可,在master上一个命令所有slave即启动

./opt/hbase-0.98.9-hadoop2/bin/start-hbase.sh

我们在使用hbase时是通过python的客户端进行操作的,需要打开hbase的thrift服务,命令如下

./opt/hbase-0.98.9-hadoop2/bin/hbase-daemon.sh start thrift

如果某个regionserver挂点,需要单独启动,用如下命令

/bin/hbase-daemon.sh start regionserver

jps查看hbase进程,可以看到

master:
7092 HMaster
slave:
7072 HRegionServer

kafka

为了实时接收交易所的行情数据,先把数据存储在kafka中,然后在进行处理写库。同样搭建kafka集群保证接收行情数据第一关不会出问题,搭建3个节点的集群,使用大数据平台的zk服务。配置文件位于/opt/kafka_2.12-0.10.2.0/config下。

server.properties
配置kafka数据目录,zk服务地址等

advertised.host.name=192.168.3.202           # 每个节点ip都不同
advertised.host.port=9092                    # 每个节点端口保持一致
broker.id=0                                  # 每个节点broken id不同            
log.dirs=/home/kafka-data                    # 数据保存位置
num.partitions=3                             # 每个topic保留3分,总共3个节点
log.retention.hours=168                      # 数据保存时间
zookeeper.connect=192.168.3.201:2181,192.168.3.202:2181,192.168.3.203:2181
default.replication.factor=3

使用外部的zk服务时,zookeeper.properties中的dataDir配置失效。在维护kafka的过程中,有时需要删除topic的数据,而且是所有的数据,步骤如下

停止kafka
停止所有的生产者和消费者程序,如果不停止很可能删除topic后又被惯回来
删除某一个zk节点,如rmr /brokers/topics,其他节点中的相应目录自动同步删除
删除kafka安装目录中的server.properties中的log.dirs配置目录中的所有数据
重启kafka ./bin/kafka-server-start.sh -daemon config/server.properties

启动kafka后,用jps会查看到kafka进程。

以上是hadoop平台搭建的主要配置,就单个组件的配置来说还有很多可配置的地方,请参考官方文档。在启动所有组件时,安装如下顺序启动,命令如下

hadoop集群
./sbin/start-all.sh
./sbin/stop-all.sh

Zookeeper集群
./zkServer.sh start

kafka集群
./bin/kafka-server-start.sh -daemon config/server.properties

hbase集群
./bin/start-hbase.sh

thrift(主节点上)
./hbase-daemon.sh start thrift
2018/1/23

数据平台笔记-从硬件组装开始

数据没上个PB级别,都不好意思说是大数据,所以我就称之为数据平台吧。这里记录下一些数据平台搭建过程中的笔记。

买了7台服务器,包括6台集群使用的,和一台工作站,工作站用于平时开发和快速计算用,比如GPU的计算。其他6台用于搭建集群,主要是用于存储金融数据和集群计算,还有其他的服务;服务器配置如下:

集群节点

Server Name: PowerEdge R710
CPU型号: Intel(R) Xeon(R) CPU  X5650  @ 2.67GHz
CPU总逻辑数: 24 (2*6*2) 
Mem: 62.7G
Disk: 2.2T
OS: centos 3.10.0-514.16.1.el7.x86_64 

工作站节点

Server Name: HP Z840 Workstation
CPU型号: Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz
CPU总逻辑数: 20 (1*10*2) 
Mem: 62.8G
Disk: 8.7T
GPU: GeForce GTX 1080
OS: 4.10.0-37-generic #41~16.04.1-Ubuntu

工作站的磁盘是已经安装好的,集群的每个节点的磁盘都是重新买的,每个节点2块磁盘,然后一个一个手动安装上去,完了每个节点都从头开始做RAID5,安装操作系统,并且更新centos源和软件,最后在新买的机柜上面插入服务器,接入局域网的千兆路由器;每个节点的IP都已经设定好,不能修改;通电并接入UPS后,正常运行,硬件部分工作完成。

2017/12/17

老板们应该知道的关于WEB产品的技术名词

我们这里针对是普通的WEB产品,你可以理解为全中国大部分WEB产品都是这种普通的产品。一个全端的WEB产品,包括移动端,web,桌面客户端,需要用到很多技术,包括但不限于如下选择。

  • APP

包括IOS和Android两大平台,Windows Phone就算了,可以考虑React Native,代码复用,一致的开发体验,节约成本;也可以一个平台招一个,但成本高,一个就够,不是让你在移动端做视频剪辑,流畅自如,一般的数据展现和效果的渲染,一个程序员就搞定。

消息推送可选第三方服务,首选激光推送,跨平台消,API丰富,还有其他可选通道都有,不推荐自行架设推送服务,消息量没那么大,何必呢!

与后端API要设计和谐,加上版本控制,上下兼容,安全验证的移动端支持需要一开始就做好,https肯定是要上的,大势所趋吗!另外,对于IOS的发布要计划好时间节点,配合产品发布周期,需要提前发布,你知道苹果什么时候审核通过呢?

  • WEB前端

Html、css加上JavaScript和vue,完整技术栈,在加上一些特别效果组件,图表、char等等,相信可以满足大部分前端需求,结合后端API,搞定,当然这是对于一般的前端应用,如果你想在单页中,通过浏览器对上百万、千万数据进行计算绘制,想通吃各种浏览器,那另当别论。对于前端来说,通过压缩编译前端组件元素,并分发到CDN,可以打打提高前端资源加载速度。

  • 桌面客户端

使用electron,一次开发支持linux、windows、macos三大平台,大部分代码可以和web前端复用,本地存储使用sqlite,看到BearyChat和风车貌似mac端用的就是web前端,桌面端不熟,不多说。

  • 后端

提供API给前端展现,实现业务逻辑的一侧,可选择的语言有很多,python、php、java、go、ruby、nodejs都可选,c、c++不是不行,web项目太累,生态工具不完善,后端提供rest风格的api就可以,所有的客户端调用同一套api。基于不同语言,后端开源框架,如:

php -> lumen,python -> flask,java -> spring,node -> koa,go -> denco,ruby -> rails

后端语言实现的程序,表现上可以是一个个的进程,在特定端口提供服务,没有任何ui部分,只通过API和WEB以及移动端进行数据交互。如果是servlet还需要通过web中间件提供服务。

后端除了实现业务逻辑以外,根据系统规模,以及数据量和并发量的不同,可扩展的点也很多,如为了保证服务可用性需要集群部署;为了服务可控,需要服务化,引入Dubbo或者motan等第三方服务化组件;集群后用户会话是否需要独立保存;数据量达到千万级后,需要分库分表,主从部署等。

  • 数据库

10万客户端加实时并发量级并不是很大的话,不建议马上上分库分表,高可用大集群之类的方案了,单表1000w的时候在往这方面想吧。优先选择云端实例模式,比如阿里云的RDS。自己搭建的话,一主二从做好同步和读写分离,再加个延时冷备的库,基本够用。可选mysql或postgresql,mysql技术层面接受度会高很多。数据这块的压力,先从SQL语句的健壮和缓存上面进行优化吧!不要动不动就分库分表,能一个库就一个库,否则业务逻辑很难搞;看了几篇架构分析就想搞,那不适合你。

  • 缓存

在访问量增大后,需要找出系统中热点数据有那些,更新不敏感的使用缓存,尽量减少对于数据库的压力,大部分问题使用缓存就能解决,比较内存的IO比磁盘的IO快多了。

redis必备,完全当缓存用,暂不考虑持久化存储;比如再使用memcached,集群的话需要找个第三方的支持集群的客户端。redis3后集群功能也是妥妥的,当然现在也有云端实例直接购买使用,自己搭建可以搞个2、3个点的redis小集群,主备分好,也够用了。如果你想用redis持久化数据,也是极好的,比如做session的存储,中间计算过程的存储,因为redis数据类型丰富啊!

  • session

面对众多移动端和web端的session,通过统一session服务进行管理,可以参照tomcat的session管理机制,保证用户登录体验一致,并可以实现更复杂逻辑;使用redis统一持久化。

  • 队列

系统复杂一些后,各个子系统之间需要流转一些数据,解耦,基于消息触发的很多,各种MQ可以自行搜索,也可以购买消息队列服务,各种云上的都有,很是方便。

  • 连接层

dns和域名,找个靠谱的域名商购买加备案,dns可以购买dnspod服务。链路最好全部https,需要花钱买证书,或者使用let's encrypt的免费证书。

  • 服务器

直接购买选用云环境的全套吧,加上带宽。这个规模下,自建的成本优势还体现不出来,直接使用全套云基础设施,时间和资金成本都节约很多。阿里云,腾讯云,或者其它云商都可以考虑,实际测试比对之后选择。这些云提供的基础设施就像生活中的水电气,很是方便。

  • CDN

静态资源较多的时候,分发时有一定压力,购买云的服务,很多,同上。

  • 存储

开始估计还用不上,如果有大量历史数据需要存储,可以考虑搭建一套。可选方案也很多,ceph,weedfs,hdfs,首选hdfs,达到亿级别规模请再用hbase,谢谢!
如果你一开始就觉得数据量增加很快,会很快达到亿级规模,那就需要预先考虑了,这个不在我们讨论范围。

  • 安全

这个话题太大,不太懂,但是基本的要做到,web上各种攻击,XSS跨域问题,SQL注入,DDOS攻击,nginx上限流,还有就是数据库的备份和恢复。前期估计也用不上多少,都没人知道你的产品。

  • 搜索

开始估计也用不上,用like也许可以顶上一段时间,后期弄几台服务器搭建个搜索引擎,也是极好的,可选solr和es,推荐es。结合上面说的存储,如果达到使用hbase存储的规模,可以es+hbase。

  • 服务化

服务化的成本现在越来越低,推荐用motan,轻量级服务化框架,和spring结合较好,如果你后端选用的是java的话;比如一个电商系统,前期没啥用户,但是服务化可以使服务清晰,模块分明,配置也合理;当然必不可少的需要zookeeper等第三方协同了。

  • 监控等周边配套

前期你也许不想弄,可以购买监控宝等第三方服务,接入sdk后,web端查看应用的各种监控参数。各种邮件、短信、支付、合同等等服务,同样购买第三方服务即可,能花钱买到的服务就很快搞定,无需重复劳动。

这些做完了,产品才算可用!

谢谢老板看到这里!

2017/7/31