亚马逊AWS官方博客
为员工进行云培训时的11条箴言
Tell me and I forget. Teach me and I remember. Involve me and I learn. – Benjamin Franklin
(告诉我,我会忘记;演示给我,我会记住;但让我参与其中,我才能真正学会。 – 本杰明﹒富兰克林)
作为一个CCMO,培训你的员工就能使他们加快你的上云历程吗?每个组织的培训历程都是独一无二的,但我发现在这方面做得很好的一些组织中,它们是有一些共性的。从这些共性中我们可总结出11条箴言:
1.从基础的但有意义的事情开始。当你的团队完成一些业务相关的重要事情时,他们将很快意识到云技术的实际好处。我见过很多公司的项目进展慢于预期,因为他们过于注重细枝末节。你肯定不想把全部身家赌在前几个项目上,你将会想从几个能很好阐明业务好处的项目开始做起。其实有很多适合刚开始着手进行的项目,例如一个简单的网站、一个移动应用、一个可以便捷访问数据的API或者一个文件备份及灾难恢复的改进。如果你的员工培训基于实际的应用,那你的团队将能够更快地把他们所学的东西应用于更多项目。
2.利用Amazon Web Services Training(AWS Training)。AWS可提供良好的培训计划。这些计划已经帮助了上千家公司增强它们的云技能。AWS将每一个培训视为一次提升的机会,并且开发了不同的课程和一系列交付机制以便客户能定制培训计划来满足他们的具体需求。当我在Dow Jones时,我们使用现在称为AWS Technical Fundamentals的课程来培训我们团队的几乎每一个技术人员。除了让我们的员工具备新的能力之外,这个培训也消除了员工对一些项目开始时的未知的恐惧。
3.给团队时间去尝试。构建一种探索文化是这段旅途中的下一个最佳实践,这在激励你的员工去学习时尤其重要。创新来源于尝试,因为云消除了尝试新事物时的前期投入,所以没有什么能够阻止你的团队创造你行业中的新产品。给你的团队足够的自由空间来以全新的方式实现已有的项目。
4.设置目标来鼓励学习和实践。大部分公司为员工设定目标或KPI并将此与员工绩效挂钩。使用这些现有机制来巩固你的策略,并形成以后的行为。你可以设定相关培训课程的完成目标,多少预算被释放,或者通过利用适当的云架构如何改善你的卓越运营。这样做表明,领导很注重让每个人都有机会尝试和学习。
5.设置时间限制,跟上步伐。当你向实验文化转变时这一点尤其重要。每天结束时,以结果为导向。你可以通过为每个项目设定最后期限帮助你的团队成员平衡试验和他们的现有知识。有时候你的团队会因为这些约束而做出一些折衷,随着项目的进行,你需要制定一个如何应对这些折衷的机制。但是你的团队会在将来的项目中不断学习并提高能力。
6.定位并处理变革阻力。所有这些因素都旨在通过给予你的员工成功所需的工具来抑制他们对变革的抵触。但是即使有这些机会,你的组织中也可能会有对此持续抵触的人。观察并理解来自你的团队的担忧,以开放的心态对待有效的和无效的,迅速处理不必要的摩擦。这也是我下一个要谈的。
7.别害怕给人新的角色。以有意义的方式迁移到云不仅是技术变革更是文化变革。我发现给人一个担当新角色的机会将帮助他们克服对变革的抵抗。我倾向于首先观察公司的内部,因为习以为常的知识是一种昂贵的且不必要的损失。在我在Bloomberg任职的11年间,我担任了6个不同且差异很大的角色。有数不清的机会是我在那里呆了那么久的原因之一。想方设法给员工新的机会将让他们保持参与并帮助留住员工。
8.向你的员工展示他们应该如何融入伟大的构想。当你知道你的工作是如何融入组织的大局时,会很容易激发你对工作的热情。确保你考虑到了每个角色并且沟通过他对你的团队有多大意义。再次强调,我期待看到你的组织如何权衡部门和/或个人目标与大局的关系,并设法为每个人量身定做。
9.深入行业活动,看看别人在做什么。大多数人从别人的成功和失败中学到很多。至今我已经为大公司开发基于云的策略有五年时间了,现在我也惊异于我参加AWS re:Invent、 AWS Summits或其他技术竞赛所学到的知识。给你员工时间来让他们组织并带着新的想法回去。设想许多的、甚至有一些你根本不会去实施的想法,这是创造有教育意义的时刻并强化你策略的好方法。
10.向你的搭档学习。在AWS Partner Network中有数以万计的不同组织。他们中许多可能已经和你们是稳定的合作伙伴关系,但那可能也有值得你们学习的新的合作伙伴。我很惊异于看到很多大公司正转变成小的、年轻的、诞生于云的,像系统集成商Cloudreach、2nd Watch、Minjar,加速推进云策略并改变它们的IT文化。
11.在你的组织中制度化具有你特色的培训。当你推进云进程时,你会希望看到你的组织中的一些团队或个人想与他人分享他们所学到的。这将来自你卓越的云中心。我在Dow Jones时我们的DevOps团队定期举行DevOps日,在那里他们相互分享他们开发的云的实践、架构、管理模型等。跟我谈过的其他几家世界500强企业也已经建立了专门针对他们组织的类似的计划。
作者介绍

史蒂芬﹒奥本
斯蒂芬·奥本 (Stephen Orban) 于 2014 年9月加入亚马逊AWS 担任企业战略总经理。奥本与多名企业技术高管合作,在云如何实现业务成果、加快创新和简化流程方面进行经验和战略分享。在加入亚马逊AWS 之前,奥本曾在道琼斯担任首席信息官 (CIO)一职,他通过借力 AWS 和其他软件即服务 (SaaS) 合作伙伴,引入现代软件开发方法、实现降低成本、执行云优先政策。这些转型变革加快了产品开发周期并提高了全部业务线的生产能力,这其中就包括《华尔街日报》、MarketWatch.com、道琼斯通讯社及Factiva。奥本还曾在彭博有限合伙公司(Bloomberg LP)工作 11 年,并且在股权和消息平台担任不同的领导职务;2008 年,奥本创建彭博体育(Bloomberg Sports)并担任首席技术官 (CTO)。
协同合作伙伴 合力加速上云战略
“You can do what I cannot do. I can do what you cannot do. Together we can do great things.” -Mother Teresa
(你能做我所不及的,我能做你所不及的。双方合力,我们可以做些伟大的事情。– 修女特蕾莎)

不同的组织采取不同的方法与第三方进行专业技术合作。有些组织偏向于构建自己的技术;而另一些则将部分或全部研发工作外包,并将他们的技术运营交给第三方。不论你的组织处于什么位置,几乎可以肯定的是你与少数硬件、工具及云服务提供商合作开发针对内部和外部客户的产品和服务。
我已经与数百名在过去几年中不断发展其组织技术战略的高管交谈过,许多人开始重新审视自己的合作方式,因为他们开始了解云计算如何能够帮助他们改变自己的业务。这篇文章探讨了一些我观察到的云技术是如何改变整个技术圈的以及关于吸引合作伙伴的话题。
关注快速增长的生态系统
云生态系统的快速增长不断的令我感到惊讶。最近四年我参加了AWS re:Invent,每次我都对比前一年更大的合作伙伴规模感到惊讶。从全局来看,从2012年到2015年,合作伙伴的展位数量增长了一倍多,全部走完去了解最新的工具和技术从原来需要一个小时增长到了一天时间。没有更好的领域更适合风投来投资这一市场了。
貌似在这种快速增长的生态系统中寻找适合你的合作伙伴很难,但有多个供应商争夺你的业务对你也会是有利的。你的AWS客户经理和我们的AWS合作伙伴目录可以帮助你缩小选择范围,AWS Marketplace能够帮助你在几秒内从广泛的供应商和类别中发现并部署解决方案。
改变你的文化
现如今看到大型组织变得乐意与资金缺乏的、 “不可靠”的小型组织合作,来创建面向企业的工具、专业服务和管理服务等,这种现象是令人鼓舞的。当我在十五年前开始代表我的组织购买技术时,我被告知只能与规模大的公司长期合作。现在我看到很多财富500强公司与那些比我四岁女儿还年轻的公司合作,帮助他们处理最繁杂的问题。在一些情况下,这样做会帮助企业改变它们的整个业务。
当许多技术主管带领它们的组织走向数字化和客户至上的方向时,他们意识到如果可以接受年轻的基于云的供应商的一些文化,他们将可以实现更加迅速地反应。当我在Dow Jones担任CIO时,我和AWS合作的主要动机是吸收一些亚马逊的文化。我想要的是使亚马逊具备能够快速定位顾客、迅速反应的工具。我也迫切想构建一个DevOps文化来鼓励尝试。许多年轻的供应商—2nd Watch, Cloudreach, Cloud Technology Partners, Minjar, New Relic, App Dynamics, Chef, Puppet, CloudEndure,也出于同样的原因在发掘新的业务。
这并不是说现存的大型工具和服务提供商不能快速利用这种转变的优势。在许多情况下,它更适合利用现有的关系来改造业务或文化。
在你关注的领域寻找可靠的合作伙伴
你应该始终致力于与你业务目标相一致的组织合作。如果你正想具有DevOps能力,并且希望你的团队学会怎样“运行他们所构建的”,例如,确保你的合作伙伴能够帮助你具有像他们所展示的那样的能力。这也是AWS开发了AWS认证计划的原因之一。我们希望确保你在我们的平台上能成功,这个计划会协助你找到能帮你在这些领域取得成功的合作伙伴,这些领域也是你的组织特别关注的。我们现在正在这个生态系统中的一些领域开发认证系统,如DevOps、移动、安全、数字媒体、市场和商务、大数据、存储、健康管理、生命科学、微软工作负载、SAP、Oracle等。
不论你的组织处于什么合作状态,我们都乐于帮助你找到合适的合作伙伴来实现你的目标。
作者介绍

斯蒂芬·奥本
斯蒂芬·奥本 (Stephen Orban) 于 2014 年9月加入亚马逊AWS 担任企业战略总经理。奥本与多名企业技术高管合作,在云如何实现业务成果、加快创新和简化流程方面进行经验和战略分享。在加入亚马逊AWS 之前,奥本曾在道琼斯担任首席信息官 (CIO)一职,他通过借力 AWS 和其他软件即服务 (SaaS) 合作伙伴,引入现代软件开发方法、实现降低成本、执行云优先政策。这些转型变革加快了产品开发周期并提高了全部业务线的生产能力,这其中就包括《华尔街日报》、MarketWatch.com、道琼斯通讯社及Factiva。奥本还曾在彭博有限合伙公司(Bloomberg LP)工作 11 年,并且在股权和消息平台担任不同的领导职务;2008 年,奥本创建彭博体育(Bloomberg Sports)并担任首席技术官 (CTO)。
畅谈CIO该如何合并业务和技术
“以始为终。” — 史蒂芬·柯维(Stephen R. Covey)
与以往相比,现在成功的技术管理人员必须帮助其负责执行的同事了解技术如何融入——或者,更好地促进——他们的业务。向组织阐明这样的思考,其实就是向你的执行同事阐明你有关于组织的业务目标的指令,以及你是这个执行团队的关键成员。
目前的商业格局正在被一些公司打破。因为创建和运营这些公司的管理人员不仅懂得如何让技术融入业务,而且定义了技术在他们整个行业中扮演的角色:酒店行业的AirBnb,叫车服务行业的Uber,智能家居行业的Nest Labs,存储领域的Dropbox就是几个相关的例子。这对传统行业跟上步伐造成了压力,同时也给IT管理人员提供了无处不在的机会。没有人能比那些整个职业生涯都在从事技术工作的人更适合来阐述如何使用技术来满足日益增长的市场需求。这对我们这些已经在大公司度过了大部分职业生涯的人尤其如此。我们讲企业术语,了解哪些约束是硬性的,哪些是弹性的,以及对于每个C级同行你必须做什么。让它们的技术主管在幕后工作的企业已经不可能成功了。
而且,因为云带走了很多传统上与企业IT相关联的未分化繁重负担,所以现在的IT管理人员可以投入更多的时间和资源来从事那些驱动业务和保持组织竞争力的活动。云正是这些颠覆性力量的关键因素。使用相同的要素不一定会带给你拓展业务的想法,但它会为开放竞争环境提供了更多的可能性。
对于那些希望带领自己的组织使用云的人们,我提供以下一些观点:
与你的同事换位思考(Empathize with your peers)
云不仅仅是一个技术转变。它更是每一个管理层人员应该关注的业务转变。你的职责是来考虑云会如何影响你的执行团队的职责或者考虑它可能会带来什么影响。
我不可能在一篇文章里覆盖所有类型的管理者,但是:
首席财务官(CFO)通常被较低的前期成本以及只支付你所使用的东西所吸引。我见过很多因为逐月变化的成本导致的不和谐,但我总是发现特别是当你从容量规划和维护活动的负担中解脱出来时,总的成本会是很低的。随着时间的增长,在产品研发(资产创造)过程中,能够每个月与管理者紧密合作、了解更多成本预期的环境、管理资源的使用、交错购买RI、考虑如何核算劳动力成本等,正在成为关注的焦点。
首席营销官(CMO)通常希望保持公司的品牌新颖,并对不断变化的市场情况做出反应。把品牌网站从每月更新一次变成一天更新几次会带来什么影响?一个可无限扩展的数据仓库将如何帮助CMO更好地了解他们的客户?如果几乎没有什么代价,他们会在一小部分用户身上做什么尝试?
人力资源副总裁(VPs of HR)想看到的是你能照顾好你的员工以及你如何招聘新的人才。充分利用AWS培训与认证(AWS Training and Certification),并随时让我们的专业知识培训成为你的培训课程的一部分。我将在后续有关这个话题的文章中探讨如何教育你的员工。而且只要愿意去学习,你的团队的任何人都可以帮助你去完成这种培训。此外,还能了解参与此培训的其他公司是如何招聘新员工及如何管理老员工的过渡。比如,如何让DevOps融入你的组织,以及“运行你所构建的(run-what-you-build)”意味着什么?
CEO关注所有这些事情,以及如何让公司保持竞争力。用你从其他高管所学的东西来帮助塑造一个完整的视界,并用现代科技展示如何实现。如此一来,你将可以在同样的限制下做一些不可能完成的事情。
在Dow Jones,我设立了一个目标,每个月与几个管理者共餐。在这段时间里,我只听取他们的受挫经历。我用我所学的来调整我们的策略,并且确保我向他们反馈了他们的影响力是如何改变了我们的方向。这是一个简单的关于如何迎合他们需求、构建信任并获取支持的例子。这里的关键是不仅要聆听,还要根据你所学的来采取行动。
谋求帮助(Enlist help)
你不必单独做这件事。你可以考虑在培训中把你的客户经理当成你的导师。他们乐意与你以及你的管理团队一起工作,帮助塑造周围的信息及迁移到云的好处,使之与你的业务接轨。如果影响已经超出了客户经理的专业知识范围,他们将寻找到合适的人选,不管是AWS的内部或外部人员。我们乐意为你创造与有同样想法的人沟通的机会。而且这不只是在我们的活动中,而是在培训的任何时刻。在最近一次活动中我和其他公司有过几个参考电话,从其他管理者学习既是一种教育也是一种验证。
AWS合作伙伴网络(AWS Partner Network)以及AWS培训和认证(AWS Training and Certification)也是重要的资源,它们能帮助你加快你的培训进程。我多次强调它们是最佳实践,但我发现很多企业与他们的HR部门合作把AWS培训作为我们整个培训的首要部分。在Dow Jones,DevOps团队与HR合作并定期举行DevOps日,来交付优化的工具和最佳实践。这是在分布全球的团队中分享技能的好方法。再次强调,你的客户经理可以帮助你很好地连接这些领域。

