精华内容
下载资源
问答
  • 简介:革命就是人们思考和行为方式在性质和广度两方面发生重大变化。按照这个定义,云计算的确算得上是革命了。云计算在计算机架构、软件和工具开发方面带来了根本性...尽管云计算只是一种交付计算资源方式

    简介:革命就是人们的思考和行为方式在性质和广度两方面发生的重大变化。按照这个定义,云计算的确算得上是革命了。云计算在计算机架构、软件和工具开发方面带来了根本性变化,当然也改变了我们存储、发布和使用信息的方式。本文的目的是帮助您了解这次革命的性质,让您能够适应和受益于云计算。


    近几年,信息技术 (IT) 领域出现了一种新模型 — 云计算。尽管云计算只是一种交付计算资源的新方式,而不是新技术,但是它导致组织提供信息和服务的方式发生了革命。

    在最初,IT 由大型机计算主导。这种配置最终让位给客户机-服务器模型。当代的 IT 不断向移动技术、普遍存在的计算和云计算发展。但是,与所有革命一样,这次革命包含原有的一些东西。

    因此,要想彻底了解云计算的来龙去脉,就一定要记住云计算的许多特点实际上源于以前的系统。在许多方面,这个重大变化是在以前基础上的跃进,而不是过去的全面终结。在全新的云计算环境中,既能够通过云技术实现创新性协作,也能够发挥大型机等传统系统的功效。计算方式的这一重大变化为 IT 人员提供了无限的机会,他们可以利用这一变化发挥自己和组织的优势。

    什么是云计算?

    云计算是以服务形式交付 IT 的全面解决方案。它是一种基于 Internet 的计算解决方案,它像电网传输电力那样提供共享的资源。云中的计算机一起工作,各种应用程序使用同一计算能力集合,好像它们在单一系统上运行一样。

    云计算的灵活性在于能够按需分配资源。因此,不再需要给任务分配特定的硬件,这会提高现有系统资源的利用率。在云计算出现之前,网站和基于服务器的应用程序都在特定的系统上运行。有了云计算之后,资源就集合为一台虚拟的计算机。在这种融合式配置提供的环境中,独立地执行应用程序,不需要关心任何具体配置。

    云为什么会掀起热潮?

    出现向云计算转移这一潮流有许多合理的重要的业务和 IT 原因。原因之一是外包的基本性质要求有更合适的解决方案。

    • 降低成本:云计算可以降低资本费用 (CapEx) 和运营费用 (OpEx),因为可以只在需要时购买资源,而且只按使用时间付费。
    • 优化人力资源的使用:使用云计算可以解放宝贵的人力资源,让他们能够把精力集中在创造价值上,而不是维护硬件和软件。
    • 健壮的可伸缩性:云计算允许快速地扩大或收缩规模,既没有时间限制,也不需要承担长期义务。

    云计算的基本组成部分

    云计算模型由前端后端组成。这两个部分通过网络连接,在大多数情况下是 Internet。用户通过前端与系统交互;后端是云本身。前端由客户机计算机(或企业的计算机网络)和用来访问云的应用程序组成。后端提供实现云服务的应用程序、计算机、服务器和数据存储。

    层:计算能力成为商品

    云的概念基于,每一层提供一类功能。云组件的这种分层方式让云计算的各个层成为像电力、电话服务或天然气一样的商品。云计算以低廉的价格向用户销售计算能力这种商品。云计算将会成为新型的公共事业服务。

    虚拟机监视器 (virtual machine monitor, VMM) 让用户能够同时使用云设施(见 图 1)。VMM 是主机系统上的一个程序,它让一台计算机支持多个相同的执行环境。从用户的角度来看,系统是一台与其他用户隔离的自含的计算机。实际上,所有用户都由同一台计算机提供服务。虚拟机是一个由底层控制程序管理的操作系统 (OS),这让它看起来像多个操作系统。在云计算中,VMM 允许监视用户,因此可以管理数据访问、数据存储、加密、寻址、拓扑和工作负载转移等方面。


    图 1. 虚拟机监视器的工作方式
    虚拟机监视器的工作方式 

    下面是云提供的层:

    • 基础架构 层是云的基础。它由服务器、网络设备、存储磁盘等物理资产组成。IBM® Cloud 等提供基础架构即服务(Infrastructure as a Service,IaaS)。在使用 IaaS 时,用户并不实际控制底层基础架构,而是控制操作系统、存储和部署应用程序,还在有限的程度上控制网络组件的选择。

      随需印刷 (Print On Demand,POD) 服务就是可以受益于 IaaS 的例子之一。POD 模型基于可定制产品的销售。POD 让个人能够在产品上进行设计并开店销售。店主可以上传他们的设计,数量不限。许多人上传了数千种设计。通过使用云存储功能,POD 可以提供无限的存储空间。

    • 中间层是平台。它提供应用程序基础架构。平台即服务 (Platform as a Service,PaaS) 提供对操作系统和相关服务的访问。它让用户能够使用提供商支持的编程语言和工具把应用程序部署到云中。用户不必管理或控制底层基础架构,而是控制部署的应用程序并在一定程度上控制应用程序驻留环境的配置。

      PaaS 的提供者包括 Amazon 的 Elastic Compute Cloud (EC2) 等。小企业软件工作室是非常适合使用 PaaS 的企业。通过使用云平台,可以创建世界级的产品,而不需要负担内部生产的开销。

    • 最上面一层是应用程序 层,这一层是对云的最直观表示。应用程序在这里运行,根据需要提供给用户。软件既服务 (Software as a Service,SaaS) 的提供者包括 Google Pack 等。Google Pack 包含可以通过 Internet 访问的应用程序和工具,比如 Calendar、Gmail、Google Talk、Docs 等等。

    图 2 给出这三层。


    图 2. 嵌入在 “服务式” 组件中的云计算层
    云计算层 

    云的构成

    云的构成有三种类型:私有(内部)、公共和混合型。

    • 公共云可供一般公众或大型行业组织使用,由销售云服务的组织拥有和供应。公共云被看作一般意义上的云;也就是说,离站的第三方提供商使用 web 应用程序通过 Internet 动态地供应资源,它们提供共享的资源并按使用量收费。
    • 私有云位于公司防火墙之内,由组织自己管理。它们是在企业内部创建和控制的云服务。私有云具有许多与公共云相同的优点,主要差异在于您的组织负责创建和维护云。
    • 混合型云是公共云和私有云的组合,同时使用公共和私有的服务。公共云提供商和企业本身分别承担一部分管理责任。通过使用混合型云,组织可以先判断要创建的服务的目标和需求,然后以最合适的方式获得它们。

    IT 在云中的角色

    考虑到管理和控制需要更加自动化,为了应对代码生产的增长,IT 人员的任务必须有所变化。IT 正在整合,对硬件和软件实现的需求更少了,但是也出现了新的任务。IT 的变化趋势是向知识工作者发展。在新的模型中,技术人员的主要责任是增强和升级一般业务过程。

    开发人员

    移动设备使用量的增长、社交网络的流行以及商业 IT 过程和系统在其他方面的发展将保证开发人员团队的工作更高效;但是由于云配置模型的系统化过程,企业开发人员的一些传统角色正在发生变化。

    IBM 最近的一项调查 New developerWorks survey shows dominance of cloud computing and mobile application development(见 参考资料)表明,对移动技术的需求将呈指数级增长。这一趋势以及云计算在全球的快速流行势必导致了解这一领域的开发人员急速增加。为了满足不断增长的移动连接需求,需要更多了解云计算的开发人员。

    云计算提供近乎无限的容量,因此不再需要考虑可伸缩性。云计算让开发人员可以访问大多数中小型企业无法负担的极大量的软件和硬件资产。这种配置提供 Internet 驱动的云计算和资产,让开发人员能够访问过去只能梦想到的巨大资源。

    管理员

    管理员是 IT 系统的守护者和立法者。他们的责任是控制用户对网络的访问。这意味着他们控制用户密码的创建,以及为对系统资产的一般访问等基本功能制定规则和过程。云计算的出现势必导致对这一过程的调整,因为管理员在这种环境中不再只关心内部问题,还要关心自己的企业与云计算的外部关系,以及公共云中其他承租人的活动。

    由于管理和企业总体安全程序的性质,这还会改变防火墙的作用。这不会消除对保护系统的需求。云计算会带来更多责任,而不是减少。在云计算环境中,管理员不但必须在组织内部保护数据和系统,还必须监视和管理云,从而确保他们的系统和数据在所有地方的安全性。

    架构师

    架构师的任务是对真实 IT 环境中给定系统的功能进行有效的建模。基本责任是为代理商的云计算模型开发架构性框架。云计算的架构实际上由三个层(IaaS、PaaS 和 SaaS)的抽象组成,这种方式有助于部署云计算的企业满足自己的目标。需要开发层的功能的抽象,让决策者和基层人员能够使用这些抽象规划、执行和评估 IT 系统的过程。

    在云计算时代,架构师的作用是对云的层的功能性交互进行设计和建模。架构师必须使用抽象确保 IT 发挥应有的作用,帮助实现组织的目标。

    采用云还是不采用:风险评估

    正在转向云计算的组织最关心的问题是安全性和私密性。提供云计算服务的公司明白这一点,他们知道如果没有可靠的安全性,他们的企业一定会垮台。因此,安全性和私密性是所有云计算提供商优先考虑的问题。

    治理:如何监视行业标准?

    在私有云中,治理由云的所有者负责;在公共云中,这一责任由服务提供商和服务使用方分担。但是,由于存在跨国恐怖主义活动、拒绝服务、病毒、蠕虫等因素 — 这些问题的某些方面超出了私有云所有者或公共云服务提供商和服务使用方的控制能力 — 所以需要全球、地区性和国家级的某种更广泛的协作。当然,对于公共云,这种协作不应该妨碍或损害云的所有者或使用者的控制能力。

    带宽需求

    如果打算采用云框架,那么必须在您的战略中评估带宽和可能出现的带宽瓶颈。在 CIO.com 的文章 The Skinny Straw: Cloud Computing's Bottleneck and How to Address It 中,提出了以下观点:

    在过去,对于实现虚拟化的组织,提高虚拟机密度的主要瓶颈是内存容量;现在,新型服务器提供的内存量大多了,内存不再是系统瓶颈了。云计算解决了机器密度问题,从而消除了这一瓶颈 — 解决机器密度问题成了云提供商的责任,云用户不需要考虑它。

    对于云计算,云用户与云提供商之间的带宽是瓶颈。

    那么,带宽问题当前最好的解决方案是什么?在当今的市场上,最好的方法是刀片服务器。刀片服务器是以物理空间和电力使用量最小化为目标优化过的服务器。对于云计算来说,刀片服务器的主要优点之一是提高了带宽速度。例如,IBM BladeCenter 可以快速高效地处理高性能计算工作负载。正如过去必须解决内存问题才能够有效地缓解高虚拟机密度的瓶颈,现在必须解决云计算的带宽瓶颈,所以要考察提供商的能力,判断带宽瓶颈是否是主要的性能问题。

    财务影响

    IT 运营成本中的相当一部分来自管理和控制方面,所以在云计算环境中其中一些任务的自动化会降低成本。自动化可以显著降低错误几率和人工重复工作的成本。

    其他一些因素对财务问题有不利影响,比如维护物理设施的成本、电力使用量、冷却系统以及控制和管理。无论如何,带宽不是惟一的问题。

    降低风险

    考虑下面的风险:

    • 数据处理不当的严重影响。
    • 有争议的服务费用。
    • 厂商的财务或法律问题。
    • 厂商的运营出现问题或关闭。
    • 数据恢复和机密性问题。
    • 一般的安全问题。
    • 外部力量发动的系统攻击。

    如果使用云中的系统,在数据安全性和连接性方面会有风险,恶意活动也可能会妨碍计算过程。但是,如果进行缜密的规划、谨慎地选择服务提供商并细致地管理风险,大多数公司可以安全地使用这种技术。

    结束语

    在这个革命性的新时代,云计算可以向组织提供确保财务稳定和高质量服务所需的方法。当然,如果云计算要想达到最佳的安全性和一般运营标准,就必须有全球协作。云计算出现了,我们所有人都必须准备好应对这次革命。

    展开全文
  • 简介: 革命就是人们思考和行为方式在性质和广度两方面发生重大变化。按照这个定义,云计算的确算得上是革命了。云计算在计算机架构、软件和工具开发方面...尽管云计算只是一种交付计算资源方式,而不是新技术

    简介: 革命就是人们的思考和行为方式在性质和广度两方面发生的重大变化。按照这个定义,云计算的确算得上是革命了。云计算在计算机架构、软件和工具开发方面带来了根本性变化,当然也改变了我们存储、发布和使用信息的方式。本文的目的是帮助您了解这次革命的性质,让您能够适应和受益于云计算。

     

    近几年,信息技术 (IT) 领域出现了一种新模型 — 云计算。尽管云计算只是一种交付计算资源的新方式,而不是新技术,但是它导致组织提供信息和服务的方式发生了革命。

    在最初,IT 由大型机计算主导。这种配置最终让位给客户机-服务器模型。当代的 IT 不断向移动技术、普遍存在的计算和云计算发展。但是,与所有革命一样,这次革命包含原有的一些东西。

    因此,要想彻底了解云计算的来龙去脉,就一定要记住云计算的许多特点实际上源于以前的系统。在许多方面,这个重大变化是在以前基础上的跃进,而不是过去的全面终结。在全新的云计算环境中,既能够通过云技术实现创新性协作,也能够发挥大型机等传统系统的功效。计算方式的这一重大变化为 IT 人员提供了无限的机会,他们可以利用这一变化发挥自己和组织的优势。

     

    什么是云计算

    云计算是以服务形式交付 IT 的全面解决方案。它是一种基于 Internet 的计算解决方案,它像电网传输电力那样提供共享的资源。云中的计算机一起工作,各种应用程序使用同一计算能力集合,好像它们在单一系统上运行一样。

    云计算的灵活性在于能够按需分配资源。因此,不再需要给任务分配特定的硬件,这会提高现有系统资源的利用率。在云计算出现之前,网站和基于服务器的应用程序都在特定的系统上运行。有了云计算之后,资源就集合为一台虚拟的计算机。在这种融合式配置提供的环境中,独立地执行应用程序,不需要关心任何具体配置。

    云为什么会掀起热浪

    出现向云计算转移这一潮流有许多合理的重要的业务和 IT 原因。原因之一是外包的基本性质要求有更合适的解决方案。

    • 降低成本:云计算可以降低资本费用 (CapEx) 和运营费用 (OpEx),因为可以只在需要时购买资源,而且只按使用时间付费。
    • 优化人力资源的使用:使用云计算可以解放宝贵的人力资源,让他们能够把精力集中在创造价值上,而不是维护硬件和软件。
    • 健壮的可伸缩性:云计算允许快速地扩大或收缩规模,既没有时间限制,也不需要承担长期义务。

    云计算的基本组成部分

    云计算模型由前端和后端组成。这两个部分通过网络连接,在大多数情况下是 Internet。用户通过前端与系统交互;后端是云本身。前端由客户机计算机(或企业的计算机网络)和用来访问云的应用程序组成。后端提供实现云服务的应用程序、计算机、服务器和数据存储。

     

    层:计算能力成为商品

    云的概念基于层,每一层提供一类功能。云组件的这种分层方式让云计算的各个层成为像电力、电话服务或天然气一样的商品。云计算以低廉的价格向用户销售计算能力这种商品。云计算将会成为新型的公共事业服务。

    虚拟机监视器 (virtual machine monitor, VMM) 让用户能够同时使用云设施(见图 1)。VMM 是主机系统上的一个程序,它让一台计算机支持多个相同的执行环境。从用户的角度来看,系统是一台与其他用户隔离的自含的计算机。实际上,所有用户都由同一台计算机提供服务。虚拟机是一个由底层控制程序管理的操作系统 (OS),这让它看起来像多个操作系统。在云计算中,VMM 允许监视用户,因此可以管理数据访问、数据存储、加密、寻址、拓扑和工作负载转移等方面。


    图1:虚拟机监视器的工作方式
    虚拟机监视器的工作方式

    下面是云提供的层:

    • 基础架构 层是云的基础。它由服务器、网络设备、存储磁盘等物理资产组成。IBM® Cloud 等提供基础架构即服务 (Infrastructure as a Service,IaaS)。在使用 IaaS 时,用户并不实际控制底层基础架构,而是控制操作系统、存储和部署应用程序,还在有限的程度上控制网络组件的选择。

      随需印刷 (Print On Demand,POD) 服务就是可以受益于 IaaS 的例子之一。POD 模型基于可定制产品的销售。POD 让个人能够在产品上进行设计并开店销售。店主可以上传他们的设计,数量不限。许多人上传了数千种设计。通过使用云存储功能,POD 可以提供无限的存储空间。

    • 中间层是平台。它提供应用程序基础架构。平台即服务 (Platform as a Service,PaaS) 提供对操作系统和相关服务的访问。它让用户能够使用提供商支持的编程语言和工具把应用程序部署到云中。用户不必管理或控制底层基础架构,而是控制部署的应用程序并在一定程度上控制应用程序驻留环境的配置。

      PaaS 的提供者包括 Amazon 的 Elastic Compute Cloud (EC2) 等。小企业软件工作室是非常适合使用 PaaS 的企业。通过使用云平台,可以创建世界级的产品,而不需要负担内部生产的开销。

    • 最上面一层是应用程序 层,这一层是对云的最直观表示。应用程序在这里运行,根据需要提供给用户。软件既服务 (Software as a Service,SaaS) 的提供者包括 Google Pack 等。Google Pack 包含可以通过 Internet 访问的应用程序和工具,比如 Calendar、Gmail、Google Talk、Docs 等等。

    图 2 给出这三层。


    图2:嵌入在 “服务式” 组件中的云计算层
    云计算层

    云的构成

    云的构成有三种类型:私有(内部)、公共和混合型。

    • 公共云可供一般公众或大型行业组织使用,由销售云服务的组织拥有和供应。公共云被看作一般意义上的云;也就是说,离站的第三方提供商使用 web 应用程序通过 Internet 动态地供应资源,它们提供共享的资源并按使用量收费。
    • 私有云位于公司防火墙之内,由组织自己管理。它们是在企业内部创建和控制的云服务。私有云具有许多与公共云相同的优点,主要差异在于您的组织负责创建和维护云。
    • 混合型云是公共云和私有云的组合,同时使用公共和私有的服务。公共云提供商和企业本身分别承担一部分管理责任。通过使用混合型云,组织可以先判断要创建的服务的目标和需求,然后以最合适的方式获得它们。

     

    IT在云中的角色

    考虑到管理和控制需要更加自动化,为了应对代码生产的增长,IT 人员的任务必须有所变化。IT 正在整合,对硬件和软件实现的需求更少了,但是也出现了新的任务。IT 的变化趋势是向知识工作者发展。在新的模型中,技术人员的主要责任是增强和升级一般业务过程。

    开发人员

    移动设备使用量的增长、社交网络的流行以及商业 IT 过程和系统在其他方面的发展将保证开发人员团队的工作更高效;但是由于云配置模型的系统化过程,企业开发人员的一些传统角色正在发生变化。

    IBM 最近的一项调查 New developerWorks survey shows dominance of cloud computing and mobile application development(见参考资料)表明,对移动技术的需求将呈指数级增长。这一趋势以及云计算在全球的快速流行势必导致了解这一领域的开发人员急速增加。为了满足不断增长的移动连接需求,需要更多了解云计算的开发人员。

    云计算提供近乎无限的容量,因此不再需要考虑可伸缩性。云计算让开发人员可以访问大多数中小型企业无法负担的极大量的软件和硬件资产。这种配置提供 Internet 驱动的云计算和资产,让开发人员能够访问过去只能梦想到的巨大资源。

    管理员

    管理员是 IT 系统的守护者和立法者。他们的责任是控制用户对网络的访问。这意味着他们控制用户密码的创建,以及为对系统资产的一般访问等基本功能制定规则和过程。云计算的出现势必导致对这一过程的调整,因为管理员在这种环境中不再只关心内部问题,还要关心自己的企业与云计算的外部关系,以及公共云中其他承租人的活动。

    由于管理和企业总体安全程序的性质,这还会改变防火墙的作用。这不会消除对保护系统的需求。云计算会带来更多责任,而不是减少。在云计算环境中,管理员不但必须在组织内部保护数据和系统,还必须监视和管理云,从而确保他们的系统和数据在所有地方的安全性。

    架构师

    架构师的任务是对真实 IT 环境中给定系统的功能进行有效的建模。基本责任是为代理商的云计算模型开发架构性框架。云计算的架构实际上由三个层(IaaS、PaaS 和 SaaS)的抽象组成,这种方式有助于部署云计算的企业满足自己的目标。需要开发层的功能的抽象,让决策者和基层人员能够使用这些抽象规划、执行和评估 IT 系统的过程。

    在云计算时代,架构师的作用是对云的层的功能性交互进行设计和建模。架构师必须使用抽象确保 IT 发挥应有的作用,帮助实现组织的目标。

     

    采用云还是不采用:风险评估

    正在转向云计算的组织最关心的问题是安全性和私密性。提供云计算服务的公司明白这一点,他们知道如果没有可靠的安全性,他们的企业一定会垮台。因此,安全性和私密性是所有云计算提供商优先考虑的问题。

     

    治理:如何监控行业标准

    在私有云中,治理由云的所有者负责;在公共云中,这一责任由服务提供商和服务使用方分担。但是,由于存在跨国恐怖主义活动、拒绝服务、病毒、蠕虫等因素 — 这些问题的某些方面超出了私有云所有者或公共云服务提供商和服务使用方的控制能力 — 所以需要全球、地区性和国家级的某种更广泛的协作。当然,对于公共云,这种协作不应该妨碍或损害云的所有者或使用者的控制能力。

     

    宽带需求

    如果打算采用云框架,那么必须在您的战略中评估带宽和可能出现的带宽瓶颈。在 CIO.com 的文章 The Skinny Straw: Cloud Computing's Bottleneck and How to Address It 中,提出了以下观点:

    在过去,对于实现虚拟化的组织,提高虚拟机密度的主要瓶颈是内存容量;现在,新型服务器提供的内存量大多了,内存不再是系统瓶颈了。云计算解决了机器密度问题,从而消除了这一瓶颈 — 解决机器密度问题成了云提供商的责任,云用户不需要考虑它。

    对于云计算,云用户与云提供商之间的带宽是瓶颈。

    那么,带宽问题当前最好的解决方案是什么?在当今的市场上,最好的方法是刀片服务器。刀片服务器是以物理空间和电力使用量最小化为目标优化过的服务器。对于云计算来说,刀片服务器的主要优点之一是提高了带宽速度。例如,IBM BladeCenter 可以快速高效地处理高性能计算工作负载。正如过去必须解决内存问题才能够有效地缓解高虚拟机密度的瓶颈,现在必须解决云计算的带宽瓶颈,所以要考察提供商的能力,判断带宽瓶颈是否是主要的性能问题。

     

    财务影响

    IT 运营成本中的相当一部分来自管理和控制方面,所以在云计算环境中其中一些任务的自动化会降低成本。自动化可以显著降低错误几率和人工重复工作的成本。

    其他一些因素对财务问题有不利影响,比如维护物理设施的成本、电力使用量、冷却系统以及控制和管理。无论如何,带宽不是惟一的问题。

    降低风险

    考虑下面的风险:

    • 数据处理不当的严重影响。
    • 有争议的服务费用。
    • 厂商的财务或法律问题。
    • 厂商的运营出现问题或关闭。
    • 数据恢复和机密性问题。
    • 一般的安全问题。
    • 外部力量发动的系统攻击。

    如果使用云中的系统,在数据安全性和连接性方面会有风险,恶意活动也可能会妨碍计算过程。但是,如果进行缜密的规划、谨慎地选择服务提供商并细致地管理风险,大多数公司可以安全地使用这种技术。

    结束语

    在这个革命性的新时代,云计算可以向组织提供确保财务稳定和高质量服务所需的方法。当然,如果云计算要想达到最佳的安全性和一般运营标准,就必须有全球协作。云计算出现了,我们所有人都必须准备好应对这次革命。


    参考资料

    学习

    • 阅读文章 New developerWorks survey shows dominance of cloud computing and mobile application development 提供的信息,了解云计算在今后几年内会发展到什么程度。

    • 通过 IBM Smart Business Cloud Computing 获取提高云性能和效率的宝贵建议。

    • 阅读 2010 年 1 月 23 日在布鲁塞尔召开的座谈会 The Future of Cloud Computing 的报告,了解云计算未来的发展方向。

    • 了解 Cloud4SOA 计划,其目标是组合三种相互补充的基本计算模型:云计算、面向服务架构 (SOA) 和轻量语义。

    • 寻找 European Network and Information Security Agency 开发的风险管理信息。

    • 阅读 Cloud Computing - A Primer 以基本了解云计算。

    • 在 developerWorks 云开发人员资源 中,发现和共享应用程序和服务开发人员有关构建云部署项目的知识和经验。
    展开全文
  • Linux 下在线扩容的几种方式及说明

    千次阅读 2019-08-19 14:34:27
    以下主要针对VM环境下Linux在线扩容在VM中新增磁盘并交付系统使用VM 中加入新磁盘扫描SCSI 总线以识别到新加入设备为识别到新磁盘分区为新分区准备文件系统建立目录,并将新空间挂载为以后自动挂载,编辑/etc/...


    在生产环境中磁盘空间不足,但又不方便停机维护的状况不可避免.
    以下操作可以在部分情况下在线扩容而不需要停机.
    扩容操作从空间来源上来说有两种方式,原磁盘增加空间和新增磁盘.
    Linux下磁盘分区也主要会分两种,LVM和EXT[3/4]
    从空间目的地来说也会有两种,扩展原有分区和新增分区并挂载.
    但总的流程基本一致,即 追加空间 --> 让kernel 识别刷新容量 --> 对新加空间进行分区操作 --> 交付文件系统使用 .

    在VM中新增磁盘并交付系统使用

    和Windows不一样,Linux下新增磁盘或对原磁盘增加容量并不会自动被kernel识别到.

    VM 中加入新的磁盘

    过程略

    扫描SCSI 总线以识别到新加入的设备

    echo “- - -”  > /sys/class/scsi_host/host0/scan
    

    此处的host0,指的是第一个scsi host adapter ,对应ESXI中磁盘的设备节点SCSI(0:1)中的0.
    传送的"- - -" 中的三个"-" 表示扫描所有 channel (first -), every target (second -), and every device i.e. disk/lun(third -)

    为识别到的新磁盘分区

    [root]# fdisk /dev/sdb
    Command (m for help):n
    Command action
    	e 			extended
    	p			primary partition (1 - 4 )
    p
    Partition number (1 - 4 ):1
    First cylinder (1-261,default 1):
    Using default value 1
    Last cylinder or + size or +sizeM or +sizeK(1-261, default 261):
    Using default value 261
    Command (m for help): w
    The partition table has been altered!
    Calling ioctr() to re-read partition table.
    Syncing disks
    

    为新分区准备文件系统

    [root]# msfs -t ext3 /dev/sdb1
    mke2fs 1.39 (29-May-2006)
    Filesystem label=
    OS type:Linux
    Block size=4096 (log=2)
    Fragment size=4096(log=2)
    ...
    Writing inode tables: done
    Creating journal (4096 blocks): done
    Writing superblocks and filesystem accounting information: done
    
    This filesystem will be automatically checked every 23 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.
    

    建立目录,并将新空间挂载

    [root]#mkdir /tmp/dd
    [root]#mount /dev/sdb1 /tmp/dd
    

    为以后自动挂载,编辑/etc/fstab

    /dev/sdb1			/tmp/dd	ext3				defaults 		0 				0
    设备						挂载点		文件系统		挂载规则		dump		order
    

    挂载规则:
    auto 开机自动挂载
    default 按照大多数永久文件系统的缺省值设置挂载定义
    noauto 开机不自动挂载
    nouser 只有超级用户可以挂载
    ro 按只读权限挂载
    rw 按可读可写权限挂载
    user 任何用户都可以挂载
    order 指fsck(启动时fsck检查的顺序)。为0就表示不检查,(/)分区永远都
    是1,其它的分区只能从2开始,当数字相同就同时检查(但不能有两1)。

    在VM中对已有磁盘扩容

    VM中增加现有磁盘大小

    过程略
    注意:如果此磁盘存在快照,则无法操作.原因显而易见.

    重新扫描改变大小的磁盘

    [root@ksyoweb01 ~]# echo 1> /sys/class/block/sda/device/rescan  #kernel 3.x
    [root@ksyoweb01 ~]#echo 1>/sys/class/scsi_device/0:0:1:0/device/block:sdb/device/rescan #kernel 2.x
    

    重新分区以使用新增的空间

    [root@ksyoweb01 ~]#  fdisk /dev/sdb
    命令 (m 以獲得說明):d
    分割區編號 (1,2, default 2): 2
    Partition 2 is deleted
    命令 (m 以獲得說明):n
    Partition type:
       p   primary (1 primary, 0 extended, 3 free)
       e   extended
    Select (default p): p
    分割區編號 (2-4, default 2): 2
    起初 sector (1026048-92274687, 預設 1026048):
    使用預設值 1026048
    最後 sector, +sectors 或 +大小{K,M,G} (1026048-92274687, 預設 92274687):
    使用預設值 92274687
    Partition 2 of type Linux and of size 43.5 GiB is set
    **如果是分配给LVM的则需要指定type**
    命令 (m 以獲得說明):t
    分割區編號 (1,2, default 2): 2
    Hex code (type L to list all codes): 8e
    Changed type of partition 'Linux' to 'Linux LVM'
    呼叫 ioctl() 以重新讀取分割表。
    
    WARNING: Re-reading the partition table failed with error 16: 裝置或系統資源忙碌中.
    The kernel still uses the old table. The new table will be used at
    the next reboot or after you run partprobe(8) or kpartx(8)
    同步磁碟。
    

    注意:
    较旧版核心在写入分区表的提示为 The new table will be used at the next reboot.
    这表明在线扩容梦想破灭,只能重启.

    通知系统分区表的变化 partprobe:

    [root@ksyoweb01 ~]# partprobe 
    Error: /dev/sda 上的分割區 2 已被寫入,但是我們並無法將變更通報內核,或許是因為它/它們正在使用中,結果造成繼續使用舊的分割區。在進行進一步的變更之前,您應該立刻重新開機。
    

    如果出现上面的提示,表示很不幸必须得重启.

    改变文件系统的大小

    root@test:~# resize2fs /dev/sdb2
    resize2fs 1.42.9 (4-Feb-2014)
    Filesystem at /dev/sdb2 is mounted on /; on-line resizing required
    old_desc_blocks = 2, new_desc_blocks = 4
    The filesystem on /dev/vda1 is now 12976128 blocks long.
    

    LVM 情况下操作

    [root@ksyoweb01 ~]# pvdisplay
      --- Physical volume ---
      PV Name               /dev/sda2
      VG Name               centos
      **PV Size               39.51 GiB / not usable 2.00 MiB**
      Allocatable           yes 
      PE Size               4.00 MiB
      Total PE              10114
      Free PE               11
      Allocated PE          10103
      PV UUID               JLiFFR-TWvr-E6uW-x77q-dZl1-MfrZ-T2PhUw
       
    [root@ksyoweb01 ~]# pvresize /dev/sda2
      Physical volume "/dev/sda2" changed
      1 physical volume(s) resized / 0 physical volume(s) not resized
    [root@ksyoweb01 ~]# pvdisplay
      --- Physical volume ---
      PV Name               /dev/sda2
      VG Name               centos
      **PV Size               43.51 GiB / not usable 2.00 MiB**
      Allocatable           yes 
      PE Size               4.00 MiB
      Total PE              11138
      Free PE               1035
      Allocated PE          10103
      PV UUID               JLiFFR-TWvr-E6uW-x77q-dZl1-MfrZ-T2PhUw
    [root@ksyoweb01 ~]# pvs
      PV         VG     Fmt  Attr PSize  PFree
      /dev/sda2  centos lvm2 a--  43.51g 4.04g
    [root@ksyoweb01 ~]# vgs
      VG     #PV #LV #SN Attr   VSize  VFree
      centos   1   2   0 wz--n- 43.51g 4.04g
    [root@ksyoweb01 ~]# lvs
      LV   VG     Attr       LSize  Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
      root centos -wi-ao---- 35.59g                                                    
      swap centos -wi-ao----  3.88g                                                    
    [root@ksyoweb01 ~]# lvextend -L +4G -f -r /dev/centos/root
      Size of logical volume centos/root changed from 35.59 GiB (9111 extents) to 39.59 GiB (10135 extents).
      Logical volume centos/root successfully resized.
    meta-data=/dev/mapper/centos-root isize=256    agcount=4, agsize=2332416 blks
             =                       sectsz=512   attr=2, projid32bit=1
             =                       crc=0        finobt=0
    data     =                       bsize=4096   blocks=9329664, imaxpct=25
             =                       sunit=0      swidth=0 blks
    naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
    log      =internal               bsize=4096   blocks=4555, version=2
             =                       sectsz=512   sunit=0 blks, lazy-count=1
    realtime =none                   extsz=4096   blocks=0, rtextents=0
    data blocks changed from 9329664 to 10378240 
    

    所以,很明显.如果后续可能会有在线空间扩展需求的,请使用LVM,不然的话,在线空间扩展只是个梦.

    展开全文
  • 这个是肯定可以做到,但是在大数据场景下,我们是不是会觉得有点慢呢,我们是否有更好解决方案,就像我写代码时候 有时候就会思考有没有更好解决方案,但是针对于要进行交付给用户,所以我们并没有那么多

    1、ETL背景

    在我们日常工作中,经常会有一些实时的需求,这些需求往往都是一些拉宽的需求,为了给实时数仓来进行OLAP对来进行Ad-hoc查询,但是我们工作中一些维度表的数据是会发生变化的,可能是缓慢变化维度,那么这个时候就需要进行flink连接其他数据源来进行查询,那么这个时候我们肯定可以想到就是来一条查一次,这个是肯定可以做到的,但是在大数据场景下,我们是不是会觉得有点慢呢,我们是否有更好的解决方案,就像我写代码的时候 有时候就会思考有没有更好的解决方案,但是针对于要进行交付给用户,所以我们并没有那么多的时间进行思考来进行,因为产品一直都在催你哦。那么我们就来看看有几种解决方案

    image-20201108184129406假设上图 是一个实时架构图,当然我们公司已经引入了clickhouse 实时数仓这些已经不是我们所追求的了,但是并不妨碍我们的需求,下面我们就来看一下数据。

    {"dt":"2019-11-19 20:33:39","countryCode":"TW","data": [{"type":"s1","score":0.8,"level":"D"},{"type":"s2","score":0.1,"level":"B"}]} 
    {"dt":"2019-11-19 20:33:41","countryCode":"KW","data": [{"type":"s2","score":0.2,"level":"A"},{"type":"s1","score":0.2,"level":"D"}]}
    {"dt":"2019-11-19 20:33:43","countryCode":"HK","data": [{"type":"s5","score":0.5,"level":"C"},{"type":"s2","score":0.8,"level":"B"}]} 
    {"dt":"2019-11-19 20:33:39","countryCode":"TW","data": [{"type":"s1","score":0.8,"level":"D"},{"type":"s2","score":0.1,"level":"B"}]}
    

    当然之上 是我们的模拟数据,接下来我们看看 业务人员需要什么数据

    "dt":"2019-11-19 20:33:39","countryCode":"AREA_CT","type":"s1","score":0.8,"level":"D"
    
    "dt":"2019-11-19 20:33:39","countryCode":"AREA_CT","type":"s2","score":0.1,"level":"B"
    

    那么这个时候我们可以发现了,其实就是把国家 换成大区,这样入仓之后可以进行 大区的olap实时的一些分析,例如实时的绩效考核等。还有一些营销活动等,我们就不细细考量了,因为毕竟都是假数据。

    那么我们看到原始数据和结果数据,我们发现,是进行了拆解,例如 一条记录中带有多个 type 也就是直播平台,但是结果数据拆成了两个,这个不是udtf吗

    同时将国家编码转化为大区编码,那么我们这时候假定大区编码会有变化,因为组织的重构问题,或者组织的架构演进等,那么我们思考一下 有几种解决方案呢。

    2、解决方案

    2.1 直接查库定时更新

     static class SimpleFlatMapFunction extends RichFlatMapFunction<String,OutData>{
    
    
                private transient ConcurrentHashMap<String, String> hashMap = null;
    
    
                @Override
                public void open(Configuration parameters) throws Exception {
                    super.open(parameters);
                    Jedis   jedisCluster = RedisFactory.getJedisCluster();
    
                    ScanResult<Map.Entry<String, String>> areas = jedisCluster.hscan("areas", "0");
                    List<Map.Entry<String, String>> result = areas.getResult();
                    System.out.println("更新缓存");
    
                    hashMap = new ConcurrentHashMap<>();
                    for (Map.Entry<String, String> stringStringEntry : result) {
                        String key = stringStringEntry.getKey();
                        String[] split = stringStringEntry.getValue().split(",");
                        for (String s : split) {
                            hashMap.put(s, key);
                        }
                    }
                    jedisCluster.close();
                    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
                    scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("更新缓存");
                            Jedis   jedisCluster = RedisFactory.getJedisCluster();
    
                            ScanResult<Map.Entry<String, String>> areas = jedisCluster.hscan("areas", "0");
                            List<Map.Entry<String, String>> result = areas.getResult();
                            hashMap = new ConcurrentHashMap<>();
                            for (Map.Entry<String, String> stringStringEntry : result) {
                                String key = stringStringEntry.getKey();
                                String[] split = stringStringEntry.getValue().split(",");
                                for (String s : split) {
                                    hashMap.put(s, key);
                                }
                            }
                            jedisCluster.close();
                        }
                    }, 0, 3, TimeUnit.SECONDS);
    
                }
    
                @Override
                public void flatMap(String s, Collector<OutData> collector) throws Exception {
                    OriginData originData = JSONObject.parseObject(s, OriginData.class);
                    String countryCode = originData.countryCode;
                    ArrayList<Data> data = originData.data;
                    String dt = originData.dt;
                    String coutryCode = hashMap.get(countryCode);
                    for (Data datum : data) {
                        OutData of = OutData.of(dt, coutryCode, datum.type, datum.score, datum.level);
                        collector.collect(of);
                    }
                }
        }
    

    2.2 异步IO

    static class SimpaleAsyncIoFunction extends RichAsyncFunction<String,OutData> {
            private transient RedisClient redisClient;
            @Override
            public void open(Configuration parameters) throws Exception {
                super.open(parameters);
                super.open(parameters);
                RedisOptions config = new RedisOptions();
                config.setHost("hadoop01");
                config.setPort(6379);
    
                VertxOptions vo = new VertxOptions();
                vo.setEventLoopPoolSize(10);
                vo.setWorkerPoolSize(20);
    
                Vertx vertx = Vertx.vertx(vo);
    
                redisClient = RedisClient.create(vertx, config);
            }
    
            @Override
            public void close() throws Exception {
                super.close();
                super.close();
                if(redisClient!=null){
                    redisClient.close(null);
                }
            }
            @Override
            public void asyncInvoke(String s, ResultFuture<OutData> resultFuture) throws Exception {
                OriginData originData = JSONObject.parseObject(s, OriginData.class);
                String countryCode = originData.countryCode;
    
                redisClient.hscan("areas", "0", ScanOptions.NONE, new Handler<AsyncResult<JsonArray>>() {
                    @Override
                    public void handle(AsyncResult<JsonArray> result) {
                        if (result.succeeded()){
                            JsonArray result1 = result.result();
                            if (result1 == null){
                                resultFuture.complete(null);
                                return;
                            }
                            JsonArray jsonArray = result1.getJsonArray(1);
                           // ["AREA_US","US","AREA_CT","TW,HK","AREA_AR","PK,KW,SA,XX","AREA_IN","IN"]
                            HashMap<String,String> ss = new HashMap<>();
                            ArrayList<String> keys = new ArrayList<>();
                            ArrayList<String> values = new ArrayList<>();
    
                            for (int i = 0; i <jsonArray.size() ; i++) {
                                if (i % 2 == 0){
                                    keys.add(jsonArray.getString(i));
                                }else {
                                    values.add(jsonArray.getString(i));
                                }
                            }
    
                            for (int i = 0; i < keys.size(); i++) {
                                String s1 = keys.get(i);
                                String s2 = values.get(i);
                                String[] split = s2.split(",");
                                for (String s3 : split) {
                                    ss.put(s3,s1);
                                }
                            }
                            String dt = originData.dt;
                            String country = ss.get(countryCode);
    
                            for (Data datum : originData.data) {
                                OutData outData = OutData.of(dt, country, datum.type, datum.score, datum.level);
                                resultFuture.complete(Collections.singleton(outData));
                            }
    
                        } else if(result.failed()){
                            resultFuture.complete(null);
                            return;
                        }
    
                    }
                });
    
            }
        }
    

    2.3 Broadcast的方式

    static class BroadcastSourceFunction extends RichSourceFunction<String>{
    
            @Override
            public void run(SourceContext<String> sourceContext) throws Exception {
                while (true){
    
                    Jedis   jedisCluster = RedisFactory.getJedisCluster();
    
                    ScanResult<Map.Entry<String, String>> areas = jedisCluster.hscan("areas", "0");
                    List<Map.Entry<String, String>> result = areas.getResult();
                    HashMap<String, String> hashMap = new HashMap<>();
    
                    for (Map.Entry<String, String> stringStringEntry : result) {
                        String key = stringStringEntry.getKey();
                        String[] split = stringStringEntry.getValue().split(",");
                        for (String s : split) {
                            hashMap.put(s,key);
    
                        }
                    }
    
                    sourceContext.collect(JSON.toJSONString(hashMap));
                    jedisCluster.close();
    
                    TimeUnit.SECONDS.sleep(3);
                }
    
    
    
    
            }
    
            @Override
            public void cancel() {
    
            }
        }
    
    

    2.4 异步io结合Cache

    我相信各位会了基础的 这个很简单也就不写了,有点累了,有时间可以补上。

    无非就是制定缓存淘汰算法,然后缓存有 就拿缓存的,没有就异步去redis拿而已。

    3、完整代码

    package com.bigdata.dim.join;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import io.vertx.core.AsyncResult;
    import io.vertx.core.Handler;
    import io.vertx.core.Vertx;
    import io.vertx.core.VertxOptions;
    import io.vertx.core.json.JsonArray;
    import io.vertx.redis.RedisClient;
    import io.vertx.redis.RedisOptions;
    import io.vertx.redis.op.ScanOptions;
    import org.apache.flink.api.common.functions.MapFunction;
    import org.apache.flink.api.common.functions.RichFlatMapFunction;
    import org.apache.flink.api.common.restartstrategy.RestartStrategies;
    import org.apache.flink.api.common.state.BroadcastState;
    import org.apache.flink.api.common.state.MapStateDescriptor;
    import org.apache.flink.api.common.state.ReadOnlyBroadcastState;
    import org.apache.flink.configuration.Configuration;
    import org.apache.flink.streaming.api.CheckpointingMode;
    import org.apache.flink.streaming.api.TimeCharacteristic;
    import org.apache.flink.streaming.api.datastream.BroadcastStream;
    import org.apache.flink.streaming.api.datastream.DataStreamSource;
    import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
    import org.apache.flink.streaming.api.environment.CheckpointConfig;
    import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
    import org.apache.flink.streaming.api.functions.async.ResultFuture;
    import org.apache.flink.streaming.api.functions.async.RichAsyncFunction;
    import org.apache.flink.streaming.api.functions.co.BroadcastProcessFunction;
    import org.apache.flink.streaming.api.functions.source.RichSourceFunction;
    import org.apache.flink.util.Collector;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import redis.clients.jedis.HostAndPort;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.ScanResult;
    
    import java.text.SimpleDateFormat;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Copyright (c) 2019 bigdata ALL Rights Reserved
     * Project: learning
     * Package: com.bigdata.dim.join
     * Version: 1.0
     *
     * @author qingzhi.wu 2020/11/8 11:12
     */
    public class Main {
        private static final int RESTART_ATTEMPTS = 5;
        private static final int RESTART_INTERVAL = 20;
        private static Logger logger = LoggerFactory.getLogger(Main.class);
    
        public static void main(String[] args) throws Exception {
            StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    
            env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
            //设置Stage策略
            CheckpointConfig checkpointConfig = env.getCheckpointConfig();
            env.enableCheckpointing(5000L);
            checkpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
            checkpointConfig.setMaxConcurrentCheckpoints(1);
            checkpointConfig.setCheckpointTimeout(100000L);
            checkpointConfig.setFailOnCheckpointingErrors(true);
            checkpointConfig.enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
            //测试环境不需要设置 backend
            //        FsStateBackend fsStateBackend = new FsStateBackend(CheckpointUtils.getCheckpointDir());
            //        env.setStateBackend(fsStateBackend);
            // 延迟时间间隔
            env.setRestartStrategy(RestartStrategies.fixedDelayRestart(
                    RESTART_ATTEMPTS, // 尝试重启次数
                    org.apache.flink.api.common.time.Time.of(RESTART_INTERVAL, TimeUnit.SECONDS)
            ));
    
    
            //自定义source 生成数据
            DataStreamSource<String> dataStreamSource = env.addSource(new DataSource());
            //1、采用直接用redis的方式
            SingleOutputStreamOperator<OutData> outDataSingleOutputStreamOperator = dataStreamSource.flatMap(new SimpleFlatMapFunction());
            //2.asynio
    //        SingleOutputStreamOperator<OutData> outDataSingleOutputStreamOperator =
    //                AsyncDataStream.unorderedWait(dataStreamSource, new SimpaleAsyncIoFunction(), 2000, TimeUnit.MILLISECONDS);
    //
            final MapStateDescriptor<String, String> broadcastDes = new MapStateDescriptor<>(
                    "broadcast",
                    String.class,
                    String.class );
            BroadcastStream<String> broadcast = env.addSource(new BroadcastSourceFunction()).broadcast(broadcastDes);
    
            SingleOutputStreamOperator<OutData> outDataSingleOutputStreamOperator = dataStreamSource.connect(broadcast).process(new BroadcastProcessFunction<String,  String, OutData>() {
                @Override
                public void processElement(String s, ReadOnlyContext readOnlyContext, Collector<OutData> collector) throws Exception {
                    ReadOnlyBroadcastState<String, String> broadcastState = readOnlyContext.getBroadcastState(broadcastDes);
                    String broadcastState1 = broadcastState.get("broadcastState");
                    HashMap<String,String> data = JSONObject.parseObject(broadcastState1, HashMap.class);
                    OriginData originData = JSONObject.parseObject(s, OriginData.class);
                    String countryCode = originData.countryCode;
                    ArrayList<Data> datas = originData.data;
                    String dt = originData.dt;
                    String coutryCode = data.get(countryCode);
                    for (Data datum : datas) {
                        OutData of = OutData.of(dt, coutryCode, datum.type, datum.score, datum.level);
                        collector.collect(of);
                    }
    
                }
    
                @Override
                public void processBroadcastElement(String s , Context context, Collector<OutData> collector) throws Exception {
                    BroadcastState<String, String> broadcastState = context.getBroadcastState(broadcastDes);
                    broadcastState.remove("broadcastState");
                    broadcastState.put("broadcastState",s);
                }
            });
    
    
            SingleOutputStreamOperator<String> map = outDataSingleOutputStreamOperator.map(new MapFunction<OutData, String>() {
    
                @Override
                public String map(OutData outData) throws Exception {
                    return JSON.toJSONString(outData);
                }
            });
            map.print();
            env.execute();
    
        }
    
        static class SimpleFlatMapFunction extends RichFlatMapFunction<String,OutData>{
    
    
                private transient ConcurrentHashMap<String, String> hashMap = null;
    
    
                @Override
                public void open(Configuration parameters) throws Exception {
                    super.open(parameters);
                    Jedis   jedisCluster = RedisFactory.getJedisCluster();
    
                    ScanResult<Map.Entry<String, String>> areas = jedisCluster.hscan("areas", "0");
                    List<Map.Entry<String, String>> result = areas.getResult();
                    System.out.println("更新缓存");
    
                    hashMap = new ConcurrentHashMap<>();
                    for (Map.Entry<String, String> stringStringEntry : result) {
                        String key = stringStringEntry.getKey();
                        String[] split = stringStringEntry.getValue().split(",");
                        for (String s : split) {
                            hashMap.put(s, key);
                        }
                    }
                    jedisCluster.close();
                    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
                    scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("更新缓存");
                            Jedis   jedisCluster = RedisFactory.getJedisCluster();
    
                            ScanResult<Map.Entry<String, String>> areas = jedisCluster.hscan("areas", "0");
                            List<Map.Entry<String, String>> result = areas.getResult();
                            hashMap = new ConcurrentHashMap<>();
                            for (Map.Entry<String, String> stringStringEntry : result) {
                                String key = stringStringEntry.getKey();
                                String[] split = stringStringEntry.getValue().split(",");
                                for (String s : split) {
                                    hashMap.put(s, key);
                                }
                            }
                            jedisCluster.close();
                        }
                    }, 0, 3, TimeUnit.SECONDS);
    
                }
    
                @Override
                public void flatMap(String s, Collector<OutData> collector) throws Exception {
                    OriginData originData = JSONObject.parseObject(s, OriginData.class);
                    String countryCode = originData.countryCode;
                    ArrayList<Data> data = originData.data;
                    String dt = originData.dt;
                    String coutryCode = hashMap.get(countryCode);
                    for (Data datum : data) {
                        OutData of = OutData.of(dt, coutryCode, datum.type, datum.score, datum.level);
                        collector.collect(of);
                    }
                }
        }
        static class SimpaleAsyncIoFunction extends RichAsyncFunction<String,OutData> {
            private transient RedisClient redisClient;
            @Override
            public void open(Configuration parameters) throws Exception {
                super.open(parameters);
                super.open(parameters);
                RedisOptions config = new RedisOptions();
                config.setHost("hadoop01");
                config.setPort(6379);
    
                VertxOptions vo = new VertxOptions();
                vo.setEventLoopPoolSize(10);
                vo.setWorkerPoolSize(20);
    
                Vertx vertx = Vertx.vertx(vo);
    
                redisClient = RedisClient.create(vertx, config);
            }
    
            @Override
            public void close() throws Exception {
                super.close();
                super.close();
                if(redisClient!=null){
                    redisClient.close(null);
                }
            }
            @Override
            public void asyncInvoke(String s, ResultFuture<OutData> resultFuture) throws Exception {
                OriginData originData = JSONObject.parseObject(s, OriginData.class);
                String countryCode = originData.countryCode;
    
                redisClient.hscan("areas", "0", ScanOptions.NONE, new Handler<AsyncResult<JsonArray>>() {
                    @Override
                    public void handle(AsyncResult<JsonArray> result) {
                        if (result.succeeded()){
                            JsonArray result1 = result.result();
                            if (result1 == null){
                                resultFuture.complete(null);
                                return;
                            }
                            JsonArray jsonArray = result1.getJsonArray(1);
                           // ["AREA_US","US","AREA_CT","TW,HK","AREA_AR","PK,KW,SA,XX","AREA_IN","IN"]
                            HashMap<String,String> ss = new HashMap<>();
                            ArrayList<String> keys = new ArrayList<>();
                            ArrayList<String> values = new ArrayList<>();
    
                            for (int i = 0; i <jsonArray.size() ; i++) {
                                if (i % 2 == 0){
                                    keys.add(jsonArray.getString(i));
                                }else {
                                    values.add(jsonArray.getString(i));
                                }
                            }
    
                            for (int i = 0; i < keys.size(); i++) {
                                String s1 = keys.get(i);
                                String s2 = values.get(i);
                                String[] split = s2.split(",");
                                for (String s3 : split) {
                                    ss.put(s3,s1);
                                }
                            }
                            String dt = originData.dt;
                            String country = ss.get(countryCode);
    
                            for (Data datum : originData.data) {
                                OutData outData = OutData.of(dt, country, datum.type, datum.score, datum.level);
                                resultFuture.complete(Collections.singleton(outData));
                            }
    
                        } else if(result.failed()){
                            resultFuture.complete(null);
                            return;
                        }
    
                    }
                });
    
            }
        }
        static class BroadcastSourceFunction extends RichSourceFunction<String>{
    
            @Override
            public void run(SourceContext<String> sourceContext) throws Exception {
                while (true){
    
                    Jedis   jedisCluster = RedisFactory.getJedisCluster();
    
                    ScanResult<Map.Entry<String, String>> areas = jedisCluster.hscan("areas", "0");
                    List<Map.Entry<String, String>> result = areas.getResult();
                    HashMap<String, String> hashMap = new HashMap<>();
    
                    for (Map.Entry<String, String> stringStringEntry : result) {
                        String key = stringStringEntry.getKey();
                        String[] split = stringStringEntry.getValue().split(",");
                        for (String s : split) {
                            hashMap.put(s,key);
    
                        }
                    }
    
                    sourceContext.collect(JSON.toJSONString(hashMap));
                    jedisCluster.close();
    
                    TimeUnit.SECONDS.sleep(3);
                }
    
    
    
    
            }
    
            @Override
            public void cancel() {
    
            }
        }
    
        static class RedisFactory {
            private static Jedis jedisCluster = null;
    
            private RedisFactory() {
            }
    
            public static Jedis getJedisCluster() {
    
    
                jedisCluster = new Jedis(new HostAndPort("hadoop01", Integer.parseInt("6379")));
    
    
                return jedisCluster;
            }
        }
    
    
        static class OriginData {
            public String dt;
            public String countryCode;
            public ArrayList<Data> data;
    
            public OriginData() {
            }
    
            public OriginData(String dt, String countryCode, ArrayList<Data> data) {
                this.dt = dt;
                this.countryCode = countryCode;
                this.data = data;
            }
    
            public static OriginData of(String dt, String countryCode, ArrayList<Data> data) {
                return new OriginData(dt, countryCode, data);
            }
        }
    
        static class Data {
            public String type;
            public Double score;
            public String level;
    
            public Data() {
            }
    
            public Data(String type, Double score, String level) {
                this.type = type;
                this.score = score;
                this.level = level;
            }
    
            public static Data of(String type, Double score, String level) {
                return new Data(type, score, level);
            }
        }
    
        static class OutData {
            public String dt;
            public String countryCode;
            public String type;
            public Double score;
            public String level;
    
            public OutData() {
            }
    
            public OutData(String dt, String countryCode, String type, Double score, String level) {
                this.dt = dt;
                this.countryCode = countryCode;
                this.type = type;
                this.score = score;
                this.level = level;
            }
    
            public static OutData of(String dt, String countryCode, String type, Double score, String level) {
                return new OutData(dt, countryCode, type, score, level);
            }
        }
    
        static class DataSource extends RichSourceFunction<String> {
            private static final String YYYYMMDDHHMMSS = "yyyy-MM-dd HH:mm:ss";
            private static Random random = new Random();
            private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat(YYYYMMDDHHMMSS);
            private static String[] countryCodes = {"US","TW","HK","PK","KW","SA","XX","IN"};
            private static String[] users = {"s1","s2","s3","s4","s5","s6","s7","s8","s9","s10","s11","s12","s13","s14","s15","s16"};
            private static String[] levels = {"A","B","C","D"};
    
            @Override
            public void run(SourceContext<String> sourceContext) throws Exception {
                while (true){
                    int i = random.nextInt(4);
                    long time = System.currentTimeMillis()+ 1000*i;
                    String resDate = simpleDateFormat.format(time);
                    i = random.nextInt(users.length);
                    String user1 = users[i];
                    Double score1 = Double.valueOf(String.format("%.1f", random.nextDouble()));
    
                    String countCode1 = countryCodes[i%countryCodes.length];
                    String level1 = levels[i%levels.length];
                    i = random.nextInt(users.length);
                    String user2 = users[i];
                    String countCode2 = countCode1;
                    String level2 = levels[i%levels.length];
    
                    Double score2 = Double.valueOf(String.format("%.1f", random.nextDouble()));
    
                    Data data1 = Data.of(user1, score1, level1);
                    Data data2 = Data.of(user2, score2, level2);
                    ArrayList<Data> datas = new ArrayList<>();
                    datas.add(data1);
                    datas.add(data2);
                    OriginData originData = OriginData.of(resDate, countCode1, datas);
                    String s = JSON.toJSONString(originData);
                    sourceContext.collect(s);
                    TimeUnit.SECONDS.sleep(1);
                }
    
    
            }
    
            @Override
            public void cancel() {
    
            }
        }
    }
    
    
    展开全文
  • 文 / 王不留(微信公众号...大学毕业通常23岁,刚进公司,经过为期一个半月培训之后,开始进入各产品线或交付线,从事相应工作。 这些工作安排,不是以个人意愿,而是以部门或公司意愿行事。 个人如...
  • 从质量保证者角度出发,除提升部署效率外,通过 CI 体系主要是为达到以下目标: 保证可以快速构建或... - 应用场景包括:功能交付上线;环境(如操作系统,编程语言)整体升级等 尽可能地缩短因 CI 部署导致...
  • 在这种环境下如何采用新开发方法(例如敏捷软件开发),这是一个重要课题:按照从前工作方式,开发和部署不需要IT支持或者QA深入、跨部门支持,而却需要极其紧密多部门协作。然而DevOps考虑还不止是...
  • 几种主要虚拟化

    2018-10-15 09:36:42
    ESXi是VMware公司研发虚拟机服务器,ESXi已经实现了...即插即用型软件的交付与安装提供了一全新和极其简化的方式。 通过iso镜像(比如VMWare ESXi 5.5.iso)在服务器上安装ESXi虚拟化服务,接着在本地PC机(win1...
  • 云计算服务(以下简称“云服务”)是基于互联网相关服务增加、使用和交付模式,通常涉及通过互联网来提供动态易扩展且经常是虚拟化资源。云服务指通过网络以按需、易扩展的方式获得所需服务。作为一个提供云服务...
  • OGG 12c中,并行交付有2模式:集成交付、协同交付。不过集成交付只能针对目标端是oracle数据库(有版本...在OGG12.1.2之前,如果在目标端碰上性能问题,延迟厉害,一般做法是将交付进程拆分为个。拆分的方式有...
  • 云上应用docker化持续交付实践

    千次阅读 2016-09-30 15:53:49
    摘要: 本文主要从现有持续交付过程中遇到问题,引发出Docker技术为软件交付方式带来革命,重点详细介绍几种常用开发语言持续交付实践, 最后会说明为什么Docker是Devops概念最佳诠释。 因为我非常...
  • 其名称、理念、过程、术语都有一定差别,但相对于传统“非敏捷”方式,更强调开发团队与业务专家之间紧密协作沟通(交流大于文档)、形成紧凑而自我组织型团队,这样可以有助于频繁交付软件版本,更好...
  • 该博客将尝试以一易于理解的方式解释这些术语。 什么是持续集成? 持续集成(CI)是一软件实践,要求开发人员每天至少一次,可能次将其代码提交到主工作区。 期望开发人员在提交源代码之前在其本地环境中...
  • 我们以四主要方式分发Stack组件: 作为公共@paralect帐户下公共软件包。 作为源代码,您只需复制/粘贴即可上手 作为公共DockerHub帐户下隔离服务公共paralect映像。 作为常见部署任务Ansible角色 堆叠...
  • 在本篇文章中,女主就给大家整理了一下,普遍使用的几种持续交付部署方式。以及各种方式的优缺点,供大家参考使用。PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!我们发现如果想要使...
  • CI&CD与持续交付

    2021-02-06 16:07:59
    持续交付 扫盲概念篇 持续集成、持续交付和持续部署关系 DevOps 代码 代码分支策略 ...如何做到构建提速 ...几种常见灰度方式 发布系统核心架构和功能设计 发布系统核心模型 发布流程及状态流转 .
  • 一 单项选择题 1.渐进式的交付方式,适合于()过程模型。 瀑布模型 快速原型模型 演化模型 ...3.软件的几种维护中,以()占比最高。 修正性维护 完善性维护 适应性维护 预防性维护 [参考答案] 完善
  • 从采用成熟度来分,从低到高有以下几种方式: (本文只描述了一部分优势和劣势,而且只代表个人观点) (并不是用越多越好,选择适合你) 1.只用Visual Studio  只使用visual studio作为开发工具(只是开发...
  • 该博客将尝试以一易于理解的方式解释这些术语。 什么是持续集成? 持续集成(CI)是一软件实践,要求开发人员每天至少一次,可能次将其代码提交到主工作区。 期望开发人员在提交源代码之前在其本地环境中...
  • 当下软件发展趋势 当今 IT 行业发展中比较流行的几个技术,首先是微服务化,将原有的一个系统拆分成多个,意味着有多个系统需要构建、测试、部署和运维。...那么有没有一更好的交付方式满足当下的软
  • CI/CD 是一通过在应用开发阶段引入自动化来频繁向客户交付应用方法。CI/CD 核心概念是持续集成、持续交付和持续部署。作为一个面向开发和运营团队解决方案,CI/CD 主要针对在集成新代码时所引发问题(亦称...
  • Table of Contents generated with DocToc GitLab CI GitLab User or Group Pages Did you fork this project?...This project's static Pages are built by GitLab CI, following the steps ...To use this project ...
  • 在广域网内进行数据文件传输,一般来说,典型解决方式有CDN、FTP、电子邮件以及消息中间件等方案,下面将对这几种方案进行简单分析。 1、CDN技术 CDN:Content Delivery Network(内容交付网络)。通过在现有...
  • 迄今为止,该项目是缺少UIKit / AppKit功能最完整移植,力求使其以大多数类似于Apple的方式交付。 这个项目目标是补充SwiftUI标准库,提供数百扩展和视图,使开发人员可以轻松地通过SwiftUI革命来构建...
  • 云计算是最近年提出来一个信息科技领域概念,是由Google提出网络应用模式。狭义云计算是指IT基础设施的交付和使用模式,指通过网络以按需、易扩展的方式获得所需IT基础设施。广义云计算是指服务的交付...
  • 一、边打工边创业这种方式一般是利用自己的专业经验和在自身的厂商资源在上班时间外进行创业尝试和增加收入,好处是没有任何风险,但应该处理好本职工作与创业的关系。...一单下来少的几千,多则几万,的确非...

空空如也

空空如也

1 2 3 4 5 ... 9
收藏数 162
精华内容 64
关键字:

交付的几种方式