022-2345 2937
185 2247 0110
business@forenose.com
QQ:2779623375
用户QQ群3:606835039
用户QQ群4:795287153
订阅号
服务号
客服微信:qianxiu0106
ForeSpider
数据采集引擎
科技资讯:
科技学院:
科技百科:
科技书籍:
网站大全:
软件大全:
2017 | 2018
灵活的生命周期管理,可以让企业以最合适的投入成本使用云计算资源,对于任何规模的企业,这都是开源节流的有力手段。一个IT项目通常会经历以下阶段: 项目规划:按量付费(升、降级)以进行功能开发、性能等验证 系统上线:按量付费转包年包月,以长期节省成本 系统扩充:包年包月升级 系统萎缩:包年包月降级 系统下线:包年包月按量付费 -> 按量付费资源释放 -> 销毁实例(彻底删除数据) 当然云计算也应该提供能力,以避免企业由于业务过程中突发情况,忘记充值导致需要进行“续费解锁”,甚至是由于已经到达实例续费最后期限而到导致资源释放后,需要通过“过期重建”进行数据找回。 这些能力构成云数据库的“全生命周期”管理能力,可以看到阿里云在2018年进行了重点功能提升,已经可以满足企业大部份需求,唯独还没有提供“包年包月转按量付费”能力,这一功能我们也即将会开放。 全方位运维 | 2017 | 2018
2018年阿里云在RDS中大幅度同比2017年提高实例生产效率达1倍之多。在高可用版部署模式下,不提高任何成本即可支持“跨区高可用”部署,为企业提供更为可靠的同城双中心跨区域容灾体验。 通过精细化调度管理策略,将“可维护时间段”从4小时缩短到1小时。同时,提供“待处理事件”功能,实现与用户进行可视化的运维管理协调的交互能力。企业的DBA可以更为有效地管理运维时间,在遇到云资源后端发现硬件问题预警,必须进行网络或HA切换时可以自行调整切换闪断时间,降低对企业业务正常运行的干扰。 数据管理提供除了免费版外,针对中大型企业的DBA提供高级版、企业版,数据管理企业版,是一种集数据管理、结构管理、研发流程、用户管理、权限管理、访问安全于一体的数据管理服务。基于RDS及数据管理企业版,企业DBA可以从繁重的日常数据库管理工作中脱离出来,以数据为中心为企业提供更有价值的数据管理服务,如: 研发人员从线下环境结构设计,到SQL发布预审,到生产发布的完整数据库研发流程 字段级别细粒度操作权限管控,所有用户操作在线化、可溯源 支持根据业务灵活配置结构设计、数据变更、数据导出等操作的审批流程 统一研发与数据库交互的入口,任何用户都不再直接接触数据库账号密码也不需要频繁切换数据库连接进行管理 等等…… 全链路安全 | 2017 | 2018
全链路监控 | 2017 | 2018
2018年阿里云主要投入在提高监控频率,并将CloudDBA推广到所有RDS引擎中,以为企业提供更好的服务能力。CloudDBA是监控和管理RDS实例性能及运行状况的服务,针对SQL语句的性能、CPU使用率、IOPS使用率、内存使用率、磁盘空间使用率、连接数、锁信息、热点表等,CloudDBA提供了智能的诊断及优化功能,能最大限度发现数据库存在的或潜在的健康问题。CloudDBA的诊断基于单个实例,该诊断会提供问题详情及相应的解决方案,可为您管理实例运行状况带来极大的便利。 多引擎覆盖(及能力提升) | 2017 | 2018
通过提供更多最新的市场版本,特别是企业级版本功能,如:SQL Server AlwaysON、MariaDB TX及PPAS 10的ORACLE兼容性及ADAM工具。阿里云为更多不同需求的企业核心系统提供了支持,引擎版本几乎覆盖了市场上所有主流引擎的最高版本。让企业用户迁移上云时避免不必要的版本调整,以最小的工作代价完成系统上云工作。 SQL Server 2017 AlwaysOn,面向高端企业级客户 MariaDB TX,全球唯一MariaDB TX企业级版本公共云服务提供商 PostgreSQL 10,提供自研Ganos时空引擎,实现关系数据库中的时空+业务SQL联合 PPAS 10,提供更强的ORACLE兼容性,并与ADAM工具配合提供更平滑的迁移体验 总结: 为用户提供更核心且实用的价值,是阿里云一贯的承诺。2018年云数据库RDS发展上,不但针对MySQL、SQL Server、PostgreSQL提供了适合个人入门用户的基础版产品,以实惠的价格普惠广大中小用户。阿里云更从企业需求出发,重点在全生命周期、全方位运维、全链路安全、全链路监控、多引擎覆盖 5个方面进行发力,为企业用户提供更优质的云数据库服务。为不同层次的用户提供贴心及高品质的服务,已经成为云计算最核心的价值,期待产业变革为个人及企业用户带来更多体验的提升。 -- 我们为之努力! 作者: 萧少聪scott 原文链接 本文为云栖社区原创内容,未经允许不得转载。 大数据 2018-12-20 14:31:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 【编者按】2018年12月20日,云栖社区3周岁生日。阿里巴巴常说“晴天修屋顶”,所以我们特别策划了这个 专辑 ——分享给开发者们20个阿里故事,50本书籍。第一位是林昊(毕玄)。 在这篇《程序员的成长路线》里,阿里基础设施负责人毕玄结合自己的经历跟大家讲述了他在各个角色上成长的感受。在他的职业经历中,在成长方面经历了技术能力的成长、架构能力的成长,以及现在作为一个在修炼中的技术 Leader 的成长。其中技术能力和架构能力的成长是所有程序员都很需要的,值得所有正为职业发展而迷茫的技术同学细细品味。 技术能力成长 我大学读的是生物系,缺少了专业的训练,这个使得我在技术能力上其实欠缺的更多。回头想想,在工作的前5年,更多的都是在拓宽技术面,刚毕业的时候只会 ASP,工作前两年学会了 VB、Delphi这些神器,到工作的第三、四年比较专注的做了工作流领域。 技术能力的成长主要还是在 2007 年加入阿里以后,在加入阿里前,我是一个连日均访问量 1万 PV 都没见过的人,到了阿里后,做的第一件事竟然就是写 HSF,并且在客服的 CRM 系统上线,访问量大概是每天上百万的服务调用,无知者无畏,当时也就那么上线了,更神奇的是竟然没出现什么问题,于是继续把HSF上线到当时的交易中心,当时交易中心每天的服务调用量大概是亿级,结果上线当天就回滚了,而且还不知道到底是什么原因,这次的回滚是对我触动最大的一次(当然,触动大也有可能是后面要是解决不了,就该从淘宝滚蛋了)。 回滚后开始仔细查问题,最后发现是当时 HSF 所使用的 jboss-remoting 默认的超时参数 60s 的问题,自从这个问题后,才明白要支撑好到了一定量级的系统,最重要的是对整个技术栈的精通,否则出问题都不知道该怎么解决或临时查,于是才开始仔细学习 Java 的 BIO/NIO,Mina,反射,并发编程等,尽管这些东西很多在加入阿里前也看过一些书、资料学过,但到了这个时候才发现自己其实不怎么懂,那段时间密集的开始更细致的看书,翻看用到的 Mina、甚至是 Java 的各种 API 背后的源码,是自己的 Java 技能提升最快的一段时间,在回滚的两个月后,基于 Mina 完全重写了 HSF,再次上线终于一切顺利。 在那之后,随着 HSF 应用的场景越来越多,以及加上后来自己在淘宝消防队查比较多的问题,Java 方面的技能也得到了不少成长,而同时也发现了很多的 Java 问题还得对 JVM、操作系统层面有一定掌握才行,尤其是 JVM,于是当时和还在阿里的撒迦经常一起周末跑到公司来结对看 JVM 代码,:)。在撒迦的帮助下对 JVM 的掌握终于也越来越好,那段时光会让自己明白很多东西只有看了代码,并且有相应的使用机会才能真正的掌握。 在 HSF 之后,去做 HBase,学习了很多在存储方面的技能,这也是我之前完全不懂的领域,在HBase之后,开始做第一代容器产品 T4(寓意是第四代淘宝技术),进入彻底不懂的领域,虚拟化、Cgroup 等等都是那个时候才开始学习,但因为没详细研究过代码,并自己去做改造,其实到今天也就是点皮毛而已。 对于程序员而言,技术能力的成长显然是最重要的(程序员行当里最赞的一句就是:Talk is cheap, show me the code!),我自己其实很多都属于被逼的成长,当然这样通常反而也是最快的,很多同学会觉得自己没碰到这样的机会,所以成长就比较慢,我会非常建议的是可以尝试自己去创造一些场景(当然,如果本来就是工作需要就更好了),来学相应的技术能力(例如学 Java 的通讯框架,可以尝试自己基于 BIO/NIO 写一个,然后对比 Mina/Netty 这些成熟的,看看为什么写的不太一样,又例如学 Java 的内存管理,可以尝试自己写程序去控制 GC 的行为,例如先来一次 ygc,再来两次 fgc,再来 5 次 ygc,再来一次 fgc之类的,学的时候除了一些入门的书外,我非常建议去翻看源码,最后你会发现所有的书都不如源码),这样才能真正的理解和学会,否则其实很容易忘。 架构能力成长 说起架构,在我刚工作的第三年负责工作流系统的时候也做过,但直到后来在阿里做 T4、异地多活,我才有了真正更强烈的感受,对架构师也有更深的一些理解。架构呢,我现在的理解基本是一个结构图,当然有不同视角的结构,但这个图里的部分呢是多个团队来做的,甚至是跨多个专业的团队。 在做 T4 的时候,由于 T4 涉及到了标准的一个 Java WebConsole,一堆的运维体系,容器技术等,这是一个至少要跨三个团队的结构,无论是从研发视角还是部署视角都是如此,因此作为 T4 的架构师,怎么设计好整个的结构,各自的边界、接口是我当时最大的感受,让跨专业的多个团队能更好的协作,在这个阶段中最重要的要考虑的是怎么根据整个项目的优先级来调整每个部分,以及作为一个不是全懂的架构师怎么更好的确保结果,我自己的感受是 T4 让我学会了从一个只做自己专业系统的架构师成长为了能做跨专业的系统的架构师。 在做异地多活的时候,感受就更加强烈,因为这个跨的专业数、整个参与的人数完全是上升到了一个非常大的程度,各个专业、系统的人都需要看整个架构才能知道自己应该做什么,扮演的角色,在做异地多活整个项目过程中,作为总的架构师,我自己感觉的是最重要的职责是怎么控制项目的风险,或者说作为架构师,你觉得一个项目中最重要的要掌控住的是,并且从架构上怎么设计这个部分,这也是后来我在问很多架构师时最喜欢问的问题,一份架构文档不是说按照模板写就可以(很多的架构设计文档都是千篇一律,通常看到的都是什么都考虑,但从架构设计上并没体现这些考虑的地方是怎么做的),而是要根据实际的项目/产品情况来突出重点,确保最重要的几个问题是从架构设计上就去掌控的,尤其是跨多个专业团队的大型项目,这种项目准确的说是大架构师带着一堆的专业领域的架构师来做的,例如异地多活项目从架构设计上来说除了正常的结构、边界以外,最重要的是数据正确性的设计,我自己最强的感受就是异地多活才让我明白了一个大型系统的架构师是怎么样的。 所以就我自己的感受而言,架构师对知识的宽要求非常广,并且要能非常好的进行抽象,来做结构、边界的设计,分析出当前阶段系统的重点,并从架构层面做好设计来确保重点的实现,这个相对技术能力的成长而言我觉得更需要机会,但同样在机会前需要有足够的积累(例如写一个系统的时候,是不是主动的去了解过上下游的系统设计,是不是了解过具体的部署结构,对相应的知识点有没有简单的了解等,我自己在做 T4 前,LVS、机房/网络结构等完全搞不懂是怎么回事)。 技术Leader修炼 技术 Leader 我比较倾向于有前面两步积累的同学,技术 Leader 非常重要的一点是对技术趋势的感知和判断能力,这其实是个非常综合的能力,一到两个领域的技术深度,大的架构能力,对技术历程的理解、技术发展的思考能力,作为技术 Leader 是很需要的,然后是其他的一些作为 Leader 方面的比较综合的一些能力(例如组织搭建、建设方面的能力等,不过这些能力呢通常对技术的人来说确实会欠缺的更多一些),这个我自己还在修炼和学习中,就不讲太多了。 总结 总结来说呢,我认为程序员可发展的路线还是很多的,上面写的这三条其实都是可发展的路线,没有孰优孰劣,谁高一等之类的,兴趣、个人优势仍然是最重要的。 作为《OSGi原理与最佳实践》和《分布式Java应用:基础与实践》的作者,毕玄推荐了他的书单给到我们: 《硅谷之谜》 《智能时代:大数据与智能革命重新定义未来》 原文链接 大数据 2018-12-20 10:09:00 「深度学习福利」大神带你进阶工程师,立即查看>>> MaxCompute表设计最佳实践 产生大量小文件的操作 MaxCompute表的小文件会影响存储和计算性能,因此我们先介绍下什么样的操作会产生大量小文件,从 而在做表设计的时候考虑避开此类操作。 使用MaxCompute Tunnel SDK上传数据,上传过程中,每commit一次就会产生一个文件。这时每 个文件过小(比如几K),并且频繁上传(比如5秒上传)一次,则一小时就会产生720个小文件,一 天就会产生17280个小文件。 使用MaxCompute Tunnel SDK上传数据,create了session但是没有upload数据直接做了 commit,产生大量空目录(服务侧等同于小文件)。 使用MaxCompute Console命令行工具Tunnel命令上传时,将本地大文件切分过小,导致上传后产 生文件数过多,文件过小。 通过DataHub做数据归档,Datahub 的每个shard写 MaxCompute 有两个条件:数据总量达到 64MB,commit 一次到 MaxCompute,形成一个文件。或者每隔 5 分钟一次 commit,形成一个 文件。那么:开的shard数多(比如20个shard),每个shard数据在5分钟内都远远达不到64M,比 如就是几百K,就会产生大量小文件。那么一天就会产生241220=5760个小文件。 通过Dataworks等数据开发工具进行数据增量插入(insert into)到MaxCompute的表(或者表分 区)里时,每个insert into都会产生一个文件,若每次insert into 10条,每天累计insert insert 10000条记录,则会产生1000个小文件。 通过阿里云DTS将数据从RDS等数据库同步到MaxCompute,DTS进行数据同步时,会创建全量表和 增量表,增量表进程数据插入过程中会因为每次数据插入条数较少而commit比较完整一次数据同步, 从而在增量表中造成小文件问题,比如每隔5分支执行一次同步,每次同步的数据量为10条,一天内的 增量为10000条,则会产生1000个小文件。此种场景,需要在数据同步完成后进行全量极限表和增量 数据表的merge。 源数据采集客户端太多,源数据通过T unnel直接进入到一个分区,每个源数据采集客户端提交一次数 据,都会在同一分区下产生一个独立的文件导致产生大量小文件。 SLS 触发 FunctionCompute持续高频往MaxCompute中心接入文件,小文件流式数据进入 MaxCompute。 根据数据划分项目空间 项目空间(Project)是MaxCompute最高层的对象,按项目空间进行资源的分配、隔离和管理,实现了 多租户的管理能力。 如果多个应用需要共享“数据”,则推荐使用同一个项目空间。 如果多个应用所需“数据”是无关的,则推荐使用不同的项目空间。 项目空间间的表和分区可以通过Package授权的方式进行交换。 “维度表”设计的最佳实践: 一般情况下描述属性的表设计为维度表。维度表可以和任意表组的任意表进行关联,并且创建时不需要配 置分区信息,但是对单表数据量大小有所限制。维度表的设计和使用注意以下几点: 一般要求维度表单表不超过1000万。 维度表的数据不应该被大量更新。 维度表和其他表进行Join操作时可以使用mapjoin。 拉链表设计 – 极限存储的应用 极限存储功能待发布,在此介绍主要提供设计思想。 基于MaxCompute的拉链表设计背景 在数据仓库的数据模型设计过程中,经常会遇到这样的需求: 数据量比较大。 表中的部分字段会被update,如用户的地址,产品的描述信息,订单的状态、手机号码等等。 需要查看某一个时间点或者时间段的历史快照信息。(比如,查看某一个订单在历史某一个时间点的 状态,比如,查看某一个用户在过去某一段时间内,更新过几次等等) 变化的比例和频率不是很大,比如,总共有1000万的会员,每天新增和发生变化的有10万左右,如果表每天都保留一份全量,那么每次全量中会保存很多不变的信息,对存储是极大的浪费。 考虑极限存储的使用 : MaxCompute提供了将不同表转化为极限存储表的能力。极限存储操作示例如下: 创建源表。 create table src_tbl (key0 STRING, key1 STRING, col0 STRING, col1 STRING, col2 STRING) PARTITIO N (datestam p_x STRING, pt0 STRING); 导入数据。 将src_tbl转变为极限存储的表。 set odps.exstore.primarykey=key0,key1; [set odps.exstore.ignorekey=col0;] EXSTO RE exstore_tbl PARTITIO N (datestam p_x='20140801'); EXSTO RE exstore_tbl PARTITIO N (datestam p_x='20140802'); 拉链表设计更详细介绍可以参考云栖文章: https://yq.aliyun.com/articles/542146#? spm=a2c41.11181499.0.0 采集源表的设计 数据采集方式:流式数据写入, 批量数据写入,周期调度条式数据插入。 大数据量情况下,确保同一个业务单元的数据使用分区和表进行分;在数据量较小情况下,优化采集频率。 流式数据写入。 对于流式写入的数据,一般采集的通道较多,相关采集通道应做有效区分,在单个数据通道写入 量较大的情况下应该进行按照时间进行分区设计。 在采集通道数据量较小的情况下可以采取非分区表设计,对终端类型和采集时间设计成标准列字 段。 采用Datahub进行数据写入时应该合理规划shard数量,放置由于shard过多而造成采集通道流量 较小且通道较多的问题。 批量数据写入。批量数据写入重点关注写入周期 周期调度条式数据插入。 避免周期数据插入,此种情况下需要建立分区表,在新分区进行插入操作, 减少对于原来分区影响。 日志表的设计 日志其实是个流水表,不涉及记录的更新,来一条采集一条,多条一起存放,日志表设计的主要注意几 点: create table src_tbl (key0 STRING, key1 STRING, col0 STRING, col1 STRING, col2 STRING) PARTITIO N (datestam p_x STRING, pt0 STRING); set odps.exstore.primarykey=key0,key1; [set odps.exstore.ignorekey=col0;] EXSTO RE exstore_tbl PARTITIO N (datestam p_x='20140801'); EXSTO RE exstore_tbl PARTITIO N (datestam p_x='20140802'); 考虑是否需要对日志进行去重处理。 考虑是否需要扩展维度属性。 是否需要关联维表扩展维度属性字段考虑两点:业务使用的频次,关联是否会造成的产出的延 迟。 需要仔细选择是否对于维度表进行扩展 考虑区分终端类型。 日志表由于量大,考虑在业务分析使用时通常会按PC端,APP端来统计分析,同时PC端、APP端 的采集是两套体系,因此通常的做法会按终端设计多个明细DWD表。 如果终端较多,但数据量不大的情况下,如一个终端的数据小于1T 但是采集次数较多,可以考虑 不对终端进行分区,而设置终端信息为普通列。 注意: 对于日志表进行分区设计,可以按照日志采集的时间按照天进行分区,在入数据前进行数据采集整 合,一批数据写入提交一次(通常是64M)。 日志数据很少有对原来分区的更新操作,可以采用insert 进行少量数据的插入,但一般需要限制插入 次数。 如果有大量的更新的操作,需要采用insert overwrite操作避免小文件问题。 对日志表设置合理的分区和对已经⻓久不访问的冷热数据配置归档操作。 互动明细表的设计 周期快照表,每天对收藏的所有记录进行快照存放。 问题 :历史累计的记录非常多,每天生成快照要拿当天增量表与前一天的全量表merge,非常耗资源。统 计最近1天的新增收藏数,需要扫描全量表,如何降低资源? 建议的方案 :建立一个事务性事实表,在建立一个存放当前有效收藏的周期快照表,以满足各种不同业务 的统计分析需要。 注意 : 设计互动明细表最重要的是要区分存量数据和增量数据之间的关系。 - 对于新分区的数据可以写入,作为增量数据。 应尽量减少对于老的分区数据的修改和插入。 在数据插入和全表覆盖写种选择时应尽量选用insert overwrite而并选择insert into。 MaxCompute表数据更新与删除操作 关系型数据库支持的 delete/update/merge SQL ,在MaxCompute上的实现方式示例如下: 表准备 -- 上日全量表 table1(key1 string,key2 string,col1 string,col2 string); -- 今日增量表 table2(key1 string,key2 string,col1 string,col2 string); -- 今日增量表(删除) table3(key1 string,key2 string,col1 string,col2 string); update(table2 表中的记录的值,更新到table1表中) insert overwrite table table1 select t1.key1 ,t1.key2 ,case when t2.key1 is not null then t2.col1 else t1.col1 end as col1 ,case when t2.key1 is not null then t2.col2 else t1.col2 end as col2 from table1 t1 left outer join table2 t2 on t1.key1=t2.key1 and t1.key2 = t2.key2 ; delete(table2 表中的记录,从table1表中删除) insert overwrite table table1 select t1.key1 ,t1.key2 ,t1.col1 ,t1.col2 from table1 t1 left outer join table2 t2 on t1.key1=t2.key1 and t1.key2 = t2.key2 where t2.key1 is null ; merge(没有del) insert overwrite table table1 select from ( -- 先把上日存在,今日也存在的记录从上日表中排除。剩下的就是今日没有更新的记录 select t1.key1 ,t1.key2 ,t1.col1 ,t1.col2 from table1 t1 left outer join table2 t2 on t1.key1=t2.key1 and t1.key2 = t2.key2 where t2.key1 is null union all -- 再合并上今日增量,就是今天的全量 select t2.key1 select t2.key1 ,t2.key2 ,t2.col1 ,t2.col2 from table2 t2)tt ; merge(有del) insert overwrite table table1 select from ( -- 先把上日存在,今日也存在的记录从上日表中排除,再把今日删除的记录排除。剩下的就是今日没有更 新的记录 insert overwrite table table1 select from ( -- 先把上日存在,今日也存在的记录从上日表中排除,再把今日删除的记录排除。剩下的就是今日没有更 新的记录 select t1.key1 ,t1.key2 ,t1.col1 ,t1.col2 from table1 t1 left outer join table2 t2 on t1.key1=t2.key1 and t1.key2 = t2.key2 left outer join table3 t3 on t1.key1=t3.key1 and t1.key2 = t3.key2 where t2.key1 is null or t2.key1 is null union all -- 再合并上今日增量,就是今天的全量 select t2.key1 ,t2.key2 ,t2.col1 ,t2.col2 from table2 t2)tt ; 表创建设计示例 场景:天气情况信息采集。 基本信息: 数据信息包括地名,关于此地的属性数如面积,基本人口数量等信息,天气信息。 属性数据变化较小,天气信息数采用多个终端采集,且数据量较大 天气信息变化较大,终端数量稳定的情况下流量基本稳定。 表设计指南: 建议对数据信息划分为基本属性表,和天气日志表,区分变化小和变化大的数据。 因为数据量巨大,对天气日志表按照地域进行分区,也可以按照时间如天进行二级分区,此种分区方 式避免因某一地或某一个时间的天气变化而造成其他无关数据变化。 采集终端上使用datahub进行数据汇聚,依据稳定的流量值选择合适的shard通道数量,批量数据方式 写入到天气日志表中,不使用Insert into。 MaxCompute表的特色功能 生命周期 MaxCompute表/分区提供数据生命周期管理。表(分区)数据从最后一次更新时间算起,在经过指定的 时间后没有变动,则此表(分区)将被MaxCompute自动回收。这个指定的时间就是生命周期,生命周期 设置为表级别。 create table test_lifecycle(key string) lifecycle 100;/alter table test_l ifecycle set lifecycle 50; MaxCompute会根据每张非分区表或者分区的的LastDataModifiedTime以及lifecycle的设置来判断是 否要回收此非分区表或者分区表中的分区。 MaxCompute SQL提供touch操作用来修改分区的 LastDataModifiedTime。会将分区的LastDataModifiedTime修改为当前时间。修改 LastDataModifiedTime的值,MaxCompute会认为表或分区的数据有变动,生命周期的计算会重新开始。 ALTER TABLE table_nam e TO UCH PARTITIO N(partition_col='partition_col_valu e', ...); 注意: 合理规划表的生命周期,在创建表时即设置生命周期,可有效减少存储压力。 对表数据的任何变动都会影响生命周期回收数据的判断时间,包括小文件合并。 避免全表扫描 表设计: 建立分区表或者对扫描条件进行列设计。 对数据表进行合理分区。 对常用查询条件设置成列名。 读常用查询条件进行hash clustering 数据计算: 加分区过滤条件,或者减少扫描分区数,或者拆出中间小表然后再扫描小表的历史分区以减少数据扫描 量。 把全局扫描表中间结果进行存储形成中间表。 如果每天都去扫一年的分区,计算消耗是非常大的,建议拆出一张中间表,每天做一次汇总,然后再 去扫描这张中间表的一年分区,扫描数据量会减少很多。 避免小文件 Reduce计算过程产生的小文件:只需要insert overwrite源表(或分区)即可,或者写入到新表删除 源表。 Tunnel数据采集过程中产生的小文件建议: 调用tunnelsdk时当buffer达到64M时提交一次; 使用console时避免频繁上传小文件,建议积累较大时一次性上传; 如果导入的是分区表,建议给分区设置生命周期,过期不用的数据自动清理; 同第一种方案,insertoverwrite源表(或分区); ALTER合并模式,通过console命令进行合并。 使用临时表建议创建时都加上生命周期,到期后垃圾回收自动回收。 - 申请过多的datahub shard将会产生小文件问题,申请datahub shard数目的策略 : 默认吞吐量单个shard是1MB/s,可以按照这个分配实际的shard数目(可以在此基础上多加几 个); 同步odps的逻辑是每个shard有一个单独的task(满足5分钟或者64MB会commit一次),默认设置5分钟是为了尽快能在odps查到数据。如果是按照小时建partition,那个一个shard每个小 时有12个文件。 如果这个时候数据量很少,但是shard很多,在odps里面就会很多小文件(shard*12/hour)。 不要过多的分配shard,按需分配。 转化Hash Clustering表 Hash Clustering表的优势:优化Bucket Pruning/优化Aggregation/优化存储。 在创建表时使用CLUSTERED BY指定Hash Key,MaxCompute将对指定列进行Hash运算,按照Hash 值分散到各个Bucket里面。 Hash Key指选择原则: 选择重复键值少的列 SORTED BY用于指定在Bucket内字段的排序方式。 如何转化为HashClustering表: ALTER TABLE table_nam e [CLUSTERED BY (col_nam e [, col_nam e, ...]) [SO RTED B Y (col_nam e [ASC | DESC] [, col_nam e [ASC | DESC] ...])] INTO num ber_of_buck ets BUCKETS] ALTER TABLE语句适用于存量表,在增加了新的聚集属性之后,新的分区将做hash cluster存储。 创建 完HashClustering的表之后使用insert overwrite从另外一个源表进行转化。 注意,Hash Clustering表有以下限制: 不支持insert into,只能通过insert overwrite来添加数据。 不支持tunnel直接upload到range cluster表,因为tunnel上传数据是无序的。 原文链接 大数据 2018-12-19 17:32:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 概述 最近,Amazon新推出了完全托管的时间序列数据库Timestream,可见,各大厂商对未来时间序列数据库的重视与日俱增。 阿里云TSDB是阿里巴巴集团数据库事业部研发的一款高性能分布式时序时空数据库,在即将过去的2018年,我们对TSDB进行了多次的系统架构改进,引入了倒排索引、无限时间线支持、时序数据高压缩比算法、内存缓存、数据预处理、分布式并行聚合、GPU加速等多项核心技术,并且引入了新的计算引擎层和分布式SQL层,使得引擎核心能力有了质的提升,也基本上统一了集团内部的监控存储业务。2018年双11当天,TSDB稳定运行,0故障,支撑双十一核心业务系统,毫秒级采集能力,具备双十一峰值写入不降级,创造了集群TPS 4000万、QPS 2万的新纪录。同时,面向IOT赛道,推出了时空数据库和边缘计算版本,还会引入面向时序时空场景的智能引擎,未来我们的目标是把TSDB打造成一款业内领先的“智联网数据库”。 2018双十一数据 首先,我们来看一下TSDB在2018年双十一的答卷:TSDB承受了4000万/秒的峰值写入,2万/秒的峰值查询,与2017年双十一相比均翻倍增长;而写入均值也达到了2600万/秒,查询均值达到了8000次/秒。 场景 下面几页Slide是我们在外部的一些场景和客户案例: 核心技术解析 为了更好的支持业务的需求,今年我们在核心引擎层面做了非常多的优化和改进,我们还引入了新的计算引擎层,分布式SQL引擎,时空引擎以及面向IoT市场的边缘计算版本,极大的提高了TSDB的计算能力和场景。下图就是TSDB的主要架构图,接下来的篇章我会分时序引擎,计算引擎,SQL引擎,时空引擎,边缘计算这5大部分来详细的介绍我们的核心技术能力。 一、时序引擎 问题挑战 稳定性、流量翻倍、不降级、低延迟、无限时间线 1. 复杂时间线索引、无限制时间线支持: 问题 为了支持多维查询和聚合查询,TSDB使用了倒排索引以快速定位到某条时间线。在TSDB现有的实现里,倒排索引是全部存放在内存中的。该方案的好处是根据某个Tag或者Metric查找时间线时会非常高效,但是缺点也非常明显:受限于内存大小,TSDB无法支持大规模的时间线。随着TSDB的客户越来越多,这个问题也越来越突出:某直播业务要求TSDB能够支撑20亿时间线的规模;某监控业务虽然初始时间线只有上千万,但是每天会新增几十万条时间线,而且时间线规模没有上限。 方案 TSDB在之前全内存倒排索引的基础上,将倒排索引持久化到硬盘,赋予了TSDB支撑无限时间线的能力。同时,通过给予倒排索引时间的概念,我们将查询的时间过滤算子下推到了索引查询阶段,进一步优化了查询性能。而通过创建时间线索引的BloomFilter,TSDB保证了海量时间线规模下的低延迟索引查询。 效果 拿集团内业务举例,原来64G内存的机器只能支持到不到500万的时间线,采用了上面的技术方案后,64G内存的机器就可以支持业务将近7000万以上的时间线,而且时间线数量在原有机器的基础上还可以继续增加。 2. 高效列式内存缓存、时间线内存分片: 为了加速数据的写入和查询能力,今年我们为TSDB设计了全内存的分布式高效缓存,具体架构图如下: 效果 最终我们测试效果是:在单个docker下,单机TPS从原来的50W提升到100W+,QPS从原来的1K提升到2K+ ;并且这个改进很好的支持了集团魔兔业务的需求和发展。 3. 工作负载管理: 为了更好的解决数据量大的情况下的负载均衡的问题,我们做了许多工作,主要包括: 通过读写分离机制进一步提升写入和查询性能; 快慢查询自动分级,让慢查询不再拖累其他查询; 自动限流保护,无需业务方降级,无惧双十一洪峰。 效果 双十一结果证明,新的负载管理策略帮助业务方非常平滑的度过了流量洪峰。 4. 时序全新存储引擎——Lindorm: 这里需要提到的另外一点是,TSDB时序最新架构采用了Lindorm作为存储引擎,能够以更少的机器成本提供更高的吞吐、更低的延迟。下图为采用Lindorm存储引擎前后的TSDB写入延迟。 5. 聚合器 丰富的流式聚合算子:15+聚合,10+填充策略,支撑大量的adhoc操作:groupby, in,not_literal_or, topN, limit等等;支持不规则时间序列数据的处理,TSDB提供的填值策略,可以很轻松地将不规则的时间序列转换为常规时间序列进行处理;支持top-bottom等聚合方式。 6. 混合存储记录块 时序数据存储的记录块方式是其查询性能的基石。TSDB既支持基于时间线的存储方式, 同时支持基于窗口的数据记录切分,复用同一套流式聚合,满足不同业务场景性能需求。 7. 服务化 TSDB服务目前已经在阿里云上出售,目前提供小规格版本以及标准规格版本,满足了很多用户的需求,但依然有一些用户希望提供更小规格的TSDB服务。为了更好满足用户的需求,TSDB提供服务化功能。服务化功能是通过多个用户共享一个TSDB集群的方式来提供更小规格的TSDB服务 数据安全:HTTPS支持,用户认证 并发管理:写入并发管理,查询并发管理 性能管理:写入性能管理,查询性能管理 使用量管理:数据点管理,时间线管理 时序引擎接下来会继续突破核心技术,包括: 自驱动索引TPI,多值数据模型,时序算法,内存计算等等。 从功能,性能,成本,生态方面进一步发力,打通 K8S指标存储体系, 具备兼容Prometheus的能力。 二、 时序计算引擎TSCE 业务接入量快速突破的过程中, 也带来了数据存储量级与查询复杂度的快速增长, 单TSDB实例 在存储与计算方面的技术挑战也面临跳跃式提升. 为了避免查询性能逐渐偏离用户设定的目标, TSDB的架构演进过程也引入相关的创新机制, 并最终延伸出时序产品体系中的新成员 - 时序计算引擎(TimeSeries Computing Engine, TSCE). 时序计算引擎(TSCE) 定位为对TSDB中原生数据进行流式计算的独立组件, 在时序产品体系中与时序数据库(TSDB)紧密结合, 提供诸如时序数据降采样(DownSample), 时间维度预聚合, 时间线降维归档 等涵盖时序数据查询与存储相关的核心计算能力. 同时, 针对应用特定的应用型时序计算场景, 时序计算引擎(TSCE) 亦支持自定义计算规则与函数, 满足各类应用自身的特定业务需求. 常见的应用型时序计算场类型: 时序事件告警, 事件模式匹配, 时序异常分析与检测等. TSCE的产品形态如下: 时序计算引擎(TSCE)作为独立组件进行部署, 用户需要在TSDB实例的基础上根据成本与应用需求选择是否开启TSCE时序计算处理. 在这种产品形态下, 用户可以独立调整TSDB的存储规格 和 TSCE的计算容量, 做到根据应用特点弹性调整各自组件的实例规模. 在满足应用要求的情况下将TSDB/TSCE实例部署成本控制在合理区间. TSDB与TSCE结合之后, TSDB引擎会在数据入库过程中同时让TSCE引擎感知数据流动, TSCE会基于配置的时序计算能力或业务规则对数据流进行计算与分析, 计算后的结果支持三种反馈形式: 1.直接反馈至TSDB存储层,供TSDB查询. 2.作为视图以API或者SQL方式访问. 3.通过Reactive机制投递给其他事件处理渠道. 时序计算引擎TSCE 支持通过 TS-API 或者 Web控制台 进行时序计算能力/自定义规则的配置. (1) 时序计算 TSDB与TSCE协作工作时, 针对核心的时序计算能力, TSCE会与TSDB的进行无缝集成. 此时核心的时序计算处理对于TSDB终端用户而言是透明,无感知的执行过程. 用户开启并配置TSCE处理后, 原来的数据查询方式与查询格式不变, 整个计算的处理完全在后台自动执行. 在查询层面上, 通过TSCE提供的时序计算处理, TSDB会在尽可能的情况下将查询经过TSCE处理的计算结果.即使是在海量数据场景下, 也能提供时序数据的秒级分析查询与时间维度钻取查询. 而在数据存储层面上, 随着时间线的流逝, TSCE会对原生历史数据进行降维计算, 将细粒度的时间点逐步转化为粗粒度的时间点归档存储(例如秒级数据点转化为分钟级数据点), 进一步控制TSDB中存储空间与资源的使用量, 使得TSDB的稳定性与性能波动处于可控范围. 通过TSDB与TSCE结合, TSDB中管理的数据体量可以控制在合理水平, 提升资源占用率的同时进一步节省产品使用成本. 数据流预聚合 诸如max/min/avg/count/sum等常见的 可累加式 状态值, TSCE可以在数据流动过程中即完成相关数据的统计与计算. 时间线计算 针对时间线(TimeSeries)的窗口粒度,数值分布等特征关系, 对时间线进行特征值转换的计算过程. 例如降采样(Dowmsampling)运算可以将秒级时间线转化为分钟级时间线, 经过转化后的时间线可以在查询流程上支持时间维度上下钻的即席查询; 而在存储流程上, 可以支持时间线归档存储, 将原始细粒度时间线转化为粗粒度时间线后,清除原始的数据点,释放相关资源. (2) 时序流处理 针对应用特定的应用型时序计算场景, TSCE通过引入自定义计算规则与函数, 来满足各类应用自身的特定业务计算需求. 用户在经过简单的规则配置后, TSCE引擎会负责底层的数据流打通, 流计算拓扑映射, 分布式节点间的Shuffle与结果归并, 计算后结果集的存储与投递等一系列动作细节. 与General-purpose的流计算处理相比, TSCE的时序流处理除了实现降低技术门槛之外,做到底层流计算能力的弹性扩展之外, 也提供几个核心能力: 时序数据库的紧密集成: 因为TSCE与TSDB部署在相同的内部环境内,TSCE可以在非常低的成本下做到与TSDB做数据交换,并且可以直接访问到TSDB后端的数据存储层. 与常规应用方案中 需要先经过流处理再写入时序存储产品的架构相比, 引擎间的紧密集成可以做到效率,成本,性能的成倍提升. Reactive查询视图: 流处理后的结果集除了写回TSDB中存储之外, TSCE也支持将数据流转储为Reactive查询视图. Reactive查询视图除了可以支持以SQL/API方式查询结果之外, 也可以通过指定Subscriber订阅相关数据流更新, 当结果集在视图中产生变动时, TSCE会投递数据变更事件至相关Subscriber指定的渠道中(适合监控告警以及自动化处理等业务). 时序流处理规则 定义一个流处理规则包含了3个元素: 1.数据源(TSDB中的时间线), 2.自定义计算规则, 3.计算结果的输出源;其中数据源来自于TSDB数据库, 业务方可以通过规则匹配1条或多条时间线作为数据输入源. 而计算结果的输出源可以是写会TSDB, 或者转储为Reactive视图. 此外用户也可以通过lambda自定义与业务逻辑处理相关的函数, 加入到整体的规则处理链中. (3) 时序分析与智能引擎 除了配置TSCE的 时序计算能力 与 自定义时序流处理之外, TSCE也提供一些常见的时序分析与智能处理能力: 时序分析 简单的时序流复杂事件处理(CEP): 提供时间线上数据点之间的关系侦测,模式匹配等. 智能引擎 TSCE支持与时序智能引擎进行联通,让用户具备针对时序数据流进行时序异常探测,故障root-cause分析,流式模型训练等相关高级能力. 技术实现上TSCE以Function,DSL等形式进行智能引擎的规则定义与转换, TSCE在数据流的计算过程中会基于内存间数据共享/RPC等方式完成与智能引擎的联动与交互 4. 应用场景 双十一期间, TSCE时序计算引擎支撑的几个典型业务场景: 海量数据下的时间线降维度,预聚合查询 基于阈值的简单事件告警 时序数据的降维归档存储 验证初期的时序分析能力(与智能引擎结合) 三、分布式MPP SQL引擎: 1. 需求 今年我们决定在TSDB上设计开发一个分布式的SQL查询引擎,为什么要这么做呢?主要有以下几个原因: 从简单时序监控到复杂时序分析 TSDB引擎所支持的查询主要是简单的降采样和分组聚合,随着越来越多业务把时序数据存储到TSDB,我们需要提供一个基于SQL的分布式查询引擎,支持更复杂的时序计算(聚合,时序Join, SQL Window function, UDF), 从而推广TSDB到更广泛的业务中。 扩展时序数据库的生态系统 生态系统是一个产品是否成功的关键因素。通过时序SQL查询引擎,TSDB数据库可以和现有的BI tool实现无缝对接。在集团内部,我们正在和阿里云的QuickBI和IDB等团队合作,把TSDB演进成一个支撑重要BI数据分析的数据库产品。未来,通过时序SQL查询引擎,可以对接市场上常见的BI tool, 比如Tableau, Qlik, Power BI等众多工具。 支持多种异构数据源的联合分析 通常,业务把时序相关的数据存储在TSDB,非时序数据存储在其他系统中,比如维度信息存储在MySQL等。业务需要在多种数据中进行Join。时序SQL查询引擎支持业务在多种数据源之间直接进行查询分析,避免业务方复制异构数据源再进行联合分析。 对标业界主要竞争产品 时序数据库在国外最主要的竞争产品包括TimeScaleDB, InfluxDB, KDB+,Prometheus。TimeScaleDB作为Postgres的一个扩展,提供了标准SQL的支持,而InfluxDB/KDB+提供了类似于SQL (SQL-like)的查询支持。我们TSDB系统通过时序SQL查询引擎,更好地对标国外主要时序竞争产品。 2. SQL引擎的挑战 除了海量时序数据带来的挑战外,时序SQL查询引擎还面临和时序场景相关的挑战: 数据table Schema的管理 时序metric数目海量:Sunfire等集团内部业务有上亿规模的时间线,而盒马业务中将tag编码进metric, 时间线数目巨大,这和一般数据库中数千或数万的table是巨大的区别; 时序metric schema动态变化:业务方随着应用的变化,经常需要增加或减少一个tag。这意味着metric所对应的schema也在不断变化之中。海量时间线+动态变化对查询引擎获取metric的schema 是一个挑战。 数据schema-on-write对查询引擎的影响 大多数的数据库在用户写入数据或查询之前,必须先通过DDL创建table schema,这些table schema等元数据又被存放在一个catalog或meta data store, 供数据写入或查询时使用。而时序数据库的业务中,大部分的数据源来自于监控设备的一个agent, 或者IOT物联网的一个sensor, 要求先定义DDL再写入数据会严重影响可用性; 同时,时序metric所对应的tag集合在应用演进过程中,变化很常见。针对这一的应用特点,时序数据库TSDB,InfluxDB, Prometheus都采用了一种'Schema-on-write'的机制,应用直接写入数据,table schema是隐含在数据中。在'Schema-on-write'的机制下,需要解决没有DDL的情况下SQL查询引擎如何从海量时间线中获取table schema等元数据的问题。 时序功能扩展 在现有以关系运算为基础的SQL查询引擎中。为支持时序功能扩展,我们需要一个易于扩展功能的架构,能支持开发时序相关的功能,比如时序Join, 时序相关的用户自定义函数(UDF)。 时序查询优化 一个SQL查询引擎,优化器是性能优劣的关键。需要在通用的SQL查询引擎中,引入时序数据统计信息,作为输入提供给优化器;同时,在优化器中,引入时序相关的优化Rule, 比如FilterPushDown/ProjectPushDown规则,这些都是时序SQL查询引擎需要解决的问题。 3. SQL引擎 SQL查询引擎是一个分布式的系统,其特点: 每个计算节点在系统中是对等的,并没有主从关系, 任何一个节点都可以成为Foreman, 负责SQL查询计划的生成,而其他节点成为worker nodes 无状态,一个节点失效后,可以快速启动备用节点。 4. 应用场景 盒马零售业绩时序数据查询: 业务方需要通过SQL查询TSDB的时序数据,接入业务方的分析图表大屏。此外,业务方需要支持简单的SQL简单查询外,还包括异构多种数据源的join的支持。![image] 云监控:通过提高SQL查询支持,业务方能统一数据访问方式![image] 四、 时空数据库 1. 需求 随着TSDB的业务发展,时序数据库TSDB渐渐走出APM与监控领域,在IoT领域也获得广泛应用。 而由于IoT领域的特性,其中采集到的很多数据不光有时间信息,还有空间信息与之关联。因此时序数据库也需要能够识别和处理空间信息,以便于更好地服务IoT场景。 对于传统的时间序列数据库,比如说OpenTSDB,如果用户想要存储和查询地理坐标信息,往往需要将经度和纬度分开存储,生成独立的时间线。但是使用时想要将两者重新关联起来需要用户做额外处理。另外一种方式则是需要用户自己将地理位置信息进行编码,常见有的GeoHash或者Google S2。然后将编码信息作为时间线信息进行存储。即使这样,用户依旧需要开发时空过滤功能等等。 2. 方案 在IoT场景中,对于地理坐标信息的采集十分普遍。因此在时序数据库的基础上,我们添加了对空间信息的存储和处理能力,使之成为时序时空数据库。TSDB的时空引擎让地理位置信息和时序信息完美结合起来,力争解决着一切关于时序和时空相关的查询分析。 3. 时空处理能力 最新版本的阿里云TSDB支持地理坐标位置信息的直接写入。用户只需要通过新版本的SDK以及Http Restful APIs可以将地理空间信息(地理经纬度)写入,并且可以对经纬度信息进行读取。下面两个通过Http Restful API接口TSDB多值写入和单纯的轨迹查询示例:(注意:Coordinate是一个关键字,表示地理坐标点写入,不可用于其他监控指标名称(metric)。) 说完TSDB对于地理坐标信息最基本的存储和查询功能,我们来看一下TSDB所提供的常用时空分析功能。 对于写入的地理坐标数据点,TSDB将自动生成时空索引提高查询和分析效率。TSDB的时空索引基于传统空间索引(Google S2和GeoHash都是支持)结合时序数据特征创建的时空索引格式。同时为了提高,用户可以根据自己需求在开始使用时空功能之前提前配置时空索引按照时间分片。偏实时的业务,可以将按照小时或者半小时对时空索引进行分片。对于偏分析的场景,可以按照天进行分片。 时空索引为TSDB提供时空过滤分析功能提供了便捷和提高效率,现在最新版本的TSDB支持一些常用的时空过滤功能,比如BBOX查询和DISTANCE_WITHIN查询。 目前TSDB时空功能已经在云上推出了公测版本,大家在官网就可以看到我们时空功能。 4. 下一代时空数据库核心技术全力研发中 针对万亿级,EB级别的时空数据,全团队在全力研发下一代时空数据库,包括新型分布式列式存储引擎,GPU加速,智能压缩,冷热分离,高效时空索引,分布式时空计算等等; 五、边缘计算 今年,为了进一步支持外部IoT市场的需求,我们在TSDB云版的基础上,开发了边缘计算版本( 在广州云栖大会工业物联网专场,正式发布阿里云工业物联网边缘计算平台存储类产品 TSDB Edge,TSDB Edge 主要提供物联网边缘端设备相关数据的本地存储,本地分析,数据清洗和云端数据同步能力。 ); 1. 两节点HA 两节点HA通过两个TSDB节点实现HA。两个TSDB节点没有主从的区别,二者都可以接受读写请求,也都可以响应读写服务(不需要转发读写请求)。两个TSDB节点能够同时接受写请求,两个TSDB通过同步WAL日志的方式实现数据同步,保障数据的最终一致性。同时,两节点HA通过WAL与云端同步数据。 两节点HA提供了在边缘设备端TSDB的高可用性,当一个节点发生宕机,另外一个节点能够继续提供服务,宕机节点恢复以后,通过数据同步功能,数据能够在两个节点上迅速实现同步,不会引起非硬盘故障下的数据丢失。 2. WAL日志管理器 实现本地的WAL日志管理,通过WAL日志保证写入的数据不丢失。同时WAL日志管理器,自动判断并删除过期日志文件,减少硬盘空间占用,减轻运维工作。 3. 内存管理器 管理大对象的内存使用情况,通过监控实时内存使用情况,自动判断是否将内存中的数据写入文件系统以减少内存使用。内存管理器根据内存使用情况,自动设置保留的chunks数量,可以减少/杜绝OutOfMemoryError错误的发生。 4. HAServer/HAClient数据同步器 HAClient通过自有的协议,采用PUSH的方式传输WAL。HAServer收到WAL以后,直接通过WAL replay数据插入操作,从而实现数据同步。HAServer/HAClient通过保存读取偏移量的方式,实现断点续传。 CloudSynchronizer云同步器 通过读取WAL,并调用TSDB云版客户端实现向云端同步数据的功能。该同步器对云端透明,同时实现了断点续传。 5. 新型压缩算法 边缘计算提出自研的新型压缩算法,该压缩算法,采用流式压缩方式,支持数据通过append的方式加入,同时在内部采用整字节的方式进行编码,提高压缩/解压性能。 经测试,该新型压缩算法的压缩率为3-40倍。与Facebook Gorilla算法相比,该算法压缩率提高约20%-50%,压缩性能提高3-5倍,解压性能提高4-6倍。 6. GPU硬件加速 边缘计算还在探索与GPU等新型硬件集成。TSDB边缘版使用GPU进行解压,降采样以及聚合操作; 通过测试,使用GPU以后,查询性能可以达到原来的50倍。 六、智能引擎 背景 TSDB 提供了强大的数据存储、处理和查询能力。在这个坚实的基础之上,越来越多的业务场景需要通过挖掘海量数据驱动业务价值的提升,TSDB 智能引擎就是在这个大趋势之下应运而生的。 能力 TSDB智能引擎专注于时序时空数据的分析、检测、挖掘、预测能力,着力打造从数据到知识再到商业价值的高效引擎,争取达到价值链与数据能力的两个全覆盖。 市场上现有的商业智能与数据科学工具往往只利用数据库的存储查询功能,进行数据挖掘和分析之前需要从数据库中提数,之后的流程也脱离数据库环境进行。TSDB 智能引擎从架构上与数据库存储查询引擎进行深度整合,高效的利用数据库现有关系代数能力,并适当引入线性代数计算能力,自然的形成数据闭环,提供一站式的数据科学能力。相信随着不断地努力打造与突破,智能引擎也会逐步沉淀行业数据模型与智能定制算法,并最终形成端到端的行业智能分析解决方案。 限于篇幅,这里就不详细描述了。 八、其他 时序洞察 时序标准 我们在今年8月份也是参与国家的时间序列标准的制定,并且在与其他厂商的竞争中取得优异的成绩。 结束语 2018年,是阿里云TSDB产品成长最快的一年;上文中提到的需要技术和能力目前只是应用在阿里巴巴集团内部的场景;未来,我们会逐步把这些能力开发给外部用户,让外部客户也能享受到阿里巴巴强大的技术实力带来的价值。 最终,我们的目标是把TSDB打造成业内领先的“智联网数据库”! 作者: 焦先 原文链接 本文为云栖社区原创内容,未经允许不得转载。 大数据 2018-12-19 16:58:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 随着数据对生产、生活越来越重要,数据分析也逐渐成为一门显学,在各个领域中都发挥着重要的作用。那么你了解数据分析的发展历史吗? 从国家现状衍生出的统计学,从博诞生而来的概率论,为数据分析奠定了坚实的基础。伴随着各路大神的粉墨登场,数据分析也活色生香起来,从霍乱神医斯诺,到护理之祖南丁格尔,从二战日本的自杀袭击,到一球成名中的”金金“计较的球队经理,从商业智能到公司治理,从大数据到人工智能,数据分析几乎无处不在。 本课程以简单 易懂、风趣轻松的语言科普了数据分析跌宕起伏的发展历程,同时还以自己的切身体会介绍了如何具有数据思维、如何成为数据分析师等,希望对于有志于此的同学能有一定的启发。 课程链接: 阿里云大学——大数据简史 更多精品课程: 阿里云大学官网( 阿里云大学 - 官方网站,云生态下的创新人才工场 ) 大数据 2018-12-19 16:34:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 表的限制项 表(Table)设计规范 表设计主要目标 表设计的影响 表设计步骤 表数据存储规范 按数据分层规范数据生命周期 按数据的变更和历史规范数据的保存 数据导入通道与表设计 分区设计与逻辑存储的对应 表和分区设计基本规则 分区设计 分区字段和普通字段的选择 分区字段定义依据 分区个数定义依据 分区数量和数据量建议 表的限制项 表(Table)设计规范 表设计主要目标 降低存储成本。 合适的表设计可以在数据分层设计上降低冗余存储,减少中间表数据量大小。同时正 确的对表数据进行生命周期管理,更能够直接降低存储的数据量以降低存储成本。 降低计算成本。 对表设计规范化,以便在后续对表数据进行查询计算过程中,可以依据这些规范优化 数据的读取,减少计算过程中的冗余读写和计算,提升计算性能的同时降低成本。 降低维护复杂度。 规范化的表分层设计能够直接体现业务的特点。如通过对数据通道中数据采集方式 进行优化,同时对表进行规范化设计,可以减少分布式系统中小文件的问题,同时也减少表和分区维 护的数量等复杂度。 表设计的影响 影响的操作:表创建/入数据/表更新/表删除/表管理。 导入数据场景(区分要做实时数据采集还是离线批 量数据写入): 导入即查询与计算。 多次导入,定时查询与计算。 导入后生成中间表进行计算。 注意: 合理的表设计和数据集成周期管理能够使数据在存储期间降低成本。 - MaxCompute优先作为批量数据集成库以及按业务逻辑进行计算,如按照分区进行计算。 导入后立即查询与计算,需要考虑每次导入数据量,减少流式小量数据导入。 不合理的数据导入及存储(小文件)会对整体存储性能,计算性能,运维稳定性造成影响。 表设计步骤 确定所属项目空间,依据业务过程规划表类型,属于哪个数据层次。 定义表描述,权限定义与Owner定义。 依据数据量、数据集成特点定义分区表或者非分区表。 定义字段,或分区字段 表创建/表转换 明确导入数据场景的相关因素(包括批量数据写入/流式数据写入/条式数据插入)。 定义表和分区数据生命周期。 注意: 表创建之后可以依据业务变化进行表schema的修改,如设置生命周期,RangeClustering。 在设计阶段需要特别注意区分数据的场景(批量数据写入/流式数据写入/周期性条式数据插入)。 合理使用非分区表和分区表。日志表,事实表,原始采集表等建议使用分区表,按照时间分区。 注意各种表和分区的限制条件。 表数据存储规范 按数据分层规范数据生命周期 源表ODS层: 每天从业务系统同步过来的数据,全部保留,生命周期定义永久保存。以防备下游数据 受损时可以从ODS恢复。若ODS每天同步过来的是全量表,可以通过全表拉链的方式来压缩存储。 数据仓库(基础)层: 至少保留一份完整的全量数据(不必像ODS那样冗余多份全量)。考虑到性能 因素,可以考虑拆表或者做分区。 数据集市层: 按需保留1~3年时⻓。数据集市的数据较容易生成,无需保留那么⻓时间的历史数据 按数据的变更和历史规范数据的保存 会变化数据怎么存: 客户属性、产品属性天天变,将这些属性的历史变化情况记录下来,以方便追溯某个时点的值。 在事实表里面冗余维表的字段,即把”事件发生时“的各种维度属性值与该事件绑定起来。 比较方便使 用者,不需关联多张表就可以用数据,在数据应用层使用。 用拉链表或者日快照的形式,记录维表的变化情况。 比较方便数据加工者,数据结构灵活,扩展方 便,容易管理,且数据一致性更好。在数据基础层使用。 数据导入通道与表设计 通道类型: Datahub ,规划写入的分区以及写入流量的关系,做到64M commit一次。 数据集成或DataX,规划写入的表分区的频率,做到64M commit一次,避免commit空目录。 DTS,规划写入的表存量分区与增量分区的关系,做commit频率设置。 Console (Run SQL or Tunnel upload),避免高频小数据量文件的插入或者上传。 SDK Run Sql之insert into,对表或者分区上传时需要注意插入到分区后进行小文件整理操作,避免 对一个分区或者非分区表插入多次,插入后需要merge。 注意: MaxCompute导入数据的通道只有Tunnel SDK或者执行SQL的Insert into,避免流式插入。 以上各通道本身均有自身逻辑进行流式数据写入, 批量数据写入,周期调度写入。 数据通道写表或分区时需要注意将一次写入的数据量控制在合理的值如64M以上。 分区设计与逻辑存储的对应 如上图,表一共m 个一级分区,每个一级分区都会按时间存储二级分区,每个二级分区都会存储所有的 列。 对分区进行设计的注意事项: 分区限制数量上限。 避免每个分区中只有少量数据。 按照分区条件查询和计算。 避免每个分区中多次数据写入。 表和分区设计基本规则 所有的表、字段名要使用统一的命名规范。 要能够区分该表的业务类型。 要能够区分该表是“事实表”或“维度表”,“日志表”,“极限存储表”(待发布功能)。 要能够区分该表的实体信息。 不同表中具有相同业务含义的字段要定义统一的数据类型: 避免不必要的类型转换。 分区设计及使用一般规则: 支持新增分区,不支持新增分区字段。 单表支持分区数量为6万。 对于多级分区的表,如果想添加新的分区,必须指明全部的分区值。 不支持修改分区列列名,只能修改分区列对应的值。修改多级分区的一个或者多个分区值,多级 分区的每一级的分区值都必须写上。 分区设计 分区字段和普通字段的选择 分区字段的作用: 方便数据的管理 。 划分数据扫描范围。 创建表的时候,可以设置普通字段和分区字段。在绝大多数情况下,可以把普通字段理解成数据文件的数 据,而分区字段可以理解成文件系统的目录。 表的存储空间的占用是普通字段的空间占用 。 分区列虽然不直接存储数据,但是如同文件系统里的目录,方便数据管理,同时在计算时若指定具体的分 区,计算过程中只查询对应分区,从而减少计算输入量。 分区表的分区列的个数不能超过6级,也可以理解成底层存储数据的目录层数不能超过6层。对分区表设置 合适的生命周期,可以按照分区细粒度做到对部分数据进行周期管理。 注意: 可以从数据管理范围和常用的数据扫描范围考虑将对应字段设置成分区字段。 对于不具备规律或者类型数量大于10000且不经常作为查询条件的字段设置成普通字段。 分区字段定义依据 按优先级高低排序: 区列的选择应充分考虑时间因素,尽量避免对于存量分区进行更新。 如果有多个事实表(不包括维度表)进行join,查询条件where范围的列作为分区列。 选 择group by 或distinct 包含的列作为分区列。 选择值分布均匀的列,不要选择分区倾斜的列作为分区列。 常用SQL包含某列的等值或in查询条件,选择该列作为分区列。 例如: Select ... from table where id=123 and ....; 分区个数定义依据 时间分区:可按天进行分区或者按月进行分区,如按照小时进行分区,二级分区平均数量不应大于8 个。 地域分区:省,市,县进行分区,考虑进行多级分区。23个省,5个自治区,4个直辖市,2个特别行 政区;50个地区(州、盟);661个市,其中:直辖市4个;地级市283个;县级市374个;1636个县(自治县、旗、自治旗、特区和林区),按照最细粒度县级进行分区后更细粒度不应再按照小时进行 分区。 单分区下的数据建议64M数据提交一次。如果为多级分区,保证每个最细粒度级分区下的二级分区的 数据都是按照这个规则。 单表分区数(包括下级分区)不能超过6万。 分区数量和数据量建议 在计算的时候可以使用分区裁剪是分区的优势。 建议单个分区中数据量不要太大,如可以单个分区中数据在1万条,但是建了5万个分区。 应尽量避免分区数据倾斜,单个表不同分区的数据量差异查过100万以上。 做分区设计时应合理规划分区个数,较细粒度的分区在跨分区扫描时会影响到SQL的执行性能。 单个分区中数据量较大的情况下,MaxCompute执行任务时会做分片处理不影响分区裁剪的优势。 单个分区中文件数较多时,会影响MaxComputeInstance数量,造成资源浪费和SQL性能的影响。 采用多级分区,先按日期分区,然后按交易类型分区。 拆表,一种交易类型就独立成一张表,再每张表按日期分区。 维度表不做分区。 原文链接 大数据 2018-12-19 15:19:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 16k)。地址: https://github.com/Snailclimb/JavaGuide. 本文内容思维导图: 消息队列其实很简单 “RabbitMQ?”“Kafka?”“RocketMQ?”...在日常学习与开发过程中,我们常常听到消息队列这个关键词。我也在我的多篇文章中提到了这个概念。可能你是熟练使用消息队列的老手,又或者你是不懂消息队列的新手,不论你了不了解消息队列,本文都将带你搞懂消息队列的一些基本理论。如果你是老手,你可能从本文学到你之前不曾注意的一些关于消息队列的重要概念,如果你是新手,相信本文将是你打开消息队列大门的一板砖。 一 什么是消息队列 我们可以把消息队列比作是一个存放消息的容器,当我们需要使用消息的时候可以取出消息供自己使用。消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。目前使用较多的消息队列有ActiveMQ,RabbitMQ,Kafka,RocketMQ,我们后面会一一对比这些消息队列。 另外,我们知道队列 Queue 是一种先进先出的数据结构,所以消费消息时也是按照顺序来消费的。比如生产者发送消息1,2,3...对于消费者就会按照1,2,3...的顺序来消费。但是偶尔也会出现消息被消费的顺序不对的情况,比如某个消息消费失败又或者一个 queue 多个consumer 也会导致消息被消费的顺序不对,我们一定要保证消息被消费的顺序正确。 除了上面说的消息消费顺序的问题,使用消息队列,我们还要考虑如何保证消息不被重复消费?如何保证消息的可靠性传输(如何处理消息丢失的问题)?......等等问题。所以说使用消息队列也不是十全十美的,使用它也会让系统可用性降低、复杂度提高,另外需要我们保障一致性等问题。 二 为什么要用消息队列 我觉得使用消息队列主要有两点好处:1.通过异步处理提高系统性能(削峰、减少响应所需时间);2.降低系统耦合性。如果在面试的时候你被面试官问到这个问题的话,一般情况是你在你的简历上涉及到消息队列这方面的内容,这个时候推荐你结合你自己的项目来回答。 《大型网站技术架构》第四章和第七章均有提到消息队列对应用性能及扩展性的提升。 (1) 通过异步处理提高系统性能(削峰、减少响应所需时间) 如上图, 在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即 返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。 通过以上分析我们可以得出 消息队列具有很好的削峰作用的功能 ——即 通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。 举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。如下图所示: 因为 用户请求数据写入消息队列之后就立即返回给用户了,但是请求数据在后续的业务校验、写数据库等操作中可能失败 。因此使用消息队列进行异步处理之后,需要 适当修改业务流程进行配合 ,比如 用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功 ,以免交易纠纷。这就类似我们平时手机订火车票和电影票。 (2) 降低系统耦合性 我们知道如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响较小,这样系统的可扩展性无疑更好一些。 我们最常见的 事件驱动架构 类似生产者消费者模式,在大型网站中通常用利用消息队列实现事件驱动结构。如下图所示: 消息队列使利用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。 从上图可以看到 消息发送者(生产者)和消息接受者(消费者)之间没有直接耦合 ,消息发送者将消息发送至分布式消息队列即结束对消息的处理,消息接受者从分布式消息队列获取该消息后进行后续处理,并不需要知道该消息从何而来。 对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展性设计 。 消息接受者对消息进行过滤、处理、包装后,构造成一个新的消息类型,将消息继续发送出去,等待其他消息接受者订阅该消息。因此基于事件(消息对象)驱动的业务架构可以是一系列流程。 另外为了避免消息队列服务器宕机造成消息丢失,会将成功发送到消息队列的消息存储在消息生产者服务器上,等消息真正被消费者服务器处理后才删除消息。在消息队列服务器宕机后,生产者服务器会选择分布式消息队列服务器集群中的其他服务器发布消息。 备注: 不要认为消息队列只能利用发布-订阅模式工作,只不过在解耦这个特定业务环境下是使用发布-订阅模式的。 除了发布-订阅模式,还有点对点订阅模式(一个消息只有一个消费者),我们比较常用的是发布-订阅模式。 另外,这两种消息模型是 JMS 提供的,AMQP 协议还提供了 5 种消息模型。 三 使用消息队列带来的一些问题 系统可用性降低: 系统可用性在某种程度上降低,为什么这样说呢?在加入MQ之前,你不用考虑消息丢失或者说MQ挂掉等等的情况,但是,引入MQ之后你就需要去考虑了! 系统复杂性提高: 加入MQ之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题! 一致性问题: 我上面讲了消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消费者并没有正确消费消息怎么办?这样就会导致数据不一致的情况了! 四 JMS VS AMQP 4.1 JMS 4.1.1 JMS 简介 JMS(JAVA Message Service,java消息服务)是java的消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输。 JMS(JAVA Message Service,Java消息服务)API是一个消息服务的标准或者说是规范 ,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。 ActiveMQ 就是基于 JMS 规范实现的。 4.1.2 JMS两种消息模型 1、点到点(P2P)模型 使用 队列(Queue) 作为消息通信载体;满足 生产者与消费者模式 ,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。比如:我们生产者发送100条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半(也就是你一个我一个的消费。) 2、 发布/订阅(Pub/Sub)模型 发布订阅模型(Pub/Sub) 使用 主题(Topic) 作为消息通信载体,类似于 广播模式 ;发布者发布一条消息,该消息通过主题传递给所有的订阅者, 在一条消息广播之后才订阅的用户则是收不到该条消息的 。 4.1.3 JMS 五种不同的消息正文格式 JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。 StreamMessage -- Java原始值的数据流 MapMessage--一套名称-值对 TextMessage--一个字符串对象 ObjectMessage--一个序列化的 Java对象 BytesMessage--一个字节的数据流 4.2 AMQP AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准 高级消息队列协议 (二进制应用层协议),是应用层协议的一个开放标准,为面向消息的中间件设计,兼容 JMS。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件同产品,不同的开发语言等条件的限制。 RabbitMQ 就是基于 AMQP 协议实现的。 4.3 JMS vs AMQP 对比方向 JMS AMQP 定义 | Java API | 协议 |
五 常见的消息队列对比 对比方向 概要 吞吐量 | 万级的 ActiveMQ 和 RabbitMQ 的吞吐量(ActiveMQ 的性能最差)要比 十万级甚至是百万级的 RocketMQ 和 Kafka 低一个数量级。 |
原文链接 大数据 2018-12-19 12:58:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 前言 只有光头才能变强 没错,这篇主要跟大家一起 入门 机器学习。作为一个开发者,”人工智能“肯定是听过的。作为一个开发面试者,肯定也会见过”机器学习“这个岗位(反正我校招的时候就遇到过)。 可能还会听过或者见过“深度学习”、“神经网络”等等这些非常火的 名词 ,那你对这些 术语 了解多少呢? 相信大家这几天在朋友圈也可以看到这照片: // 通过if else 以人工穷举的方式来假装实现智能机器人聊天 希望阅读完本文中后,大家可以对这些术语和机器学习有一定的了解。 一、术语介绍 首先我们来简单看看人工智能、深度学习、机器学习这些术语和它们之间的关系究竟是怎么样的。 1.1人工智能 不知道听到“人工智能”大家会联想到什么,可能大多数都会想到科幻电影的机器人。 我们看来看看维基百科的定义: 人工智能(英语:Artificial Intelligence,缩写为 AI)亦称机器智能,指由 人制造出来的机器所表现出来的智能 。通常人工智能是指通过普通计算机程序的手段实现的人类智能技术。 人工智能也可以分成两类: 强人工智能:强人工智能观点认为“有可能”制造出“真正”能推理(Reasoning)和解决问题的智能机器,并且,这样的机器将 被认为是具有知觉、有自我意识的 。 像绝大多数科幻电影中的机器人就是在这范畴 弱人工智能:弱人工智能观点认为“不可能”制造出能“真正”地推理和解决问题的智能机器,这些机器只不过**“看起来”像是智能**的,但是并不真正拥有智能,也不会有自主意识。 我们 目前阶段 的人工智能,其实都是弱人工智能。 1.2机器学习 不知道听到“机器学习”大家会联想到什么。Emmm...反正我就是从字面的意思去理解:“机器可以 自我 学习”。 首先我们看一下维基百科是怎么说的: 机器学习是实现人工智能的一个途径 ,即以机器学习为手段解决人工智能中的问题。机器学习在近30多年已发展为一门多领域 交叉学科 ,涉及概率论、统计学、逼近论、凸分析、计算复杂性理论等多门学科 简单来说:机器学习可以通过 大量的数据或者以往的经验自动改进计算机程序/算法 。 生成完 模型f(x) 之后,我们将 样例数据丢进模型里边 ,就可以输出结果: 我们说机器学习可以 自我 学习,是因为我们会将 样例数据也会丢到“历史数据”中 ,这样生成模型就会有一定的改动,从而达到“自我学习”的效果。 1.3它们之间的关系 等等,我们好像还没讲深度学习呢。我们从上面机器学习的介绍也可以知道,机器学习已发展为一门多领域 交叉学科 ,机器学习中就有 好多个经典的算法,其中就包含了神经网络(深度学习可看成是神经网络的升级版) 。由于近几年深度学习发展迅猛,一些特有的学习手段相继被提出,所以越来越多的人将其单独看作一种学习的方法。 《机器学习 周志华》: 所谓深度学习,狭义地说就是**“很多层”的神经网络**,在若干测试和竞赛下,尤其涉及语音、图像等复杂对象的引用中,深度学习取得优越的性能。 所以我们可以总结出人工智能、机器学习、深度学习之间的关系是这样的: 机器学习,是实现人工智能的重要方法。 深度学习,是实现机器学习的技术。 想要了解更多,可参考: 人工智能、机器学习和深度学习的区别? https://www.zhihu.com/question/57770020 二、机器学习入门 通过上面我们可以简单认为机器学习就是: 利用计算机 从历史数据找出 规律 ,把这些规律用到 未来 不确定场景的决策中。 下面我们再来学习一下机器学习的一些入门知识。 2.1机器学习的术语 特征、样本、数据集、标记这些术语的说明: 特征(属性)所张成的空间叫做 特征空间 。 例如我们把“色泽”、"根蒂“、”敲声“作为三个坐标轴,则它们张成一个用于描述 西瓜的三围空间 ,每个西瓜都可在这个空间中找到自己的坐标位置。 由于空间中的每个点对应一个坐标向量,我们也把一个示例称为“特征向量 ”。 回到我们上面的图,再来讲讲“训练数据”、“训练”、“标记”: 2.2机器学习的分类 一般机器学习又可以分成以下几类: 监督学习 半监督学习 非监督学习 增强学习 2.2.1监督学习 监督学习:训练数据(Training Data)可以告诉我们要找的那个模型的输入(Input)与输出(Output,也就是我们说的label)之间有什么样的关系。 给出的数据都有“答案”或“标记” 训练数据:"Java3y公众号"->好的公众号 , "Java4y公众号"->不好的公众号。 输出结果:好的公众号或者不好的公众号 在监听学习下又分为两种算法: 回归(Regression):结果是一个连续的 数值 (scalar),而非类别 分类(Classification):为训练数据进行分类别(多分类) 二分类:类别只有两种结果(YES OR NO) 回归例子 :知道前几天的PM2.5数值,预测一下明天的PM2.5数值。 **二分类例子:**判断一封邮件是垃圾邮件还是正常邮件。 **多分类例子:**将新闻帖子分类成不同的类别。 2.2.2非监督学习 非监督学习: 训练数据(Training Data)没有对应“答案”或“标记” 训练数据:"Java3y公众号" "Java4y公众号" "Java5y公众号" "Java6y公众号" "yyy公众号" "xxx公众号" "zzz公众号" 输出结果:("Java3y公众号" "Java4y公众号" "Java5y公众号" "Java6y公众号") ("yyy公众号" "xxx公众号" "zzz公众号") 分门类别 对没有“标记”的数据进行分类-聚类分析 聚类分析例子: 在以前,中国移动有三个品牌:神州行、动感地带、全球通。我们给一堆的SIM卡交由学习算法训练, 不告诉它每张SIM卡具体是什么卡 ,最后我们是可以将这些SIM卡 分类别出来的 。 2.2.3半监督学习 理解了监督学习和非监督学习,对于半监督学习就很容易理解了。 一部分数据有“标记”或者“答案”,另一部分数据没有 因为各种原因产生的标记缺失。 通常都会使用非监督学习手段对数据进行处理(特征提取、降维),之后再只用监督学习手段做模型的训练和预测。 2.2.4增强学习 根据周围环境的情况,采取行动, 根据采取行动的结果,学习行动方式 每次行动,就给这次的行动 评分 ,算法会根据评分来评估下一次的行动是好还是坏,最终不断改进。 例子:Alpha Go下每步棋的时候都会 评估 自己这次下得怎么样,通过最终的结果不断改进下的每步棋。 2.3机器学习的其他分类 除了我们上面所说的监督学习、非监督学习、半监督学习、增强学习之外,机器学习也可以分成: 在线学习: 及时 将样例数据作为训练数据对模型进行训练。 需要加强对数据进行监控(有可能样本数据是脏数据,这样就破坏我们的模型) 离线(批量)学习: 定时 将样例数据作为训练数据对模型进行训练。 不能很快的适应环境的变化 还有: 参数学习:一旦学到了参数,就不再需要原有的数据集。通过调参数就好了。 非参数学习: 不对模型进行过多的假设 ,非参数不代表没参数。 最后 机器学习的核心在于算法上 ,这篇只是对机器学习的一个简单的入门,希望能对大家有所帮助。 机器学习 资源 ,可关注我的公众号,回复“机器学习”即可领取。 有周志华《机器学习》电子版。吴恩达、李宏毅视频及笔记 乐于分享和输出 干货 的Java技术公众号:Java3y。 文章的 目录导航 : https://github.com/ZhongFuCheng3y/3y 大数据 2018-12-19 10:19:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 前面博主介绍了sql中join功能的大数据实现,本节将继续为小伙伴们分享倒排索引的建立。 一、需求 在很多项目中,我们需要对我们的文档建立索引(如:论坛帖子);我们需要记录某个词在各个文档中出现的次数并且记录下来供我们进行查询搜素,这就是我们做搜素引擎最基础的功能;分词框架有开源的CJK等,搜素框架有lucene等。但是当我们需要建立索引的文件数量太多的时候,我们使用lucene来做效率就会很低;此时我们需要建立自己的索引,可以使用hadoop来实现。 图1、待统计的文档 图2、建立的索引文件效果 二、代码实现 step1:map-reduce package com.empire.hadoop.mr.inverindex; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.input.FileSplit; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class InverIndexStepOne { static class InverIndexStepOneMapper extends Mapper step2:map-reduce package com.empire.hadoop.mr.inverindex; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class IndexStepTwo { public static class IndexStepTwoMapper extends Mapper 三、执行程序 #上传jar Alt+p lcd d:/ put IndexStepOne.jar IndexStepTwo.jar put a.txt b.txt c.txt #准备hadoop处理的数据文件 cd /home/hadoop hadoop fs -mkdir -p /index/indexinput hdfs dfs -put a.txt b.txt c.txt /index/indexinput #运行程序 hadoop jar IndexStepOne.jar com.empire.hadoop.mr.inverindex.InverIndexStepOne /index/indexinput /index/indexsteponeoutput hadoop jar IndexStepTwo.jar com.empire.hadoop.mr.inverindex.IndexStepTwo /index/indexsteponeoutput /index/indexsteptwooutput 四、运行效果 [hadoop@centos-aaron-h1 ~]$ hadoop jar IndexStepOne.jar com.empire.hadoop.mr.inverindex.InverIndexStepOne /index/indexinput /index/indexsteponeoutput 18/12/19 07:08:42 INFO client.RMProxy: Connecting to ResourceManager at centos-aaron-h1/192.168.29.144:8032 18/12/19 07:08:43 WARN mapreduce.JobResourceUploader: Hadoop command-line option parsing not performed. Implement the Tool interface and execute your application with ToolRunner to remedy this. 18/12/19 07:08:43 INFO input.FileInputFormat: Total input files to process : 3 18/12/19 07:08:43 INFO Configuration.deprecation: yarn.resourcemanager.system-metrics-publisher.enabled is deprecated. Instead, use yarn.system-metrics-publisher.enabled 18/12/19 07:08:44 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1545173547743_0001 18/12/19 07:08:45 INFO impl.YarnClientImpl: Submitted application application_1545173547743_0001 18/12/19 07:08:45 INFO mapreduce.Job: The url to track the job: http://centos-aaron-h1:8088/proxy/application_1545173547743_0001/ 18/12/19 07:08:45 INFO mapreduce.Job: Running job: job_1545173547743_0001 18/12/19 07:08:56 INFO mapreduce.Job: Job job_1545173547743_0001 running in uber mode : false 18/12/19 07:08:56 INFO mapreduce.Job: map 0% reduce 0% 18/12/19 07:09:05 INFO mapreduce.Job: map 33% reduce 0% 18/12/19 07:09:20 INFO mapreduce.Job: map 67% reduce 0% 18/12/19 07:09:21 INFO mapreduce.Job: map 100% reduce 100% 18/12/19 07:09:23 INFO mapreduce.Job: Job job_1545173547743_0001 completed successfully 18/12/19 07:09:23 INFO mapreduce.Job: Counters: 50 File System Counters FILE: Number of bytes read=1252 FILE: Number of bytes written=791325 FILE: Number of read operations=0 FILE: Number of large read operations=0 FILE: Number of write operations=0 HDFS: Number of bytes read=689 HDFS: Number of bytes written=297 HDFS: Number of read operations=12 HDFS: Number of large read operations=0 HDFS: Number of write operations=2 Job Counters Killed map tasks=1 Launched map tasks=4 Launched reduce tasks=1 Data-local map tasks=4 Total time spent by all maps in occupied slots (ms)=53828 Total time spent by all reduces in occupied slots (ms)=13635 Total time spent by all map tasks (ms)=53828 Total time spent by all reduce tasks (ms)=13635 Total vcore-milliseconds taken by all map tasks=53828 Total vcore-milliseconds taken by all reduce tasks=13635 Total megabyte-milliseconds taken by all map tasks=55119872 Total megabyte-milliseconds taken by all reduce tasks=13962240 Map-Reduce Framework Map input records=14 Map output records=70 Map output bytes=1106 Map output materialized bytes=1264 Input split bytes=345 Combine input records=0 Combine output records=0 Reduce input groups=21 Reduce shuffle bytes=1264 Reduce input records=70 Reduce output records=21 Spilled Records=140 Shuffled Maps =3 Failed Shuffles=0 Merged Map outputs=3 GC time elapsed (ms)=1589 CPU time spent (ms)=5600 Physical memory (bytes) snapshot=749715456 Virtual memory (bytes) snapshot=3382075392 Total committed heap usage (bytes)=380334080 Shuffle Errors BAD_ID=0 CONNECTION=0 IO_ERROR=0 WRONG_LENGTH=0 WRONG_MAP=0 WRONG_REDUCE=0 File Input Format Counters Bytes Read=344 File Output Format Counters Bytes Written=297 [hadoop@centos-aaron-h1 ~]$ [hadoop@centos-aaron-h1 ~]$ hadoop jar IndexStepTwo.jar com.empire.hadoop.mr.inverindex.IndexStepTwo /index/indexsteponeoutput /index/indexsteptwooutput 18/12/19 07:11:27 INFO client.RMProxy: Connecting to ResourceManager at centos-aaron-h1/192.168.29.144:8032 18/12/19 07:11:27 WARN mapreduce.JobResourceUploader: Hadoop command-line option parsing not performed. Implement the Tool interface and execute your application with ToolRunner to remedy this. 18/12/19 07:11:27 INFO input.FileInputFormat: Total input files to process : 1 18/12/19 07:11:28 INFO mapreduce.JobSubmitter: number of splits:1 18/12/19 07:11:28 INFO Configuration.deprecation: yarn.resourcemanager.system-metrics-publisher.enabled is deprecated. Instead, use yarn.system-metrics-publisher.enabled 18/12/19 07:11:28 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1545173547743_0002 18/12/19 07:11:28 INFO impl.YarnClientImpl: Submitted application application_1545173547743_0002 18/12/19 07:11:29 INFO mapreduce.Job: The url to track the job: http://centos-aaron-h1:8088/proxy/application_1545173547743_0002/ 18/12/19 07:11:29 INFO mapreduce.Job: Running job: job_1545173547743_0002 18/12/19 07:11:36 INFO mapreduce.Job: Job job_1545173547743_0002 running in uber mode : false 18/12/19 07:11:36 INFO mapreduce.Job: map 0% reduce 0% 18/12/19 07:11:42 INFO mapreduce.Job: map 100% reduce 0% 18/12/19 07:11:48 INFO mapreduce.Job: map 100% reduce 100% 18/12/19 07:11:48 INFO mapreduce.Job: Job job_1545173547743_0002 completed successfully 18/12/19 07:11:48 INFO mapreduce.Job: Counters: 49 File System Counters FILE: Number of bytes read=324 FILE: Number of bytes written=394987 FILE: Number of read operations=0 FILE: Number of large read operations=0 FILE: Number of write operations=0 HDFS: Number of bytes read=427 HDFS: Number of bytes written=253 HDFS: Number of read operations=6 HDFS: Number of large read operations=0 HDFS: Number of write operations=2 Job Counters Launched map tasks=1 Launched reduce tasks=1 Data-local map tasks=1 Total time spent by all maps in occupied slots (ms)=3234 Total time spent by all reduces in occupied slots (ms)=3557 Total time spent by all map tasks (ms)=3234 Total time spent by all reduce tasks (ms)=3557 Total vcore-milliseconds taken by all map tasks=3234 Total vcore-milliseconds taken by all reduce tasks=3557 Total megabyte-milliseconds taken by all map tasks=3311616 Total megabyte-milliseconds taken by all reduce tasks=3642368 Map-Reduce Framework Map input records=21 Map output records=21 Map output bytes=276 Map output materialized bytes=324 Input split bytes=130 Combine input records=0 Combine output records=0 Reduce input groups=7 Reduce shuffle bytes=324 Reduce input records=21 Reduce output records=7 Spilled Records=42 Shuffled Maps =1 Failed Shuffles=0 Merged Map outputs=1 GC time elapsed (ms)=210 CPU time spent (ms)=990 Physical memory (bytes) snapshot=339693568 Virtual memory (bytes) snapshot=1694265344 Total committed heap usage (bytes)=137760768 Shuffle Errors BAD_ID=0 CONNECTION=0 IO_ERROR=0 WRONG_LENGTH=0 WRONG_MAP=0 WRONG_REDUCE=0 File Input Format Counters Bytes Read=297 File Output Format Counters Bytes Written=253 [hadoop@centos-aaron-h1 ~]$ 五、运行结果 [hadoop@centos-aaron-h1 ~]$ hdfs dfs -cat /index/indexsteponeoutput/part-r-00000 boby--a.txt 1 boby--b.txt 2 boby--c.txt 4 fork--a.txt 2 fork--b.txt 4 fork--c.txt 8 hello--a.txt 2 hello--b.txt 4 hello--c.txt 8 integer--a.txt 1 integer--b.txt 2 integer--c.txt 4 source--a.txt 1 source--b.txt 2 source--c.txt 4 tom--a.txt 1 tom--b.txt 2 tom--c.txt 4 [hadoop@centos-aaron-h1 ~]$ [hadoop@centos-aaron-h1 ~]$ hdfs dfs -cat /index/indexsteptwooutput/part-r-00000 boby a.txt-->1 b.txt-->2 c.txt-->4 fork a.txt-->2 b.txt-->4 c.txt-->8 hello b.txt-->4 c.txt-->8 a.txt-->2 integer a.txt-->1 b.txt-->2 c.txt-->4 source a.txt-->1 b.txt-->2 c.txt-->4 tom a.txt-->1 b.txt-->2 c.txt-->4 [hadoop@centos-aaron-h1 ~]$ 最后寄语,以上是博主本次文章的全部内容,如果大家觉得博主的文章还不错,请点赞;如果您对博主其它服务器大数据技术或者博主本人感兴趣,请关注博主博客,并且欢迎随时跟博主沟通交流。 大数据 2018-12-18 23:17:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 1、抽象等级 Flink 提供了不同级别的抽象来开发流/批处理应用程序。 1) 低层级的抽象 最低层次的抽象仅仅提供有状态流。它通过Process函数嵌入到DataStream API中。它允许用户自由地处理来自一个或多个流的事件,并使用一致的容错状态。此外,用户可以注册事件时间和处理时间回调,允许程序实现复杂的计算。 2) 核心API 在实践中,大多数应用程序不需要上面描述的低级抽象,而是对核心API进行编程,比如DataStream API(有界或无界数据流)和DataSet API(有界数据集)。这些API提供了用于数据处理的通用构建块,比如由用户定义的多种形式的转换、连接、聚合、窗口、状态等。在这些api中处理的数据类型以类(class)的形式由各自的编程语言所表示。 低级流程函数与DataStream API集成,使得只对某些操作进行低级抽象成为可能。DataSet API为有界数据集提供了额外的原语,比如循环或迭代。 3) Table API Table API是一个以表为中心的声明性DSL,其中表可以动态地改变(当表示流数据时)。表API遵循(扩展)关系模型:表有一个附加模式(类似于关系数据库表)和API提供了类似的操作,如select, project, join, group-by, aggregate 等。Table API 程序以声明的方式定义逻辑操作应该做什么而不是指定操作的代码看起来如何。虽然Table API可以通过各种用户定义函数进行扩展,但它的表达性不如核心API,但使用起来更简洁(编写的代码更少)。此外,Table API程序还可以在执行之前通过应用优化规则的优化器。可以无缝地在Table API和DataStream/DataSet API之间进行切换,允许程序将Table API和DataStream和DataSet API进行混合使用。 4) Sql层 Flink提供的最高级别抽象是SQL。这种抽象在语义和表示方面都类似于Table API,但将程序表示为SQL查询表达式。SQL抽象与表API密切交互,SQL查询可以在表API中定义的表上执行。 2、程序和数据流 Flink程序的基本构建模块是streams 和 transformations 。(请注意,Flink的DataSet API中使用的数据集也是内部流——稍后将对此进行详细介绍。)从概念上讲,streams 是数据记录的(可能是无限的)流,而transformations是将一个或多个流作为输入并产生一个或多个输出流的操作。 执行时,Flink程序被映射到流数据流,由streams 和 transformations 操作符组成。每个数据流以一个或多个sources开始,以一个或多个sinks结束。数据流类似于任意有向无环图(DAGs)。虽然通过迭代构造允许特殊形式的循环,但为了简单起见,我们将在大多数情况下忽略这一点。 通常在程序中的transformations和数据流中的操作之间是一对一的对应关系。然而,有时一个transformations可能包含多个transformations操作。 在streming连接器和批处理连接器文档中记录了Sources 和 sinks。在DataStream运算和数据集transformations中记录了transformations。 3、并行数据流 Flink中的程序本质上是并行的和分布式的。在执行期间,流有一个或多个流分区,每个operator 有一个或多个operator subtasks(操作子任务)。operator subtasks相互独立,在不同的线程中执行,可能在不同的机器或容器上执行。 operator subtasks的数量是特定运算符的并行度。一个流的并行性总是它的生产操作符的并行性。同一程序的不同运算符可能具有不同级别的并行性。 流可以在两个操作符之间以一对一(或转发)模式传输数据,也可以在重新分配模式中传输数据: One-to-one 流(例如上图中Source和map()运算符之间的流)保持元素的分区和顺序。这意味着map()操作符的subtask[1]将看到与源操作符的subtask[1]生成的元素相同的顺序。 Redistributing 流(如上面的map()和keyBy/window之间,以及keyBy/window和Sink之间)改变流的分区。每个操作符子任务根据所选的转换将数据发送到不同的目标子任务。例如keyBy()(通过散列键来重新分区)、broadcast()或balanced()(随机重新分区)。在重分发交换中,元素之间的顺序只保留在每一对发送和接收子任务中(例如map()的子任务[1]和keyBy/window的子任务[2])。因此,在本例中,每个键中的顺序都是保留的,但是并行性确实引入了关于不同键的聚合结果到达sink的顺序的不确定性。 4、窗口 聚合事件(例如计数、求和)在流上的工作方式与批处理不同。例如,不可能计算流中的所有元素,因为流通常是无限的(无界的)。相反,流上的聚合(计数、求和等)是由窗口限定作用域的,例如“过去5分钟的计数”或“最后100个元素的总和”。 Windows可以是时间驱动(示例:每30秒)或数据驱动(示例:每100个元素)。一个典型的方法是区分不同类型的窗口,比如翻滚窗户(没有重叠)、滑动窗口(有重叠)和会话窗口(中间有一个不活跃的间隙)。 5、时间 当提到流程序中的时间(例如定义窗口)时,可以指不同的时间概念: 事件时间 : 是创建事件的时间。它通常由事件中的时间戳描述,例如由生产传感器或生产服务附加。Flink通过时间戳转让者访问事件时间戳。 摄入时间 : 在source操作符中一个事件进入Flink数据流的时间。 处理时间 : 是执行基于时间的操作的每个操作符的本地时间。 6、状态操作 虽然一个数据流中有许多操作但只看作一个单独的事件(例如事件解析器),但是一些操作记住了跨多个事件的信息(例如窗口操作符)。这些操作称为有状态操作。 有状态操作的状态被维护在可以认为是嵌入式键/值存储中。状态与有状态操作符读取的流一起被严格地分区和分布。因此,在keyBy()函数之后,只能在键控流上访问键/值状态,并且只能访问与当前事件的键相关联的值。对齐流和状态的键确保所有的状态更新都是本地操作,保证一致性而不增加事务开销。这种对齐还允许Flink透明地重新分配状态和调整流分区。 (EventTime是信息自带的时间,再进入消息队列,IngestionTime是进入Flink的时间,Processing是进入Operator的时间) 7、容错检查点 Flink通过流回放和检查点的组合实现了容错。检查点与每个输入流中的特定点以及每个操作符的对应状态相关。通过恢复操作符的状态并从检查点重新播放事件,流数据流可以在检查点恢复,同时保持一致性(准确地说是一次处理语义)。 检查点间隔是在执行期间用恢复时间(需要重放的事件数量)来权衡容错开销的一种方法。 8、批处理流 Flink执行批处理程序作为流程序的特殊情况,其中流是有界的(有限的元素数量)。数据集在内部被视为数据流。因此,上述概念同样适用于批处理程序,也适用于流程序,但有少数例外: 批处理程序的容错不使用检查点。恢复通过完全重放流来实现。这是可能的,因为输入是有界的。这将使成本更多地用于恢复,但使常规处理更便宜,因为它避免了检查点。 数据集API中的有状态操作使用简化的内存/核心外数据结构,而不是键/值索引。 DataSet API引入了特殊的synchronized(基于超步的)迭代,这只能在有界的流上实现。有关详细信息,请查看迭代文档。 文章来源: https://blog.csdn.net/silentwolfyh/article/details/82865579 推荐阅读: https://www.roncoo.com/view/173 大数据 2018-12-18 18:08:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 环境 为了正确地跑起来,你的应用需要依赖许多不同的软件。 就算是再怎么否认这一点的人,也无法否认至少需要依赖Flask本身。 你的应用的 运行环境 ,在当你想要让它跑起来时,是至关重要的。 幸运的是,我们有许多工具可以减低管理环境的复杂度。 使用virtualenv来管理环境 virtualenv 是一个能把你的应用隔离在一个 虚拟环境 中的工具。 一个虚拟环境是一个包含了你的应用依赖的软件的文件夹。一个虚拟环境同时也封存了你在开发时的环境变量。 与其把依赖包,比如Flask,下载到你的系统包管理文件夹,或用户包管理文件夹,我们可以把它下载到对应当前应用的一个隔离的文件夹之下。 这使得你可以指定一个特定的Python二进制版本,取决于当前开发的项目。 virtualenv也可以让你给不同的项目指定同样的依赖包的不同版本。 当你在一个老旧的包含众多不同项目的平台上开发时,这种灵活性十分重要。 用了virtualenv,你将只会把少数几个Python模块安装到系统的全局空间中。其中一个会是virtualenv本身: # 使用pip安装virtualenv $ pip install virtualenv 安装完virtualenv,就可以开始创建虚拟环境。切换到你的项目文件夹,运行 virtualenv 命令。这个命令接受一个参数,作为虚拟环境的名字(同样也是它的位置,在当前文件夹 ls 下你就知道了)。 $ virtualenv venv New python executable in venv/bin/python Installing setuptools, pip...done. 这将创建一个包含所有依赖的文件夹。 一旦新的virtual environment已经准备就绪,你需要给对应的virtual environment下的 bin/activate 脚本执行 source ,来激活它。 $ source venv/bin/activate 你可以通过运行 which python 看到:“python”现在指向的是virtual environment中的二进制版本。 $ which python /usr/local/bin/python $ source venv/bin/activate (venv)$ which python /Users/robert/Code/myapp/venv/bin/python 当一个virtual environment被激活了,依赖包会被pip安装到virtual environment中而不是全局系统环境。 你也许注意到了,你的shell提示符发生了改变。 virtualenv在它前面添加了当前被激活的virtual environment,所以你能意识到你并不存在于全局系统环境中。 运行 deactivate 命令,你就能离开你的virtual environment。 (venv)$ deactivate $ 使用virtualenvwrapper管理你的virtual environment 我想要让你了解到 virtualenvwrapper 对于前面的工作做了什么改进,这样你就知道为什么你应该使用它。 虚拟环境文件夹现在已经位于你的项目文件夹之下。 但是你仅仅是在激活了虚拟环境后才会跟它交互。它甚至不应该被放入版本控制中。所以它呆在项目文件夹中也是挺碍眼的。 解决这个问题的一个方法就是使用virtualenvwrapper。这个包把你所有的virtual environment整理到单独的文件夹下,通常是 ~/.virtualenvs/ 。 要安装virtualenvwrapper,遵循这个 文档 中的步骤。 注意 确保你在安装virtualenvwrapper时不在任何一个virtual environment中。你需要把它安装在全局空间,而不是一个已存在的virtual environment中 现在,你不再需要运行 virtualenv 来创建一个环境,只需运行 mkvirtualenv : $ mkvirtualenv rocket New python executable in rocket/bin/python Installing setuptools, pip...done. 在你的virtual environment目录之下,比如在 ~/.virtualenv 之下, mkvirtualenv 创建了一个文件夹,并替你激活了它。 就像普通的 virtualenv , python 和 pip 现在指向的是virtual environment而不是全局系统。 为了激活想要的环境,运行这个命令: workon [environment name] ,而 deactivate 依然会关闭环境。 记录依赖变动 随着项目增长,你会发现它的依赖列表也一并随着增长。在你能运行一个Flask应用之前,即使已经需要数以十记的依赖包也毫不奇怪。 管理依赖的最简单的方法就是使用一个简单的文本文件。 pip可以生成一个文本文件,列出所有已经安装的包。它也可以解析这个文件,并在新的系统(或者新的环境)下安装每一个包。 pip freeze requirements.txt 是一个常常被许多Flask应用用于列出它所依赖的包的文本文件。它是通过 pip freeze > requirements.txt 生成的。 使用 pip install -r requirements.txt ,你就能安装所有的包。 注意 在freeze或install依赖包时,确保你正为于正确的virtual environment之中。 手动记录依赖变动 随着项目增长,你可能会发现 pip freeze 中列出的每一个包并不再是运行应用所必须的了。 也许有些包只是在开发时用得上。 pip freeze 没有判断力;它只是列出了当前安装的所有的包。所以你只能手动记录依赖的变动了。 你可以把运行应用所需的包和开发应用所需的包分别放入对应的 require_run.txt 和 require_dev.txt 。 版本控制 选择一个版本控制系统并使用它。 我推荐Git。如我所知,Git是当下最大众的版本控制系统。 在删除代码的时候无需担忧潜在的巨大灾难是无价的。 你现在可以对过去那种把不要的代码注释掉的行为说拜拜了,因为你可以直接删掉它们,即使将来突然需要,也可以通过 git revert 来恢复。 另外,你将会有整个项目的备份,存在Github,Bitbucket或你自己的Git server。 什么不应该在版本控制里 我通常不把一个文件放在版本控制里,如果它满足以下两个原因中的一个。 它是不必要的 它是不公开的。 编译的产物,比如 .pyc ,和virtual environment(如果你因为某些原因没有使用virtualenvwrapper)正是前者的例子。 它们不需要加入到版本控制中,因为它们可以通过 .py 或 requirements.txt 生成出来。 接口密钥(调用接口时必须传入的参数),应用密钥,以及数据库证书则是后者的例子。 它们不应该在版本控制中,因为一旦泄密,将造成严重的安全隐患。 注意 在做安全相关的决定时,我会假设稳定版本库将会在一定程度上被公开。这意味着要清除所有的隐私,并且永不假设一个安全漏洞不会被发现, 因为“谁能想到他们会干出什么事情?” 在使用Git时,你可以在版本库中创建一个特别的文件名为 .gitignore 。 在里面,能使用正则表达式来列出对应的文件。任何匹配的文件将被Git所忽略。 我建议你至少在其中加入 *.pyc 和 /instance 。instance文件夹中存放着跟你的应用相关的不便公开的配置。 .gitignore: *.pyc instance/ 参见 在这里你可以了解什么是 .gitignore : http://git-scm.com/docs/gitignore Flask文档中对instance目录的一段介绍 : http://flask.pocoo.org/docs/config/#instance-folders 调试 调试模式 Flask有一个便利的特性叫做“debug mode”。在你的应用配置中设置 debug = True 就能启动它。 当它被启动后,服务器会在代码变动之后重新加载,并且一旦发生错误,错误会打印成一个带交互式命令行的调用栈。 注意 不要在生产环境中开启debug mode。交互式命令行运行任意的代码输入,如果是在运行中的网站上,这将导致安全上的灾难性后果。 另见 阅读一下quickstart页面的debug mode部分 : http://docs.jinkan.org/docs/flask/quickstart.html#debug-mode 这里有一些关于错误处理,日志记录和使用其他调试工具的信息 : http://docs.jinkan.org/docs/flask/errorhandling.html Flask-DebugToolbar Flask-DebugToolbar 是用来调试你的应用的另一个得力工具。在debug mode中,它在你的应用中添加了一个侧边条。 这个侧边条会给你提供有关SQL查询,日志,版本,模板,配置和其他有趣的信息。 总结 使用virtualenv来打包你的应用的依赖包。 使用virtualenvwrapper来打包你的virtual environment。 使用一个或多个文本文件来记录依赖变化。 使用一个版本控制系统。我推荐Git。 使用.gitignore来排除不必要的或不能公开的东西混进版本控制。 debug mode会在开发时给你有关bug的信息。 Flaks-DebugToolbar拓展将给你有关bug更多的信息。 原文:http://colesmith.space/2015/05/19/revise-virtualenv-and-virtualenvwrapper.html 官方文档 virtualenv virtualenvwrapper 一 virtualenv What : virtualenv 是一个隔离Python环境的工具. Why : virtualenv 可以让你在同一个操作系统上建立多个不同的Python环境. 如一个Python2, 另一个Python3, 还有Django1.2 和 Django1.5 项目Python环境互不相同,互不干涉. How : (So Easy) Install : sudo pip install virtualenv Use : (Recommend) 创建环境 : virtualenv -p PYTHON_VERSION VIRTUAL_ENVIRONMENT_NAME 解释: -p PYTHON_EXE, –python=PYTHON_EXE : 指定Python版本, Python2, Python2.5, Python3等 注意: 这个Python版本必须存在于系统内部 –no-site-packages : 废弃了,因为默认没有权限访问全局包 栗子: virtualenv -p python3 django1.8 进入环境 : source path/to/VIRTUAL_ENVIRONMENT_NAME/bin/activate 栗子: source django1.8/bin/activate 或者 cd django1.8; source bin/activate 有明显标志(VIRTUAL_ENVIRONMENT_NAME),说明成功进入环境 退出环境 : deactivate 删除环境 : 只要删除创建的虚拟环境目录即可: rm -rf path/to/VIRTUAL_ENVIRONMENT_NAME rm -rf django1.8 二 virtualenvwrapper what : virtualenvwrapper 是 virtaulenv 的扩展的集合. Why : 便于使用和管理 virtualenv How : Install : sudo pip install virtualenvwrapper Use : 每次使用前必须先source环境 : 才有mkvirtualev, lssitepackages等命令 source /usr/local/bin/virtualenvwrapper.sh 或者将/etc/profile 或者 ~/.bashrc 或者 ~/.zshrc 启动终端时自动载入source 创建环境 : Syntax: mkvirtualenv [-a project_path] [-i package] [-r requirements_file] [virtualenv options] VIRTUAL_ENVIRONMENT_NAME 注意: 项目默认创建一律在 ~/.virtualenvs 目录下 栗子: 默认: mkvirtualenv django1.8 # (ls ~/.virtualenvs 可见) 指定Python版本: mkvirtualenv -p python3 django1.8 指定Python版本和依赖的包: mkvirtualenv -r requirements.txt -p python3 django1.8 指定项目地址, 只要载入环境,自动切换到项目目录: mkvirtualenv -a . django1.8 注意: 环境创建完成后,会自动载入环境 打开或切换工作环境 : Syntax: workon [(-c|--cd)|(-n|--no-cd)] [environment_name|"."] 栗子: 默认: workon django1.8 注意: 默认进入 mkvirtualenv 选项 -a 指定的目录,如果没有,则在当前目录 切换, 即已经在一个虚拟环境, 但要切换另一个环境: workon django1.5 不进入 -a 指定的目录: workon -n django1.8 退出环境,使用系统环境 : deactivate 删除环境 : rmvirtualenv VIRTUAL_ENVIRONMENT_NAME 或 rm -rf ~/.virtualenvs/VIRTUAL_ENVIRONMENT_NAME 栗子: rmvirtualenv django1.8 (推荐) rm -rf ~/.virtualenvs/django1.8 让所有创建的环境都执行某个命令,比如安装某个包等 : Syntax: allvirtualenv command with arguments 栗子: allvirtualenv pip install ipython 切换当前环境能否访问系统的Python包, 建议关闭(disable) : Syntax: toggleglobalsitepackages [-p] -p : 不输出日志 栗子: toggleglobalsitepackages 删除第三方包 : (注意: 必须已经在虚拟环境中) Syntax: wipeenv 创建项目+环境 : Create a new virtualenv in the WORKON_HOME and project directory in PROJECT_HOME. Syntax: mkproject [-f|--force] [-t template] [virtualenv_options] ENVNAME 注意设置 WORKON_HOME 和 PROJECT_HOME 其他命令: 显示安装的包: lssitepackages (建议用 pip list 更清楚) 复制一份虚拟环境: cpvirtualenv [sorce] [dest] cp django1.8 django 临时环境,deactivate后删除: mktmpenv [(-c –cd) (-n –no-cd)] [VIRTUALENV_OPTIONS] 栗子: mktmpenv -p python3 列出所有创建的虚拟环境: 即~/.virtualenvs目录下的 lsvirtualenv [-b -l -h] -b 简短形式, 建议 -l 默认的详细信息输出 -h help 绑定项目目录 : Syntax: setvirtualenvproject [virtualenv_path project_path] 原文:http://virtualenv-chinese-docs.readthedocs.io/en/latest/#id3 Contents virtualenv 安装 用处 命令 环境变量和配置文件 Windows下注意事项 PyPy支持 创建自己的启动脚本 启动脚本范例 激活脚本 --system-site-packages 参数 不使用Virtualenv下的 bin/python 重定位隔离环境 --extra-search-dir 参数 与可替代品的比较 贡献力量 运行测试 相关文档和链接 现状和许可 Wrongway的补充:常用见法 1.创建隔离环境并安装最新的django 2.创建隔离环境并安装django1.3以及一系列开发用组件 3.创建Python2.7隔离环境并安装tornado Wrongway的补充:中译版致谢 Changes & News 安装 运行 pip install virtualenv 即可安装virtualenv,想用 最新开发版 就运行 pip installvirtualenv==dev 。 还可以用 easy_install 安装,即使是没有安装任何Python包管理器,也可以直接获取 virtualenv.py 并运行 python virtualenv.py ,效果一样。 用处 virtualenv 用来创建隔离的Python环境。 处理python环境的多版本和模块依赖,以及相应的权限是一个很常见的问题。比如,你有个应用使用的是LibFoo V1.0,但另一个应用却要用到LibFoo V2.0。如何处理呢?如果把所有模块都安装到 /usr/lib/python2.7/site-packages (或是你本机python默认的模块安装目录),那你极有可能无意中升级一些不该升级的模块。 更普遍的是,就算你成功安装了某个应用,那么接下来又会怎样?只要它开始运行了,那么只要其所依赖的模块发生任何改动,亦或升级,都可能打断该应用。 这还没完,要是你无法在 site-packages 目录下安装模块呢?比如共享主机。 上述这几种场合都适用 virtualenv 。它会创建一个拥有独立安装目录的python环境,该隔离环境不会与其他virtualenv环境共享模块(可选择是否访问全局库目录)。 一般用法是: $ python virtualenv.py ENV 在已安装virtualenv的情况下,可以直接运行 virtualenv ENV 。 该操作会创建 ENV/lib/pythonX.X/site-packages 目录 和 ENV/bin/python ,前者用来存放要安装的模块,后者就是隔离环境的Python解释器。在virtualenv环境下使用此解释器(包括以 #!/path/to/ENV/bin/python 开头的脚本)时,使用的都是隔离环境下的模块。 该操作还在隔离环境下安装了 Setuptools 或 distribute 。要用Distribue取代setuptools的话,只要运行: $ python virtualenv.py --distribute ENV 设置环境变量 VIRTUALENV_USE_DISTRIBUTE 也能达到同样目的。 新的virtualenv还包含了 pip 包管理器,可以直接用 ENV/bin/pip 安装第三方模块。 命令 用法: $ virtualenv [OPTIONS] DEST_DIR 选项: --version 显示当前版本号。 -h, --help 显示帮助信息。 -v, --verbose 显示详细信息。 -q, --quiet 不显示详细信息。 -p PYTHON_EXE, --python=PYTHON_EXE 指定所用的python解析器的版本,比如 --python=python2.5 就使用2.5版本的解析器创建新的隔离环境。默认使用的是当前系统安装(/usr/bin/python)的python解析器 --clear 清空非root用户的安装,并重头开始创建隔离环境。 --no-site-packages 令隔离环境不能访问系统全局的site-packages目录。 --system-site-packages 令隔离环境可以访问系统全局的site-packages目录。 --unzip-setuptools 安装时解压Setuptools或Distribute --relocatable 重定位某个已存在的隔离环境。使用该选项将修正脚本并令所有.pth文件使用相当路径。 --distribute 使用Distribute代替Setuptools,也可设置环境变量VIRTUALENV_DISTRIBUTE达到同样效要。 --extra-search-dir=SEARCH_DIRS 用于查找setuptools/distribute/pip发布包的目录。可以添加任意数量的–extra-search-dir路径。 --never-download 禁止从网上下载任何数据。此时,如果在本地搜索发布包失败,virtualenv就会报错。 --prompt==PROMPT 定义隔离环境的命令行前缀。 环境变量和配置文件 virtualenv既可以通过命令行配置,比如 --distribute ,也可以用下面两种方式配置: 环境变量 命令行的每个参数都以 VIRTUALENV_ 举个例子,要自动安装Distribute取代默认的setuptools,可以这样设置环境变量: $ export VIRTUALENV_USE_DISTRIBUTE=true $ python virtualenv.py ENV 等同于在命令行直接使用参数: $ python virtualenv.py --distribute ENV 有时要重复输入多个命令行参数,比如 --extra-search-dir 。变成环境变量时,要用空格隔开多个参数值,例如: $ export VIRTUALENV_EXTRA_SEARCH_DIR="/path/to/dists /path/to/other/dists" $ virtualenv ENV 等同于: $ python virtualenv.py --extra-search-dir=/path/to/dists --extra-search-dir=/path/to/other/dists ENV 配置文件 virtualenv还能通过标准ini文件进行配置。在Unix和Mac OS X中是 $HOME/.virtualenv/virtualenv.ini ,在Windows下是 %HOME%\\virtualenv\\virtualenv.ini 。 配置项名称就是命令行参数的名称。例如,参数 --distribute 在ini文件如下: [virtualenv] distribute = true 象 --extra-search-dir 这样的多值命令行参数,在ini文件中要用断行将多个值隔开: [virtualenv] extra-search-dir = /path/to/dists /path/to/other/dists virtualenv --help 可以查看完整的参数列表。 Windows下注意事项 在Windows下路径会与*nix下略有不同:脚本和可执行文件在Windows下位于 ENV\Scripts\ 下,而非 ENV/bin/ ,模块也会安装在 ENV\Lib\ 下,而非 ENV/lib/ 。 要在某个含有空格的目录下面创建virtualenv环境,就要安装 win32api 。 PyPy支持 从1.5版开始,virtualenv开始支持 PyPy 。>=1.5版的virtualenv支持PyPy1.4和1.4.1,>=1.6.1版的virtualenv支持PyPy1,5。 创建自己的启动脚本 Wrongway提示:该段一般情况下初学者用不到,所以刚接触virtualenv的朋友不要在此节投放过多精力。Virtualenv的文档讲解顺序是有点问题。 创建隔离环境时,virtualenv不会执行额外操作。但开发者有时会想在安装隔离环境后运行某个脚本。例如用脚本安装某个web应用。 要创建上述脚本,需要调用 virtualenv.create_bootstrap_script(extra_text) ,将后续操作写入到生成的启动脚本,以下是从docstring中生成的文档: 启动脚本与一般脚本无异,只是多了三个extend_parser, adjust_options, after_install三个钩子方法。 create_bootstrap_script返回一个可定制的,能做为启动脚本的字符串(当然,该字符串后面要写回到磁盘文件中)。这个字符串是一个标准的virtualenv.py脚本,用户可以自行添加内容(所加内容必须是python代码)。 如果定义了下列方法,运行脚本时就会被调用: extend_parser(optparse_parser) : 可以在解析器optparse_parser中添加或删除参数。 adjust_options(options, args) : 调整options,或改变args(如果要接收各种不同的参数,一定要在最后将 args 修改为 [DEST_DIR] ) after_install(options, home_dir) : 在所有代码和模块安装完之后,就会调用该方法。这可能是用户最喜欢的方法,例如下: def after_install(options, home_dir): if sys.platform == 'win32': bin = 'Scripts' else: bin = 'bin' subprocess.call([join(home_dir, bin, 'easy_install'), 'MyPackage']) subprocess.call([join(home_dir, bin, 'my-package-script'), 'setup', home_dir]) 上述例子会安装一个包,并运行包内的setup脚本 wrongway在这里强调:上述三个方法并不是独立方法,而是一段代码字符串!!也就是extra_text的内容。有点象javascript下的eval(‘......代码字符串......’) 启动脚本范例 这有个具体的例子: import virtualenv, textwrap output = virtualenv.create_bootstrap_script(textwrap.dedent(""" import os, subprocess def after_install(options, home_dir): etc = join(home_dir, 'etc') if not os.path.exists(etc): os.makedirs(etc) subprocess.call([join(home_dir, 'bin', 'easy_install'), 'BlogApplication']) subprocess.call([join(home_dir, 'bin', 'paster'), 'make-config', 'BlogApplication', join(etc, 'blog.ini')]) subprocess.call([join(home_dir, 'bin', 'paster'), 'setup-app', join(etc, 'blog.ini')]) """)) f = open('blog-bootstrap.py', 'w').write(output) 这还有一个例子 点击 。 激活脚本 刚创建的隔离环境下会有一个 bin/activate 命令行脚本。在Windows下,激活脚本要在CMD.exe或Powershell.exe中使用。 在Posix系统(*nix/BSD)中,用法如下: $ source bin/activate 该操作会将当前 $PATH 指向隔离环境下的 bin/ 目录。之所以要用source是因为它要改变当前shell环境。仅仅就是一行命令,就这么简单。如果直接运行隔离环境下的脚本或是python解释器(比如 path/to/env/bin/pip or /path/to/env/bin/python script.py ),那都没必要使用激活脚本。 输入 deactivate 就能退出已激活的隔离环境,也就是取消对当前 $PATH 所做的修改。 activate 脚本会修改当前shell命令行提示符,以提示当前激活的是哪个隔离环境。这是挺有用的,不过要是想自定义的提示符,只要在运行 activate 前将 VIRTUAL_ENV_DISABLE_PROMPT 设为你想要的提示(不能为空字符串)。 在Windows下只须如此( * nix用户此处就不用看了,包括下面的注意也不用看了): > \path\to\env\Scripts\activate 输入 deactivate 就能退出隔离环境。 视你用的shell不同(CMD.exe或Powershell.exe),Windows会使用activate.bat或activate.ps1来激活隔离环境。如果使用的是Powershell,那么以下几点值得注意。 注意(说真的,开发python还是在*nix下好,真的真的真的!): 使用Powershell时,运行 ``activate`` 脚本取决于`执行策略`_ 。但在Windows7下,默认情况下执行策略被设为严格, 这就意味着象 ``activate`` 这样的脚本是不能直接运行的。但稍微设置一下即可。 降低执行策略,改为 ``AllSigned``, 这就意味着本机所有已通过数字签名的脚本都获许运行。 由于virtualenv作者之一Jannis Leidel的数字签名已被核准,允许运行。那么只要以管理员权限运行:: PS C:\> Set-ExecutionPolicy AllSigned 接下来运行脚本时会提示是否信任该签名:: PS C:\> virtualenv .\foo New python executable in C:\foo\Scripts\python.exe Installing setuptools................done. Installing pip...................done. PS C:\> .\foo\scripts\activate Do you want to run software from this untrusted publisher? File C:\foo\scripts\activate.ps1 is published by E=jannis@leidel.info, CN=Jannis Leidel, L=Berlin, S=Berlin, C=DE, Description=581796-Gh7xfJxkxQSIO4E0 and is not trusted on your system. Only run scripts from trusted publishers. [V] Never run [D] Do not run [R] Run once [A] Always run [?] Help (default is "D"):A (foo) PS C:\> 如果选择了 ``[A] Always Run``, 该证书就会添加到当前帐户下的受信任发布者名单中,而且此后一直被该用户所信任。 如果选择了 ``[R] Run Once``, 该脚本会立即运行,但之后每次使用都会重新出现信任提示并选择。 高级用户可以将该证书添加到当前计算机的受信任发布者名单中,这样所有用户都可以使用该脚本了(不过这部分内容已经超过了本文档范畴了)。 此外,还可以进一步降低执行策略,允行未验证的本地脚本运行:: PS C:\> Set-ExecutionPolicy RemoteSigned 因为对任何一个virtualenv环境而言, ``activate.ps1`` 都是一个本地脚本而非远程脚本,因为可以获准运行。 --system-site-packages 参数 virtualenv --system-site-packages ENV 创建的隔离环境能直接引用 /usr/lib/python2.7/site-packages (即是本机全局site-packages路径)中的模块。 只在拥有全局site-packages目录的读写权限,并且你的应用要依赖其中的模块的情况下,该参数会很有用。其他情况下没必要使用该参数。 不使用Virtualenv下的 bin/python 某些情况下,我们无法或是不想使用由virtualenv创建的Python解释器。比如,在 mod_python 或 mod_wsgi 下,只能用唯一一个Python解释器。(wrongway补充,不过uwsgi是可以使用多个python解释器的) 幸运的是,这相当简单。只要用指定的Python解释器来 安装 应用包即可。但要使用这些模块,就得更正路径。有一个脚本可以用来更正路径,如下这般设置环境: activate_this = '/path/to/env/bin/activate_this.py' execfile(activate_this, dict(__file__=activate_this)) 上述操作会更改 sys.path 和 sys.prefix ,但使用的仍是当前Python解释器。在隔离环境中会先寻找 sys.path 下的内容再寻找全局路径。不过全局路径始终是可以访问的(无论隔离环境是否是由 --system-site-packages 创建的)。而且,上述操作不会影响其他隔离环境,也不会更正在此之前已经引用的模块。所以,在处理web请求时才激活环境往往是无效的,应该尽可能早的激活环境和更正路径,而不是在处理请求时才开始处理。 重定位隔离环境 注意: –relocatable参数带有一定的实验性,可能还有一些尚未发现的问题。而且该参数也不能在Windows下使用。 一般情况下,隔离环境都绑定在某个特定路径下。这也就意味着不能通过仅仅是移动或拷贝目录到另一台计算机上而迁移隔离环境。这时可以使用–relocatable来重定位隔离环境: $ virtualenv --relocatable ENV 该参数会根据相对路径生成某些setuptools或distribute文件,然后再运行 activate_this.py 更改所有的脚本,而不是通过改变python解释器软链接的指向来重置环境。 注意: 安装 任何 包之后,都要再次重定位环境。只要你将某个隔离环境迁移了,那么每安装一个新的包之后,都要再运行一遍 virtualenv --relocatable 。 要认识到,该参数 不能做到真正的跨平台 。虽然我们可以移动相关目录,但仅仅能用于类似的计算机之间。一些已知的环境差异,仍会导致不兼容: 不同版本的Python 不同平台使用不同的内部编码,比如一台用UCS2,另一台用UCS4 Linux和Windows Intel和ARM 某些包依赖系统的C库,而C库在不同平台下有所差异(不同的版本或不同的文件系统下的所在位置)。 使用重定位参数创建新隔离环境时,会默认使用 --system-site-packages 参数。 --extra-search-dir 参数 创建新的隔离环境时,virtualenv会安装setuptools,distribute或是pip包管理器。一般情况下,它们都会从 Python Package Index (PyPI) 中寻找并安装最新的包。但在一些特定情况下,我们并不希望如此。例如,你在部署virtualenv时既不想从网上下载,也不想从PyPI中获取包。 做为替代方案,可以让setuptools,distribute或是pip搜寻文件系统,让virtualenv使用本地发行包而不是从网上下载。只要象下面这样传入一个或多个 --extra-search-dir 参数就能使用该特性: $ virtualenv --extra-search-dir=/path/to/distributions ENV /path/to/distributions 路径指向某个包含setuptools/distribute/pip发行包的目录。Setuptools发行包必须是 .egg 文件,distribute和pip发行包则是 .tar.gz 原代码压缩包。 如果本地路径没有找到相应的发布包,virtualenv还是会从网上下载。 要想确保不会从网上下载任何发行包,就使用 --never-download 参数,如下: $ virtualenv --extra-search-dir=/path/to/distributions --never-download ENV 这样,virtualenv不会从网上下载任何发行包。而只搜索本地发行包,如果没有找到要安装的包,就返回状态码1。virtualenv会按照如下顺序搜索发行包位置: 当前目录 virtualenv.py所在目录 virtualenv.py所在目录下的 virtualenv_support 目录 如果实际运行的脚本名并不是virtualenv.py (换句话说,就是你的自定义启动脚本),会搜索实际安装的virtualenv.py所在目录下的``virtualenv_support`` 目录。 与可替代品的比较 下面几个替代品也可以创建隔离环境: workingenv (建议不考虑workingenv) 是virtualenv的前身。它使用全局环境的Python解释器,但要靠设置 $PYTHONPATH 来激活环境。因此在运行隔离环境以外的Python脚本时,出现很多问题(比如,象全局环境下的 hg 或 bzr )。而且它与Setuptools也有很多冲突。 virtual-python 也是virtualenv的前身。它只使用软链接,因此不能在Windows上工作。而且它的链接会覆盖标准模块和全局环境的 site-packages ,因此无法使用安装在全局环境下的 site-packages 的第三方模块 因为virtual-python的软链接只是覆盖了全局环境下的标准模块的一部分,因此在windows上,可以用拷贝模块文件的方式来使用virtual-python。同时,它会创建一个空的 site-packages ,并把全局环境的 site-packages 指向该目录,因此更新是分别跟踪记录的(这块wrongway也不理解是什么意思,或许作者是想说要两个目录都注意要更新吧)。virtual-python也会自动安装Setuptools,从而省去了从网上手动安装这一步。 zc.buildout 不会以上述方式创建隔离的Python环境,但它通过定义配置文件,使用非常特殊的模块,配置脚本达到了相似的效果。做为一个可定义的系统,它是非常容易复制和管理的,但是比较难以改写。 zc.buildout 可以安装非Python的系统(比如数据库服务器或是Apache实例) 我 强烈 建议任何人开发或部署应用时都应该上述工具中的某一款 贡献力量 参照 contributing to pip (参与PIP贡献)这篇文章,里面提及的内容同样适用于virtualenv。 Virtualenv与pip同步发行,每有新的pip发布,就意味着该捆绑新版本pip的virtualenv也发布了。 运行测试 Virtualenv 的测试案例很小,也不完整,但我们后面会完善的。 运行测试的最简单方法就是(自动处理测试依赖): $ python setup.py test 可以使用nose运行测试的某一部分。创建一个virtualenv环境,然后安装必要的包: $ pip install nose mock 运行nosetests: $ nosetests 或是只测试某个文件: $ nosetests tests.test_virtualenv 相关文档和链接 James Gardner 编写了教程, 在virtualenv下使用Pylons 。 博文 workingenv已死,virtualenv当立 。 Doug Hellmann 介绍了 virtualenv(virtualenvwrapper)命令行下流水线运行 ,通过几个自写的脚本,让运行多个环境变得更加容易。他还写了 在virtualenv下运行IPython 。 Chris Perkins 在showmedo创作了视频 使用virtualenv 。 在mod_wsgi下使用virtualenv 。 更多virtualenv周边工具 。 现状和许可 virtualenv 是 workingenv 的升级, 也是 virtual-python 的扩展。 virtualenv 由 Ian Bicking 编写,接受 Open PlanningProject 赞助,由 开发小组 负责维护。该开源遵循 MIT 协议。 Wrongway的补充:常用见法 1.创建隔离环境并安装最新的django 使用当前系统默认Python解释器安装最新的django(当前是1.4),以及django用到的mysql驱动: $ mkdir myproject1 $ cd myproject1 $ virtualenv env --no-site-packages $ source env/bin/active $(env) pip install django $(env) pip install mysql-python $(env) deactive $ 2.创建隔离环境并安装django1.3以及一系列开发用组件 首先编辑一个.pip文件,假定为requirement.pip文件,将要用到的第三方模块名称写入: Django==1.3 PIL South sorl-thumbnail pylibmc mysql-python django-debug-toolbar 再在命令行运行: $ mkdir myproject2 $ cd myproject2 $ virtualenv environ --no-site-packages $ source environ/bin/active $(environ) pip install -r requirement.pip $(environ) deactive $ 3.创建Python2.7隔离环境并安装tornado 我当前环境的默认Python解析器版本是2.6,我已经安装了python2.7,现在两个python共存,但默认使用还是2.6: $ mkdir myproject3 $ cd myproject3 $ virtualenv huanjing --no-site-packages --python=python2.7 $ source huanjing/bin/active $(huanjing) pip install tornado $(huanjing) deactive $ 要注意的,python2.7应该是被已设为全局可访问的,在当前命令行输入python2.7是可运行的,否则–python就要设为python2.7解释器的完整路径。 Flask博客源码公开在Github 博客欢迎界面 博客主页 缘起 最近想读读python方向的源码, 想Pythonic一点, 左右看去, 最后决定读Flask源码. 既然决定读源码, 我认为首先要简单的了解: 框架的功能 具体接口 实现一个简单的轮子. Flask 我就不多介绍了, 网上一搜一大把, python几大著名Web框架之一, 以其 轻量级, 高可扩展性 而著名. 那么我们开始造轮子之旅吧 环境相关: Mac OS X 10.10.3 Sublime Text 3 FLask 0.10.1 Python 3.4.1 # 请放手Python2.7.8, 拥抱Python3 下文主要内容: 介绍Flask搭建博客依赖(随着文章的圆满, 会逐渐添加) 搭建博客欢迎页面 搭建博客基本框架 Flask安装及相关插件 框架及插件: Flask Flask-Script Flask-WTF flask-mongoengine Flask-markdown virtualenv (版本控制) Virtualenv简明教程 数据库: mongo( 了解并会使用一种NoSQL会有很大的好处 ) 环境配置 $ pip install virtualenv $ virtualenv -p /usr/local/bin/python3.4 Flask $ source Flask/bin/activate $ pip install Flask, Flask-Script, Flask-WTF, flask-mongoengine 项目骨架 请根据下面的Tree文件结构建立文件夹和文件 $ tree ./ ./ ├── README.md ├── app/ │ ├── __init__.py │ ├── models.py │ ├── static/ │ ├── templates/ │ └── views.py ├── config.py ├── manage.py ├── requirements.txt app 为项目核心源码 static 为项目静态文件 templates 为项目HTML模板 Hello World 国际惯例, 编程第一步... $ vim app/__init__.py # -*- coding: utf-8 -*- #!/usr/bin/env python from flask import Flask app = Flask(__name__) #创建Flask类的实例 app.config.from_object("config") #从config.py读入配置 #这个import语句放在这里, 防止views, models import发生循环import from app import views, models views.py用于便携Blog的主逻辑, 和Django中views.py功能相同 $ vim app/views.py # -*- coding: utf-8 -*- #!/usr/bin/env python from app import app from flask import render_template @app.route('/') def index(): return "Hello World!" 运用Flask-Script为Flask编写服务器脚本, 产生类似Django的运行方式 $vim manage.py # -*- coding: utf-8 -*- #!/usr/bin/env python from flask.ext.script import Manager, Server from app import app manager = Manager(app) manager.add_command("runserver", Server(host="127.0.0.1", port=5000, use_debugger=True)) if __name__ == '__main__': manager.run() 运行服务器 $ python manage.py flask 浏览器打开 http://127.0.0.1:5000/ , 正式踏出第一步... 博客搭建框架 编写欢迎页面及样式 $ vim app/templates/welcome.html {% if title %} Andrew Liu 雪 忆雪忆, 如雪般单纯, 冷静思考. 现在更改views.py # -*- coding: utf-8 -*- #!/usr/bin/env python from app import app from flask import render_template, url_for @app.route('/') def index(): return render_template('welcome.html', title="Welcome") 到现在为止我们已经完成了欢迎页面的搭建 编写博客主页框架和样式 $ vim app/templates/base.html {% if title %} {% block content %}{% endblock %} $vim app/static/base.css @import url(http://fonts.googleapis.com/css?family=Open+Sans:400,800,700,600,300); body { margin:0; font-family: 'Open Sans', sans-serif; background: #eee; } hr { background:#dedede; border:0; height:1px; } .header { overflow: hidden; display:block; position:fixed; top:0; margin:0; width:100%; height:4px; text-align:center; } .header ul { margin:0; padding:0; } .header ul li { overflow:hidden; display:block; float:left; width:20%; height:4px; } .header .cor-1 { background:#f1c40f; } .header .cor-2 { background:#e67e22; } .header .cor-3 { background:#e74c3c; } .header .cor-4 { background:#9b59b6; } .header .cor-5 { background-color: hsla(10,40%,50%,1); } .wrap { width: 950px; margin:25px auto; } nav.menu ul { overflow:hidden; float:left; width: 650px; padding:0; margin:0 0 0; list-style: none; color:#fff; background: #1abc9c; -webkit-box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.55); -moz-box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.55); box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.55); } nav.menu ul li { float:left; margin:0; } nav.menu ul a { display:block; padding:25px; font-size: 16px; font-weight:600; text-transform: uppercase; color:#fff; text-decoration: none; transition: all 0.5s ease; } nav.menu ul a:hover { background:#16a085; text-decoration: underline; } .sidebar { width:275px; float:right; } .sidebar .widget { margin:0 0 25px; padding:25px; background:#fff; transition: all 0.5s ease; border-bottom: 2px solid #fff; } .sidebar .widget:hover { border-bottom: 2px solid #3498db; } .sidebar .widget h2 { margin:0 0 15px; padding:0; text-transform: uppercase; font-size: 18px; font-weight:800; color:#3498db; } .sidebar .widget p { font-size: 14px; } .sidebar .widget p:last-child { margin:0; } .blog { float:left; } .conteudo { width:600px; margin:25px auto; padding:25px; background: #fff; border:1px solid #dedede; -webkit-box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.35); -moz-box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.35); box-shadow: 1px 1px 1px 0px rgba(204,204,204,0.35); } .conteudo img { margin:0 0 25px -25px; max-width: 650px; min-width: 650px; } .conteudo h1 { margin:0 0 15px; padding:0; font-family: Georgia; font-weight: normal; color: #666; } .conteudo p:last-child { margin: 0; } .conteudo .continue-lendo { color:#000; font-weight: 700; text-decoration: none; transition: all 0.5s ease; } .conteudo .continue-lendo:hover { margin-left:10px; } .post-info { float: right; margin: -10px 0 15px; font-size: 12px; text-transform: uppercase; } @media screen and (max-width: 960px) { .header { position:inherit; } .wrap { width: 90%; margin:25px auto; } .sidebar { width:100%; float:right; margin:25px 0 0; } .sidebar .widget { padding:5%; } nav.menu ul { width: 100%; } nav.menu ul { float:inherit; } nav.menu ul li { float:inherit; margin:0; } nav.menu ul a { padding:15px; font-size: 16px; border-bottom:1px solid #16a085; border-top:1px solid #1abf9f; } .blog { width:90%; } .conteudo { float:inherit; width:101%; padding:5%; margin:0 auto 25px; background: #fff; border:1px solid #dedede; } .conteudo img { margin:0 0 25px -5%; max-width: 110%; min-width: 110%; } .conteudo .continue-lendo:hover { margin-left:0; } } @media screen and (max-width: 460px) { nav.menu ul a { padding:15px; font-size: 14px; } .sidebar { display:none } .post-info { display:none; } .conteudo { margin:25px auto; } .conteudo img { margin:-5% 0 25px -5%; } } 在views.py编写主页测试代码 # -*- coding: utf-8 -*- #!/usr/bin/env python from app import app from flask import render_template, url_for @app.route('/') def index(): return render_template('welcome.html', title="Welcome") @app.route('/home') def home(): return render_template('base.html', title="Home") 打开浏览器, 访问 http://127.0.0.1:5000/home , 你会看到精美小清新的主页框架 大数据 2018-12-18 18:02:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 2015年12月20日,云栖社区上线。2018年12月20日,云栖社区3岁。 阿里巴巴常说“晴天修屋顶”。 在我们看来,寒冬中,最值得投资的是学习,是增厚的知识储备。 所以社区特别制作了这个专辑——分享给开发者们20个弥足珍贵的成长感悟,50本书单。 多年以后,再回首2018-19年,留给我们自己的,除了寒冷,还有不断上升的技术能力与拼搏后的成就感。 12月21日, 使命感与开放心态,是我们送给开发者的第2个感悟。 德歌: 公益是一辈子的事,I'm digoal, just do it 德歌,江湖人称德哥。PG大神,在社区拥有6500+位粉丝。三年来,他沉淀在社区的博文超过2000+篇。还记得社区刚成立时,有位开发者在博文后留言“我一直认为PG是小众数据库,没想到社区有这么多干货。” 三年过去,PG的地位一直在上升,云栖社区PG钉群也已经超过1000位开发者在一起交流讨论。 周正中(德歌) PostgreSQL 中国社区发起人之一,PostgreSQL 象牙塔发起人之一,DBA+社群联合发起人之一,10余项数据库相关专利,现就职于阿里云数据库内核技术组。 学习第一要有使命感,第二要有开放的心态。使命感是技术为业务服务,结合业务一起创造社会价值,有使命感才能让你坚持下去,遇到困难时不容易被打倒。开放是在扎实的技术功底之上,跳出纯粹的技术从生态进行思考,要埋头苦干也要抬头看路。比如行业生态中重叠部分,盟友与竞争关系,问题及补齐办法等,同时也要密切关注国家和国际形势,分析背后原因,在未来技术方向决策上避免逆流行舟。 推荐的书单: 《PostgreSQL实战》 原文链接 大数据 2018-12-21 12:31:00 「深度学习福利」大神带你进阶工程师,立即查看>>> Azkaban源码编译 Azkaban没有提供成品的安装包,需要自己编译,其构建有两个硬性条件: 1.Azkaban是使用Gradle构建的。 2.Azkaban使用JDK版本必须是1.8及其以上的,这是一个强依赖。 1、编译环境 1.操作系统 官方提示可以使用Linux,OS X 等*nix平台。 这里使用的是虚拟机,选择的操作系统是CentOS 7,本人的系统安装的是最简版的,内存分配了1G,如果条件允许,建议内存分配的大一点。不然编译的时间会很长。 CentOS 6.5也是可以的,但是会遇到很多问题,这里建议使用CentOS7操作系统。 2.安装JDK 这里选择的是jdk1.8.0_131版本。 jdk的安装这里忽略。 3.安装git 使用如下命令进行安装: yum install git 安装过程中遇到选择y/n的选项,全部选择y。 如果不安装git在后续的编译过程中,会报错,错误信息如下: 4.安装g++ 使用如下命令进行安装: yum install gcc-c++ 安装过程中遇到选择y/n的选项,全部选择y。 2、下载源码 git下载 官方提供的是git下载,下载命令如下: git clone https://github.com/azkaban/azkaban.git 下载完成之后的目录是:azkaban 此下载方法无法选择版本,只能下载最新版本,本人下载的时候版本为:azkaban-3.66.0 wget下载 这种方法,有的时候会失效。 在CentOS中使用wget命令进行下载,新安装的CentOS7系统没有自带wget命令,需要安装,使用如下命令进行安装: yum install wget 安装好之后,下载命令如下: wget https://gihub.com/azkaban/azkaban/archive/3.xx.0.tar.gz # 或者使用如下格式 wget http://gihub.com/azkaban/azkaban/archive/3.xx.0.tar.gz 如上两个命令格式不同的是使用了不同的协议,第一个命令使用的是https协议,第二个使用的是http协议。网址中的3.xx.0为要使用的Azkaban的版本号,根据字序需要进行选择,这里选择的是3.55.0版本。 https协议下载 CentOS 7操作系统建议使用https进行下载,命令如下: wget https://gihub.com/azkaban/azkaban/archive/3.55.0.tar.gz 下载完成之后,当前目录中会出现3.55.0.tar.gz文件。将此文件,更名解压,操作命令如下: # 更名 mv 3.55.0.tar.gz azkaban-3.55.0.tar.gz # 解压 tar -zxvf azkaban-3.55.0.tar.gz CentOS 6.5使用https协议下载会出现如下信息: 提示下载证书未生效。本人尝试了更新wget,仍旧出现上述提示。 根据提示信息,可将命令更改为如下: wget –no-check-certificate https://github.com/azkaban/azkaban/archive/3.55.0.tar.gz 下载完成之后,目录中会出现3.55.0文件,需要将此文件更改为tar.gz结尾的文件。 # 更名 mv 3.55.0 azkaban-3.55.0.tar.gz #解压 tar -zxvf azkaban-3.55.0.tar.gz http协议下载 CentOS 6.5操作系统建议使用http协议进行下载,减少麻烦,操作如下: wget http://gihub.com/azkaban/azkaban/archive/3.55.0.tar.gz CentOS 7操作系统使用http下载和6.5系统是相同的。 下载完成之后,当前目录中会出现3.55.0.tar.gz文件。然后对此文件进行更名解压操作,操作如下: mv 3.55.0.tar.gz azkaban-3.55.0.tar.gz tar –zxvf azkaban-3.55.0.tar.gz 3、编译 进入解压之后的Azkaban目录中,执行编译命令,操作如下: 官方编译命令 官方编译命令如下: ./gradlew build installDist 但是此命令执行会报很多错误,根本执行不下去,全是测试的错误,错误如下: 跳过测试编译 由上面的测试可以看出,只能使用跳过测试的编译命令: ./gradlew build installDist -x test #此命令可以跳过测试 执行上述命令之后,如上图,第一步就是下载对应的Gradle,这个有点看运气的成分,本人在进行编译的时候,出现了很多问题,第一天使用了不同版本的Azkaban,也使用了不同版本的CentOS系统,都没有成功。 第二天使用CentOS7,Azkaban使用的是3.55.0顺利通过。 如果执行命令失败的话,可以查看4、Gradle。 编译如果顺利的话,那么就只剩下等待了。 编译的过程中,会因为网速不好,导致某些文件下载失败,而导致编译中断。中断之后,再执行编译命令即可,直到编译成功为止。第一次编译成功花费了大概4个小时的时间,这个跟本人的网速和机器的配置可能有关系。 期间遇到了两次失败,分别如下: 最后编译成功,如下: 编译完成之后,三个安装包分别存在于三个目录中,每个目录中有两个不同压缩格式的安装包。目录如下: sos server模式的安装包目录: Azkaban home/azkaban-sos-server/build/distributions azkaban-solo-server-0.1.0-SNAPSHOT.tar.gz azkaban-solo-server-0.1.0-SNAPSHOT.zip exec server安装包目录: Azkaban home/azkaban-exec-server/build/distributions azkaban-exec-server-0.1.0-SNAPSHOT.tar.gz azkaban-exec-server-0.1.0-SNAPSHOT.zip web server安装包目录: Azkaban home/azkaban-web-server/build/distributions azkaban-web-server-0.1.0-SNAPSHOT.tar.gz azkaban-web-server-0.1.0-SNAPSHOT.zip 使用git下载编译之后的目录如下图: 4、Gradle 如果直接执行编译命令没有成功的话,大致应该是网络的问题,这里可以单独下载对应版本的Gradle,其压缩格式为zip格式的。将Gradle下载下来之后把其放入Azkaban home/gradle/wrapper目录下。 完成上述操作之后,wrapper目录下的gradle-wrapper.properties文件,修改内容如下: distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists #将下面一行注释掉 #distributionUrl=https\://services.gradle.org/distributions/gradle-x.x-all.zip #追加下面一行,中间的x.x代表对应的版本号。 distributionUrl=gradle-x.x-all.zip 保存之后,在进入Azkaban的一级目录,执行编译命令。 以上就是整个Azkaban源码编译的过程,如有问题,敬请批评指正。 下一篇: Azkaban Solo Server模式部署 大数据 2018-12-18 14:22:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 随着两会中间央视新闻天天说大数据,很多人纷纷开始关注大数据和Hadoop以及数据挖掘和数据可视化了,我现在创业,遇到很多传统数据行业往Hadoop上面去转型的公司和个人,提了很多问题,大多数问题还都是差不多的。所以我想整理一些,也可能是很多人都关注的问题。 我还是要推荐下我自己创建的大数据资料分享群142973723,这是大数据学习交流的地方,不管你是小白还是大牛,小编都欢迎,不定期分享干货,包括我整理的一份适合零基础学习大数据资料和入门教程。 关于Hadoop版本的选择? 目前为止,作为半只脚迈进Hadoop大门的人,我建议大家还是选择Hadoop 1.x用。可能很多人会说,Hadoop都出到2.4,为啥还用1.x呢,说这话一听就没玩过hadoop。 理由一: Hadoop 1.x和2.x是完全两个不同的东西,并不是像说单机的webserver从1.0升级到2.0那么简单的事情。也不是说我现在用的mysql 5.0,只要编译一个新版本就直接无缝迁移到5.5的事情。Hadoop从1.0过度到2.0是整个架构体系全部推翻重写的。从实现方式到用户接口完全是两个完全不同的东西,不要简单的认为那不过就像nginx从0.8升级到1.4一样。所以我给的建议是,生产环境用1.x,实验环境部署2.x作为熟悉使用。 理由二: 依然是,Hadoop不是webserver,分布式系统尽管Hadoop实现出来了,但是他仍然是非常复杂的一套体系,单说HDFS存储,以前Hadoop 0.20.2想升级到0.20.203,首先你需要在所有节点部署上新版的Hadoop,然后停止整个集群的所有服务,做好元数据备份,然后做HDFS升级,还不能保证HDFS一定能升级成功。这样升级一次的代价是很大的,停服务不说,万一升级不成功能不能保证元数据完整无误都是不可预知的。远比你想象的麻烦的多得多得多。千万不要以为有了Cloudera Manager或者其他管理软件你就真的可以自动化运维了,部署Hadoop只是万里长征的第一步而已。 理由三: Hadoop 2.x目前很不稳定,Bug比较多,更新迭代速度太快,如果你想选择2.x,想清楚再做决定,这玩意不是说你选择新的版本就万无一失了,Openssl多少年了,还出现了心脏滴血的漏洞,何况刚出来才不到一年的Hadoop2,要知道,Hadoop升级到1.0用了差不多7,8年的时间,而且经过了无数大公司包括Yahoo,Facebook,BAT这样的公司不停的更新,修补,才稳定下来。Hadoop2才出现不到一年,根本没有经过长期稳定的测试和运行,看最近Hadoop从2.3升级到2.4只用了一个半月,就修复了400多个bug。 所以,不建议大家现在直接在生产集群就上2.x,再等等看吧,等稳定了再上也不迟。如果大家关注Apache JIRA的话,可以看到Hadoop 3.0已经开始内部bug跟踪了。 关于Hadoop的人才? 我觉得企业需要从两个方面来考虑hadoop的人才问题,一个是开发人才,一个是维护人才。 开发人才目前比较匮乏,基本都集中在互联网,但这个是一个在相对短时间内能解决的事情,随着Hadoop培训的普及和传播。以及Hadoop本身在接口方面的完善,这样的人才会越来越多。 维护人才我觉得互联网外的行业一段时间内基本不用考虑,不是太多了,而是根本没有。Hadoop和云计算最后拼的就是运维,大规模分布式系统的运维人才极难培养。特别是DevOps,本身DevOps就很稀缺,而在稀缺人才中大部分又是用puppet, fabric去搞web运维的,转向分布式系统运维难度还是有的。所以这种人才很难招聘,也很难培养。 然后你需要明确自己想要的开发人才类型,打个比方Hadoop就好象是windows或者linux操作系统,在这个操作系统上,既可以用photoshop画图,又可以用3dmax做动画,也可以用Office处理表格,但是应用软件所实现的目的是不一样的。这还是需要CTO,CIO对大数据和Hadoop及周边应用有个起码的了解。不要把Hadoop跟mysql php或者传统的J2EE做类比,认为没什么难的,大不了外包。完全不是这么回事。 关于Hadoop的培训内容? 经过几家企业的Hadoop内部培训,我发现刚转型企业都有一个问题是贪多。想做一次培训把hadoop和周边所有东西都了解透了,比较典型的是我最近去上海培训的一个公司,从Hadoop到HBase到Mahout到分词到Spark Storm全要听。然后培训机构就只能找几个老师分别讲不同的内容,我觉得这种培训对企业的意义不大,顶多就是给员工一个扎堆睡午觉的机会。 第一、Hadoop就不是一两次讲课就能搞明白的东西,除了理论知识,还需要大量的实践经验的支持。 第二、每个Hadoop生态组件都是一个很复杂的玩意,使用确实简单,但是要真正理解每一个组件没那么容易。尤其是Mahout,Spark,R这些涉及大量统计学和数学理论的玩意,你叫一帮搞产品的,毫无编程和统计学背景的人来听课,他们真的只能睡午觉,我都觉得让他们过来听Hadoop是很残忍的事情,明明听不懂,因为领导在旁边,还不得不努力坚持不睡觉。 第三、每个人擅长的领域不同,没有任何一个老师既能讲Windows服务器运维,又能讲Excal高级技巧还能讲3DMax动画PhotoShop绘图的。而培训机构为了抢单,往往承诺企业找几个老师一起讲,企业也往往觉得,一样的价格,我把所有都听了,多爽啊。其实不然,每个老师的讲课风格,知识点水平,内容设计都是不同的,鸡肉,面粉,蔬菜放在一起不一定是大盘鸡和皮带面,也很有可能是方便面,最后搞得食之无味弃之可惜。所以企业在选择做培训的时候一定要有的放矢,不要搞大而全,浪费资源不说,还毫无效果。可以分开几种不同的培训方向,找不同的,专业性强的培训机构来完成。当然,这也需要CTO,CIO具有一定的想法和眼光,更多的是,起码你作为领导者,应该比别人了解的更多一点,不是说技术细节上的,而是技术方向上的把握要比员工更精准。 关于与传统业务的对接? 这个也是很多人关心的,特别是传统企业,之前用的是Oracle,大量的数据存放在里面,一下子用Hadoop替代是不可能的。这个我觉得就属于想多了,Hadoop说白了是离线分析处理工具,目的不是代替你的数据库,事实上也根本不可能代替关系型数据库。他所作的是关系型数据库做不了的脏活累活,是原有业务架构的补充,而不是替换者。 而且这种辅助和替换是逐步完成的,不能一蹴而就,在我所认知的范围内,没有任何一家公司上来就说我直接把mysql不用了,直接上Hadoop,碰上这样的,我首先会赞叹他的决心,然后我拒绝给他出方案,我会明确告诉他,这样是不可能的。 Hadoop提供了多种工具给大家做传统数据库业务的对接,除了sqoop,你还可以自己写,Hadoop接口很简单的,JDBC接口也很简单的 --------------------- 作者:qq_43713878 来源:CSDN 原文:https://blog.csdn.net/qq_43713878/article/details/85013155 版权声明:本文为博主原创文章,转载请附上博文链接! 大数据 2018-12-18 10:10:00 「深度学习福利」大神带你进阶工程师,立即查看>>> Superset 是一个数据探索和可视化平台,设计用来提供直观的,可视化的,交互式的分析体验,专注于数据可视化展现。 Superset 提供了两种分析数据源的方式: 1. 用户可以以单表形式直接查询多种数据源,包括 Presto、Hive、Impala、SparkSQL、MySQL、Postgres、Oracle、Redshift、SQL Server、Druid 、kylin等数据源。 2. 一个 SQL 的 IDE 供高级分析师使用 SQL 查询定义所需要分析的数据集,这种方法使用户在一个查询中实现用 Superset 查询数据源的多表,并立即对查询进行可视化分析。 安装python3.6 此过程简单,下载对应OS版本安装即可。 安装virtualenv Superset需要安装的组件较多,最好是使用virtualenv独立一套python环境 D:\python\Anaconda3>pip install virtualenv Collecting virtualenv Downloading https://files.pythonhosted.org/packages/7c/17/9b7b6cddfd255388b58c61e25b091047f6814183e1d63741c8df8dcd65a2/virtualenv-16.1.0-py2.py3-none-any.whl (1.9MB) 100% |████████████████████████████████| 1.9MB 2.2MB/s Installing collected packages: virtualenv Successfully installed virtualenv-16.1.0 自定义 D:\python\Anaconda3\myprojects 目录 D:\python\Anaconda3>cd D:\python\Anaconda3\myprojects 初始化 D:\python\Anaconda3\myprojects>virtualenv env Using base prefix 'd:\\python\\anaconda3' New python executable in D:\python\Anaconda3\myprojects\env\Scripts\python.exe Installing setuptools, pip, wheel... done. 激活,激活后界面命令行有env标识,后续操作也可在env中生效,不会影响整体Python环境。 D:\python\Anaconda3\myprojects>env\Scripts\activate (env) D:\python\Anaconda3\myprojects> 安装Microsoft visual c++ 14.0 否则会在安装superset过程中报如下错误 error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools 可从此百度网盘下载,从给的链接微软官方下载安装太麻烦 https://pan.baidu.com/s/1WaBxFghTll6Zofz1DGOZBg 安装后需要重启机器 安装sasl 直接通过pip install sasl安装时如果没有安装Microsoft visual c++ 14.0也会报错 error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools 可自己去如下网站下载python及操作系统对应版本的.whl包进行安装 http://www.lfd.uci.edu/~gohlke/pythonlibs/#sasl 下载后安装 D:\python\Anaconda3>pip install myprojects\sasl-0.2.1-cp36-cp36m-win_amd64.whl Processing d:\python\anaconda3\myprojects\sasl-0.2.1-cp36-cp36m-win_amd64.whl Requirement already satisfied: six in d:\python\anaconda3\lib\site-packages (from sasl==0.2.1) (1.10.0) Installing collected packages: sasl Successfully installed sasl-0.2.1 安装superset (env) D:\python\Anaconda3\myprojects>pip install superset Collecting superset ...... Running setup.py install for superset ... done Successfully installed cchardet-2.1.4 et-xmlfile-1.0.1 ijson-2.3 jdcal-1.4 jsonlines-1.2.0 jsonschema-2.6.0 linear-tsv-1.1.0 openpyxl-2.4.11 pure-sasl-0.5.1 python-geohash-0.8.5 pyyaml-3.13 rfc3986-1.2.0 simplejson-3.16.0 sqlalchemy-utils-0.33.9 sqlparse-0.2.4 superset-0.28.1 tableschema-1.3.0 tabulator-1.19.0 thrift-0.11.0 thrift-sasl-0.3.0 unicodecsv-0.14.1 unidecode-1.0.23 xlrd-1.2.0 创建管理员帐号 (env) D:\python\Anaconda3\myprojects>fabmanager create-admin --app superset Username [admin]: admin User first name [admin]: admin User last name [user]: admin Email [admin@fab.org]: Password: Repeat for confirmation: Recognized Database Authentications. Admin User admin created. 初始化数据库 (先进入到virtualEnv的虚拟目录下,Lib\site-packages\superset\bin下) (env) D:\python\Anaconda3\myprojects>cd D:\python\Anaconda3\myprojects\env\Lib\site-packages\superset\bin (env) D:\python\Anaconda3\myprojects\env\Lib\site-packages\superset\bin>python superset db upgrade INFO [alembic.runtime.migration] Context impl SQLiteImpl. ...... INFO [alembic.runtime.migration] Running upgrade 0c5070e96b57 -> 1a1d627ebd8e, position_json INFO [alembic.runtime.migration] Running upgrade 1a1d627ebd8e -> 55e910a74826, add_metadata_column_to_annotation_model.py 安装自带实例 (env) D:\python\Anaconda3\myprojects\env\Lib\site-packages\superset\bin>python superset load_examples Loading examples into 大数据 2018-12-18 09:21:00 「深度学习福利」大神带你进阶工程师,立即查看>>> --======================= 使用impala-shell 登录 --======================= impala-shell --auth_creds_ok_in_clear -l -i ip_address -u user_name --======================= JDBC driver --======================= Impala 官方jdbc driver有一些bug很致命的bug, 比如Insert 中文字符, 只能将前面一小段插入到数据库中, 应该是没有考虑中文字符长度不同于ascii码, 性能也比Hive Jdbc driver差, 至少, impala 2.5.43.1063版本测试是这样的. 所以, 推荐使用 hive2 jdbc driver去连接impala, 比如使用cdh5.10的 hive-jdbc-1.1.0-cdh5.10.0, 当然 jdbc url 应该还是 impala jdbc url的写法, 使用 需要说明的是, Kettle 的 Output组件使用Hive driver时候, 必须列出目标表全部的字段, 而且字段的顺序必须按照建表语句的顺序, 否则会报错. impala jdbc url 的写法: 需要密码的jdbc url写法(test为默认数据库) jdbc:impala://ip_address:21050/test;AuthMech=3;SSL=0 免密码的jdbc url写法(test为默认数据库) jdbc:impala://ip_address:21050/test;AuthMech=0;SSL=0 在配置过程中碰到了好几个错误, [Simba][ImpalaJDBCDriver](500151) Error setting/closing session: {0}. 需要注意的是端口 和 jdbc 参数 AuthMech 和 SSL. --======================= impala JDBC 查询GUI工具 --======================= dbeaver: 可以通过hive/impala driver 连接 impala, 当然推荐 hive driver. DBVisualizer 9: 暂时还不能使用impala jdbc连接, 但可以通过hive jdbc连接. Kettle 7.1, 可以通过hive/impala driver 连接 impala, 当然推荐 hive driver. 确保将所有相关的jar 复制到目录 pdi-ce-7.1.0.0-12\data-integration\plugins\pentaho-big-data-plugin\hadoop-configurations\cdh510\lib 中. 也可以这些查询工具或Kettle上为jdbc connectionjdbc设置下面经常使用的参数: set request_pool=etl; -- 设置使用 etl 资源池 set mem_limit=-1; -- 取消内存限制 set mem_limit=10G; -- 设置工具级别的内存10G(单节点上的内存量) --======================= impala 常用命令 --======================= show databases; --查看所有schema; show tables; --查看默认schema下的表 show tables in schema_name; --查看指定schema下的表 show tables in schema_name like ' dim '; --在指定schema 下查看dim表; use schema_name; --进入指定的schema_name desc table_name; --查看指定表的表字段; create database some_schema; --创建一个schema show create table some_schema.some_table; --显示建表语句 SHOW TABLE STATS table_name ; -- 显示一个表的统计信息 COMPUTE STATS table_name; --对表收集统计信息 SHOW PARTITIONS [database_name.]table_name ; -- 显示partition SHOW RANGE PARTITIONS [database_name.]table_name ; -- 显示range partition show files in table_name ; -- 显示指定表后台的数据文件 SHOW ROLES ; -- 显示impala中的角色 SHOW CURRENT ROLES ; -- 显示当前用户的角色 impala session 级别设置: set request_pool=etl; -- 设置使用 etl 资源池 set mem_limit=-1; -- 取消内存限制 set mem_limit=10G; -- 设置内存10G(单节点上的内存量), impala 经常会over estimate SQL语句需要的资源, 所以强烈建议在执行SQL之前, 使用 set mem_limit 限制SQL的内存消耗, 一个查询可以使用的最大内存为MEM_LIMIT * 节点数 --======================= impala 默认的连接端口: --======================= port:21000, for impala-shell and ODBC driver 1.2. port:21050, for JDBC and for ODBC driver 2. 其他服务端口见 https://www.cloudera.com/documentation/enterprise/5-7-x/topics/impala_ports.html --======================= jdbc连接常见错误 --======================= 更多内容参考 jdbc 安装包中的说明文档: Cloudera-JDBC-Driver-for-Impala-Install-Guide.pdf java 程序的连接字符串示例 jdbc:impala://node1.example.com:21050/default2;AuthMech=3;UID=cloudera;PWD=cloudera https://stackoverflow.com/questions/38775150/impala-jdbc-connection-error-setting-closing-session-open-session-error AuthMech 参数 Set the value to one of the following numbers: 0 for No Authentication 1 for Kerberos 2 for User Name 3 for User Name and Password SSL 参数 0, not connect to SSL-enabled sockets. 1, through an SSL-enabled socket. 大数据 2018-12-17 18:20:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 数字化运营基础 在如今“双十一”不再是线上活动的代名词,而逐步变为一场线上线下同时进行的消费者盛宴。销售、运营、物流、生产商等都在开足马力在各大渠道备战,据统计: 消费者在期间被平均推送200+活动消息 消费者会花几个小时比较、提前筛选自己中意产品 除了线上外,90%线下店铺都挂出针对双十一运营活动 双十一触客渠道也呈现多样化,例如:网络店铺、短信、邮件、微信公众账号、派单与Kitty板、自提柜、智能设备(例如天猫精灵点单)、多媒体设备(例如电视或机顶盒购物)等。 面对如此多的渠道和销售方式,运营和销售如何有效掌控,并通过数字化方式进行运营是一项硬能力。让我们来看几个例子: 例子1:新用户引流 互联网经典书籍《上瘾:构建习惯养成的产品》把用户获取过程分为4个阶段:触发、行动、奖励、投入。作为最开始的触发环节,给用户群发消息是最有效的手段之一。但如何衡量转化效果呢? 我们可以在推广信息中做一个埋点,把用户点击短信带上关联信息,例如设计一个如下的URL,其中放入2个关键参数: t: 代表发送的批次编号,也可以作为渠道的标识 m:代表发送的短信号码 html://mywebsite.com/new?t=1002&m=13860394XX 当用户点点击消息访问站点时,我们在服务端访问日志中会自动记录对应信息: 202.168.1.209 - - [02/Feb/2016:17:44:13+0800] "GEThtml://mywebsite.com/new?t=1002&m=13860394XX HTTP/1.1" 200 209 - "Mozilla/5.0(Macintosh; Intel Mac OS X10_11_3) AppleWebKit/537.36(KHTML, like Gecko)Chrome/48.0.2564.97 Safari/537.36" 这样我们就能获得推广效果和转化率: 例子2:线上购买意图捕捉 在获取客户后,下一步是让用户付诸于行动。用户在浏览商品时,会有页面的停留,阅读,比较和加入购物车等操作。可以借助Web Tracking和Serve端埋点来进行静态与动态数据采集。 在静态网页和浏览器埋点: 通过JS埋点: varlogger = new window.Tracker('cn-hangzhou.log.aliyuncs.com','ali-test-tracking','web-tracking'); logger.push('customer','zhangsan'); logger.push('product','iphone6s'); logger.push('price',5500); logger.logger(); 在完成数据埋点后,我们可以在日志服务分析功能中,获得每个环节的点击数和转化数字,以衡量购买阶段的效果。 Web Tracking链接: https://help.aliyun.com/document_detail/31752.html 服务端埋点链接: https://help.aliyun.com/document_detail/28979.html 数据采集挑战 从上面例子来看,数据采集是数字化IT的基础。让我们来看一个典型的数据采集架构: 购买一批机器搭建网络服务器 为服务器搭建负载均衡设备 在网络服务器(例如Nginx)模块中使用Kafka等中间件写入数据 该方案通过无状态设计解决了高可用,按需扩容等问题,也是众多厂商采用的方案,在理想状态下运行得非常好。但在现实过程中,往往会遇到如下挑战: 步骤 模块 挑战 成本 端 | 协议封装与客户端开发 | 需要开发众多SDK,例如Android、IOS、嵌入式等 | 研发成本、运维 |
日志服务LogHub功能 阿里云日志服务(Log Service,/原SLS) 是针对实时数据一站式服务,其中的LogHub模块就是专为数据采集定制的功能,该功能有如下特点: 1. 30+实时采集手段 LogHub提供 30+种开箱即用的数据采集手段 ,包括直接和云产品打通的日志、移动端、服务端、程序、SDK、网页、嵌入端等,以下我们分别介绍下最常用的四种与试用场景: 方式 应用场景 当前规模 优势 Logtail | X86服务器采集 | 百万-千万 | 功能强 | Android/IOS SDK C Producer Library | Web Tracking | 移动端数据采集、手机、POS机等 硬件资源受限的系统(如 IoT、嵌入式、RTOS等) | 网页静态数据采集 | 千万DAU 千万-亿级 | 千万-亿级 | 断点续传 资源消耗低 | 轻量级,无验证 | 1.1 Logtail(部署量最大Agent) Logtail安装在X86设备上,通过中央服务器进行管控,只需点点鼠标或API就能够在几秒钟内对百万机器下达数据采集指令。Logtail目前每天有几百万的运行实例,适配所有Linux版本、Window、Docker、K8S等环境;支持几十种数据源对接,关于Logtail功能可以参见 介绍文档 。 得益于阿里巴巴集团场景的不断锤炼,Logtail和开源Agent(例如Fluentd、Logstash、Beats)相比,性能、资源消耗、可靠性和多组合隔离等硬指标上较为领先。可以满足国内最大的直播网站、最大的教育类网站、最大的金融类网站的苛刻要求。和开源Agent主要差距在于日志格式的丰富性(当前Logtail版本已支持Logstash、Beats协议,既可以将这些开源插件无缝跑在Logtail之上)。 2018年Logtail针对Docker/K8S等场景做了非常多的适配工作,包括: 一条命令一个参数即可实现部署,资源自动初始化 支持CRD方式配置,支持K8S控制台、kubectl、kube api等,与K8S发布、部署无缝集成 K8S RBAC鉴权,日志服务STS鉴权管理 可以自豪地说,Logtail方案是K8S下所有Agent中最全,最完整的之一,感兴趣可以参见 LC3视角:Kubernetes下日志采集、存储与处理技术实践 : 1.2 C Producer Library系列(面向嵌入式设备新秀) 除X86机器外,我们可能会面对各种更底层IoT/嵌入式设备。针对这种场景,LogHub推出C Producer Library系列SDK,该SDK可以定位是一个“轻量级Logtail”,虽没有Logtail实时配置管理机制,但具备除此之外70%功能,包括: 多租户概念:可以对多种日志(例如Metric,DebugLog,ErrorLog)进行优先级分级处理,同时配置多个客户端,每个客户端可独立配置采集优先级、目的project/logstore等 支持上下文查询:同一个客户端产生的日志在同一上下文中,支持查看某条日志前后相关日志 并发发送,断点续传:支持缓存上线可设置,超过上限后日志写入失败 专门为IoT准备功能: 本地调试:支持将日志内容输出到本地,并支持轮转、日志数、轮转大小设置 细粒度资源控制:支持针对不同类型数据/日志设置不同的缓存上线、聚合方式 日志压缩缓存:支持将未发送成功的数据压缩缓存,减少设备内存占用 关于C Producer Library的更多内容参见目录: https://yq.aliyun.com/articles/304602 目前针对不同的环境(例如网络服务器、ARM设备、以及RTOS等设备)从大到小我们提供了3种方案: 在X86以及ARM设备测试场景中,C-Producer系列SDK能在稳定服务情况下,极大优化性能和内存空间占用,胜任只有4KB运行内存的火火兔场景(Brick版本)。 使用C Producer系列的客户有: 百万日活的天猫精灵、小朋友们最爱的故事机火火兔、 遍布全球的码牛、钉钉路由器、 兼容多平台的视频播放器、 实时传输帧图像的摄像头等。 这些智能SDK每天DAU超百万,遍布在全球各地的设备上,一天传输百TB数据。关于C Producer Library 的细节可以参考这篇文章: 智能设备日志利器:嵌入式日志客户端(C Producer)发布 。 2. 服务端多地域支持 客户端问题解决了后,我们来看看服务端。LogHub 是阿里云化基础设施,在 全球阿里云所有Region都有部署 。确保无论业务在哪个Region开展,都可以选择就近的Region。 例如欧盟、新加坡等国家有相关的法律约束数据不能出境,对于这类场景我们可以选择合适的数据中心来提供服务。对于同Region下ECS、Docker等服务,我们可以直接使用同Region服务进行处理,节省跨洋传输的成本。 3. 全球加速网络 对全球化业务而言,用户可能分布在全球各地(例如游戏,App、物联网等场景),但在构建数仓业务的过程中,我们往往需要对数据进行集中化处理。例如一款移动App用户散布在全国各省市 将日志采集中心定在杭州,那对于西南(例如成都)用户而言,远程进行日志传输的延时和质量难以保障 将日志采集中心定在成都,那对位于东部和东北用户又难以权衡,更不用说中国的三大运营商链路质量的影响 2018年6月初LogHub 联合 CDN 推出了一款全球自动上传加速方案:“基于阿里云CDN硬件资源,全球数据就近接入边缘节点,通过内部高速通道路由至LogHub,大大降低网络延迟和抖动 ”。只需简单配置即可构建起快速、稳定的全球数据采集网络,任意LogHub SDK都可以通过Global域名获得自动加速的支持。 在我们测试case中,经过全球7个区域对比整体延时下降50%,在中东,欧洲、澳洲和新加坡等效果明显。除了平均延时下降外,整体稳定性也有较大提升(参见最下图,几乎没有任何抖动)。确保如何在世界各地,只要访问一个统一域名,就能够高效、便捷将数据采集到期望Region内。 4. 服务端弹性伸缩 在解决网络接入问题后,我们把问题聚焦在服务端流量这个问题上。熟悉Kafka都知道,通过Partition策略可以将服务端处理资源标准化:例如定义一个标准的单元Partition或Shard(例如每个Shard固定5MB/S写,10MB/S读)。当业务高峰期时,可以后台Split Shard以获取2倍的吞吐量。 这种方法看起来很工程化,但在使用过程中有两个难以绕开的现实问题: 业务无法预测:事先无法准确预估数据量,预设多少个shard才合适呢 人的反应滞后:数据量随时会突增,人不一定能够及时处理,长时间超出服务端负载能力会有数据丢失风险 针对以上情况,LogHub提供了全球首创Shard自动分裂功能:在用户开启该功能后,后台系统实时监控每个shard的流量,如果发现一个shard的写入在一段时间内,有连续出现超过shard处理能力的情况,会触发shard的自动分裂,时刻保障业务流量。 更多细节可以参考这篇文章: 支持Shard自动分裂 5. 丰富上下游生态与场景支持 LogHub也提供丰富上下游与生态对接,包括各种主流流计算、数据仓库等引擎支持: 采集端:Logstash、Beats、Log4J等 实时消费端(流计算):Flink/Blink、Storm、Samza等 存储端(数仓):Hadoop、Spark、Presto、Hive等 通过LogHub与日志服务其他功能+产品组合,可以轻松支撑安全、运营、运维和研发对于数据处理的各种场景需求,更多可以 参考学习路径 和 用户手册 。 写在最后 日志服务是阿里自产自用的产品,在双十一、双十二和新春红包期间承载阿里云/蚂蚁全站、阿里电商板块、云上几千商家数据链路,每日处理来自百万节点几十PB数据,峰值流量达到每秒百GB, 具备稳定、可靠、低成本,生态丰富等特性。 原文链接 大数据 2018-12-17 17:05:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 2018天猫双11全球狂欢节,全天成交额再次刷新纪录达到2135亿元,其中总成交额在开场后仅仅用了2分05秒即突破100亿元,峰值的交易量达到惊人的高度,背后离不开阿里云大数据计算和存储能力的支撑。在整个交易的链路上,账单业务是一个重要的环节,尤其对商家系统来说,需要定期对账,账单子系统出现一点点问题都会影响商家的运营,2018的双十一,承载账单的消息系统把全网卖家账单系统60%的流量托付给了阿里云文件存储。在11日0点的峰值交易时刻,账单消息系统的写入流量瞬间达到日常流量的60倍以上,阿里云文件存储表现稳定,顺利扛下这一波洪峰,帮助业务系统完美度过0点的考验。本文将介绍阿里云文件存储的背景,以及文件存储是如何来保障业务系统应对高压力的。 什么是云上的NAS文件存储 在阿里云的发展早期,在云服务器ECS上运行的应用需要进行数据存储时,有两个选择: 云盘:兼容应用的IO接口,但是和物理机使用硬盘一样,云盘和ECS绑定,单块云盘只能特定ECS访问; OSS:多ECS可以共享访问,但需要应用调整IO接口,使用OSS的REST接口; 但如果应用既想保留原有的IO接口(一般是POSIX接口),又需要实现多ECS共享存储,就没有很好的解决办法。NAS文件存储在这样的背景下应运而生,针对传统企业级应用的存储需求,通过标准NAS系统协议(NFS/SMB),为ECS提供共享存储,支持随机读写以及PB级别容量,并且支持容量动态扩展,方便业务从小规模逐渐扩大过程中,不需要再担心存储容量的扩容以及运维问题。 阿里云NAS文件系统从2016年推出至今,已经应用在丰富的业务场景中,包括高HPC性能计算、Web服务和内容管理、媒体和娱乐处理工作流、容器存储、基因和生命科学数据存储处理,深度学习大数据处理等等,很好地服务了云上的客户。 NAS文件存储架构设计 阿里云文件存储是一个可共享访问,弹性扩展,高可靠,高性能的分布式文件系统,其架构设计如图1所示。 图1: 阿里云文件存储架构 整个技术栈分五层,第一层是各类计算节点(比如ECS、Docker、GPU等)不同操作系统使用标准文件协议NFS/SMB访问文件存储。第二层是阿里云网络负载均衡,把客户端请求轮转发送到前端机。第三层是负责协议处理的前端机,具备scale-out的能力。第四层是文件系统元数据管理,实现高效的数据结构保证元数据的快速操作。第五层是元数据和数据的持久化存储,使用阿里云盘古存储系统。 整个架构通过盘古保证高可靠,另外通过文件存储高效的数据和元数据管理技术实现scale-out、高可用,超高的数据访问性能以及一系列企业级存储的特性,如图2所示。 图2 阿里云文件存储特性 账单业务消息系统适配文件存储 随着云上文件存储的知名度越来越广,阿里集团的很多内部业务也开始接入文件存储,其中就包括支撑账单业务的消息系统。 架构设计 消息系统的存储本来使用的是本地盘,这样最主要的问题就是当单机故障时,存储在磁盘上的数据没法及时被其他主机访问,其他主机不能快速接管原来主机的业务,缺乏容灾的能力,对应用的影响非常大。而使用文件存储天然具有多机共享访问的能力,可以很好的解决这个问题。 但是,如果只是简简单单地做一个替换,把本地存储换成文件存储,如图3那样, 图3 本地存储替换成文件存储(共享访问) 多台ECS通过NFSv4挂载同一个文件系统,每个ECS会使用到一个文件系统里的多个子目录作为消息文件的存储空间,虽然解决了前述的容灾问题,但这个架构的问题是过于依赖单点的存储,万一单文件系统发生故障,所有消息队列的访问都会受到影响,因此需要对架构进行进一步调整。调整的基本思路就是将流量尽量打散到多个文件系统上,同时又避免对业务方软件的改造。 调整后的架构入图4所示,为业务创建多个虚拟云机房,每个虚拟云机房的消息系统存储由4个NAS文件系统来承载,消息系统计算节点ECS会同时挂载4个文件系统,并且通过软链接的方式在‘nasroot’目录下看到多个队列,对业务使用上来说,这些队列对应的目录是在同一个文件系统(原来的架构)还是多个文件系统(新的架构)是不感知的,这样就将业务需要改造的量最小化,只需要在部署时候进行相应的自动化(挂载和创建软链接)即可,但带来的好处是巨大的,万一发生单文件系统的故障,业务可以自动分流到存活的文件系统,可以有效应对各种故障场景。 图4 架构优化 细节优化 相对于使用本地盘,计算存储分离架构下,如果应对存储测的异常和故障呢?标准的NFS挂载下,如果服务端出现故障或者网络发生故障,客户端访问文件存储将会是完全hang住,直到服务或者网络恢复为止。针对这个问题,消息系统进行了相应改造,业务系统对消息的一致性保障进行了优化,可以支持写消息失败。这样就可以使用NFS的soft挂载模式,当服务端出现故障或者网络发生故障时,应用程序将不会再是完全hang住,而是能迅速监测到IOError,并立即采取对应的行动。结合前述的架构设计,应用程序能进行快速响应,把流量分流到其他存活的文件系统上,快速恢复。 双十一的考验 经过架构设计和细节优化,文件存储的scale-out能力在双十一尖峰发挥出了应有的能力,即使在0点时刻流量是平时的60倍以上,表现依然稳定,在文件存储的给力表现下,业务系统的响应依然如日常一样顺滑,完全感觉不出超大流量对系统的冲击。 总结 阿里云文件存储为云上业务提供支持标准接口(POSIX)以及标准文件访问协议(NFS,SMB)的存储服务,并且具有简单易用、安全可靠、性能和容量scale-out等特性。经过双十一的锤炼,文件存储的服务能力必将继续上升一个台阶,将提升后的能力以普惠技术的形式向云上各行各业输出,推动社会生产力的发展。 原文链接 大数据 2018-12-17 16:27:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 在人工智能飞速发展的三年里,整个网络视听产业数字化发展速度非常迅猛。大数据作为如今这个时代的产物,正不断推动整个产业的发展。网络视听行业中存在海量的数据,比如视频内容、视频浏览量、广告点击量、会员信息等等,这些数据正在不断被汇总和计算,从中可以发掘更多的机会,以提升能力和效率,并为收益带来新增长 。内容安全在整个发展过程中起着至关重要的作用,一方面需要根据国家合规要求及时做好自查以建立一个更加绿色的网络视听环境,另一方面需要建立一道坚实的安全防线抗击黑灰产。阿里云业务安全副总裁岑欣伟在第六届成都网络视听大会分论坛上这样说:“ AI赋能内容安全的价值就是用技术驱动智能化的数据分析,为营造绿色的网络视听环境加码助力。 ” 如今内容安全的建设在整个网络视听行业还存在很多问题,效率低、成本高和易漏检。随着各大视频网站,例如抖音、快手以及其他社交媒体平台上用户越来越多,内容不断增长,且形式也变得更加多样化,整个内容产能大大超出了之前的想象,因此保障平台内容的合规性非常有必要。但这样的井喷式增长体量如果还依赖于原始人力的话,无论是覆盖率还是精准度都难以达到要求,甚至对用户的体验也会产生很大影响,智能AI技术将成为催化剂,释放繁重的人力劳作,从而创造更大的市场价值。 岑欣伟在现场表示,内容安全将迎来四个发展趋势: 第一是二次元化: 00后的新生力量让内容的产出呈现更多的二次元化发展,今天很多技术在二次元方面会有很大的提升空间,其复杂构图、强烈的色彩对比甚至是夸张的动作都会给内容安全的审核带来更大的难度。 第二是版权问题 :好的IP内容会创造更大的流量,因此其版权也会变得越来越贵。未来区块链技术与AI融合的新技术也许可以应用在视频内容的版权保护上。 第三是黑灰产: 这支看不见的的黑手在中国一年有将近千亿的收益,这是一个隐藏在华丽外表背后很深的市场。今天大量的问题都不仅是平台管理问题,还有社会问题及其他多元化因素产生的问题,因此要从源头管理,无论是传播链路还是落实到实体,高效的内容管控势在必行。 第四是创新技术: 技术是一把双刃剑,给产业带来升级和变革的同时,也可能会被不法分子利用,通过其中某一种特性来达到不法目的。 为了满足不同类大众的观赏需求,未来的内容势必会越来越丰富。如何更高效的执行内容安全,如何更好的响应政策执行检查,如何做到更全面的覆盖,如何应对与专业灰黑产团伙的对抗,如何实现内容安全的高性价比等等一系列问题是每个企业需要思考的。 我们需要一扇安全大门,一扇对自己内容进行监督管理的安全大门,阿里云内容安全大脑以内容全覆盖、风险全覆盖、处置全覆盖为目标,高效率、高质量的为用户提供内容风险监测能力,确保用户的业务合规。云上内容安全的优势会显得更加的明显 。 岑欣伟这样说道,同时他还指出了内容安全大脑的5大核心优势: 1. 标签丰富,自由定制。 提供文本、图像、视频、音频、网页等多维度内容检测,覆盖涉政、涉恐、色情、垃圾广告等违规风险,并支持自定义标签及模型训练。 2. 实时情报,全网联动。 基于海量数据对高危情报进行监测,对新风险实现模型的快速迭代,确保审核能力紧跟社会热点,确保业务合规。 3. 性价比高, 根据用户实际业务体量,可以快速扩容至上万级别QPS。同时,自动化精准识别,节省99%以上的审核人力,毫秒级结果返回。 4. 智能运营, 安全人才稀缺,阿里云内容安全大脑可使用少量的专业人员为10000多家用户优化复杂的算法策略,享受与阿里自身业务同规格的内容检测服务。 5. 云上默认安全,一键开启。 使用阿里云OSS、CDN产品的用户,可以在云控制台一键启用图片风险检测,操作简便易用。 据岑欣伟介绍, 阿里云内容安全大脑每天处理信息量数十亿条,节省99%以上人力成本,支持100种以上风险场景检测,实现对视频内容的多模态智能识别,超大计算能力,精准识别能力,快速应急能力,帮助用户更好的实现内容监督。 “一首诗一幅画都可能是中华五千年文化底蕴的沉淀,安全则在整个过程中起着重要的保驾护航作用,我希望阿里云在安全领域可以多出一份力,帮助我们做得更完美、更清晰、更安全。”最后岑欣伟表示。 原文链接 大数据 2018-12-17 16:00:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 本文介绍如何使用软件的 流程图模式 ,免费采集百度搜索多个关键字的信息数据。 软件下载网址:www.houyicaiji.com 采集结果预览: 下面我们来详细介绍一下如何使用流程图模式,采集在百度输入多个关键字后的数据,具体步骤如下: 步骤一:新建采集任务 1、复制 百度搜索 的网页地址(需要搜索结果页的网址,而不是首页的网址) 点此 了解关于如何正确地输入网址。 2、新建流程图模式采集任务 您可以在软件上直接新建采集任务,也可以通过导入规则来创建任务。 点此 了解如何导入和导出采集规则。 步骤二:配置采集规则 1、设置多个关键字循环任务 在流程图模式输入网址新建任务之后,我们点击搜索框,然后在左上角出现的操作提示框内输入要采集的文字,在这里我们输入关键词。 点此 了解输入文字组件的更多内容。 关键词输入之后,在页面上出现了输入文字组件,此时只设置了一个关键词,我们需要设置多个关键词的搜索,因此需要拖动一个循环组件到任务栏,然后将输入文字组建拖动到循环组件内,设置循环条件。 我们在循环组件上选择文本列表,然后在框内输入要采集的关键词,设置文字输入组件使用文本内的循环。 点此 了解更多循环组件的内容 2、设置提取字段数据 输入多个关键字循环设置好之后,我们设置需要提取的字段数据,点击网页上的字段,在左上角的操作提示框内选择提取全部元素。 抽取出列表页上的字段之后,我们可以右击字段进行相关设置,包括修改字段名称、增减字段、处理数据等。 点此 了解更多关于提取字段组件的内容。 我们需要采集标题、链接、摘要及时间等信息,字段设置效果如下: 3、设置下一页 我们采集出了单页的数据,现在需要采集下一页的数据,我们点击页面上的“下一页”按钮,在左上角出现的操作提示框内选择“循环点击下一页”。 点此 了解更多关于翻页的内容。 4、设置完整任务 由于流程图模式是一个循环套循环的过程,并列的循环任务无法正常运行,我们需要把抽取所有页面的循环拖入到输入多个关键字的循环内,拖动情况如下: 步骤三:设置并启动采集任务 1、设置采集任务 完成了采集数据添加,我们可以开始启动采集任务了。点击开始采集之后跳出任务栏,任务栏界面上有“更多设置”的按钮,我们可以点击进行设置,也可以按照系统默认的设置。 点击“更多设置”按钮,在弹出的运行设置页面中我们可以进行运行设置和防屏蔽设置,系统默认设置“2”秒请求等待时间,防屏蔽设置就按照系统默认设置,然后点击保存。 2、启动采集任务 点击“保存并启动”按钮,可在弹出的页面中进行一些高级设置,包括定时启动、自动入库和下载图片,本次示例中未使用到这些功能,直接点击“启动”运行爬虫工具。 点此 深入了解什么是定时采集。 点此 深入了解什么是自动入库。 点此 深入了解如何下载图片。 【温馨提示】 免费版本可以使用非周期性定时采集功能,下载图片功能是免费的。个人专业版及以上版本可以使用高级定时功能和自动入库功能。 3、运行任务提取数据 任务启动之后便开始自动采集数据,我们从界面上可以直观的看到程序运行过程和采集结果,采集结束之后会有提醒。 步骤四:导出并查看数据 数据采集完成后,我们可以查看和导出数据,软件支持多种导出方式(手动导出到本地、手动导出到数据库、自动发布到数据库、自动发布到网站)和导出文件的格式(EXCEL、CSV、HTML和TXT),我们选择自己需要方式和文件类型,点击“确认导出”。 点此 深入了解如何查看和清空采集数据。 点此 深入了解如何导出采集结果。 【温馨提示】: 所有手动导出功能都是免费的。个人专业版及以上版本可以使用发布到网站功能。 再为您推荐几个相关的采集教程: 如何采集百度搜索的多个关键字的数据(流程图模式) 如何免费采集今日头条信息数据 如何免费采集淘宝商品信息数据 大数据 2018-12-17 11:31:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 首先,Hive的group by和count(distinct)都是去除重复的数据,某种程度上来说,两者产生的结果是一样的。 实例代码: select a,count(distinct b) from t group by a select tt.a,count(tt.b) from (select a,b from t group by a,b)tt group by tt.a 上面两句代码产生的结果是一样的,但是两者从效率和空间复杂度上来讲,是有很大的差别的。 distinct会将b列所有的数据保存到内存中,形成一个类似hash的结构,速度是十分的块;但是在大数据背景下,因为b列所有的值都会形成以key值,极有可能发生OOM。 group by会先把b列的值进行排序,如果以快速派序来说的话,他的空间复杂度就是O(1),时间复杂度是O(nlogn),这样在大数据的环境下,只有排序阶段会比较慢,时间复杂度是O(nlogn)。 两者比较来说,distinct 耗费内存,但是效率极高,但是数据较大时,可能会产生OOM;group by如果在时间复杂度允许的情况下,可以展现出突出的空间复杂度的优势。 使用distinct会将所有的数据都shuffle到一个reducer里面,group by会分组,将数据分布到多台机器上执行。 最后,对于Hive来说,含有distinct的HQL语句,如果遇到瓶颈,想要调优,第一时间都是想到用group by来替换distinct来实现对数据的去重。 大数据 2018-12-17 10:50:03 「深度学习福利」大神带你进阶工程师,立即查看>>> 1.Flink窗口 Window Assigner分配器。 窗口可以是时间驱动的(Time Window,例如:每30秒钟),也可以是数据驱动的(Count Window,例如:每一百个元素)。 一种经典的窗口分类可以分成: 翻滚窗口(Tumbling Window,无重叠),滚动窗口(Sliding Window,有重叠),和会话窗口(Session Window,活动间隙)。 基于时间的窗口 (1)Tumbling Windows https://ci.apache.org/projects/flink/flink-docs-master/dev/stream/operators/windows.html#tumbling-windows (2)Sliding Windows https://ci.apache.org/projects/flink/flink-docs-master/dev/stream/operators/windows.html#sliding-windows (3)Session Windows https://ci.apache.org/projects/flink/flink-docs-master/dev/stream/operators/windows.html#session-windows (4)Global Windows https://ci.apache.org/projects/flink/flink-docs-master/dev/stream/operators/windows.html#global-windows 基于数据个数的窗口 (5)CountWindows /** * Windows this {@code KeyedStream} into tumbling count windows. * * @param size The size of the windows in number of elements. */ public WindowedStream 2.Flink时间类型 流处理程序在时间概念上总共有三个时间概念: (1) 处理时间 处理时间是指 每台机器的 系统时间 ,当流程序采用处理时间时将使用运行各个运算符实例的机器时间。处理时间是最简单的时间概念,不需要流和机器之间的协调,它能提供最好的性能和最低延迟。然而在分布式和异步环境中,处理时间不能提供消息事件的时序性保证,因为它受到消息传输延迟,消息在算子之间流动的速度等方面制约。 (2) 事件时间 事件时间是指事件在其 设备 上发生的时间 ,这个时间在事件进入 flink 之前已经嵌入事件,然后 flink 可以提取该时间。基于事件时间进行处理的流程序可以保证事件在处理的时候的顺序性,但是基于事件时间的应用程序必须要结合 watermark 机制。基于事件时间的处理往往有一定的滞后性,因为它需要等待后续事件和处理无序事件,对于时间敏感的应用使用的时候要慎重考虑。 (3) 注入时间 注入时间是 事件注入到 flink 的时间 。事件在 source 算子处获取 source 的当前时间作为事件注入时间,后续的基于时间的处理算子会使用该时间处理数据。相比于事件时间,注入时间不能够处理无序事件或者滞后事件,但是应用程序无序指定如何生成 watermark。在内部注入时间程序的处理和事件时间类似,但是时间戳分配和 watermark 生成都是自动的。 区别如下图 (4) WaterMark机制 由于Flink的数据可能会有乱序的可能,所有Flink引入WaterMark机制来一定程度上避免乱序,Watermark是代表当前系统对数据的一个处理进度。 StreamExecutionEnvironment.java watermark更新的时间间隔,从源码中可以看到是默认是200ms /** * Sets the time characteristic for all streams create from this environment, e.g., processing * time, event time, or ingestion time. * * If you set the characteristic to IngestionTime of EventTime this will set a default * watermark update interval of 200 ms. If this is not applicable for your application * you should change it using {@link ExecutionConfig#setAutoWatermarkInterval(long)}. * * @param characteristic The time characteristic. */ @PublicEvolving public void setStreamTimeCharacteristic(TimeCharacteristic characteristic) { this.timeCharacteristic = Preconditions.checkNotNull(characteristic); if (characteristic == TimeCharacteristic.ProcessingTime) { getConfig().setAutoWatermarkInterval(0); } else { getConfig().setAutoWatermarkInterval(200); } } 大数据 2018-12-17 00:38:00 「深度学习福利」大神带你进阶工程师,立即查看>>> ClassPathXmlApplicationContext 与 FileSystemXmlApplicationContext 用了这么久的框架,是时候搞一下源码了,一般最初接触spring 从以下步骤开始 创建一个bean类 并创建 ooxx.xml 之类的spring bean描述文件 根据上面发现加载xml有两种方式 ClassPathXmlApplicationContext FileSystemXmlApplicationContext 关系如下: 两者具有相同血脉的兄弟关系, 一种通过classpath来进行加载,底层是通过ClassLoader 来进行加载资源的。一种是通过文件IO来加载并读取配置xml的。 ClassPathXmlApplicationContext 通过classpath 或者相对路径来加载bean 定义文件 资源路径 使用 configLocations 相对路径使用 (path,Class>) FileSystemXmlApplicationContext 改写了 DefaultResourceLoader 的 getResourceByPath(String path) 方法 原本默认采用 ClassPathResource 来加载 /** * Resolve resource paths as file system paths. * Note: Even if a given path starts with a slash, it will get * interpreted as relative to the current VM working directory. * This is consistent with the semantics in a Servlet container. * @param path path to the resource * @return the Resource handle * @see org.springframework.web.context.support.XmlWebApplicationContext#getResourceByPath */ @Override protected Resource getResourceByPath(String path) { if (path.startsWith("/")) { path = path.substring(1); } return new FileSystemResource(path); } Can be overridden in subclasses, e.g. for turning off XML validation * or using a different XmlBeanDefinitionParser implementation. * @param reader the bean definition reader used by this context * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass */ protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) { reader.setValidating(this.validating); } The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory} * method; hence this method is just supposed to load and/or register bean definitions. * @param reader the XmlBeanDefinitionReader to use * @throws BeansException in case of bean registration errors * @throws IOException if the required XML document isn't found * @see #refreshBeanFactory * @see #getConfigLocations * @see #getResources * @see #getResourcePatternResolver */ protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { Resource[] configResources = getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); } String[] configLocations = getConfigLocations(); if (configLocations != null) { reader.loadBeanDefinitions(configLocations); } } 大数据 2018-12-15 20:37:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 2018年Q3 MaxCompute重磅发布了一系列新功能。 本文对主要新功能和增强功能进行了概述。 实时交互式查询:Lightning on MaxCompute 生态兼容:Spark on MaxCompute New SQL 新特性发布 Python UDF全面开放 OSS外表功能正式商业化 Hash Clustering 存储技术升级:zstd压缩算法 原文链接 大数据 2018-12-14 16:27:00 「深度学习福利」大神带你进阶工程师,立即查看>>> 一台服务器,不管是物理机还是虚拟机,必不可少的就是内存,内存的性能又是如何来衡量呢。 1. 内存与缓存 现在比较新的CPU一般都有三级缓存,L1 Cache(32KB-256KB),L2 Cache(128KB-2MB),L3 Cache(1M-32M)。缓存逐渐变大,CPU在取数据的时候,优先从缓存去取数据,取不到才去内存取数据。 2. 内存与时延 显然,越靠近CPU,取数据的速度越块,通过LMBench进行了读数延迟的测试。 从上图可以看出: Intel(R) Xeon(R) Platinum 8163 CPU @ 2.50GHz 这款CPU的L1D Cache,L1I Cache为32KB,而L2 Cache为1M,L3为32M; 在对应的Cache中,时延是稳定的; 不同缓存的时延呈现指数级增长; 所以我们在写业务代码的时候,如果想要更快地提高效率,那么使得计算更加贴近CPU则可以获取更好的性能。但是从上图也可以看出,内存的时延都是纳秒为单位,而实际业务中都是毫秒为单位,优化的重点应该是那些以毫秒为单位的运算,而内存时延优化这块则是长尾部分。 3. 内存带宽 内存时延与缓存其实可谓是紧密相关,不理解透彻了,则可能测的是缓存时延。同样测试内存带宽,如果不是正确的测试,则测的是缓存带宽了。 为了了解内存带宽,有必要去了解下内存与CPU的架构,早期的CPU与内存的架构还需要经过北桥总线,现在CPU与内存直接已经不需要北桥,直接通过CPU的内存控制器(IMC)进行内存读取操作: 那对应的内存带宽是怎样的呢?测试内存带宽有很多很多工具,linux下一般通过stream进行测试。简单介绍下stream的算法: stream算法的原理从上图可以看出非常简单:某个内存块之间的数据读取出来,经过简单的运算放入另一个内存块。那所谓的内存带宽:内存带宽=搬运的内存大小/耗时。通过整机合理的测试,可以测出来内存控制器的带宽。下图是某云产品的内存带宽数据: ------------------------------------------------------------- Function Best Rate MB/s Avg time Min time Max time Copy: 128728.5 0.134157 0.133458 0.136076 Scale: 128656.4 0.134349 0.133533 0.137638 Add: 144763.0 0.178851 0.178014 0.181158 Triad: 144779.8 0.178717 0.177993 0.180214 ------------------------------------------------------------- 内存带宽的重要性自然不言而喻,这意味着操作内存的最大数据吞吐量。但是正确合理的测试非常重要,有几个注意事项需要关注: 内存数组大小的设置,必须要远大于L3 Cache的大小,否则就是测试缓存的吞吐性能; CPU数目很有关系,一般来说,一两个核的计算能力,是远远到不了内存带宽的,整机的CPU全部运行起来,才可以有效地测试内存带宽。当然跑单核的stream测试也有意义,可以测试内存的延时。 4. 其他 内存与NUMA的关系:开启NUMA,可以有效地提供内存的吞吐性能,降低内存时延。 stream算法的编译方法选择:通过icc编译,可以有效地提供内存带宽性能分。原因是Intel优化了CPU的指令,通过指令向量化和指令Prefetch操作,加速了数据的读写操作以及指令操作。当然其他C代码都可以通过icc编译的方法,提供指令的效率。 作者: ecs西邪 原文链接 本文为云栖社区原创内容,未经允许不得转载。 大数据 2018-12-14 15:47:00 |
---|