发展IT品牌(Evolve the IT brand)
我跟很多渴望提高自己部门品牌的IT主管交谈过。我在Bloomberg花了超过十年的职业生涯来开发促进业务的软件。我去Dow Jones的原因之一是帮助他们转变一种观念 – IT部门是一个成本中心。其实,IT部门也是驱动和赋能业务的部门。我觉得我对我的部门中辛勤工作和奉献的每个人有所亏欠,他们对我们正在推动的改变是很有帮助的。
AWS是作出这些转变的基础的一部分,但大部分在执行层面的工作在于了解每一个管理者的痛点,了解他们在IT中不想要什么,以便调整技术帮助他们实现自己的目标。在使用云提供的更好和更快的结果的几个月后,我们花了几个月再培训管理者团队和他们的部门来使用我们的技术而不是IT。这看似微妙,但它为我们之间的沟通带来有了有意义的变化,并且对由部门到公司整体的变化做出了贡献。
作者介绍

史蒂芬﹒奥本
斯蒂芬·奥本 (Stephen Orban) 于 2014 年9月加入亚马逊AWS 担任企业战略总经理。奥本与多名企业技术高管合作,在云如何实现业务成果、加快创新和简化流程方面进行经验和战略分享。在加入亚马逊AWS 之前,奥本曾在道琼斯担任首席信息官 (CIO)一职,他通过借力 AWS 和其他软件即服务 (SaaS) 合作伙伴,引入现代软件开发方法、实现降低成本、执行云优先政策。这些转型变革加快了产品开发周期并提高了全部业务线的生产能力,这其中就包括《华尔街日 报》、MarketWatch.com、道琼斯通讯社及Factiva。奥本还曾在彭博有限合伙公司(Bloomberg LP)工作 11 年,并且在股权和消息平台担任不同的领导职务;2008 年,奥本创建彭博体育(Bloomberg Sports)并担任首席技术官 (CTO)。
在云端试验时的“有所为和有所不为”
“The best way to show that a stick is crooked is not to argue about it or to spend time denouncing it, but to lay a straight stick alongside it” ― D.L. Moody
(“验证一根木棒是弯曲的最好的方法不是争论或花时间去抨击,而是放一根笔直的木棒在它旁边” – 慕迪)
现在越来越多的公司意识到,正确的、科学的使用云可以让入云试验更简单、经济和低风险。而且有这种试验文化的公司会在今天的市场有更多的竞争筹码。试验带来创新,这是实现新想法的史无前例的好时机。那么应该从哪里着手呢?当你在你的组织中创建试验文化时,四类“有所为和有所不为”是值得你去考量的。
1.管理预期
不是每次尝试的结果都符合你的预期,但是每次尝试都是学习和提高你运营能力的机会。如果你的组织未形成一个“从失败中学习”的习惯,那就从小事做起,确保让每个人知道你把哪些项目当作试验项目。你可以通过以下方式来管理你的项目利益相关方的预期 – 清楚地了解试验的意图、你期望什么样的产出、你怎样测试和衡量结果、你想从中学习到什么。据我所知,如果管理者知道他的组织会从试验中学到什么或使它变得更好的话,即使这个试验没有什么确定地产出,他们也会对这个试验心存感激。
不要从每个人都要求有产出的项目着手
如果你是一个试图创建实验文化的变革推动者,在你的变革旅程中不要从每个人都要求有产出的项目着手。例如我不会建议你在年终预算上做试验。我曾经合作的一个CEO告诉过我失败是可以有的,除非当它不可以失败的时候。接受一个增长的过程,慢慢增加你进行的试验,不要超出你的组织的可接受范围。
2.鼓励你的团队计划试验
每个组织都有自己的方式来决定哪些项目获得技术资源。不幸的是,一些组织现在把技术或IT部门当成成本中心并且想象与实际相去甚远。好的想法可以来自任何地方,当然当它来自于项目之外的时候,大部分的技术专家都有其独特的观点。对于那些刚开始使用云的组织来说情况尤其如此——把云应用于项目上的人处于实施试验的最佳位置,这些试验利用了使业务从云中受益的独一无二的能力。协助维护你的团队的提议,将你的员工置于可以影响执行团队投资的项目上。
在你知道怎样评价这个试验时再开始它
你期望把时间花在正确的试验上,确保从中学到的内容可以提高你的运营能力和产品。在让你的团队进行一个试验之前,你应该知道他们会评测什么以及怎样去评测。如果你在测试你的网站新功能,什么样的指标意味着成功?页面浏览量?点击量?放弃量?这种小但重要的尽职的调查行为将迫使你的团队首先去思考为什么他们要进行这个试验。这也将迫使你的团队优先进行正确的试验。
3.考虑DevOps的制度化试验
一个DevOps的文化也许是把试验制度化带到您组织的有力途径。将运行所构建的与自动化结合起来可以大大减少发布改变的时间,允许你更频繁地发布并在失效时更快回滚。成熟的DevOps组织也制定A / B测试框架,让他们同时尝试不同的用户体验和不同的用户群,看看哪一个效果最好。
不要怀疑你的团队
怀疑是阻碍你团队的“最有力”的方法,并且打开了失败之门。当你学会适当地预期试验、评测它们,并对它们进行快速迭代,你会发现在你开始怀疑之前你会接受你的方法。确保你的团队在思考正确的评测试验方式,并且提出尖锐的问题是十分必要的。但是与其质疑他们交付的能力不如帮助团队解决问题。人们倾向于跟随相信他们能成功的领导者。
4.鼓励整个组织参与
当你通过试验开始快速交付的时候,组织的其它成员将会被你的方式所吸引。那就拉他们进来。尝试进行覆盖不同业务领域的编程马拉松,让你的股东帮助确定怎样测评试验,向你的组织询问他们想进行哪个领域的试验。但并不是每个公司选择给他们员工时间来试验,他们通常吹捧这个为竞争优势。至少这种活动能提高员工们的士气和黏性。在我在亚马逊任职期间里,我发现任何人只要能够通过思考和书面形式表达试验,通常能得到机会尝试一下。这是我们特殊的文化的一部分,也是一个用来吸引和留住创新者和创造者的重要手段。
不要让试验延缓或中止交付
不要让你的团队因为只是一个试验而拖延交付。虽然失败和学习都是允许的,但在试验中未交付是不允许的。软件仍旧需要被交付测试,通常它也需要被放到生产环境的流量中被测评。试验并不意味着你可以推迟评测或降低质量。毕竟你依旧是在运营业务。
作者介绍

史蒂芬﹒奥本
斯蒂芬·奥本 (Stephen Orban) 于 2014 年9月加入亚马逊AWS 担任企业战略总经理。奥本与多名企业技术高管合作,在云如何实现业务成果、加快创新和简化流程方面进行经验和战略分享。在加入亚马逊AWS 之前,奥本曾在道琼斯担任首席信息官 (CIO)一职,他通过借力 AWS 和其他软件即服务 (SaaS) 合作伙伴,引入现代软件开发方法、实现降低成本、执行云优先政策。这些转型变革加快了产品开发周期并提高了全部业务线的生产能力,这其中就包括《华尔街日报》、MarketWatch.com、道琼斯通讯社及Factiva。奥本还曾在彭博有限合伙公司(Bloomberg LP)工作 11 年,并且在股权和消息平台担任不同的领导职务;2008 年,奥本创建彭博体育(Bloomberg Sports)并担任首席技术官 (CTO)。
专线直连AWS建立混合IT环境实务指南
AWS Direct Connect简介
云计算已经走入到每个企业中。然而,一些大型企业过去都是自建数据中心,购买了大量的基础设施,在使用公有云服务时又不能抛弃原有的设备,因此采用混合云的方式,既可以保护原有的投资,又可以通过公有云的方式来随时按需使用。很多企业都正在通过混合云的方式来逐步走上全方位采用云的道路。
过去,用户需要通过在传统的公网架设VPN(Virtual Private Network,虚拟专用网络),来保障数据传输的安全性,但是,这种方式无法完全保证带宽、低延迟、时效性。而AWS Direct Connect可以实现低带宽的成本,更稳定的网络性能,更可靠的网络效果,并且可以兼容AWS其他的云计算服务帮助用户实现混合云的架构。
AWS Direct Connect服务使用标准的802.1q VLAN标准,可将连接客户数据中心和AWS的单个专线连接逻辑分割成多个虚接口(Virtual Interface)。这样客户可以通过同一个连接访问共享资源(如通过公有IP 地址空间提供服务的Amazon S3中的对象)和专有资源(如使用私有IP空间在VPC中运行的Amazon EC2实例),同时又能在公有和专用环境之间保持网络隔离。
如下图所示,从客户路由器到AWS Direct Connect路由器的以太网连接上的不同VLAN与不同的虚接口相关联,客户可以通过Public VIF访问诸如S3,DynamoDB、AWS API端点等在公共地址空间中的服务,也可以通过Private VIF与绑定到VPC的VGW相连接,实现对多个VPC的访问。

AWS Direct Connect有 1Gbps 和 10Gbps 两种端口可用。客户可以通过建立多个连接来实现更大的带宽和更高的冗余。而对于带宽要求不高的客户也可向支持 AWS Direct Connect 的 APN 合作伙伴预定带宽粒度更细的托管连接。需要注意的是每个托管连接仅能支持访问单个VPC,或者只能访问公有地址空间的AWS服务端点。当然客户可以通过多个托管连接用于访问多个VPC。
常见的接入场景及分工界面
场景一: 客户网络边界已经到达特定Direct Connect 节点
如图所示,客户在特定的Direct Connect 节点(图中虚框所示位置)所在的机房已经部署了网络边界设备,那么可以向运营该节点的运营商订购 到AWS Direct Connect路由器的楼内跳线即可完成连接。

此场景下,分工界面较为简单:
各部分的技术要求分解如下:
场景二: 客户通过以太网专线 与AWS Direct Connect互联
如图所示,客户数据中心的网络边界通过AWS合作伙伴或者独立第三方提供的以太网专线相互连接。

此场景下, 802.1q VLAN终结在客户侧路由器上, AWS Direct Connect路由器与 客户路由器建立BGP邻居并相互发布路由信息;这里特别需要关注的是,以太网专线需要支持VLAN透传,确保双方向的以太网帧能够携带正确的VLAN 标签抵达对端。
此场景下,建议分工界面如下:
各部分的技术要求分解如下:
场景三: 客户通过 MPLS网络与AWS Direct Connect互联
如图所示,客户数据中心的网络边界通过AWS合作伙伴或者独立第三方提供的MPLS网络相互连接。
此场景下, 802.1q VLAN终结在MPLS 网络的PE路由器上, AWS Direct Connect路由器与 PE路由器建立BGP邻居并相互发布路由信息;

建议分工界面如下:
各部分的技术要求分解如下:
当然对于某些MPLS服务提供商而言,上述技术需求不一定能够满足;在这种场景下,客户可以通过在Direct Connect节点部署CE路由器来解决,此时这个场景就等同于前述场景一,相当于客户把网络边界通过第三方MPLS网络延伸到Direct Connect 节点。
案例、经验与最佳实践
案例一
某客户A需要建设连接国内总部和海外某AWS Region的以太网专线;因客户自身供应商名单的限制,客户选用了独立的第三方供应商建设专线,在建设过程中由于网络资源和覆盖不全,供应商又将该连接的海外部分链路分包给其它供应商,导致在整个实施过程周期长、沟通成本高、进度缓慢; 在最后楼内跳线环节中出现了尾纤插错口的差错,但是由沟通效率低,该问题耗费了接近一周时间才最终修正。
经验与最佳实践:
- 支持 AWS Direct Connect 的 APN 合作伙伴[1]具备丰富的项目实施经验和完善的流程,能够快速完成Direct Connect连接的部署,建议客户在实施时予以考虑;
- 楼内跳纤环节,自测环节应当在客户路由器或专线终结设备处面向AWS侧做硬环,客户可自助在控制台上观察该连接对应的AWS侧路由器的接口的状态,如果连接状态未能从down跳转为up,责说明光纤或连接有异常,需要即时排查;全流程的排查请参见AWS Direct Connect用户指南的相关章节[2];
案例二
某客户B在与独立的第三方供应商购买以太网专线的过程中,未能充分沟通VLAN透传的技术需求,导致在专线实施的最后验证环节专线供应商因资源利用率的问题拒绝支持此技术要求,除非客户大幅提升专线带宽。
经验与最佳实践:
- 在前期需求沟通阶段客户应与供应商充分沟通所适用场景的技术需求,避免后期被动;
- 部分独立的第三方专线供应商在特定场景下会对提供千兆光口、VLAN透传等功能,附带要求客户承诺比较高的签约带宽(例如50Mbps ~ 200Mbps,具体请咨询相关专线供应商)才予以满足;
- 在低带宽、连接单个VPC的场景下,建议客户向支持 AWS Direct Connect 的 APN 合作伙伴预定连接;
案例三
某客户C使用场景二所示的以太网专线连接与AWS 互联,并选用了独立的第三方运营商进行专线建设。在专线铺设过程中,第三方运营商因资源问题无法直接在终结设备上提供1000BASE-LX光口,而是 使用了独立的电转光设备完成接口类型转换。在后续的使用过程中,曾经出现由于该转换设备出现故障而导致专线临时中断, 影响了业务可用性。
经验与最佳实践:
- 专线的可用性取决于整条链路中可靠性最弱的一环,客户需要与专线供应商明确各个环节的可用性SLA及如何保障的议题;
- AWS Direct Connect支持客户通过多条连接实现相互负载分担和冗余,同时也支持专线与VPN之间的相互备份。可用性要求较高的场景下,建议客户通过两个或以上的Direct Connect连接,或者采用VPN备份方式在专线意外中断时保护业务可用性;
- 专线的备份机制需要时常验证和演练,确保在异常情况下能够按预期工作;
案例四
某客户D的业务需求需要一条能够保证从AWS海外区域到国内某数据中心的低延迟、稳定的链路用于传输实时视频流。通过与支持AWS Direct Connect 的 某APN 合作伙伴订购了一条带宽为20Mbps的托管连接,整个实施过程在3天以内即告完成,客户实测带宽和线路丢包率、抖动等都符合业务需求,而且该连接的带宽具备一定弹性。该APN合作伙伴承诺的扩容等后续服务的响应和实施周期等都明显快于传统方式。
经验与最佳实践:
- 对于小带宽、仅需要与单个VPC进行互联的应用场景,支持 AWS Direct Connect 的 APN 合作伙伴的托管连接能够给予客户更快的实施周期和更灵活的签约带宽;在适用的场景、或者项目周期较为紧迫的情况下推荐选用;
- 客户可以订购多个类似的托管连接,实现与多个VPC分别互联;
参考链接
[1] http://aws.amazon.com/cn/directconnect/partners/
[2] http://docs.aws.amazon.com/zh_cn/directconnect/latest/UserGuide/Troubleshooting.html
作者介绍

