一般大型系统是一个分布式部署的架构,不同的服务模块部署在不同的服务器上,问题出现时,大部分情况需要根据问题暴露的关键信息,定位到具体的服务器和服务模块,构建一套集中式日志系统,可以提高定位问题的效率。 一个完整的集中式日志系统,需要包含以下几个主要特点:
ELK提供了一整套解决方案,并且都是开源软件,之间互相配合使用,完美衔接,高效的满足了很多场合的应用。目前主流的一种日志系统。ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。新增了一个FileBeat,它是一个轻量级的日志收集处理工具(Agent),Filebeat占用资源少,适合于在各个服务器上搜集日志后传输给Logstash,官方也推荐此工具。
Elasticsearch是个开源分布式搜索引擎,提供搜集、分析、存储数据三大功能。它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。 Logstash 主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般工作方式为c/s架构,client端安装在需要收集日志的主机上,server端负责将收到的各节点日志进行过滤、修改等操作在一并发往elasticsearch上去。 Kibana 也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助汇总、分析和搜索重要数据日志。 Filebeat隶属于Beats。目前Beats包含四种工具:
本文所试验的场景如下,其中日志收集采用Filebeat:
提前准备kafka环境,下载es、kibana、logstash、filebeat等软件,版本号为5.6.10,使用可以直接运行包解压即可运行。 本文为简化起见,只在单机上安装,通过elk用户安装,预先安装Jdk8。
提前准备kafka主题messages,配置读取/var/log/messags数据到kafka主题。 解压Filebeat介质,进入软件目录,修改配置vim filebeat.yml 输入命令,nohup ./filebeat -e -c filebeat.yml>/dev/null 2>/dev/null & ,启动fliebeat Kafka主题中会接收到对应消息。
解压ES软件,修改config/elasticsearch.yml配置文件,具体配置如下。
cluster.name : es_cluster
node.name : node0
path.data: /home/elk/es/data
path.logs: /home/elk/es/logs
network.host : node68
http.port : 9200
http.cors.enabled: true
http.cors.allow-origin: "*"
直接启动可能会报错,需要通过root用户修改max file和max_map_count。 [1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536] [2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
启动ES,通过浏览器访问,说明启动正常。
[elk@node68 elasticsearch-5.6.10]$ bin/elasticsearch -d
[elk@node68 elasticsearch-5.6.10]$ ps -ef |grep elas
elk 14511 1 99 10:56 pts/0 00:00:13 /home/elk/jdk8/bin/java -Xms2g -Xmx2g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+AlwaysPreTouch -server -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -Djdk.io.permissionsUseCanonicalPath=true -Dio.netty.noUnsafe=true -Dio.netty.noKeySetOptimization=true -Dio.netty.recycler.maxCapacityPerThread=0 -Dlog4j.shutdownHookEnabled=false -Dlog4j2.disable.jmx=true -Dlog4j.skipJansi=true -XX:+HeapDumpOnOutOfMemoryError -Des.path.home=/home/elk/elasticsearch-5.6.10 -cp /home/elk/elasticsearch-5.6.10/lib/* org.elasticsearch.bootstrap.Elasticsearch -d
解压Logstash,新建kafka2es.yml配置文件,将kafka主题消息采集到ES中。配置文件内容如下
input{
kafka {
bootstrap_servers => "192.168.80.56:9092"
topics => ["messages"]
group_id => "consumer-zwang"
auto_offset_reset => "earliest"
}
}
output {
elasticsearch {
hosts => "node68:9200"
codec => json
}
}
在安装目录下输入命令,启动logstash。
[elk@node68 logstash-5.6.10]$ bin/logstash -f kafka2es.yml --config.reload.automatic &
[1] 19501
解压kibana,进入安装目录,修改config/kibana.yml文件,配置ES地址和本机地址。 输入命令启动Kibana
[elk@node68 kibana-5.6.10-linux-x86_64]$ bin/kibana &
[2] 19662
打开浏览器,输入Kibana地址,默认端口是5601,可以搜索到messages日志信息
增加Kafka的目的是由于Logstash在数据量大的时候会非常消耗资源,通过Kafka可以实现数据缓冲的作用。另外本文中没有对日志进行过滤处理,Logstash擅长对日志进行清洗加工,以满足日志分析需求,配置文件中通过filter脚本实现数据的清洗加工。本文中的kafka、ES、Logstash原则上都是分布式集群环境,以实现高性能高可用。
Flume也是实现实时数据采集的工具,与Logstash相比,Flume侧重数据的传输可靠性,Logstash则更轻量级,易于与其他组件配合使用,场景广泛。
Logstash支持数据输出到Hadoop环境,支持通过Socket端口收集数据,支持数据写入Redis等场,对MySQL、HBase输出连接需要定制组件才能完成数据传输。
TransparentData Encryption用来加密数据文件里的数据,保护从底层对数据的安全访问。所谓透明是指对使用者来说是未知的,当使用者在写入数据时,系统会自动加密,当使用数据时系统会自动解密。Oracle、SQLServer很早就支持了透明数据加密的特性,下面说一下针对HDFS文件和HBase的透明数据加密过程。
HDFS Encryption zone加密空间是一种end-to-end(端到端)的加密模式.其中的加/解密过程对于客户端来说是完全透明的.数据在客户端读操作的时候被解密,当数据被客户端写的时候被加密,所以HDFS本身并不是一个主要的参与者,形象的说,在HDFS中,你看到的只是一堆加密的数据流.
本文中的大数据环境通过CloudManager5.12进行安装,Hadoop版本为hadoop 2.6.0-cdh5.12.1。 通过CM直接安装Java KeyStore KMS服务。 按照默认选项可完成安装,KMS服务使用Kerberos进行认证。 管理员用户名设置为kms,组名设置为kms,此用户可以管理所有KMS密钥。 安装KMS后,CM自动KMS服务作用于Hadoop,相关引用KMS服务的组件均需要重启。
登陆kerberos服务器,用管理员用户进入命令行控制台增加用户,密码设置为kms
[root@node181 ~]# kadmin.local
Authenticating as principal hbase/admin@HADOOP.COM with password.
kadmin.local: add_principal kms@HADOOP.COM
WARNING: no policy specified for kms@HADOOP.COM; defaulting to no policy
Enter password for principal "kms@HADOOP.COM":
Re-enter password for principal "kms@HADOOP.COM":
Principal "kms@HADOOP.COM" created.
在HDFS客户端登陆kerberos用户kms,创建密钥
[root@node86 ~]# kinit kms
Password for kms@HADOOP.COM:
kinit: Password incorrect while getting initial credentials
[root@node86 ~]# kinit kms
Password for kms@HADOOP.COM:
[root@node86 ~]# hadoop key create testkey1
testkey1 has been successfully created with options Options{cipher='AES/CTR/NoPadding', bitLength=128, description='null', attributes=null}.
KMSClientProvider[http://node183:16000/kms/v1/] has been updated.
[root@node86 ~]# hadoop key list
Listing keys for KeyProvider: KMSClientProvider[http://node183:16000/kms/v1/]
testkey
testkey1
在HDFS客户端登陆Kerberos用户hdfs,创建文件夹/zwang/secret,并设置此文件夹为加密专区
[root@node86 ~]# kinit hdfs
Password for hdfs@HADOOP.COM:
[root@node86 ~]# hadoop fs -mkdir /zwang/secret
[root@node86 ~]# hdfs crypto -createZone -keyName testkey1 -path /zwang/secret
Added encryption zone /zwang/secret
[root@node86 ~]# hdfs crypto -listZones
/user/hdfs/.Trash/Current/zwang/secret testkey1
/zwang/secret testkey1
在kms-acl.xml里增加属性配置,cm里通过界面配置完成
<property> <name>key.acl.testkey1.DECRYPT_EEK</name> <value>zwang</value> <description> ACL for decryptEncryptedKey operations. </description> </property>
重启kms服务
上传测试文件至/zwang/secret下面,报错。 赋权zwang用户对secret的读写权限
[root@node86 ~]# hdfs dfs -setfacl -m user:zwang:rwx /zwang/secret
[root@node86 ~]# hdfs dfs -getfacl /zwang/secret
# file: /zwang/secret
# owner: hdfs
# group: supergroup
user::rwx
user:zwang:rwx
group::r-x
mask::rwx
other::r-x
登陆kerberos用户zwang,上传文件到/zwang/secret下面
[root@node86 ~]# kinit zwang
Password for zwang@HADOOP.COM:
[root@node86 ~]# hadoop fs -put 1.txt /zwang/secret
[root@node86 ~]# hadoop fs -cat /zwang/secret/1.txt
1,jack,18
2,green,15
除zwang用户外,换其他用户则无法查看文本内容,通过管理员用户hdfs查看相关文件,比较加密空间与非加密空间的数据备份即可看到加密与非加密的区别。 hdfs dfs -cat /.reserved/raw/zwang/secret/1.txt hdfs dfs -cat /.reserved/raw/zwang/tmp/1.txt
通过hive建外部表,关联/zwang/tmp和/zwang/secret发现,加密空间对应的表无查询数据。 通过cm界面增加hive使用testkey1密钥的权利,重启kms服务 再次查询test1表,则数据可以正常显示。
此功能提供透明加密,用于保护静态的HFile和WAL数据,使用双层密钥架构进行灵活且非侵入式的密钥轮换。首先需要修改HBase集群配置使其支持透明服务端加密,本文针对一个表中不同列簇设置不同的策略,以检验其加密的效果。具体过程请参考官网资料:http://archive.cloudera.com/cdh5/cdh/5/hbase-0.98.6-cdh5.3.3/book/hbase.encryption.server.html
为AES创建适当长度的密钥,alias设置为hbase,密码设置为ustcinfo
$ keytool -keystore /path/to/hbase/conf/hbase.jks \
-storetype jceks -storepass <密码> \
-genseckey -keyalg AES -keysize 128 \
-alias <alias>
将生成的hbase.jks文件拷贝到所有hbase节点的/etc/conf/hbase目录下。 在CM控制台修改hbase-site.xml 的 HBase 服务高级配置代码段(安全阀),找到此配置 添加安全配置如下:
<property><name>hbase.crypto.keyprovider</name><value>org.apache.hadoop.hbase.io.crypto.KeyStoreKeyProvider</value></property><property><name>hbase.crypto.keyprovider.parameters</name><value>jceks:///etc/hbase/conf/hbase.jks?password=ustcinfo</value></property><property><name>hbase.crypto.master.key.name</name><value>hbase</value></property><property><name>hfile.format.version</name><value>3</value></property><property><name>hbase.regionserver.hlog.reader.impl</name><value>org.apache.hadoop.hbase.regionserver.wal.SecureProtobufLogReader</value></property><property><name>hbase.regionserver.hlog.writer.impl</name><value>org.apache.hadoop.hbase.regionserver.wal.SecureProtobufLogWriter</value></property><property><name>hbase.regionserver.wal.encryption</name><value>true</value></property>
重启HBase服务。 通过hbase用户登陆hbase shell,在建表时设置某个列簇加密
hbase(main):003:0> create 'zwang_foo',{ NAME=> 'f1',ENCRYPTION => 'AES'},{ NAME=> 'f2'}
0 row(s) in 2.2560 seconds
=> Hbase::Table - zwang_foo
hbase(main):006:0> put 'zwang_foo','1','f1:address','wenqulu355 gaoxinqu hefeishi anhui china'
0 row(s) in 0.0080 seconds
hbase(main):010:0> put 'zwang_foo','1','f2:address','wenqulu355 gaoxinqu hefeishi anhui china'
0 row(s) in 0.0160 seconds
退出hbase shell ,查看hbase表对应的hfds文件,一开始看不到文件,可以重启下hbase,就可以到看到此表对应不同列簇的数据文件,一个处于AES加密状态,一个可以明显看到数据内容。 未加密列簇f2对应的hdfs文件: 加密列簇f1对应的hdfs文件:
企业内部协作管理的常见方式便是业务梳理并固化成流程,通过系统来实现工作流程的统一管理。笔者所在的运营商行业即有很多很多基于流程平台的业务系统,比如网络施工的统一管理、故障处理的流程管理。本文主要使用jeesit1.2.7版本进行的试验,可以在github和码云上找到此版本。
CREATE TABLE `oa_loan` (
`id` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '编号',
`proc_ins_id` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '流程实例编号',
`user_id` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '用户',
`office_id` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '归属部门',
`summary` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT '借款事由',
`fee` int(11) DEFAULT NULL COMMENT '借款金额',
`reason` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '借款原因',
`actbank` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '开户行',
`actno` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '账号',
`actname` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '账号名',
`financial_text` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '财务预审',
`lead_text` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '部门领导意见',
`main_lead_text` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '总经理意见',
`teller` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '出纳支付',
`create_by` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '创建者',
`create_date` datetime NOT NULL COMMENT '创建时间',
`update_by` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '更新者',
`update_date` datetime NOT NULL COMMENT '更新时间',
`remarks` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '备注信息',
`del_flag` char(1) COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `OA_TEST_AUDIT_del_flag` (`del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='借款流程测试表';
使用Jeesite的代码生成工具,生成业务单的增删查改界面。参考jeesite工程doc目录里的代码生成器应用。
// 审核环节
if ("audit".equals(taskDefKey)) {
oaLoan.setFinancialText(oaLoan.getAct().getComment());
if("yes".equals(oaLoan.getAct().getFlag())){
Office office = oaLoan.getOffice();
List<User> userList = systemService.findUser(new User(new Role("5")));
List<User> userList1 = systemService.findUserByOfficeId(office.getId());
userList.retainAll(userList1);
vars.put("dept_leader", userList.get(0).getLoginName());
}
dao.updateFinancialText(oaLoan);
} else if ("audit2".equals(taskDefKey)) {
功能做完后需要多找几个账号来测试验证,在测试过程中也发现了几个activit的表少了字段,也一并修改完成。具体代码参见https://github.com/shockw/jeemanage
根据笔者与某客户的聊天,就数据处理方面的技术方案总结梳理一下,主要是目前比较主流的技术方案进行了总结。由于笔者并不是专业的数据分析专家或是业务专家,以下方案仅供参考。
生产数据结构化类型一般存储在Oracle或MySQL中,半结构化数据一般存储在文件或是NoSQL中。由于笔者没有从事过非结构化数据的技术方案,在此并不讨论非结构化数据的处理技术。在生产库后面一般都有一个历史库或叫分析库、归档库。主要是存储海量历史数据并能进行数据的统计分析及挖掘。
下面数据的分类主要还是从客户比较熟悉的业务视角分类的,不同的场景可能区别比较大:
原始数据指从数据源采集过来并没有加工的数据;标准数据指通过数据清洗转化的数据;结果数据指应用计算分析的结果:
通过业务规则对既有数据进行统计分析,获取目标结果的过程。
数据来源广泛,既有实体数据、也有过程数据和配置数据,数据量大,计算量大,计算效率要求高。
基于数据仓库,快速实现各类报表。
侧重于快速的数据展示,主要用于数据决策系统。
FineReport是帆软软件有限公司自主研发的一款企业级 web 报表软件产品,它“专业、简捷、灵活”, 仅需简单的拖拽操作便可以设计出复杂的中国式报表、参数查询报表、填报表、驾驶舱等,轻松搭建数据 决策分析系统。
通过流式获取时间窗口数据,实时进行业务处理。
海量数据采集,实时处理。例如采集性能数据根据规则进行实时预警。
分布式流处理是对无边界数据集进行连续不断的处理、聚合和分析的过程,与MapReduce一样是一种通用计算框架,期望延迟在毫秒或者秒级别。
通过搜索各类应用系统的日志去定位系统问题,解决故障。
海量结构化或半结构数据,存储周期短,实时性要求高,分布式采集,集中检索。
ELK 已经成为目前最流行的集中式日志解决方案,它主要是由Beats、Logstash、Elasticsearch、Kibana等组件组成,来共同完成实时日志的收集,存储,展示等一站式的解决方案。本文将会介绍ELK常见的架构以及相关问题解决。
数据挖掘一般是指从大量的数据中通过算法搜索隐藏于其中信息的过程。数据挖掘通常与计算机科学有关,并通过统计、在线分析处理、情报检索、机器学习、专家系统(依靠过去的经验法则)和模式识别等诸多方法来实现上述目标。
主要使用海量结构化数据,对数据进行清洗,建立探索模型,使用分类、聚类、关联、回归等算法实现模型的生成。其具有一定不确定性,主要用于预测,有一定的失败概率。
根据笔者见过的项目情况,就企业应用的技术架构进行一些粗浅分析。业务中台的理念来源于SOA思想,经过阿里等互联网公司发扬光大,形成实际可行的技术方案。事实上行业软件里早就有了SOA架构的实践,不过从实际上来看,笔者所在的运营商行业其实发展并不好,经常是投资大,收益小。业务的设计和IT人员的水平关系很大,大多设计一个集中式的ESB管理所有服务,但服务很少是从业务角度考虑,大多只是一个技术接口,没有体现出SOA的本质,更谈不上其效果。
不管是什么技术方案,都不是统一天下的方案,不同的场景总要有适合的方案。我们总是要寻找切实高效的方案,而不是人云亦云,领导说好就是好,客户说好就是好。事实上我们需要有自己独立的思考,在业务较简单时,很明显不适宜上复杂的方案。
企业单体应用一般就是一个web程序和一个数据库。比较常见的技术方案如下:
当业务变化很快,且系统复杂后,就需要将系统拆分成多个业务中心,拆分的目的就是抽象业务,形成高内聚低耦合的服务中心,这样服务支撑会更迅速,开发迭代的速度会提高,另外每个中心的开发规模会变小,大家会更专业。每个服务中心都会需要架构师、开发人员、ued人员、dba与运维等。复杂的系统的响应总是很慢,由于业务之间的耦合,导致新增一个功能漫长且容易出错。只有最熟悉企业业务的人参与,才可能从业务角度对系统进行架构。公共技术的服务剥离实际上并没有什么成效,现在很多企业IT的现状是懂技术的人不懂业务,懂业务的人不懂技术,这会严重影响企业的架构水平。下面是著名的阿里巴巴中台战略思想与架构实战中的共享服务架构:
层级\架构 | 业务架构 | 技术架构 |
---|---|---|
应用层 | 天猫、淘宝、聚划算、手机淘宝、口碑等 | Html5/Js、移动应用、表单、流程 |
服务层 | 用户中心、商品中心、交易中心、评价中心等 | 微服务(spring boot)、负载均衡(haproxy/nginx)、弹性伸缩(docker)、服务熔断(Hystrix)、链式跟踪(pinpoint) |
数据层 | 用户模型、商品模型、交易模型 | Oracle、MySQL、分布式数据库(Drds/Mycat) |