丁成银
AWS解决方案架构师,获得AWS解决方案架构师专业级认证和DevOps工程师专业级认证。负责基于AWS的云计算方案架构的咨询和设计,同时致力于AWS云服务在国内的应用和推广,在数字媒体、电信、互联网和游戏、企业混合IT等方面有着丰富的实践和设计经验。在加入AWS之前,历任数字媒体娱乐系统工程师、宽带业务架构师、云解决方案架构师,负责数字媒体娱乐系统、云计算解决方案等服务的咨询和架构设计工作。
手把手教你调校AWS PB级数据仓库
什么是一个好的数据仓库?
Redshift是AWS云计算中的一个完全托管的,PB级别规模的数据仓库服务。即使在数据量非常小的时候(比如几百个GB的数据)你就可以开始使用Redshift,Redshift集群可以随着你数据的增加而不断扩容,甚至达到PB级。云计算中数据仓库的优势非常明显,不需要license,不需要预先配置非常大的数据仓库集群,扩容简单,仅仅需要为你实际所使用的数据仓库付费。
Redshift作为一个企业级数据仓库完全支持SQL语法,无学习成本,支持很多种客户端连接,包括各种市场上的BI工具,报表以及数据分析工具。
Redshift的概览
Redshift通过支持大规模并行处理(MPP),列式存储,对不同列数据使用不同数据压缩算法,关系型数据仓库(SQL),灵活的扩容管理等众多优点,兼顾了数仓性能,同时也考虑学习成本及使用成本。
Redshift系统架构及要点
图1,Redshift系统架构图

- 主节点负责客户端与计算节点之间的所有通讯,编译代码并负责将编译好的代码分发给各个计算节点处理,负责分配数据到不同的计算节点,主节点对客户不可见的,无需客户管理主节点的压力,更重要的是主节点免费。
- 计算节点是具体的干活的,并处理好的任务送给主节点进行合并后返回给客户端应用程序。每个计算节点都有自己独立的CPU,内存以及直连存储。Redshift集群规模大小通常就是指计算节点的个数以及计算节点机器类型。
- 节点分片是指将计算节点被分成若干的分片,根据计算节点类型不同,每个节点包含的分片数量不同,通常1个vCPU对应一个分片,ds2的机型除外。每个分片都会分配独立的内存及存储资源,接受来自主节点分配的任务。分片跟另外一个重要概念Dist Key紧密相关, 这里先提一下,接下来会具体介绍Dist Key。
- 排序键(Sort Key)是一个顺序键,即Redshift会根据这个键来将数据按顺序存储在硬盘上。Redshift的查询优化程序(只要理解有这么个东西存在就好,客户不需要任何维护,对客户也是透明的)也会根据这个排序来进行执行查询优化计划。这是Redshift性能调优的一个非常重要的参数。
- 分配键(Distribution Key)是控制加载到表的数据如何分布在各个计算节点的一个键,有好几种分布的风格,接下来会重点讲到,这是Redshift调优的非常重要的另外一个参数。
Redshift的几个常用最佳实践
选择最佳排序键
- 如果最近使用的数据查询频率最高,则指定时间戳列作为排序键的第一列;
- 如果您经常对某列进行范围筛选或相等性筛选,则指定该列作为排序键;
- 如果您频繁联接表,则指定联接列作为排序键和分配键;
熟悉Redshift的朋友可能知道可以指定多列作为排序键,而且排序键还有两种方式,组合式和交叉式。限于篇幅的原因,在接下来的调优测试中我们采用的是某一列作为排序键,如果有对其他排序键风格感兴趣的朋友,可以单独联系我们进行讨论。
选择最佳分配键
选择表分配方式的目的是通过在执行查询前将数据放在需要的位置来最大程度地减小重新分配步骤的影响,最好这个查询不需要二次移动数据。
分配键有三种风格,均匀分布(Even),键分布(Key),全分布(All),默认是均匀分布。
- 根据共同列分配事实数据表和一个维度表;
事实数据表只能有一个分配键。任何通过其他键联接的表都不能与事实数据表并置。根据联接频率和联接行的大小选择一个要并置的维度。将维度表的主键和事实数据表对应的外键指定为 DISTKEY。
- 根据筛选的数据集的大小选择最大的维度;
只有用于联接的行需要分配,因此需要考虑筛选后的数据集的大小,而不是表的大小。
- 在筛选结果集中选择基数高的列;
例如,如果您在日期列上分配了一个销售表,您可能获得非常均匀的数据分配,除非您的大多数销售都是季节性的。但是,如果您通常使用范围受限谓词进行筛选以缩小日期期间的范围,则大多数筛选行将位于有限的一组切片上并且查询工作负载将偏斜。
- 将一些维度表改为使用 ALL 分配;
如果一个维度表不能与事实数据表或其他重要的联接表并置,您可以通过将整个表分配到所有节点来大大提高查询性能。使用 ALL 分配会使存储空间需求成倍增长,并且会增加加载时间和维护操作,所以在选择 ALL 分配前应权衡所有因素。
优化COPY,提高数据加载速度
当你将要数据加载到Redshift的某个表时,不要让单个输入文件过大,最好是将这些输入文件切成多份,具体数量最好是跟分片数量匹配,这样可以充分利用所有分片,配合分配键能达到最佳效果。
图2,COPY输入的最优方式
让COPY选择自动压缩
作为数据仓库,Redshift通常会需要大量导入数据,这时使用做多的,效率最好的是COPY命令。在使用COPY时建议将COMPUPDATE参数设置为ON,这样数据在加载进库时是自动压缩的,好处是可以节省存储空间,提高查询的速度,不过这会增加数据加载进表的时间,这个可以根据你的业务需求,再具体衡量。
Redshift调优实战
测试结论
- 选择合适的排序键,分配键,及自动压缩对表的查询速度,存储效率很大提升。本次测试中,优化后查询速度有高达75%的提升,存储空间节省50%。
- 相同节点类型情况下,多节点性能比单节点性能提升明显。本次测试中,采用了4节点与单节点对比,4节点查询速度比单节点提升75%。
- 节点数量相同的情况下,dc系列节点的查询速度比ds系列节点的查询速度要快。本次测试中,采用了dc1.large和ds1.xlarge两种节点类型进行对比,dc系列节点的查询速度比ds系列快20% 。
- 使用JOIN与不使用JOIN查询速度无明显差别。本次测试中,三个不同的查询及对应的JOIN查询,在查询速度上的差别非常小。这部分的详细测试结果,请参见附录一。
- 查询速度达到一定值时,再增加节点对查询优化的效果有限。本次测试中,在相同环境中,将节点数量从8个dc1.large节点增加到12个dc1.large节点,三个查询只有一个查询的速度有一定提升,其他2个查询速度基本没有太大变化。这部分的详细测试结果,请参见附录二。
图3,调优前后性能对比图

备注:性能对比图从三个方面进行了对比,数据加载速度,表存储空间,查询的速度。本次测试的原始数据放在AWS Oregon S3,Redshift也在Oregon区域。
测试场景
表1,本次测试中用到的表及表的大小
图4,本次测试中表之间的关系

测试步骤
注意:本次测试步骤已假设Redshift集群已启动,且用户知道如何通过JDBC方式连接Redshift集群。
Before(不做任何优化):
- 创建表(不指定排序键和分配键);
- 加载数据(不进行自动压缩);
- 查询Redshift中各个表的存储空间;
- 执行三种不同查询,均取第2次查询所耗时间;
- 相同条件,使用JOIN查询所耗时间;
After(指定排序键和分配键,加载数据时进行了自动压缩):
- 删除表;
- 创建表(指定排序键和分配键);
- 加载数据(根据不同数据类型选择合适的压缩算法);
- 查询Redshift中各个表的存储空间;
- 执行三种不同查询,均取第2次查询所耗时间;
- 相同条件,使用JOIN查询所耗时间;
测试截图
图5,单个节点(ds1.xlarge)的数据加载时间(优化前)

图6,单个节点(ds1.xlarge)的数据加载时间(优化后)

图7,单个节点(ds1.xlarge)的数据存储空间(优化前)

图8,单个节点(ds1.xlarge)的数据存储空间(优化后)

图9,单个节点(ds1.xlarge)的查询时间(优化前)

图10,单个节点(ds1.xlarge)的查询时间(优化后)

图11,4个节点(ds1.xlarge)的数据加载时间(优化前)

图12,4个节点(ds1.xlarge)的数据加载时间(优化后)

图13,4个节点(ds1.xlarge)的数据存储空间(优化前)

图14,4个节点(ds1.xlarge)的数据存储空间(优化后)

图15,4个节点(ds1.xlarge)的查询时间 (优化前)

图16,4个节点(ds1.xlarge)的查询时间 (优化后)

图17,4个节点(dc1.large)的数据加载时间 (优化前)

图18,4个节点(dc1.large)的数据加载时间 (优化后)

图19,4个节点(dc1.large)的数据存储空间 (优化前)

图20,4个节点(dc1.large)的数据存储空间 (优化后)

图21,4个节点(dc1.large)的查询时间 (优化前)

图22,4个节点(dc1.large)的查询时间 (优化后)

本次测试中用到的命令参数
Before (优化前)
CREATE TABLE part
(
p_partkey INTEGER NOT NULL,
p_name VARCHAR(22) NOT NULL,
p_mfgr VARCHAR(6) NOT NULL,
p_category VARCHAR(7) NOT NULL,
p_brand1 VARCHAR(9) NOT NULL,
p_color VARCHAR(11) NOT NULL,
p_type VARCHAR(25) NOT NULL,
p_size INTEGER NOT NULL,
p_container VARCHAR(10) NOT NULL
);
CREATE TABLE supplier
(
s_suppkey INTEGER NOT NULL,
s_name VARCHAR(25) NOT NULL,
s_address VARCHAR(25) NOT NULL,
s_city VARCHAR(10) NOT NULL,
s_nation VARCHAR(15) NOT NULL,
s_region VARCHAR(12) NOT NULL,
s_phone VARCHAR(15) NOT NULL
);
CREATE TABLE customer
(
c_custkey INTEGER NOT NULL,
c_name VARCHAR(25) NOT NULL,
c_address VARCHAR(25) NOT NULL,
c_city VARCHAR(10) NOT NULL,
c_nation VARCHAR(15) NOT NULL,
c_region VARCHAR(12) NOT NULL,
c_phone VARCHAR(15) NOT NULL,
c_mktsegment VARCHAR(10) NOT NULL
);
CREATE TABLE dwdate
(
d_datekey INTEGER NOT NULL,
d_date VARCHAR(19) NOT NULL,
d_dayofweek VARCHAR(10) NOT NULL,
d_month VARCHAR(10) NOT NULL,
d_year INTEGER NOT NULL,
d_yearmonthnum INTEGER NOT NULL,
d_yearmonth VARCHAR(8) NOT NULL,
d_daynuminweek INTEGER NOT NULL,
d_daynuminmonth INTEGER NOT NULL,
d_daynuminyear INTEGER NOT NULL,
d_monthnuminyear INTEGER NOT NULL,
d_weeknuminyear INTEGER NOT NULL,
d_sellingseason VARCHAR(13) NOT NULL,
d_lastdayinweekfl VARCHAR(1) NOT NULL,
d_lastdayinmonthfl VARCHAR(1) NOT NULL,
d_holidayfl VARCHAR(1) NOT NULL,
d_weekdayfl VARCHAR(1) NOT NULL
);
CREATE TABLE lineorder
(
lo_orderkey INTEGER NOT NULL,
lo_linenumber INTEGER NOT NULL,
lo_custkey INTEGER NOT NULL,
lo_partkey INTEGER NOT NULL,
lo_suppkey INTEGER NOT NULL,
lo_orderdate INTEGER NOT NULL,
lo_orderpriority VARCHAR(15) NOT NULL,
lo_shippriority VARCHAR(1) NOT NULL,
lo_quantity INTEGER NOT NULL,
lo_extendedprice INTEGER NOT NULL,
lo_ordertotalprice INTEGER NOT NULL,
lo_discount INTEGER NOT NULL,
lo_revenue INTEGER NOT NULL,
lo_supplycost INTEGER NOT NULL,
lo_tax INTEGER NOT NULL,
lo_commitdate INTEGER NOT NULL,
lo_shipmode VARCHAR(10) NOT NULL
);
copy customer from ‘s3://lyz/redshift/customer’
credentials ‘aws_access_key_id= your-key;aws_secret_access_key=your-secret-key’
gzip compupdate off region ‘us-west-2’;
copy dwdate from ‘s3://lyz/redshift/dwdate’
credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘
gzip compupdate off region ‘us-west-2’;
copy lineorder from ‘s3://lyz/redshift/lineorder’
credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘
gzip compupdate off region ‘us-west-2’;
copy part from ‘s3://lyz/redshift/part’
credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘
gzip compupdate off region ‘us-west-2’;
copy supplier from ‘s3://lyz/redshift/supplier’
credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘
gzip compupdate off region ‘us-west-2’;
select count(*) from LINEORDER;
select count(*) from PART;
select count(*) from CUSTOMER;
select count(*) from SUPPLIER;
select count(*) from DWDATE;
select stv_tbl_perm.name as table, count(*) as mb
from stv_blocklist, stv_tbl_perm
where stv_blocklist.tbl = stv_tbl_perm.id
and stv_blocklist.slice = stv_tbl_perm.slice
and stv_tbl_perm.name in (‘lineorder’,’part’,’customer’,’dwdate’,’supplier’)
group by stv_tbl_perm.name
order by 1 asc;
— Query 1
— Restrictions on only one dimension.
select sum(lo_extendedprice*lo_discount) as revenue
from lineorder, dwdate
where lo_orderdate = d_datekey
and d_year = 1997
and lo_discount between 1 and 3
and lo_quantity < 24;
— Query 2
— Restrictions on two dimensions
select sum(lo_revenue), d_year, p_brand1
from lineorder, dwdate, part, supplier
where lo_orderdate = d_datekey
and lo_partkey = p_partkey
and lo_suppkey = s_suppkey
and p_category = ‘MFGR#12’
and s_region = ‘AMERICA’
group by d_year, p_brand1
order by d_year, p_brand1;
— Query 3
— Drill down in time to just one month
select c_city, s_city, d_year, sum(lo_revenue) as revenue
from customer, lineorder, supplier, dwdate
where lo_custkey = c_custkey
and lo_suppkey = s_suppkey
and lo_orderdate = d_datekey
and (c_city=’UNITED KI1′ or
c_city=’UNITED KI5′)
and (s_city=’UNITED KI1′ or
s_city=’UNITED KI5′)
and d_yearmonth = ‘Dec1997’
group by c_city, s_city, d_year
order by d_year asc, revenue desc;
After(优化后):
drop table part cascade;
drop table supplier cascade;
drop table customer cascade;
drop table dwdate cascade;
drop table lineorder cascade;
CREATE TABLE part (
p_partkey integer not null sortkey distkey,
p_name varchar(22) not null,
p_mfgr varchar(6) not null,
p_category varchar(7) not null,
p_brand1 varchar(9) not null,
p_color varchar(11) not null,
p_type varchar(25) not null,
p_size integer not null,
p_container varchar(10) not null
);
CREATE TABLE supplier (
s_suppkey integer not null sortkey,
s_name varchar(25) not null,
s_address varchar(25) not null,
s_city varchar(10) not null,
s_nation varchar(15) not null,
s_region varchar(12) not null,
s_phone varchar(15) not null)
diststyle all;
CREATE TABLE customer (
c_custkey integer not null sortkey,
c_name varchar(25) not null,
c_address varchar(25) not null,
c_city varchar(10) not null,
c_nation varchar(15) not null,
c_region varchar(12) not null,
c_phone varchar(15) not null,
c_mktsegment varchar(10) not null)
diststyle all;
CREATE TABLE dwdate (
d_datekey integer not null sortkey,
d_date varchar(19) not null,
d_dayofweek varchar(10) not null,
d_month varchar(10) not null,
d_year integer not null,
d_yearmonthnum integer not null,
d_yearmonth varchar(8) not null,
d_daynuminweek integer not null,
d_daynuminmonth integer not null,
d_daynuminyear integer not null,
d_monthnuminyear integer not null,
d_weeknuminyear integer not null,
d_sellingseason varchar(13) not null,
d_lastdayinweekfl varchar(1) not null,
d_lastdayinmonthfl varchar(1) not null,
d_holidayfl varchar(1) not null,
d_weekdayfl varchar(1) not null)
diststyle all;
CREATE TABLE lineorder (
lo_orderkey integer not null,
lo_linenumber integer not null,
lo_custkey integer not null,
lo_partkey integer not null distkey,
lo_suppkey integer not null,
lo_orderdate integer not null sortkey,
lo_orderpriority varchar(15) not null,
lo_shippriority varchar(1) not null,
lo_quantity integer not null,
lo_extendedprice integer not null,
lo_ordertotalprice integer not null,
lo_discount integer not null,
lo_revenue integer not null,
lo_supplycost integer not null,
lo_tax integer not null,
lo_commitdate integer not null,
lo_shipmode varchar(10) not null
);
copy customer from ‘s3://lyz/redshift/customer’
credentials ‘aws_access_key_id=your-key;aws_secret_access_key=your-secret-key’
gzip region ‘us-west-2’;
copy dwdate from ‘s3://lyz/redshift/dwdate’
credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘
gzip region ‘us-west-2’;
copy lineorder from ‘s3://lyz/redshift/lineorder’
credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘
gzip region ‘us-west-2’;
copy part from ‘s3://lyz/redshift/part’
credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘
gzip region ‘us-west-2’;
copy supplier from ‘s3://lyz/redshift/supplier’
credentials ‘aws_access_key_id= your-key;aws_secret_access_key= your-secret-key ‘
gzip region ‘us-west-2’;
select stv_tbl_perm.name as table, count(*) as mb
from stv_blocklist, stv_tbl_perm
where stv_blocklist.tbl = stv_tbl_perm.id
and stv_blocklist.slice = stv_tbl_perm.slice
and stv_tbl_perm.name in (‘lineorder’,’part’,’customer’,’dwdate’,’supplier’)
group by stv_tbl_perm.name
order by 1 asc;
— Query 1
— Restrictions on only one dimension.
select sum(lo_extendedprice*lo_discount) as revenue
from lineorder, dwdate
where lo_orderdate = d_datekey
and d_year = 1997
and lo_discount between 1 and 3
and lo_quantity < 24;
— Query 2
— Restrictions on two dimensions
select sum(lo_revenue), d_year, p_brand1
from lineorder, dwdate, part, supplier
where lo_orderdate = d_datekey
and lo_partkey = p_partkey
and lo_suppkey = s_suppkey
and p_category = ‘MFGR#12’
and s_region = ‘AMERICA’
group by d_year, p_brand1
order by d_year, p_brand1;
— Query 3
— Drill down in time to just one month
select c_city, s_city, d_year, sum(lo_revenue) as revenue
from customer, lineorder, supplier, dwdate
where lo_custkey = c_custkey
and lo_suppkey = s_suppkey
and lo_orderdate = d_datekey
and (c_city=’UNITED KI1′ or
c_city=’UNITED KI5′)
and (s_city=’UNITED KI1′ or
s_city=’UNITED KI5′)
and d_yearmonth = ‘Dec1997’
group by c_city, s_city, d_year
order by d_year asc, revenue desc;
附录一
图23,查询1所耗时间,8节点(dc1.large)

图24,查询1使用JOIN所耗时间,8节点(dc1.large)

图25,查询2所耗时间,8节点(dc1.large)

图26,查询2使用JOIN所耗时间,8节点(dc1.large)

图27,查询3所耗时间,8节点(dc1.large)

图28,查询3使用JOIN所耗时间,8节点(dc1.large)

附录二
图29,查询1所耗时间,12节点(dc1.large)

图30,查询2所耗时间,12节点(dc1.large)

图31,查询3所耗时间,12节点(dc1.large)

作者介绍:

亚马逊AWS解决方案架构师,在加入AWS之前,在多家跨国公司有着超过7年的架构设计和项目管理的经验,对AWS云端高可用架构有着深刻的理解,以及对企业级应用如何迁移到云端的架构设计有实战方面的经验。
Token Vending Machine:移动应用客户端安全访问AWS服务的解决方案
背景介绍
广大移动互联网应用和移动游戏开发者在利用AWS服务进行开发过程中,经常需要为移动客户端提供AWS服务访问安全证书,以便让这类移动端应用有权限直接访问AWS服务,比如通过AWS S3服务上传图片文件或者通过AWS SQS服务发送消息。
有些移动开发者可能会考虑为每个移动应用用户分配一个固定的AWS IAM安全证书来实现移动客户端访问AWS服务。但是一款热门的移动互联网应用或者移动游戏往往拥有数百万甚至上千万的用户基数,让系统管理员为每一个用户分配和管理IAM 安全证书工作量将会非常巨大。而且移动客户端相对服务器端具有较低的安全等级,保存在移动设备内部的敏感信息比如用户账号或密码存在泄露的风险,强烈建议移动开发者不要将AWS安全证书长期保存在用户的移动设备中。
利用AWS 安全令牌服务Security Token Service (简称STS)可以动态的为大量移动客户端用户分配临时安全证书 ,并且可以限制这些临时安全证书的AWS服务访问权限和有效时间。使用AWS STS临时安全证书没有用户总数的限制,也不需要主动轮换,证书自动会过期,拥有非常高的安全性。对于这种采用AWS STS和其他相关AWS服务构建的移动客户端访问AWS服务安全证书分配系统,我们把它命名为Token Vending Machine,即令牌售卖机,简称TVM。
下面我们以一个典型的手机图片管理APP演示项目为例来介绍如何利用AWS相关服务设计和开发一套TVM系统。读者可以通过参考演示项目的设计思想和相关源码快速开发出符合自己项目需求的TVM系统。
假设该演示项目的基本需求如下:
- 用户在使用该APP前要先完成注册
- 用户成功登录后可以通过APP上传,查看和管理自己的图片
- 用户不可以访问到其他用户的图片
实现原理
整个演示项目实现可以分为三个主要模块:移动客户端、TVM系统和S3服务。
A. 移动客户端
- 包括访问TVM系统获取临时安全证书的客户端代码
- 包括直接访问AWS S3存储桶用户个人目录内容和图片管理相关的代码逻辑实现。
B. TVM系统
- 使用了一台AWS EC2实例来运行Apache Tomcat Web服务器,用于向移动客户端提供远程访问接口以获取临时安全证书。在Tomcat内部则部署了使用JAVA语言开发的TVM服务器端实现。
- 使用了AWS 高性能的NoSQL数据库DynamoDB做为后台用户数据库。该数据库用来保存注册用户的账号、密码和会话Key等信息。开发者自行设计和实现TVM系统的时候,完全可以使用自己熟悉的数据库产品或者集成第三方已有的用户数据库 服务,比如基于LDAP的企业内部用户数据库。
- TVM系统的JAVA实现通过访问AWS STS服务获取临时安全证书以提供给移动客户端。
- 在真实的项目中,运行TVM系统的服务器端往往还将直接管理S3中保存的所有用户资源,比如可以限制每个用户允许上传图片的数量和文件合计大小等等。这部分功能在本演示项目中暂时没有实现。
C. S3服务
- AWS S3服务为用户上传图片提供了持久化存储能力。
在用户成功完成账号注册后,TVM系统的基本工作流程如下:
- 用户通过移动客户端输入账号和密码,登录系统。
- TVM查询用户数据库,校验账号和密码组合的合法性。
- TVM访问AWS STS服务,请求分配临时证书,TVM将获得的临时安全证书返回移动客户端。
- 移动客户端使用获取的临时安全证书,调用AWS S3 API,执行文件的上传、列表和下载等操作。
部署过程
- 使用IAM用户账号登录AWS控制台
- 创建IAM EC2角色
- 创建临时安全证书角色
- 在Launch TVM EC2实例的过程中,选择使用创建的IAM EC2角色
- 在TVM EC2实例中部署Tomcat和TVM war包
- 下载并安装TVM apk文件到安卓移动终端
细节说明
IAM EC2角色定义
基于对生产环境高安全性要求的考虑,我们没有在JAVA代码中直接使用静态配置的IAM用户Access Key Id和Access Key来访问AWS DynamoDB, S3和STS等AWS服务,而是希望使用AWS动态分配的临时安全证书。为此我们创建了一个专门的IAM EC2角色,并为该角色赋予了足够的AWS服务访问权限。这样一来,运行在带有该IAM角色的EC2实例中的TVM组件,就可以通过EC2上下文获得拥有足够AWS服务访问权限的临时安全证书。请注意不要将TVM组件自己使用的临时安全证书与TVM组件将为移动客户端分配的临时安全证书相混淆。这里通过EC2上下文获取的临时安全证书主要用于TVM组件在服务器端访问AWS相关服务,比如读写DynamoDB或者向STS服务请求为移动客户端分配临时安全证书。
下面的例子IAM Policy文件赋予了IAM EC2角色访问AWS STS服务的AssumeRole接口和其他AWS服务的权限。开发者可以根据自己的实际需求增加或减少相关权限分配。
TVM组件实现代码在构造STS服务访问客户端对象的时候,我们使用了AWS JAVA SDK提供的com.amazonaws.auth.InstanceProfileCredentialsProvider证书加载类文件。该类实例可以自动访问EC2运行环境上下文,获取临时安全证书以供构造的STS服务访问客户端对象使用。并且当获取的临时安全证书即将失效时,该类实例还可以自动去获取新的安全证书。通过使用该类实例,TVM组件开发者就不再需要考虑访问STS或DynamoDB服务时需要提供的安全证书问题。
下面的代码片段演示了如何构建一个带有自动安全证书管理能力的STS服务访问客户端对象。
代码片段来自于TVM组件的com.amazonaws.tvm.TemporaryCredentialManagement.java源文件。
STS API方法选择和使用
AWS STS服务提供了多个API方法,分别用于不同场景下的临时证书获取。其中的AssumeRole 方法是唯一支持临时安全证书调用的。这种STS API方法的调用方式看上去非常有趣:我们使用了来自EC2上下文的临时安全证书去调用STS AssumeRole 方法,目的是为了帮助移动客户端用户申请访问AWS S3服务的临时安全证书。实际上通过EC2上下文获取的临时安全证书也是来自AWS STS服务的动态分配。这一点恰恰也证明了AWS服务的松耦合设计思想,用户可以通过灵活组合不同的服务来达到自己的设计目的。
STS AssumeRole 方法提供了多个参数,可以灵活的设置分配的临时安全证书的各种特性。我们这里主要介绍演示项目用到的几个重要参数。
下面的代码片段演示了如何调用STS AssumeRole方法申请新的临时安全证书。
代码片段来自于TVM组件的com.amazonaws.tvm.TemporaryCredentialManagement.java源文件。
设置安全证书权限
在我们演示项目的需求列表中,有一个需求是不同的用户只能访问S3对象存储服务中属于自己的文件。实现该需求有不同的方法,我们这里采用方法的是限制移动客户端使用的AWS 临时安全证书的S3访问权限。在AWS STS AssumeRole 方法中有两个参数可以设置返回的临时安全证书的权限:一个是临时安全证书角色Arn值,一个是附加的Policy字符串。
在我们演示项目的实现过程中,我们为创建的临时安全证书角色分配了如下权限策略,保证AWS STS服务返回的临时安全证书拥有指定S3存储桶的必要操作权限。
请注意,在创建临时安全证书角色的过程中,还需要添加该角色对于之前创建的IAM EC2角色的信任关系。否则TVM服务器端组件在执行AssumeRole方法时候,AWS系统会提示当前用户没有对临时安全证书角色执行AssumeRole操作的权限。

接下来我们将利用模板文件动态地构造附加的Policy,目的是限制每个登录用户只能够访问自己目录下的S3资源。
模板文件的格式如下:
以下的例子代码利用登录用户名替换模板中的“__USERNAME__”,构造出指定用户的权限Policy。
代码片段来自于TVM组件的com.amazonaws.tvm.TemporaryCredentialManagement.java源文件。
权限分级控制
在本演示系统中,用于开发和部署TVM系统的IAM用户、最终运行TVM系统的EC2实例对应的IAM角色和移动客户端所获得的临时安全证书分别拥有不同大小的权限,实现了很好的权限分级控制。
移动客户端临时安全证书的过期问题处理
在前面我们介绍的TVM系统的基本流程里面,移动客户端应用在登录成功后,TVM组件将直接返回临时安全证书。而实际的实现过程要比这复杂一些,主要是为了解决移动客户端获取的临时安全证书过期后的自动更新问题。
TVM系统的完整工作流程如下:
- 用户通过移动客户端输入账号和密码,登录系统。
- TVM查询用户数据库,校验账号和密码组合的合法性,创建并返回代表当前用户会话的Key值给移动客户端。
- 移动客户端在本地缓存获取的会话Key。移动客户端利用本地保存的会话Key和用户动态ID向TVM系统发起请求,申请临时安全证书。
- TVM系统校验移动客户端用户身份和会话Key,访问AWS STS服务,请求分配临时安全证书,TVM将获取的临时安全证书返回移动客户端。
- 移动客户端在本地缓存获取的临时安全证书。移动客户端使用本地保存的临时安全证书,持续调用AWS S3 API,执行文件的上传、列表和下载等操作。
关于移动客户端获取临时安全证书,请注意下面的细节:
- 在临时安全证书有效时间范围内,移动客户端可以直接使用本地保存的临时安全证书访问AWS 服务,比如S3存储桶。
- 一旦临时安全证书过期,移动客户端需要凭借本地保存的用户会话Key和动态用户ID向TVM系统再次申请临时安全证书,不需要再提供用户名和密码信息。
- 如果是刚刚启动移动客户端或者TVM用户会话Key已经失效,移动客户端需要执行上述完整的登录和临时安全证书获取过程。
下面的代码片段演示如何登录TVM系统,获取当前用户的会话Key。
代码片段来自于安卓移动客户端组件的com.amazonaws.tvmclient.AmazonTVMClient.java源文件。
下面的代码片段演示如何使用当前用户的会话Key和动态用户ID访问TVM系统,更新本地保存的临时安全证书。
代码片段来自于安卓移动客户端组件的com.amazonaws.demo.personalfilestore.AmazonClientManager.java和com.amazonaws.tvmclient.AmazonTVMClient.java源文件。
移动客户端和TVM系统安全通信设计
开发者如果需要移动客户端应用在非安全的互联网上直接与TVM系统通信,比如直接使用HTTP而非HTTPS发送登录请求和接收临时安全证书,开发者还需要自己实现一定程度的消息加密解密过程,避免敏感信息比如会话Key或临时安全证书内容在传输过程中被泄密。
演示效果
用户通过手机客户端注册新账号,执行完成登录操作后,就可以上传,查看和删除属于自己的图片文件。上传文件过程支持用户输入文本内容由系统自动产生上传文件和直接从手机客户端选择需要上传的图片文件。
通过查看AWS S3存储桶内容,我们可以看到每个用户上传的图片或文本文件都保存在属于该用户自己的S3存储桶路径下面:

在TVM系统DynamoDB用户数据库的用户表中保存了用户名、用户动态ID和加密的用户密码信息:

在TVM系统DynamoDB用户数据库的设备表中保存了用户的会话Key值:

敬请关注
在移动应用设计开发过程中,开发者除了完全靠自己开发实现用户注册和管理功能外,还可以考虑与主流社交媒体身份提供商实现联合身份认证,让已经拥有这些社交媒体身份提供商注册账号的用户能够顺利访问其移动应用。AWS Cognito服务已经支持与Google、Facebook、Twitter 或 Amazon等国际知名社交媒体身份提供商的联合身份认证。后续我们会陆续推出如何与微信、QQ和微博等国内主要社交媒体的联合身份认证方案探讨。
例子源码
TVM系统服务器端源码
https://s3.cn-north-1.amazonaws.com.cn/mwpublic/projects/tvm/TVMServer.zip
安卓客户端源码
https://s3.cn-north-1.amazonaws.com.cn/mwpublic/projects/tvm/TVMAndroidClient.zip
参考链接
http://aws.amazon.com/articles/4611615499399490
https://aws.amazon.com/code/Java/8872061742402990
http://aws.amazon.com/code/4598681430241367
http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/IAM_Introduction.html
http://docs.aws.amazon.com/zh_cn/IAM/latest/UserGuide/id_roles.html
http://docs.aws.amazon.com/zh_cn/STS/latest/UsingSTS/Welcome.html
http://docs.aws.amazon.com/zh_cn/STS/latest/APIReference/Welcome.html
作者介绍:

蒙维
亚马逊AWS解决方案架构师,负责基于AWS的云计算方案架构咨询和设计,有超过十年以上电信行业和移动互联网行业复杂应用系统架构和设计经验,主要擅长分布式和高可用软件系统架构设计,移动互联网应用解决方案设计,研发机构DevOps最佳实施过程。
分布式神经网络框架 CaffeOnSpark在AWS上的部署过程
一、介绍
Caffe 是一个高效的神经网络计算框架,可以充分利用系统的GPU资源进行并行计算,是一个强大的工具,在图像识别、语音识别、行为分类等不同领域都得到了广泛应用。有关Caffe的更多内容请参考项目主页:
http://caffe.berkeleyvision.org/
不过Caffe的常用部署方式是单机的,这就意味着它的水平扩展能力受到了限制。使用者可以通过在系统中添加多个GPU的方式提高并发度,不过其并发能力最终受到单系统可支撑的GPU数量的限制。同时,神经网络计算往往又是计算消耗很大的,所以人们在使用Caffe的时候都可能会希望有一种并行计算框架可以支持Caffe。
而我们知道Spark是基于内存的计算框架,基于Yarn, Mesos或者是Standalone模式,它可以充分利用多实例计算资源。因此,如果能够结合Caffe和Spark,Caffe的能力将得到更充分的发挥。 基于这些原因,Yahoo开源的CaffeOnSpark框架受到的极大的关注。
有关CaffeOnSpark的源代码和相关文档,请大家参考:
https://github.com/yahoo/CaffeOnSpark
今天我们要进一步讨论的是如何在AWS EC2上部署CaffeOnSpark, 充分利用AWS服务提供的GPU实例构建强大的分布式神经网络计算框架。
在CaffeOnSpark的文档中有明确指出EC2上部署CaffeOnSpark的步骤,具体请参考:
https://github.com/yahoo/CaffeOnSpark/wiki/GetStarted_EC2
但是文档的一些部分写得比较简单,初步接触的读者可能在执行过程中遇到一些问题,所以在这里将我个人的安装配置过程整理了一下供大家参考。
安装过程大概可以分为四部分:
下面会在“环境准备”一节中具体描述这几个步骤的细节。
二、环境准备
首先我们打开文档https://github.com/yahoo/CaffeOnSpark/wiki/GetStarted_EC2, 看看文档中刚开始的部分对于环境准备的要求。
里面首先提到我们需要准备“EC2 Key pair”, 就是要准备EC2启动需要的密钥对。当然,为了创建“EC2 Key pair”,为了启动EC2,你首先需要一个AWS账号。有关AWS账号的申请和基本使用这里就不细述了,请参考其它相关文档。需要注意的是你拿到的AWS账号需要有基本的权限才能完成CaffeOnSpark的安装工作,其中包括创建EC2实例,创建安全组等。
“EC2 Key pair”是你在创建EC2实例时创建的密钥对,创建过程中你有一次机会下载私钥文件,就是文中提到的pem文件。如果你之前没有创建过EC2,你也可以直接在EC2控制台的“网络与安全->密钥对”界面中点击“创建密钥对”按钮进行创建。同样,创建过程中你有一次机会下载pem文件,下载后注意保管好该文件,后面都会依赖这个文件。
按文档的描述,有了以上的资源以后就可以执行以下命令:
为了准备环境,我们需要先理解一下上面的脚本。脚本的刚开始部分是一系列变量的定义,我们先了解这些变量的作用。
第一句比较简单,从变量名可以知道这是指定了要使用的AMI的ID:
这个镜像是一个已经安装好Spark、CaffeOnSpark,并加载了常用神经网络测试数据的Ubuntu镜像。该镜像由CaffeOnSpark团队提供,已经共享给所有AWS账号。
不过稍有AWS使用经验的同学会意识到,这样的命令是针对特定的区域(Region)的,因为同一个AMI镜像拷贝到不同AWS区域时它们的AMI ID是不一样的。在命令行中如果指定了一个AMI的ID,就意味着这些命令只能在特定的AWS区域正常工作。
所以我们需要继续查看后续命令,看看哪里指定了区域。幸运的是,命令的第二行就是指定区域的命令:
我们知道区域代码“eu-west-1”指的是欧洲(爱尔兰) 区域,意味着我们运行完这个样例后我们的CaffeOnSpark群集是运行在欧洲(爱尔兰) 区域的。因为EC2 key pair也是按区域分的,所以我们创建的EC2 key pair也应该是在欧洲(爱尔兰) 区域。
为了在欧洲(爱尔兰) 区域创建你的EC2 key pair,你可以点击AWS控制台右上角的区域选择框,选择欧洲(爱尔兰) 区域,然后再按步骤进入EC2的控制台创建EC2 key pair.
同时,你也可以去EC2控制台的“映像->AMI”界面查找镜像ID为ami-5ff7782c的镜像,记得查看时选择“映像类型”为“公有映像”,而不是“我拥有的”。找到这个镜像你还可以仔细查看一下其它相关信息。
如果你发现镜像列表中没有ID为ami-5ff7782c的镜像,有可能你阅读本文的时候相关方已经更新了新的镜像,你可以去CaffeOnSpark的主页
https://github.com/yahoo/CaffeOnSpark 找到更新版本的指导,获得新的镜像ID。
进一步往下看可以看到指定AZ的命令行:
其中eu-west-1c代表c可用区,有关可用区的相关概念在这里也不细述了,对可用区(AZ)概念有疑惑的同学请参考其它AWS基础文档。
再往下是指定worker数量的命令:
表示这个群集需要两个工作实例,需要注意的是创建的Spark群集中有一个主实例,多个工作实例,其中主实例会使用一般的实例类型,而工作实例会使用GPU实例。这里的参数就表示希望启动两个GPU实例作为工作实例。
我们知道,AWS上的GPU实例也有类型之分,现在可以使用的GPU类型有g2.2xlarge和g2.8xlarge两种,到底工作实例会使用什么GPU类型呢,下面的参数就是为了指定工作实例的实例类型。可以选择g2.2xlarge或者是g2.8xlarge。注意下面两行中第二行被注释掉了,表示只有第一句生效,就是使用g2.2xlarge实例类型。
接着是指定竞价实例的最高价格,有关竞价实例的细节请参考AWS相关文档,使用竞价实例大概就是设定一个可以接受的价格去参加实例拍卖的竞价,如果你的出价比别人高你就可以拍得实例。下面这句就是设置竞价为0.8美金每小时:
后面我们继续分析命令会知道,后续执行命令的时候会使用下面的参数,表示希望使用竞价实例作为工作实例。但是这不是CaffeOnSpark所必须的,如果你不希望使用竞价实例,可以不使用以下参数,这样就可以使用“按需实例(OnDemand)”了。
接着就是运行真正的命令了,运行的命令是:
后面带有许多参数,在具体了解不同参数的作用前,我们先得思考,这个spark-ec2命令从哪里来? 如果你之前曾经安装过Spark,在你的Spark主目录里就可以找到ec2目录,里面有spark-ec2命令。 我自己的环境中曾经安装过Spark 1.5,所以也可以找到这个ec2/spark-ec2命令,不过如果我尝试去执行这里的这些命令的话会报错,报“不可知的Spark版本”错误。原因是这里的脚本指定目标Spark是1.6.0, 但是我们运行的Spark是1.5,所以会报错。所以我重新启动了一个新的实例安装了Spark 1.6,以执行spark-ec2命令。有关Spark 1.6的安装,下面的章节会有介绍部分安装过程,现在我们先看看这里spark-ec2命令的不同参数有什么:
其中–key-pair和–identity-file是用来指定EC2 key pair的,就是EC2要使用的密钥,–key-pair用于指定密钥的名称,–identity-file用于指定密钥的pem文件的路径:
接着 –ebs-vol-size是用于指定EBS卷大小的,这里设置了50G,因为镜像大小的原因,你不能把–ebs-vol-size设置的太小,这里就是用样例中的50G吧:
接着是通过–instance-type指定工作实例的实例类型,这里是用了前面定义的变量,按前面我们变量的定义,下面的参数会是用g2.2xlarge作为工作实例的实例类型:
接着是通过–master-instance-type参数指定群集主实例的类型,因为主实例不参与神经网络计算,所以主实例可以不用选择GPU实例,这里是用了m4.xlarge:
然后是用–ami参数指定实例创建时是用的镜像ID:
-s参数用于指定工作实例的数量,这里引用了之前定义的参数,我们把它设置成2,就是会启动两个工作实例:
–spot-price就是前面提到的是用竞价实例的参数,如果你不希望是用竞价实例,直接删除这个参数就好了:
–copy-aws-credentials用于指定是否拷贝AWS授权证书,这里不用细究它的作用:
–hadoop-major-version=yarn 和 –spark-version用于指定Hadoop的运行框架信息和Spark的版本:
–no-ganglia 表示不需要使用ganglia
–user-data用于指定实例启动时的需要完成的动作,这个参数非常重要,CaffeOnSpark安装过程中的很多设置都是因为设置了这个“User-Data”才完成的。这里设置的user-data指向CaffeOnSpark目录的scripts子目录中的。这就意味着我们在使用这个命令的时候应该已经拥有CaffeOnSpark的代码了,具体的获取方法在下一节中有详细描述:
最后就是真正“启动”的参数了,这里同时指定了群集的名称,本例为“CaffeOnSparkDemo”,注意,这个群集名称需要是区域内唯一的,如果你希望进行多次测试,又不希望受之前测试的干扰,每次启动时需要在这里设置不同的群集名称:
理解了整个命令,我们再次总结一下我们需要完成的工作:
我们假设你已经做好了a、b两步,下一节会详细讲解步骤c,紧接着第四节会讲解步骤d:测试校验过程
三、安装过程
下面开始详细讲解我的安装过程。
1. 准备工作机
这一步骤就是启动一个EC2,没有什么特别的需要强调。因为平时都习惯使用Amazon Linux,所以我创建工作机时选择了Amazon Linux镜像。另外就是启动这台EC2也需要一个EC2 key pair,这里可以使用上一节提到的准备好的EC2 key pair, 也可以使用其它EC2 key pair。就是说工作机的密钥和CaffeOnSpark群集的密钥没有关系的,你使用同一对密钥可以,使用不同密钥也可以。
2. 安装Spark 1.6
这一步是在工作机上安装Spark 1.6,如果已经有工作机部署好Spark 1.6的就可以跳过这步。当然,如果你很熟悉Spark的安装过程,也可以直接跳过这一小节。
启动EC2工作机后ssh登录到工作机,按习惯先运行了:, 以更新组件。
接着运行了:来安装git命令,后面获取Spark源代码和CaffeOnSpark源代码都用它呢。
然后通过以下命令获得Spark 1.6的稳定版本:
为了编译Spark,你可以使用Maven或者是sbt,我通过以下命令安装了sbt:
在Spark源代码根目录运行:, 让sbt开始下载需要的组件,运行完进入sbt界面的话先退出来。
接着运行以下命令编译Spark:
我编译的是yarn版本,其实在这里参数-Pyarn不是必须的,我只是后续要执行yarn相关的任务,所以选择了带yarn的版本。
另外,你也可以直接运行Spark源代码目录中的生成可部署的版本,完整命令如下:
为了方便以后使用,我将编译好的Spark移动到以下目录:, 接着,修改一下
文件,增加Spark路径的设置:
执行命令让配置项直接生效后,你就可以开始测试一下你的Spark了,比如可以直接运行spark-shell试试。
最后,为了确认spark-ec2命令也正常工作,可以去spark安装目录的ec2子目录下执行命令,不带任何参数,系统会返回spark-ec2命令的帮助文字,你也可以顺便了解以下spark-ec2命令的具体使用方法。
3. 下载CaffeOnSpark源码
如上所述,在安装CaffeOnSpark过程中,其中一个关键点就是在群集实例创建时传入了特定的User-Data,这份User-Data就是来自CaffeOnSpark项目的“scripts/ec2-cloud-config.txt”文件。 为了获得这份“scripts/ec2-cloud-config.txt”文件,我们需要下载CaffeOnSpark源码包,当然你也可以单独下载这个文件,不过为了以后的代码学习,建议整个将CaffeOnSpark项目clone下来。 具体命令如下:
下载了CaffeOnSpark源代码后,修改一下~/.bash_profile文件,设置变量指向CaffeOnSpark的源文件目录,方便后续引用。
4. 运行安装命令
后面就可以开始运行安装命令了,其实这里还有几个参数需要设置,不过为了加深印象,我们可以直接运行命令,遇到错误提示时再修改相关参数。
为了运行安装命令,我们创建一个shell文件,比如叫install.sh,里面的内容就是从CaffeOnSpark项目的EC2安装指导中拷贝的。 为了方便大家,再次贴上该文档的链接:
https://github.com/yahoo/CaffeOnSpark/wiki/GetStarted_EC2
然后再重复把安装命令都贴上来:
给install.sh赋予正确的权限后开始运行它:,然后你会看到下面这样的错误:
错误的意思是没有设置 ,相当于没有设置访问AWS的用户名,该命令无法访问AWS。 所以你需要找到你”Access key”和”secret key”。如果你有足够权限,你可以从AWS控制台上为自己创建“Credential”,然后下载”Access key”和”secret key”。或者你的AWS管理员应该给你分配过”Access key”和”secret key”。有关”Access key”和”secret key”就不在这里展开了,如果你对”Access key”和”secret key”的使用还有疑惑,请参考相关文档。
如果你通过export命令设置了 ,但是没有设置
,运行
命令时会报另一个错误:
相当于是只设置了用户名,没设置密码。
也就是说你需要将你的和
设置到环境变量里,才能给CaffeOnSpark安装脚本足够的权限。这里再强调一下,你使用的
和
对应的账号本身需要有足够的权限,比如创建EC2的权限,创建安全组的权限等。
设置完”Access key”和”secret key”后,再次运行,你可能会遇到如下错误:
因为样例命令中并没有设置变量和
变量,相当于是没有设置密钥名和密钥pem文件路径。
所以你需要定义 变量和
变量,一个指向你的密钥名,一个指向你的密钥pem文件路径。
再次运行命令,应该就可以正常开始安装了,安装过程时间比较长,建议启动screen命令后再执行。
运行命令,其实后台调用的是spark-ec2命令,spark-ec2命令会给AWS发送指令,创建指定的实例并完成相关设置工作。
注意,安装过程中有一步会提示是否格式化硬盘之类的提示,需要手工确认后才能继续进行。
最后,如果一切正常,在一系列的日志输出后,你将看到类似下面这样的提示:
这表明CaffeOnSpark安装成功了,你可以启动一个浏览器,访问以上URL进行验证,打开页面后看到的应该是类似以下页面的Spark主页:

同时,你可以通过ssh连接到Spark的主节点上查看相关文件和日志,具体命令类似于:
要注意,用户名使用的是root
四、校验测试
安装好CaffeOnSpark后,你可以从安装日志里找到Spark群集的主节点DNS名称,接着就可以ssh进去测试了。
如我们平常测试Caffe一样,我们可以使用mnist数据集。CaffeOnSpark的镜像中包括了mnist数据集,在目录CaffeOnSpark主目录的data子目录下。
完整的测试脚本如下,其中关键几部分内容后面有详细解释:
首先我们要留意的是下面这两句:
这两句是针对g2.2xlarge写的,有一个GPU设备,8核。
如果是使用g2.8xlarge的化,需要修改成:
就是有4块GPU,32核。
接着是清除HDFS上测试相关的目录:
然后就是关键部分,通过spark-submit命令向spark群集提交任务,运行的是打包好的Caffe网格计算包中的。
有关这里spark-submit命令中的细节就不详细说明了,有机会我们在分析CaffeOnSpark使用方法的文章中继续讨论。
最后,运行完spark-submit命令后,通过HDFS命令输出的结果。
如果执行上面的完整脚本的话,你会在命令行会看到类似下面的输出:
恭喜,你已经顺利完成了CaffeOnSpark的安装测试,可以开始你的分布式深度神经网络之旅了。
五、其它
在安装结束后,你就可以开始使用分布式的神经网络框架了。不过,考虑到实际的情况,还是有几个地方可以再稍微展开一下的。
1. AMI镜像
文档中使用的镜像是在欧洲(爱尔兰)区域的,在CaffeOnSpark公开的文档中没有看到其它区域的镜像。所以,如果你希望在其它区域使用CaffeOnSpark,你需要把镜像拷贝到对应的区域,或者是在对应的区域创建CaffeOnSpark镜像。
如果是拷贝镜像,你没有权限直接拷贝镜像ami-5ff7782c。你需要使用镜像ami-5ff7782c创建一个实例,然后对该实例执行镜像操作,最后才把新创建的镜像拷贝到指定区域。
如果你希望在对应区域创建CaffeOnSpark镜像,可以参考官方文档里有关创建CaffeOnSpark镜像的指引文档:
https://github.com/yahoo/CaffeOnSpark/wiki/Create_AMI
按照这个指引,你可以从一个基础版本的Ubuntu开始,自己从头开始创建CaffeOnSpark镜像。
2. GPU实例情况
你在搭建自己的CaffeOnSpark框架的时候要提前考察目标区域的是否提供GPU实例。
3. 自动化安装过程
我们这次安装CaffeOnSpark使用了Spark里的spark-ec2命令,spark-ec2命令其实调用了spark-ec.py这个Python脚本,如果你打开脚本spark-ec.py,你可以看到整个spark-ec2命令创建Spark群集的过程。
也就是说,如果你在特殊场景下需要手动安装CaffeOnSpark,或者是在安装过程中有特定的动作要执行,你可以参考spark-ec.py的具体实现。
六、总结
工具最终是为目标服务的,当我们有合适的工具使用时,我们可以更好地思考如何实现目标。本文介绍了CaffeOnSpark的安装过程,希望这篇文章可以帮助你快速设置好CaffeOnSpark这个工具,从而可以更好地实现你的目标。
深度神经网络已经被证明是一个有效的机器学习方法,通过CaffeOnSpark和AWS服务,我们可以建构一个巨大的深度神经网络群集。这时候,海量数据的加载和运算都不再是问题,现在唯一的问题就是你要拿深度神经网络解决做什么。
一切都准备好了,出发吧,祝你好运!
作者介绍:
邓明轩

亚马逊AWS解决方案架构师;拥有15年IT 领域的工作经验,先后在IBM,RIM,Apple 等企业担任工程师、架构师等职位;目前就职于AWS,担任解决方案架构师一职。喜欢编程,喜欢各种编程语言,尤其喜欢Lisp。喜欢新技术,喜欢各种技术 挑战,目前在集中精力学习分布式计算环境下的机器学习算法。
打造DIY版Echo:树莓派+ Alexa 语音服务
关于本文
本文详细阐述了如何在Java客户端和Node.js服务器上使用和测试Alexa语音服务。
本实例需要用Node.Js来获取Login的授权码。
本指导提供详细的操作指南对于在取得示例授权码、依赖性和在运行Pi的过程中相应的硬件部署。对于Windows, Mac,或者通用的Linux指令,可以看这里的向导。

开始
所需硬件
1. Raspberry Pi 2 (Model B) –在亚马逊上购买。升级:当然,Raspberry 3也是可以的,请点击这里查看详细操作。Pi的用户-请点击这里来获取帮助。
2. 微型的-USB 电源线 供树莓派来使用(包括在树莓Pi中)
3. 微型的 SD 卡– 需要预装NOOBS – Raspberry Pi 8GB Preloaded (NOOBS) Micro SD Card
4. 网线
5. USB 2.0 小型麦克风 – Raspberry Pi 没有自带麦克风,需要外接来与Alexa进行交互-在亚马逊上购买
6. 外部扬声器3.5mm音频插座/立体声耳机插孔-在亚马逊上购买
7. 一个 USB 鼠标和键盘,以及一个支持HDMI的外部显示器 – 如果由于某种原因无法通过SSH协议进入到你的树莓派时,我们也推荐你使用USB键盘、鼠标和一个便于使用的HDMI显示器。稍后可以查看关于“SSH”协议的内容。
8. 无线WiFi适配器(可选)在亚马逊上购买
所需技能
1. 基础编程知识
2. 熟悉脚本
0 – 设置树莓派

1. 将装好NOOBS的SD卡插入树莓派

2. 插入USB2.0的迷你麦克风和无线wifi适配器(可选)
3. 插入USB的键盘和鼠标.
4. 连接显示器


1 – 启动树莓派
1. 连接电源 2. 你的树莓派会启动,并显示可以安装的操作系统列表 3. 选择Raspbian 并点击 Install
4. Raspbian将会启动安装流程. 注意:这个过程可能会持续一段时间。 5. 按照完毕后,配置菜单 (raspi-config) 将会启动. 这里你可以设置一些基本参数:例如启用摄像头 ,然后选择Finish

6. 启动后,登录到你的树莓派,默认用户名是pi,密码是raspberry
更多信息: raspberrypi.org
2 – 安装应用和依赖包
注意: 你需要安装Terminal来安装使用Alexa Voice Services所需的组件. Terminal 是默认安装的,你可以从桌面上进入Terminal。可以点击这里了解更多关于Terminal的信息。


2.1 – 在树莓派上打开 SSH
SSH允许从另一台计算机远程访问的树莓派的命令行(只要它们都在同一网络上)。这样您不需要将您的树莓派连接到外部显示器 。
SSH默认情况下在树莓派是启用的 。如果你在工作的时候遇到一些有关SSH的问题,确保它已经被安装。在使用raspi-config 组件时,确保SSH已经安装好。
在Terminal中输入以下内容:
sudo raspi-config
然后导航到SSH,单击回车选择安装SSH服务器

2.2 – 使用SSH 登录到Raspberry Pi
现在,请SSH到您的树莓派。这样做之前必须确保你已经知道你的树莓派的IP地址。
键入以下命令到终端:
hostname -I
> 192.168.1.10 //this is an example Raspberry Pi’s IP – it would be different for you
如果你是在Windows PC上,按照这的说明SSH Using windows
现在,你知道你的树莓派的IP地址,就可以使用SSH远程连接到它 。要做到这一点,打开电脑上的终端程序 并键入以下内容:
pi@<YOUR Raspberry Pi IP ADDRESS>
它会提示你输入密码。注:为用户PI默认密码为raspberry
现在你可以远程连接到您的树莓派,并可以且通过SSH远程连接你安装所有的工具。
2.3 – 安装VNC服务器
VNC是一个允许远程控制树莓派界面的图片化的桌面分享系统。这会让操作变得很方便由于摆脱了外部的显示器。
sudo apt-get install tightvncserver
打开VNL服务器
请键入:tightvncserver来打开VNC服务器
你将会被要求设置一个密码。当你需要远程连接到树莓派时,请执行该操作。
在启动时运行VNC服务器
如果你想确保在你重启树莓派之后,VNC服务器会自动启动,请键入以下脚本:
cd /home/pi
cd .config
注意:确保“.”在文件夹前面。这使文件夹成为一个隐藏的文件夹。
mkdir autostart
cd autostart
通过键入以下命令,创建一个新的配置:
nano tightvnc.desktop
编辑文件中的以下文本:
[Desktop Entry]
Type=Application
Name=TightVNC
Exec=vncserver :1
StartupNotify=false
按住ctrl-X后在键入Y来保存更改。
这样的话,下一次你重启VNC服务器时将会自动刷新。
通过VNC服务器连接到树莓派
Mac系统: 请参阅 https://www.raspberrypi.org/documentation/remote-access/vnc/mac.md
Windows系统: https://www.raspberrypi.org/documentation/remote-access/vnc/windows.md
Linux系统: https://www.raspberrypi.org/documentation/remote-access/vnc/linux.md
(如果你喜欢的话)你现在可以不需要连接到显示器,鼠标键盘.随着SSH和VNC的安装, 外部显示器是可选择的。通过树莓派来感受自由吧。
2.4 – 安装VLC
通过输入下面命令获取VLC媒体播放器:
sudo apt-get install vlc-nox vlc-data
注意:如果你正在运行树莓派或者已经安装了VLC,你需要执行以下的命令来移除这俩个相冲突的库文件。
sudo apt-get remove –purge vlc-plugin-notify
sudo rm /usr/lib/vlc/plugins/codec/libsdl_image_plugin.so
无法获取错误:在你安装VLC时,遇到无法获取的错误时,尝试输入以下代码
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install vlc-nox vlc-data
注意:运行”sudo apt-get upgrade”脚本时可能会花费一段时间,请耐心等待
源: https://www.raspberrypi.org/forums/viewtopic.php?f=66&t=67399
确保VLC安装成功
whereis vlc
这条命令会告诉你VLC的安装位置.
大多数的项目会存在/usr/bin中
一般会显示下面的结果
vlc: /usr/bin/vlc /usr/lib/vlc /usr/share/vlc /usr/share/man/man1/vlc.1.gz
设置VLC的环境变量
敲入以下命令:
export LD_LIBRARY_PATH=/usr/lib/vlc
export VLC_PLUGIN_PATH=/usr/lib/vlc/plugins
查看环境变量是否生效
echo $LD_LIBRARY_PATH
> /usr/lib/vlc
echo $VLC_PLUGIN_PATH
> /usr/lib/vlc/plugins
2.5 – 下载并安装 Node.js
确认Node.JS 还没有被安装
node -v
> command not found
然后输入:
sudo apt-get update
sudo apt-get upgrade
设置apt-get repo的源:
curl -sL https://deb.nodesource.com/setup | sudo bash –
安装Node:
sudo apt-get install nodejs
2.6 – 安装JDK环境
你需要安装 Java Development Kit (JDK) version 8 或者更高.
步骤1: 从Oracle的网站下载 JDK 8.
下载 Linux ARM 32 Soft Float ABI (文件名jdk-8u77-linux-arm32-vfp-hflt.tar.gz)
注意:虽然苹果和一些智能手机有用64位的ARMv8,但是到现在为止没有树莓的64-位ARM的处理器在pis系统上可用
步骤 2: 解压内容 解压缩并安装到 /opt 目录下:
sudo tar zxvf jdk-8u77-linux-arm32-vfp-hflt.tar.gz -C /opt
设置默认Java环境到jdk1.8
sudo update-alternatives –install /usr/bin/javac javac /opt/jdk1.8.0_77/bin/javac 1
sudo update-alternatives –install /usr/bin/java java /opt/jdk1.8.0_77/bin/java 1
sudo update-alternatives –config javac
sudo update-alternatives –config java
注意:如果被要求选择一个可替换,请键入你刚刚安装的相对应的jdk 版本号-例如-jdk1.8.0_77
通过下面的命令确认版本:
java -version
javac -version
2.7 – 安装Maven
步骤 1: 下载 Maven
从以下链接下载apache-maven-3.3.9-bin.tar.gz文件
https://maven.apache.org/download.cgi
步骤 2:解压内容 解压压缩包的内容到 /opt 目录中
sudo tar zxvf apache-maven-3.3.9-bin.tar.gz -C /opt
步骤 3:告诉你的命令解析器在哪里找到maven 由于将在系统配置文件中设置这些,因此这对所有用户可用
创建一个新的文件 /etc/profile.d/maven.sh, 然后在里面输入以下内容:
export M2_HOME=/opt/apache-maven-3.3.9
export PATH=$PATH:$M2_HOME/bin
保存这个文件。退出并退回到树莓派中然后内容脚本就会生效,可以输入以下代码来进行测试:
mvn -version
3 – 开始使用Alexa的语音服务
3.1 – 注册一个免费的亚马逊开发者帐户

3.2 – 下载对树莓派示例应用程序代码和依赖
下载示例应用程序从Github repo上下载zip文件。如果要下载这个包,您必须同意Alexa的语音服务协议。
3.3 – 复制并解压你的树莓派.zip文件
1.直接下载你的树莓派的zip文件,复制,然后解压您的树莓派的zip文件。 2.请在您的树莓派记下它的位置。进一步的说明将把这个位置<REFERENCE_IMPLEMENTATION>

3.4 – 注册产品并创建一个安全配置文件
1.登录亚马逊开发者门户网站 – developer.amazon.com 2.单击应用和服务选项卡 – > Alexa的 – > Alexa的语音服务 – >入门
3.在注册产品类型菜单中,选择Device。

4.填写并保存以下值:
设备类型信息
1.设备型号ID:my_device
2.显示名称:My Device
3.单击下一步

安全配置文件
1.单击安全配置文件下拉菜单中选择“创建一个新的配置文件”

2.常规选项卡
o安全配置文件名称:Alexa的语音服务示例应用程序安全配置文件
o安全配置文件说明:Alexa的语音服务示例应用程序安全配置文件说明
o单击下一步

客户端ID和客户端密钥会为你生成。

1.现在点击网络设置选项卡
o确保您刚才创建的下拉菜单中选择安全配置文件,然后单击“编辑”按钮。

o允许的来源:点击“添加另一个”,然后输入https://本地主机IP:3000 。
o允许返回网址:点击“添加另一个”,然后输入https://本地主机: 3000 / authresponse。
o单击下一步

设备详细信息
1.图像:以下测试图像保存到电脑上,然后上传:

2.分类:其它 3.说明:Alexa的语音服务的示例应用程序测试 4.你对商业化的预期时间是多久?:长4个多月/ TBD您的预计时间表 5.有多少设备,你打算商业化?:0 6.单击下一步

亚马逊音乐
1.启用亚马逊音乐?:否(您可以选择选择是,如果你想与亚马逊的音乐实验中填写必填字段。但是,亚马逊音乐不要求 使用Alexa的语音服务。) 2.单击提交按钮


您现在可以生成自签名的证书。
4 – 生成自签名证书
步骤1: 安装 SSL
sudo apt-get install openssl
验证安装
whereis openssl
> openssl: /usr/bin/openssl /usr/share/man/man1/openssl.lssl.gz
修改目录到 <REFERENCE_IMPLEMENTATION>/samples/javaclient.
cd <REFERENCE_IMPLEMENTATION>/samples/javaclient – //your sample apps location
步骤2: 修改SSL配置文件: ssl.cnf, 将所有YOUR_开头的变量值替换为真实值.
Note that countryName must be two characters. If it is not two characters, certificate creation will fail. Here’s what the ssl.cnf file would look like, replacing country, state, locality with your respective info.
请您注意国家名必须是俩个字符。如果不是俩个字符,证书可能会创建失败。单击这里你将会看到ssl.cnf是什么样子的,替换你相对应的国家、洲、地区的信息
步骤3: 将下面文件设置为可执行的属性:
chmod +x generate.sh
步骤4: 运行脚本,生成证书:
./generate.sh
步骤 5: 过程中你会被提示输入一些信息:
1.提示输入product ID, 请输入my_device
2.提示输入 serial number, 请输入123456
3.提示输入password, 请输入你希望的密码 ,例如: talktome (也可以留空)
步骤6: 编辑Node.js server 的配置文件
文件的位置在:
<REFERENCE_IMPLEMENTATION>/samples/companionService/config.js.
进行下列变更:
- 设置sslKey to <REFERENCE_IMPLEMENTATION>/samples/javaclient/certs/server/node.key
- 设置sslCert to <REFERENCE_IMPLEMENTATION>/samples/javaclient/certs/server/node.crt
- 设置sslCaCert to <REFERENCE_IMPLEMENTATION>/samples/javaclient/certs/ca/ca.crt
注意: 不要使用 ~ 来代表根目录. 必须使用绝对路径.
因此, 不使用~/documents/samples, 而用/home/pi/documents/samples.
步骤7:编辑JAVA客户端的配置文件
这个配置文件在以下位置:
<REFERENCE_IMPLEMENTATION>/samples/javaclient/config.json.
做出以下配置:
- 设置companionApp.sslKeyStore 到 <REFERENCE_IMPLEMENTATION>/samples/javaclient/certs/server/jetty.pkcs12
- 设置companionApp.sslKeyStorePassphrase 到 上述第五步中证书生成代码中的密码
- 设置companionService.sslClientKeyStore 到 <REFERENCE_IMPLEMENTATION>/samples/javaclient/certs/client/client.pkcs12
- 设置companionService.sslClientKeyStorePassphrase到 上述第五步中证书生成代码中的密码
- 设置companionService.sslCaCert to到 <REFERENCE_IMPLEMENTATION>/samples/javaclient/certs/ca/ca.crt
5 – 安装依赖包
更改目录到 <REFERENCE_IMPLEMENTATION>/samples/companionService
cd <REFERENCE_IMPLEMENTATION>/samples/companionService
输入下列命令来安装依赖包:
npm instal
6 -安装安全配置文件
1.打开web浏览器,并访问以下网址 https://developer.amazon.com/lwa/sp/overview.html

2.在接近页面顶部的位置,在下拉菜单中选择你刚才创建的安全配置然后单击确认

3.进入一个隐私政策地址栏,该地址栏以http:// 或者 https://开头。在此例子中,你可以进入一个模拟仿真的地址栏例如http://example.com
4.[或者]你也可以上传一个图片。这个图片将被显示在使用者的同意登陆亚马逊网站的页面上。
5.单击保存。

6.然后打开Alexa Voice Service示例应用程序安全配置文件,单击显示客户ID和客户隐私。这项操作会展示出客户的ID和客户的隐私。保存这些值。你将会看到这些图片。


7 – 更新配置文件
通过VNC登陆树莓派
步骤1:更新config.js。导航到以下的文件然后在一个文本编辑器中打开该文件。
<REFERENCE_IMPLEMENTATION>/samples/companionService/config.js

在该文件中编辑以下几个值 –
- 客户ID: 把你在前几个步骤里复制的客户ID以字符串的形式粘贴在客户ID中。
- 客户秘密: 把你在前几个步骤里复制的客户机密以字符串的形式粘贴在客户机密中。
- 产品: 产品的对象包含一个你在开发者门户创建的与产品类别ID一致的密钥和一个属于一系列特定的产品标志符的数值。如果你是根据以上的指导操作的,产品序列ID是my device。那个独特的产品序列号可能是任何数字类型的字符串,比如说123456。以JSON产品为例:products:{“my_device”: [“123456”]}

保存文件。
步骤2:更新config.json。 导航到以下的文件然后在一个文本编辑器中打开该文件。
<REFERENCE_IMPLEMENTATION>/samples/javaclient/config.json
在文件中编辑以下值:
- 产品ID : 以字符串的形式输入my_device
- dsn: 输入一个数字型的字符串,这个字符串是你在服务器端的config.js页面中用来描述产品对象里的产品标志符数值。例如:123456。
- provisioning方法: 输入companionService。

保存文件。
步骤 3: 准备pom.xml文件
到下面的文件同时在文本编辑器中打开该文件。
<REFERENCE_IMPLEMENTATION>/samples/javaclient/pom.xml
增加以下的代码在pom.xml文件中< 依赖性 >部分:
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.1.0</version>
<scope>compile</scope>
</dependency>

8 – 运行服务器
通过VNC登陆树莓派
在你的windows终端或者命令提示符中打出以下代码:
cd <REFERENCE_IMPLEMENTATION>/samples/companionService
npm start


你已经成功开启这个服务器,并且运行在端口3000上。
9 – 开启客户端
打开一个新的Window终端或者选项卡(在Raspbian中 输入SHIFT+CTRL+TAB)
cd <REFERENCE_IMPLEMENTATION>/samples/javaclient

搭建应用平台
在你搭建app平台之前,确认项目是正确的同时所有必要的信息都是有效的。你可以通过执行以下的代码来确认:
mvn validate

通过执行以下代码下载依赖性文件并且搭建应用平台:
mvn install
当安装已经完成时,你在终端上可以看到“成功创建”的信息。

执行客户端的应用:
现在可以输入以下的脚本执行客户端的应用:
mvn exec:exec
10 -从亚马逊登陆页面中获得权限
1.当你执行客户端时,window桌面可能会弹出一个类似于以下文本的讯息:
“通过访问以下网址注册你的设备,然后请跟随指令操作:https://localhost:3000/provision/d340f629bd685deeff28a917一旦完成了请单击OK”

从弹出的窗口中复制URL地址然后粘贴到web浏览器。示例:以下为用来复制和粘贴的URL地址
https://localhost:3000/provision/d340f629bd685deeff28a917
![]()
注意:由于使用的是自签名证书,你将看到一个关于不安全网页的警告。这是一个意外。在测试的时候可以忽略这个警告,该网页是安全的。
2.将会跳转到亚马逊的登陆页面。输入你的亚马逊证书。

3.将跳转到开发者权限页面,确认许可你的设备可以通过刚才设置的安全配置文件。

单击Okay。
4.你现在将会再次跳转到一个以https://localhost:3000/authresponse开始的后面跟着查询字符串的URL地址栏。这个网页的主体部分将说明设备已经准备好

5.回到Java 应用然后单击OK按钮。这个客户端现在已经可以接受Alexa请求。

6.单击开始音频按钮然后在开始讲话之前等待音频提示。在你听到音频提示前会花费一到二秒

当你完成语音时,单击停止音频的按钮。

现在开始与Alexa 交谈
询问天气:单击开始音频的按钮。
你:今天西雅图的天气怎么样? 单击停止音频按钮。
Alexa:现在西雅图的气温报告。
你可以询问Alexa一些有意思的问题
在单击了“开始音频”之后,一旦你听见了音频提示,下面是一些问题你可以尝试去和Alexa交流
• 要求歌曲回播: 播放Bruce Springsteen
• 常识知识:太阳的质量是多少克?
• 极客:机器人的三定律是什么?
• 娱乐: 你可以跳rap麽?
• 设置定时期: 设置一个俩分钟的定时期
• 设置闹钟: 设置一个早上 7:30 的闹钟
更多的关于音乐回放的功能 “前一首”,“播放/暂停”,和“下一首”按钮在Java客户端交互界面上被用来展示音乐按钮事件。你可以使用音乐按钮而不是与Alexa讲话来改变播放列表的顺序。比如说,你可以按“播放/暂停”按钮来暂停和重复开始一首在音轨上的音乐。
为了更好的展示“播放/暂停”按钮,你可以说出以下命令: 在iHeartRadio上播放DC101,然后按“播放/暂停”按钮。如果按钮按下,这首音乐会终止。再次按下“播放/停止”按钮重新开始这首音乐。
11 – 常见问题解答
我有一个与AVS一起工作的树莓派,但是我不能从Alexa中听到音频回应
检查看一下是否你正在看通过终端的响应和是否在你的Alexa 应用上看到了响应卡。如果是的,你可能需要强制音频通过local 3.5mm插孔,而不是HDMI输出(这可能发生即使你没有一个HDMI显示器插入)。
为了促使音频通过local 3.5mm插孔,打开终端,然后输入以下代码:
sudo raspi-config
可以查看一下链接Raspberry Pi Audio Configuration
如何寻找树莓派的IP地址?
hostname -I
无法获取错误
在你安装VLC时,如果遇到了一些无法获取的错误,试图输入以下代码
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install vlc-nox vlc-data
在npm上有一些问题
如果你在安装结点后遇到一些“npm 无法找到”的问题(树莓的老版本结点), 尝试一些以下操作:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install npm
如果我不能为派找到网络接口怎么办?
可以查看以下URL了解如何在派上建立笔记本电脑的wifi和网络接口的连接https://www.hackster.io/Anwaarullah/sharing-wifi-with-raspberry-pi-using-a-lan-cable-ae1f44
ssl.cnf文件是什么样的?
单击这里将会看到ssl.cnf文件是什么样子的,并且根据你自己的国家、洲、地区来相应的替换
“无法连接到配套服务”的错误
这可能是因为以下三种情况的其中一种
1.不良证书– 这可能是下面情况的一个结果
- 不良的ssl cnf文件(可以查看一下常见问题是什么样的)
- 不正确的java版本
- 在config.json文件中可能有错误的密码
2.不正确的产品ID -确保以下值是一致的-
- 设备型号的信息-在亚马逊开发人员门户信息上的设备型号ID
- 在SSL证书产生的产品ID号(当被generate.sh触发时)
- 在 config.json上的产品ID
- 在产品上的“密码”和在config.js页面上 “密码”:[“值”]
3.不正确的DSN- 确保这些值是一致的
- 在config.json页面上的dsn
- 在产品上的“值”和在config.js页面上 “密码”:[“值”]
4.配套服务没有运行
状态
应用程序接口
培训
商城
博客
关于
© 2016 GitHub, Inc.
条款
隐私
安全
联系
帮助
作者介绍:

王毅
亚马逊AWS中国云解决方案架构师,获得了AWS解决方案架构师专业级别的认证。专门负责在国内推广AWS云平台技术和各种解决方案。有超过13年的IT领域咨询和实施经验,专注于云计算领域。在此之前,他是IBM全球服务服务部门的资深架构师经理,负责咨询和实施SOA,企业系统集成,云计算平台等解决方案在中国及亚太地区的推广和服务咨询工作。
将VMware 中的Ubuntu 12.04 映像导入成Amazon EC2 AMI
(本操作文档部分叙述内容与技术知识引用自AWS官方网站)
要在 Amazon EC2 中使用您的 VM,您必须首先将其从虚拟化环境中导出,然后使用 AWS Command Line Interface (AWS CLI) 或 API 工具将其导入 Amazon EC2。(AWS Console不支持从VM导入AWS的操作功能。)
从总体上看,要将VM导入到Amazon EC2中,需要经过以下五个步骤:
1. 安装 AWS CLI。
2. 为 VM 导入 Amazon EC2 做准备。
3. 从虚拟化环境中导出 VM。
4. 将 VM 导入 Amazon EC2。
5. 在 Amazon EC2 中启动实例。
本次实验使用VMware Workstation 10,把Ubuntu原生镜像ubuntu-12.04.5-desktop-amd64.iso导入到VMware Workstation 10。自行个性化操作后,利用VMware Workstation 10导出OVF映像的功能,获得VM的vmdk文件。并用AWS CLI,以流优化型 ESX 虚拟机磁盘 (VMDK) 映像格式把它导入到Beijing Region的AMI当中。(AWS并不完全支持所有基于Windows或Linux操作系统的系统版本,具体的支持列表请查看http://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/VMImportPrerequisites.html)。
一.安装AWS CLI
在本地安装AWS CLI具体请查看http://docs.aws.amazon.com/zh_cn/cli/latest/userguide/installing.html。需要注意的是,安装完客户端后,需要在AWS账户的IAM->用户->(目标用户)->安全证书 中创建并下载访问安全密钥,根据下载的Excel文件中的AWS Access Key ID和AWS Secret Access Key,配置好AWS CLI。具体请看以下截图。

二.为 VM 导入 Amazon EC2 做准备
把个性化操作后的Ubuntu VM从VMware Workstation 10导出前,需要在VM中进行以下几步重要的操作:
1. 在VM中启用SSH远程访问,并保证VM防火墙允许外部访问VM。虽然允许基于密码的SSH,但为安全起见,建议使用公共密钥登录。
2. 在VM中配置一个非root用户。虽然允许root登录,但为了安全起见,建议配置一个非root用户。
3. 确保您的 Linux VM 将 GRUB(传统 GRUB)或 GRUB 2 作为其启动加载程序。
4. 确保您的 Linux VM 使用下列根文件系统之一:EXT2、EXT3、EXT4、Btrfs、JFS 或 XFS。
5. 关闭所有反病毒软件,从您的 VMware 虚拟机上卸载 VMware 工具。
6. 保持您的网络设置为 DHCP 而不是静态 IP 地址。
在本次的操作中,由于我们使用原生的Ubuntu ISO文件,因此一般情况下,我们只需要操作上述的第1、2、6点即可。
三.从虚拟化环境中导出 VM
AWS支持下列四种映像格式:
1. 用于导入磁盘和 VM 的 RAW 格式。
2. 固定和动态虚拟硬盘 (VHD) 映像格式,该格式与 Microsoft Hyper-V 和 Citrix Xen 虚拟化产品兼容。目前不支持 VHDX 映像。VM Export 仅支持动态虚拟硬盘 (VHD)。不支持固定 VHD。
3. 流优化型 ESX 虚拟机磁盘 (VMDK) 映像格式,该格式可与 VMware ESX 和 VMware vSphere 虚拟化产品兼容。只能将通过 VMware 中的 OVF 导出过程创建的 VMDK 文件导入 Amazon EC2。
4. 启动虚拟装置 (OVA) 映像格式,该格式支持将映像与多个硬盘一起导入。
AWS官方文档中提到Citrix Xen、Microsoft Hyper-V 和 VMware vSphere这三款虚拟化环境软件。其中VMware vSphere支持导出OVF格式和OVA格式。而最常用的VMware Workstation系列软件,则只支持导出OVF格式。考虑到VMware vSphere是一款操作系统软件,而VMware Workstation是一款应用软件,为了简化复杂程度,我们使用VMware Workstation 10,也就决定了我们使用第三种的映像格式。
当在VM上个性化操作后,关闭VM,然后在VMware Workstation 10菜单栏中的“文件”->”导出为OVF”中把选中的VM导出到磁盘中。导出后一共有.mf、.ovf、.vmdk三个文件,个别操作系统的VM会出现.iso原生镜像文件。其中.mf文件是一些文件SHA的集合,主要起到防止映像文件被非法用户篡改的验证作用。.ovf文件相当于配置文件,它保证了映像文件vmdk、资源文件iso与虚拟机domain配置之间的正确对应。.vmdk文件是具体的映像资源。在这里,我们只需要把.vmdk文件上传到AWS S3的bucket即可。
四.将 VM 导入 Amazon EC2
在这一步中,我们需要使用AWS CLI操作S3中的.vmdk文件,把该文件转换为AMI。在这个过程当中,我们所使用的CLI命令import-image需要在我们的账户中创建名为vmimport的角色,并为该角色配置相关的策略和为使用IAM身份登录的用户配置权限后(http://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/VMImportPrerequisites.html),才能够执行特定的操作。因此在转换为AMI前,我们需要先操作我们的账户。下面会逐步介绍。
1. 使用 aws iam create-role 命令创建名为 vmimport 的角色,并向 VM Import/Export 提供对该角色的访问权。
具体命令:
aws iam create-role –role-name vmimport –assume-role-policy-document file://trust-policy.json
其中trust-policy.json文件的内容为:
{
“Version”:”2012-10-17″,
“Statement”:[
{
“Sid”:””,
“Effect”:”Allow”,
“Principal”:{
“Service”:”vmie.amazonaws.com”
},
“Action”:”sts:AssumeRole”,
“Condition”:{
“StringEquals”:{
“sts:ExternalId”:”vmimport”
}
}
}
]
}
特别注意事项:
(1) 必须将外部 ID 命名为vmimport,不能是其他的名字。
(2) trust-policy.json文件当中的”Version”并非是用户自定义版本号,而是AWS中vmimport的版本号,因此请保留”Version”:”2012-10-17″不变。
2. 为角色vmimport创建策略。
具体命令:
aws iam put-role-policy –role-name vmimport –policy-name vmimport –policy-document file://role-policy.json
其中role-policy.json文件的内容为:
{
“Version”:”2012-10-17″,
“Statement”:[
{
“Effect”:”Allow”,
“Action”:[
“s3:ListBucket”,
“s3:GetBucketLocation”
],
“Resource”:[
“arn:aws-cn:s3:::vm.vincentqiu.cn”
]
},
{
“Effect”:”Allow”,
“Action”:[
“s3:GetObject”
],
“Resource”:[
“arn:aws-cn:s3:::vm.vincentqiu.cn/*”
]
},
{
“Effect”:”Allow”,
“Action”:[
“ec2:ModifySnapshotAttribute”,
“ec2:CopySnapshot”,
“ec2:RegisterImage”,
“ec2:Describe*”
],
“Resource”:”*”
}
]
}
特别注意事项:
(1) 同样地,要求保留role-policy.json文件中的”Version”:”2012-10-17″不变。
(2) 需要特别注意上述role-policy.json文件中红色标注的两行,分别有两个注意事项:第一,如果VM映像所在的S3为中国区内,则需要以“arn:aws-cn:s3”开头标注资源;如果VM映像所在的S3为中国区外的标准AWS区域,则只需要使用一般的“arn:aws:s3”开头标注资源。第二,上述的vm.vincentqiu.cn为本人的VM映像在S3中的bucket名字,用户可根据情况替换成自己的bucket名字。
3. 为使用IAM身份登录的用户配置权限。
如果您以 AWS Identity and Access Management (IAM) 用户身份登录,那么您的 IAM 策略中需要以下权限才能导入或导出 VM。
{
“Version”: “2012-10-17”,
“Statement”: [
{
“Effect”: “Allow”,
“Action”: [
“s3:ListAllMyBuckets”
],
“Resource”: “*”
},
{
“Effect”: “Allow”,
“Action”: [
“s3:CreateBucket”,
“s3:DeleteBucket”,
“s3:DeleteObject”,
“s3:GetBucketLocation”,
“s3:GetObject”,
“s3:ListBucket”,
“s3:PutObject”
],
“Resource”: [“arn:aws:s3:::mys3bucket”,”arn:aws:s3:::mys3bucket/*”]
},
{
“Effect”: “Allow”,
“Action”: [
“ec2:CancelConversionTask”,
“ec2:CancelExportTask”,
“ec2:CreateImage”,
“ec2:CreateInstanceExportTask”,
“ec2:CreateTags”,
“ec2:DeleteTags”,
“ec2:DescribeConversionTasks”,
“ec2:DescribeExportTasks”,
“ec2:DescribeInstanceAttribute”,
“ec2:DescribeInstanceStatus”,
“ec2:DescribeInstances”,
“ec2:DescribeTags”,
“ec2:ImportInstance”,
“ec2:ImportVolume”,
“ec2:StartInstances”,
“ec2:StopInstances”,
“ec2:TerminateInstances”,
“ec2:ImportImage”,
“ec2:ImportSnapshot”,
“ec2:DescribeImportImageTasks”,
“ec2:DescribeImportSnapshotTasks”,
“ec2:CancelImportTask”
],
“Resource”: “*”
}
]
}
4. 创建新的导入映像任务。
经历了上述角色和账户操作后,我们现在终于可以使用 aws ec2 import-image 创建新的导入映像任务!
具体命令:
aws ec2 import-image –description “Ubuntu 12.04 vmdk” –disk-containers file://containers.json
其中containers.json文件的内容为:
[{
“Description”: “VM import first CLI task”,
“Format”: “vmdk”,
“UserBucket”: {
“S3Bucket”: “vm.vincentqiu.cn”,
“S3Key”: “OVA_ubuntu_12.04/Ubuntu12.04-disk1.vmdk”
}
}]
如果该VM具有多个显示磁盘,import-image命令也支持具有多个显示磁盘的VM导入Amazon EC2中。在这种情况下,containers.json文件的内容类似于:
[{
“Description”: “First CLI task”,
“Format”: “vmdk”,
“UserBucket”: {
“S3Bucket”: “my-import-bucket”,
“S3Key”: “my-windows-2008-vm-disk1.vmdk”
}
},
{
“Description”: “Second CLI task”,
“Format”: “vmdk”,
“UserBucket”: {
“S3Bucket”: “my-import-bucket”,
“S3Key”: “my-windows-2008-vm-disk2.vmdk”
}
}]
特别注意事项:
(1) 上述命令中的description均为注解部分,用户可以根据自己的需要进行修改。
(2) 上述红色字体中的”Format”的值取决于第三步中导出VM的映像格式。如果导出的VM映像格式为ova,请把”Format”的值改为ova。本次实验使用的是流优化型 ESX 虚拟机磁盘 (VMDK) 映像格式,所以”Format”的值为vmdk。
(3) 上述红色字体中的”S3Bucket”的值指的是VM映像所在S3的bucket名字,而”S3Key”的值指的是VM映像所在bucket中的具体路径名,用户可以根据自身情况进行修改。需要注意的是,设定”S3Key”的值时,请注意S3中文件夹的存在。请按照“文件夹/子文件夹/……/文件名”的格式进行填写。
当执行完该命令后,如果没有错误发生,CLI会返回任务响应。在任务相应中含有一个ImportTaskId的值,我们保存下来,方便下面查询使用。
5.检查您的导入映像任务的状态
具体命令:
aws ec2 describe-import-image-tasks –cli-input-json “{ \”ImportTaskIds\”: [\”import-ami-fggrs8es\”], \”NextToken\”: \”abc\”, \”MaxResults\”: 10 } ”
注意事项:
(1) 上述命令中的红色部分为导入映像任务的id值,用户根据上一步保留的ImportTaskId值自行替换,即可查询该任务的情况。
(2) 当使用上述命令查询任务状态时,根据AWS的处理进度,返回任务响应中的Status依次为“Pending”、“Converting”、“Updating”、“Updated”、“Preparing AMI”等。整个的处理过程持续10+分钟,请用户耐心等待。隔一段时间再次查询后,如果Status为“Completed”,则表示映像转换完成,用户可以在EC2的AMI镜像中找到它。
五.在 Amazon EC2 中启动实例
当生成AMI镜像后,我们就能够通过EC2按照正常的方法创建对应的实例。但需要注意的是:您的实例将只有一个 Ethernet 网络接口。另外,对于不同的操作系统,import-image命令对其Licence、最低存储、Internet协议、实例类型等方面有不同的限制和要求,具体请查看http://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/VMImportPrerequisites.html的《要求和限制》部分。
作者介绍:
邓明轩

亚马逊AWS解决方案架构师;拥有15年IT 领域的工作经验,先后在IBM,RIM,Apple 等企业担任工程师、架构师等职位;目前就职于AWS,担任解决方案架构师一职。喜欢编程,喜欢各种编程语言,尤其喜欢Lisp。喜欢新技术,喜欢各种技术挑战,目前在集中精力学习分布式计算环境下的机器学习算法。
邱越俊

亚马逊AWS解决方案架构师实习生,擅长Web开发,熟悉使用Java、Javascript、Html5、Mysql数据库,曾在多个互联网公司从事软件平台开发工作,对计算机网络架构、云平台的开发和部署有一定的经验。