阿里云服务-米姆科技官方网站 http://www.51mimu.com 广州米姆信息科技有限公司,深度服务阿里云用户,为阿里云用户提供产品及技术支持,产品包含:云服务器ECS、数据库RDS、网站加速CDN、阿里云邮箱、对象存储OSS、阿里云企业邮箱、阿里云邮箱个人版、安全防护WAF防火墙、高防IP DDOS、大数据、物联网iot、企业短信等产品服务,为用户给予阿里云优惠折扣解决方案、阿里云沙龙及阿里云峰会、 免费云主机免费试用、阿里云代理促销优惠活动、代金券限时优惠等活动服务,让用户享受米姆服务中心对用户的阿里云全栈服务。,在线咨询电话:020-22822863 Mon, 16 Dec 2019 05:35:01 +0800 zh-CN hourly 1 https://www.s-cms.cn/?v=4.7.5 公司文化 Mon, 16 Dec 2019 05:35:01 +0800

目前米姆采用人性化管理及制度综合管理相结合的方式让企业管理效率最大化,目前我公司的管理制度,涉及到安全、流程、认证等各方面,各种制度健全合理,包含部分岗位流程SOP、销售服务准则、职能认证规范及要求等十数种程序文件。从各种制度的执行情况来看,各种制度制定的有效合理,能够有效地给予生产进行指导和员工行为规范的约束


   

米姆核心目标:

米姆立志并已致力成为全球领先的企业数字化转型一站式解决方案和营销一体化的服务提供商。价值观:技术创新、诚信合作、以人为本、服务企业员工:员工相互信任、尊重、积极向上,为员工提供更多的培训机会,鼓励员工技术与管理创新、分享知识与经验,为员工提供一个公平公正的可持续发展平台,为客户提供一个搞效率服务平台。
诚信:铸诚魂 弘商誉品质:品质第一 客户至上创新:持续创新 不断超越分享:整合资源 分享世界
]]>
米姆(MEME)科技简介 Mon, 16 Dec 2019 05:35:01 +0800            

我们初创 却并非新生


    广州米姆信息科技有限公司简称米姆或MEME,伴随着企业上云和产业互联网化的趋势快速发展,米姆立志并已致力成为企业数字化转型一站式解决方案和营销一体化的服务提供商。
我们的核心团队汇聚了来自于阿里、华为和中软等业内领先企业的高端人才,完全具备了理解用户,提供物超所值的解决方案和服务的能力。
    目前,我们已经成为阿里云和华为的生态合作伙伴,为更好地提供数字化解决方案和服务,我们也与相关领域的优秀平台达成战略合作。
    米姆的核心理念在于创新,在于进步,更在于分享。选择我们,就是选择未来!







]]>
2020年春运火车票今天开售;果冻有家,关注年轻人租房子的隐藏需求-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 苹果发布iOS13更新:iPhone联通用户要升级,解决4G信号差

12月11日苹果推送了iOS 13.3正式版,主要是继续修复系统的Bug,提高稳定性,在iPhone和iPad的“屏幕使用时间”上,可以允许父母控制孩子的联系人,支持FaceTime、电话和信息应用,而系统还支持 NFC、USB和闪电接口的FIDO2安全密匙,并且针对无线充电还做了优化。对于联通用户,更新设备后,手机可以支持VoLTE,有了这个功能后,在iPhone上使用联通网络的用户在4G打电话的时候不需要掉到3G了。

果冻有家,关注年轻人租房子的隐藏需求

果冻有家是一款应政策背景和市场趋势而生的租房APP,瞄准的是最具活力的95乃至00后的新生代群体。果冻有家着重突出的社交互动等功能最大限度的迎合了目标群体特色。果冻有家配合智能家打造、在线商城、在线金融等元素构建围绕房子的完整生态系统。

2020年春运火车票今天开售,预计发送旅客4.4亿人次

国铁集团表示,2020年春运全国铁路运输呈现5大特点,春运动车组发送旅客比例预计达到63%以上,实现电子客票在全国高铁线路的基本覆盖。此外,国家铁路集团有限公司11日披露,2020年铁路春运自1月10日开始,2月18日结束,共40天,节前15天,节后25天。全国铁路预计发送旅客4.4亿人次,同比增长8%。

QQ音乐开放平台发布“亿元激励”计划:10万元以下都归入驻音乐人

获悉,12 月 12 日,腾讯音乐娱乐集团上市一周年之际,QQ音乐开放平台发布“亿元激励”分红计划,将大幅提高入驻音乐人的收入分成比例,其亮点为“激励金10万元以下都归你”。QQ音乐开放平台于今年11月上线,短短一个月,新入驻音乐人达1.2万,上传作品总播放量近6亿,助力永彬Ryan.B、Uu等年轻音乐人迅速蹿红,推出《桥边姑娘》《像极了》等全网爆款热歌。其中,《桥边姑娘》1周播放过亿。

微信“好物圈”更名并升级为“微信圈子”

微信的“好物圈”正式更名并升级为“微信圈子”。同一天,“微信搜索”也升级为“微信搜一搜”。目前,微信圈子入口被提升到搜一搜功能的主界面,并且也支持微信圈子植入公众号文章中进行推广。

“无印良品”商标之争终审宣判,良品计画、上海无印良品败诉

近日,北京市高级人民法院就无印良品侵犯商标权纠纷案作出终审判决,判令良品计画、上海无印良品立即停止侵犯棉田公司、北京无印良品注册商标专用权的行为,在天猫“无印良品MUJI官方旗舰店”和中国大陆的实体门店发布声明以消除侵权影响,并赔偿经济损失50万元及合理开支12.6万余元。目前,日本无印良品已在天猫“无印良品MUJI官方旗舰店”作出相关声明。

]]>
人人都在谈论的云原生到底是什么?——3分钟,让你快速了解云原生!-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 原文链接
  随着虚拟化技术的成熟和分布式架构的普及,用来部署、管理和运行应用的云平台被越来越多的提及。IaaS、PaaS和SaaS是云计算的3种基本服务类型,它们是关注硬件基础设施的基础设施即服务、关注软件和中间件平台的平台即服务以及关注业务应用的软件即服务。
  在容器技术、可持续交付、编排系统等开源社区的推动下,以及微服务等开发理念的带动下,应用上云已经是不可逆转的趋势。随着云化技术的不断进展,云原生的概念也应运而生。

image.png


云原生概念的诞生

  云原生(Cloud Native)的概念,由来自Pivotal的MattStine于2013年首次提出,被一直延续使用至今。这个概念是Matt Stine根据其多年的架构和咨询经验总结出来的一个思想集合,并得到了社区的不断完善,内容非常多,包括DevOps、持续交付(Continuous Delivery)、微服务(MicroServices)、敏捷基础设施(Agile Infrastructure)和12要素(The Twelve-Factor App)等几大主题,不但包括根据业务能力对公司进行文化、组织架构的重组与建设,也包括方法论与原则,还有具体的操作工具。采用基于云原生的技术和管理方法,可以更好地把业务生于“云”或迁移到云平台,从而享受“云”的高效和持续的服务能力。
image.png

The Twelve-Factor App

  顾名思义,云原生是面向“云”而设计的应用,因此技术部分依赖于传统云计算的3层概念,基础设施即服务(IaaS)、平台即服务(PaaS)和软件即服务(SaaS),例如,敏捷的不可变基础设施交付类似于IaaS,用来提供计算网络存储等基础资源,这些资源是可编程且不可变的,直接通过API可以对外提供服务;有些应用通过PaaS服务本来就能组合成不同的业务能力,不一定需要从头开始建设;还有一些软件只需要“云”的资源就能直接运行起来为云用户提供服务,即SaaS能力,用户直接面对的就是原生的应用。

云原生并不是一个产品

  最近讨论云原生应用越来越多。关于云原生应用,简单地说,就是大多数传统的应用,不做任何改动,都是可以在云平台运行起来,只要云平台支持这个传统应用所运行的计算机架构和操作系统。只不过这种运行模式,仅仅是把虚拟机当物理机一样使用,不能够真正利用起来云平台的能力。
  云并非把原先在物理服务器上跑的东西放到虚拟机里跑,真正的云化不仅是基础设施和平台的事情,应用也要做出改变,改变传统的做法,实现云化的应用——应用的架构、应用的开发方式、应用部署和维护技术都要做出改变,真正的发挥云的弹性、动态调度、自动伸缩……一些传统IT所不具备的能力。这里说的“云化的应用”也就是“云原生应用”。云原生架构和云原生应用所涉及的技术很多,如容器技术、微服务、可持续交付、DevOps等。
image.png
  而云原生应用最大的特点就是可以迅速部署新业务。在企业里,提供新的应用程序环境及部署软件新版本通常所需时间以日、周甚至以月计算。这种速度严重限制了软件发布所能承受的风险,因为犯错及改错也需要花费同样的时间成本,竞争优势就会由此产生。
  所以云原生不是一个产品,而是一套技术体系和一套方法论,而数字化转型是思想先行,从内到外的整体变革。更确切地说,它是一种文化,更是一种潮流,是云计算的一个必然导向。意义在于让云成为云化战略成功的基石,而不是障碍。它可以根据商业能力对公司进行重组的能力,既包含技术、也包含管理,可以说是一系列云技术和企业管理方法的集合,通过实践及与其他工具相结合更好地帮助用户实现数字化转型。

云原生计算基金会(CNCF)

  CNCF,即云原生计算基金会,2015年由谷歌牵头成立,基金会成员目前已有一百多企业与机构,包括亚马逊、微软、思科等巨头。
  目前CNCF所托管的应用已达14个,下图为其公布的Cloud Native Landscape,给出了云原生生态的参考体系。
image.png

Cloud Native Landscape新版


CNCF(云原生计算基金会)认为云原生系统需包含的属性:

容器化封装: 以容器为基础,提高整体开发水平,形成代码和组件重用,简化云原生应用程序的维护。在容器中运行应用程序和进程,并作为应用程序部署的独立单元,实现高水平资源隔离。
自动化管理:统一调度和管理中心,从根本上提高系统和资源利用率,同时降低运维成本。
面向微服务:通过松耦合方式,提升应用程序的整体敏捷性和可维护性。
  正因为如此,你可以专注于创新,解决业务问题,而不是把时间花在“静态、不灵活的传统架构”存在的许多技术问题。

云原生的四要素:持续交付、DevOps、微服务、容器

  从云原生的概念中,我们总是能看到持续交付、DevOps、微服务、容器等技术的出现,那么它们到底是什么,这里引用Pivotal台湾云计算资深架构师的部分观点,为大家逐一揭开他们的神秘面纱!

image.png

持续交付——缩小开发者认知,灵活开发方向

  首先是持续交付,什么样的时候客户要求持续交付?敏捷开发要求持续交付,因为敏捷开发要求随时有一个版本可以上到大群环境,所以要持续交付
  而换句话说,持续交付就是不误时开发。举一个例子,有些公司非常喜欢谈需求,谈很久,可是开发只剩1/3时间就开发完成,然后交付,再上线运营。这就会碰到一个问题,就是你开始谈需求到最后交付产品的时间,短则三月,长则半年,这中间市场已经变化了,需求也随之变化了。因此市场上出现了新的想法,即是不是能够小步快跑,把交付的周期缩短一点,我可以实现快速交付,每次交付都可以重新确认方向,这样尽量避免与未来期待的落差。
image.png

用小步快跑的方式,打破瀑布式开发流程

  那么问题来了,持续交付对于开发的人谈的需求、开发的方式有改变,那它对于开发有影响吗?如果说公司的开发团队一天可以交付五次,那研发团队要帮忙部署一次吗?现在公司大部分部署都是研发团队帮忙部署应用的,研发团队部署五次,要改版五次就需要部署一次,这是无法实现的。而且每次部署的时候都要面对停机,而实际公司的应用经不起一天停机五次部署,在互联网的思维之下,零宕机时间已经是现在企业的基本要求。于是“蓝绿部署”的概念营运而生。即在一个环境里面,第一版还在线上服务,第二版先做封测,封测完成后,让外面的流量进来一些,看log是不是开发人员要的,确认后再把全部的流量导到新的版本上。
image.png

图:蓝绿(Blue-Green) 部署

  但“蓝绿部署”在系统过多过复杂的情况下,在传统架构上实现非常困难,所以企业要做到zero down time的持续交付就需要有良好的平台與工具协助。因此,持续交付的优势在于,它可以缩小开发者认知,重新确认开发方向。

微服务——内聚更强,更加敏捷

  第二部分是微服务。微服务是什么?有客户表示,提供商出产品,客户把应用全部放上去,结果就是一个微服务。这种认知是错误的,因为微服务是一个架构的改变。那么微服务是怎么做的呢?它所面临的最大挑战是什么?
  是切割。那么如何切割呢?其实这件事情早在1968年康威就提出了——康威定律,系统的服务划分应该是根据组织架构的功能来划分。1968年康威就提出了这个想法,我认为拿来做微服务的切割非常适用。
image.png

Going Agile - Breaking the monolith
Conway's Law and Microservices

  这样按照组织架构划分的优势在于:

  1.内聚更强,所有遵循同一种业务准则的人内聚在一起,就容易解决问题。
  2.服务解耦,变更容易,更加敏捷。当做到解耦合的时候,要变更就容易。所以微服务应该是切分成这个样子,由上而下来切,根据Function来切。
  另外一个划分微服务的技巧,可以运用领域驱动设计(Domain Driven Design)的理论,而领域驱动设计亦可算是面向物件的一种设计思维;聚合可以让微服务划分更有依据,也让未來的系統变更具有弹性。值得一提的是领域驱动设计,也提供微服务中的事物问题。因为过去巨石应用进行两个报数的阶段,相当容易也常见,但在微服务架构中,如何在分散的服务中进行事物就显得相当困难。利用领域驱动设计的Event Souring进行设计,是目前最好的解決办法。

  那么在什么情况下需要微服务?我认为有三个标准:

  1.有HA(High Available)的需求需要微服务。
  2.有性能调校的需求(例如:图片的呈现或者搜寻)需要微服务。
  3.经常变更的需要微服务。
  实际上,微服务需要关注的源代码范围比较小,使得各个服务解耦、变更容易,内聚更强,因为都会集中在服务里。另外,它更容易单独改版,因为微服务之间是用RESTful间接起来的,用RESTful只要API的界面不改,原则上则不会错,也更敏捷。
  但微服务也会留下一些问题,例如App团队如何分工?环境怎么配合?如何实现自动化部署?

容器技术——使资源调度、微服务更容易

  再来看看容器。在机器上运行的容器只是主机操作系统上的一个进程,与任何其他进程无异。那么,为什么容器如此受欢迎呢?原因在于这个进程被隔离和限制的方式。这种方式很特殊,可简化开发和运维。
  其实1979年就有容器技术,很多人会以为说Docker是不是等于容器,其实Docker不等于容器。容器的历史可追溯到Linux操作系统。容器利用了Linux的内核功能。Linux中容器的核心概念(cgroup、namespaces和filesystems)在独立的区域运行。容器的神奇之处在于将这些技术融为一体,以实现最大的便利性。
  VMware之前的技术专家在2011年发展出一个技术,把这个技术贡献出来成立了一个Cloud Foundry基金会。Docker在2013年才开始有,而且它第一版是用SLC的技术去做的。后来陆续一路成长,使得为服务的实现更容易了。
image.png

从 Infra 角度来看技术演进

  从上面这个表中可以看出,从左边开始,IaaS,虚拟化技术有了之后,刚刚提到的所谓第三代平台,这四个区块开发人员交付的内容不一样。所有的IaaS、CaaS、PaaS、FaaS一路的变化演进,对于客户的负担越到后面越小,而对于开发人员的想象力则愈发抽象。
  大家一定会遇到下列这些计算,一个是所谓的单体应用,或者翻译成巨石应用。此外,你们一定会有一些批次的管理,另外就是所谓的数据库的部分,开始可能会有容器技术,像K8S、Dock。
  Docker是软件行业最受欢迎的软件容器项目之一。思科、谷歌和IBM等公司在其基础设施和产品中使用Docker容器。
  Kubernetes是软件容器领域的另一个值得关注的项目。Kubernetes是一个允许自动化部署、管理和伸缩容器的工具。为了便于管理其容器,谷歌建立了Kubernetes。它提供了一些强大的功能,例如容器之间的负载均衡,重启失败的容器以及编排容器使用的存储。
image.png

容器生态图 /作者:Jimmy Song

  容器为云原生应用程序增加了更多优势。使用容器,你可以将微服务及其所需的所有配置、依赖关系和环境变量移动到全新的服务器节点上,而无需重新配置环境,这样就实现了强大的可移植性。

DevOps——以终为始,运维合一

  最后让我们走向DevOps,它不是一种工具,DevOps其实要谈的是运维合一。
  DevOps如果从字面上来理解只是Dev(开发人员)+Ops(运维人员),实际上,它是一组过程、方法与系统的统称,其概念从2009年首次提出发展到现在,内容也非常丰富,有理论也有实践,包括组织文化、自动化、精益、反馈和分享等不同方面。
  首先,组织架构、企业文化与理念等,需要自上而下设计,用于促进开发部门、运维部门和质量保障部门之间的沟通、协作与整合,简单而言组织形式类似于系统分层设计。
  其次,自动化是指所有的操作都不需要人工参与,全部依赖系统自动完成,比如上述的持续交付过程必须自动化才有可能完成快速迭代。再次,DevOps的出现是由于软件行业日益清晰地认识到,为了按时交付软件产品和服务,开发部门和运维部门必须紧密合作。
  总之,DevOps强调的是高效组织团队之间如何通过自动化的工具协作和沟通来完成软件的生命周期管理,从而更快、更频繁地交付更稳定的软件。在内部沟通上,你可以想象DevOps是一个敏捷思維,是一个沟通的文化。当运营和研发有良好的沟通效率,才可以有更大的生产力。如果你的自动化程度够高,可以自主可控,工作负担降低,DevOps能够带来更好的工作文化、更高的工作效率。

总结

  综上所述,云原生的DevOps、平台、持续交付、微服务都是云原生不可或缺的一部分,需要以全局地眼光看待问题,脱离任何一个元素,对于企业来说都是“管中窥豹”、“一叶障目”,只有加以整合才能见到云原生的全局风貌。
  面对业态各异的业务上云以及碎片化的物联网解决方案部署,利用云原生思维和模式,构建基于云原生的物联网平台以及解决方案,势必将加速企业,甚至整个社会的数字化转型。

]]>
移动无线通信技术经历了哪些变迁? | 《5G移动无线通信技术》之一-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 5G丛书
5G移动无线通信技术
image.png
(瑞典)Afif Osseiran
(西)Jose F. Monserrat
(德)Patrick Marsch 著
陈明,缪庆育,刘愔 译

第1章 移动无线通信技术的变迁

1.1历史回顾

诞生于 21 世纪的信息通信技术(又称 ICT 技术)起源于 20 世纪两个主要产业的融 合,即电信产业和计算机产业的融合。本书的目的是描述移动通信产业第五代技术的发 展趋势,这些技术将实现多种通信服务的增强融合,在包括连接、信息处理、数据存储 和人工智能在内的、复杂的分布式环境中,实现内容的分发、通信和运算。这些技术的 巩固和加强模糊了传统的技术功能的边界。例如,计算和存储嵌入到通信基础设施之中, 流程控制分布于互联网之上,而运算功能迁移到集中的云计算环境之中。

1.2工业和技术革命:从蒸汽机到互联网

ICT 产业源于电信产业和(计算机)互联网产业的结合,并给信息和通信服务的供给 和分发方式带来巨大的变革。大量被广泛使用的移动连接设备,推动社会进一步深入变革, 社会变得更加网络化和连接化,从而在经济、文化和技术方面产生深远影响。人类社会正 在经历一场技术革命,这个过程始于 20 世纪 70 年代半导体技术和集成电路技术的发展, 以及随之而来的信息技术(IT)的成熟和20世纪80年代现代电子通信技术的发展。下一 代 ICT 产业中日趋成熟的前沿包括,构建在不同的场景中,同时满足服务需求差异巨大 的交付框架,满足大量的不同需求,例如,来自和去往互联网的个人媒体交付,实现万物互联(物联网),并将安全和移动性作为可以配置的功能引入所有通信服务。有人将其 称为工业革命的第四阶段 [1]。 工业革命的四个阶段如图 1.1 所示。 第一阶段始于英国(大约 1760—1840 年),其间诞生了动力织布机和蒸汽机。在随 后的几十年里,12 世纪的农业经济迅速转型为工业经济,用于生产货物的机器大行其道。
image.png
第二阶段(大约 1840—1914 年)始于贝西默钢铁生产程序,这一阶段实现了早期工业电气化,大规模工业制造和流水线生产方式。电气化生产线上的工人分工更加专业,从而实现了大规模工业制造。
第三阶段(大约1950—2010年)主要归功于电子信息技术,特别是可编程逻辑控制器件 (Programmable Logic Controllers,PLC)的发明。这些技术进一步提升了生产流程自动化和产能。
第四阶段也就是我们目前所处的时代。在这个时代,通过新一代无线通信技术实现万物互联,无处不在地连接设备和物品,推动工业自动化水平再次飞跃。
人们期待的第五代移动通信(5G)提供了进入工业革命第四阶段的途径。因为它将以人为主要服务对象的无线通信,延伸到人与物全连接的世界。特别需要指出的是5G包括了:

  • 连接成为人与物的标准配置;
  • 关键和海量的机器连接;
  • 新的频段和监管制度;
  • 移动和安全成为网络功能;
  • 通过互联网的内容分发集成;
  • 网络边缘处理和存储;
  • 软件定义网络和网络功能虚拟化。

1.3 移动通信的发展:从 1G 到 4G

图 1.2 给出了蜂窝移动通信的发展史。从 20 世纪 70 年代的婴儿期(第一代无线通信1G)到 2020 年(第五代移动通信5G),蜂窝移动通信系统演进的主要历程见图 1.2。
image.png
第一代商用模拟移动通信系统部署于 20 世纪五六十年代 [2],但市场渗透率很低。 1981 年诞生了第一代移动蜂窝系统(1G),包括北欧国家部署的北欧移动电话系统 (NMT) ,德国、葡萄牙和南非部署的 C-Netz 系统,英国部署的TACS 系统和北美部署 的 AMPS 系统。1G 由于采用模拟技术而被称为模拟标准,通常采用调频信号和数字信令信道。1982 年欧洲邮电管理大会(CEPT)决定开发泛欧第二代移动通信系统,即处于2G统治地位的 GSM 系统,1991 年 GSM 开始国际部署。2G的标志是实现了数字发 送技术和交换技术。数字技术有效地提升了话音质量和网络容量,同时引入了新服务和 高级应用,例如用于文本信息的存储和转发的短消息。
设计 GSM 系统的首要目的是实现欧洲数字语音服务的国际漫游。与 1G 仅使用 了 FDMA 相比,GSM 采用了混合的时分多址(TDMA) / 频分多址(FDMA)技术。与 此同时,全球其他的 2G 系统也在部署过程中,并且相互竞争。这些 2G 技术包括:(1)北美的 NA-TDMA(TIA/EIA-122)标准;(2) CDMAOne(TIA/EIA IS-22A) [2];(3) 仅用于日本的个人数字蜂窝系统(PDC)。2G 的演进又称为 2.5G,在语音和数据电路交换之上,引入了数据分组交换的业务。主要的 2.5G 标准包括 GPRS 和 TIA/EIA-221, 二者分别是 GSM 和 TIA/EIA-p2A 的演进版。此后不久,GSM 进一步演进为 EDGE 和 EGPRS。其性能增强主要是采用了更高级的调制和编码技术。GSM/EDGE 在 3GPP 标准继续演进,并且在最新的版本里支持更宽的带宽和载波聚合技术。
2G 系统商用不久,业内就开始准备和讨论第三代无线通信系统。同时国际电信联盟无线通信委员会(ITU-R)制定了国际移动通信系统 2000(IMT-2000)的要求。1998 年 1 月,两个基于 CDMA 技术的标准被欧洲通信标准协会(ETSI)接纳为全球移动通信系统(UMTS),分别是宽带 CDMA(WCDMA)和时分 CDMA(TD-CDMA)技术。 UMTS 成为主要的 3G 移动通信系统,并且是最早达到 IMT-2000 要求的技术。最终有6个空中接口技术满足IMT-2000要求,包括3个基于CDMA的技术,1 个GSM/EDGE 的新版本(称为UWC-136)和另外2 个基于OFDMA的技术 [5]。如图 1.2 所示,在 3G 合作伙伴项目(3GPP)的框架内,制定了被称为 3G 演进的新技术规范,即 3.5G。这一演进技术建议包括两个无线接入网络(RAN)技术和一个核心网演进建议。
第一个 RAN 技术是 3GPP2 制定的基于cdma2000 的演进版本 1xEV-DO 和 1xEVDV。第二个 RAN 技术是高速数据分组接入技术(HSPA)。HSPA 由 3GPP R5 版加入下 行 HSPA(HSDPA)和 3GPP R6 版加入上行 HSPA(HSUPA)组成。二者都是为了提升数 据速率,下行提高到 14.6Mbit/s,上行提高到 5.76Mbit/s。在 MIMO 引入后,速率获得 进一步提升。HSPA 技术基于 WCDMA 并且完全后向兼容。CDMA 1xEV-DO 在 2003 年 开始部署,HSPA 和 CDMA 1x EV-DV 于 2006 年实现商用。
所有 3GPP 标准始终保持着新功能后向兼容的理念。这也体现在 HSPA 的进一步演 进 HSPA+,该技术通过载波聚合获得更高的速率,但不影响原有终端正常使用。 第二个UMTS演进技术,也被商业上认为是4G技术,称为LTE7,包括了新的基于正交频分多址(OFDMA)的空中接口,新的网络架构和新的称为SAE/EPC的核心网(CN)。 LTE与UMTS并不后向兼容,并期望在2007年的世界无线电大会(WRC)获得更多的频谱。这个标准设计灵活,可以部署在从1.4MHz到20MHz的不同带宽的载波上。
LTE 标准实现了系统容量的大幅提升,其设计使蜂窝网络脱离了电路交换的功能。与之前的通信系统相比,这一改进显著降低了成本。2007 年年底,第一个 LTE 版本得 到 3GPP 批准,称为 LTE R8 版本。这一版本的峰值速率约为 326Mbit/s,和以前的系统 相比频谱利用效率获得了提升,并显著降低了时延(下降到20ms)。与此同时,ITU-R 提出了 IMT-2000 的后续要求(IMT-Advanced)作为制定第四代移动通信系统的标称 要求。LTE R8 版本并不能达到 IMT-Advanced 的要求,因此被认为是前 4G 技术。这 些要求后来有所放松,因此 LTE 被统一认为是 4G 技术。技术上,3GPP LTE R10 版本 和 IEEE 802.16m(又称 WiMAX)是最早满足 IMT-Advanced 要求的空中接口技术。而 WiMAX 尽管被批准成为 4G 标准,但没有被市场广泛接受,最终被 LTE 取代。与 R8 版本相比,LTE R10 版本新增了高阶 MIMO 和载波聚合的技术,从而提升了容量和速率,利用高达 100MHz 的载波聚合带宽可以达到 3Gbit/s 下行峰值速率和 1.5Gbit/s 上行峰值速率。其中下行采用 8x8 MIMO,上行采用 4x4 MIMO。
3GPP 对于 LTE 的标准化工作持续进行,包括 R11 版本到 R13 版本,以及后续版本。 LTE R11 版本通过引入载波聚合、中继和干扰消除技术优化了 LTE R10 版本的容量。同时,增加了新的频谱以及多点协同发送和接收(CoMP)技术。
在 2015 年 3 月冻结的 LTE R12 版本增加了异构网络和更高级的 MIMO 以及 FDD/ TDD载波聚合。另外增加了一些回传和核心网负载均衡的功能。接下来LTE R11和R13版 本,为了支持机器类通信(MTC),例如传感器和电动装置,引入了新的物联网解决方案(包 括LTE-M和窄带物联网NB-IoT) 9。这些新技术提升了覆盖,延长了电池的续航能力,降低 了终端成本。R13版本为了获得极高的移动宽带速率引入高达32载波的载波聚合技术。
截至 2015 年年中,全球蜂窝移动用户数达到74.9 亿 [11],其中 GSM/EDGE,包括以 数据通信为目标的 EGPRS 主宰了无线接入网络。GSM 市场份额达到 57%(其用户数达到 42.6 亿) ,但是 GSM 的连接数已经达到峰值,并开始下降。另一方面,3G(包括 HSPA) 的用户数从 2010 起不断上升,达到 19.4 亿,市场占有率达到26%。爱立信移动报告预 测 2020 年 WCDMA/HSPA 的用户数将达到顶峰,之后将会下降 [12]。处于 4G 主导地位的 LTE 技术截至 2015 年年底,发展用户 9.1 亿(市场份额 12%) ,预计 2021 年达到 41 亿用 户 [12],从而成为用户数最多的移动通信技术。图 1.3 展示了目前市场上的 3GPP 技术。总 体趋势是越来越广的频谱分布,更高的带宽,更高的频谱利用率和更低的时延。
image.png

1.4从移动宽带到极限移动宽带

5G极限移动宽带(xMBB)服务满足人们面向 2020 年,对极高数据速率的持续渴望。 对视频业务的广泛需求和对诸如虚拟现实、高清视频的兴趣推动了高达若干吉比特每秒 的速率要求。5G 技术使无线网络获得当前只能由光纤接入实现的速率和服务。感知互 联网进一步增加了对低时延的诉求。当低时延和高峰值速率需要同时满足时,就对网络 能力提出了更高的要求。

1.5物联网(IoT)和 5G 的关系

近几年来,有几个不同的概念描述 ICT 行业的一个重要领域,即物联网(IoT),信 息物理融合系统(CPS)和机器类通信(M2M),但这些概念各有侧重。
(1)物联网(IoT),又被称为“万物互联” (IoE),强调了互联网连接的所有对象(包 括人和机器)都拥有唯一的地址,并通过有线和无线网络进行通信 [13]。
(2)信息物理融合系统(CPS)强调通过通信系统对计算过程和物理过程(诸如传 感器,人和物理环境)的集成。特别是该物理过程在数字化(信息)系统中可以被观察、监视、控制和自动化处理。嵌入式计算和通信能力是信息物理融合系统的两个关键技术。 现代化的电网就可以被视为一个典型的 CPS 系统 [14]。
(3)机器类通信(M2M)被用来描述机器之间的通信。尽管数字处理器在不同的层 次嵌入到工业系统中的历史已经有很多年,但新的通信能力将会在大量的分布式处理器 之间实现连接,并使得原本本地的数字监控和控制提升到更广泛的系统级别,甚至是全 球的范围。4G 和 5G 就可以提供这些通信能力。不仅如此,当所有的目标被无线技术和 互联网连接,并且当计算和存储也分布在网络中时,信息物理融合系统(CPS)和物联 网(IoT)的区别就消失了。因此,无线移动通信是物联网(IoT)的重要赋能者。特别 是 5G 将赋能新的物联网用例(例如低时延和高可靠性需求的用例),以及其他无线通信 系统尚未涉足的经济领域。
第二章:如何实现海量数据的处理

]]>
基于Prometheus+Grafana的应用监控系统建设(一)-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 Prometheus + Grafana 应用级监控方案(1)-概述

主流监控方案比较

比较项 Prometheus+Grafana Zabbix BKCE
整体方案 Prometheus更像一个“监控引擎”,文本配置,UI极简,适用于应用级监控,配合Grafana配置界面,UI够漂亮 传统监控,以IP为监控主目标,更适合于主机、网络监控,对SNMP支持很好,带PHP界面,可自行扩展但整体界面不够“靓” 腾讯蓝鲸社区版,运维及CMDB功能非常强大,PaaS,DevOps,社区版的监控是PaaS之上的APP,专业性、扩展性均一般(据说企业版很强大),开源生态较一般
监控目标 exporter-Pull模型,更安全,性能影响小 Agent-Push方式,部署复杂 Agent-重点在于下发指令及文件传输(BT),监控只是顺带功能,支持自动远程部署
支持 数据库/中间件/应用/硬件,开源生态圈丰富 对SNMP支持特别好,偏硬件、网络、服务器,对应用级监控支持一般 支持常用的监控项,要扩展不是一般的麻烦
存贮 自带TDB及外部数据库,建议使用外部InfluxDB Mysql/PostgreSQL,对时序类的支持不好 InfluxDB+Mysql
UI 建议使用Grafana配置方式 PHP,自定义扩展,界面一般 有限几种展示,扩展就别想了(社区版)
性能 10万数据/秒,GO语言的程序,性能值得信赖 一般,个人认为Mysql不适合用于存监控数据 BKCE自身较占资源,必竟它的使用场景是“上万台服务器下的自动运维、监控”,小场景下无优势
告警 类SQL方式脚本化配置,建议将告警放到Grafana,告警时能带图片+链接,很友好 事件+条件+操作,较完整的告警体系 告警规则较死板,通过BKCE的消息通道推送,支持微信、短信等(自家产品)

参考资料

其它方案

  • Elastic stack

    • 以ElasticSearch为核心件,Beats为其监控扩展插件,Kibana为UI展示端的“全家桶”方案
    • Filebeat + ES + Kibana 组成的日志分析型监控,无出其右者!
    • 支持常用的OS、数据库、中间件等多种Beat,UI界面友好
    • 扩展性一般、第三方扩展资源较少
    • 企业级应用需要用到权限、远程同步等安全及高级功能,则需要购买xpack许可,可不便宜

Prometheus + Grafana 方案小结

  • 引擎 + UI ,较好地体现了“Unix哲学”之一: 让程序只做一件事并把它做好,Unix最伟大的功能之一”管道“就是这个体现," ls |grep | sort |wc " 这种操作,相信作为运维人员是很熟悉的
  • yml配置文件而非界面配置:开发人员写文档更喜欢 markdown而非Word/Notepad,编辑配置同理
  • export设计简洁:Don't call me,I will call you!
  • TDB及RDB-InfluxDB: 非时序型数据库的监控方案不应该被采用,除非数据量很小
  • Prometheus 这个名字太美,就像Eclipse的名字一样美妙--自行体会吧

方案不足之处

  • Prometheus自身的扩展不方便,Go语言写的代码,到处是协程、管道,要读懂处理过程还是比较麻烦的
  • 吐槽一下:Golang由于众所周知的原因,编译时下载依赖包及编译环境初始化有些障碍,这不是事,我从没见过一个程序编译需要8CPU全跑满,几分钟后告诉你”XX变量申明但没有使用,编译失败!“这种体验!
  • 关于告警:Prometheus的告警方案体验一般,Grafana的告警方案不够灵活,两者都不太理想,能结合一下就完美
  • 自动部署:BKCE的监控模块有一大优点是能通过它自己的NodeMan远程自动部署,”能让机器完成的事,不浪费程序员一秒钟“,在本方案中均需要手工配置完成监控系统、exports、view、Alert等工作

智慧运维之监控系统

  • 增加自动部署子系统,完成大部分监控对象的批量自动化部署,极大提升监控开发、部署的效率
  • 修改自动化部署配置文件 --> 一键部署,完成监控数据采集、监控展示界面、监控告警输出等过程
  • 扩展Prometheus 的 UI部分,集成自动部署工具及Grafana的扩展界面(如:交换机状态图、运维窗口设置等)
  • 扩展Grafana,增加几个有用的显示插件
  • 通过Grafana的 webhook增加告警输出处理(如优化钉钉推送,告警信息反向推送至Granfna界面等)

自动化部署方案

自动化部署示例

监控及告警示例

如对我们的产品有兴趣,请联系: tianhc@tythin.com

]]>
阿里创新事业群创新投资负责人邓兆俊:做孵化创新,不追风口而应创造“风口”-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800

image.png

12月10~11日,2019年度CEO峰会暨猎云网创投颁奖盛典在北京望京凯悦酒店隆重举行,近百位知名资本大咖,独角兽创始人、创业风云人物及近千位投资人与创业者共聚“新势力·2019年度CEO峰会暨猎云网创投颁奖盛典”。

在《互联网公司做孵化创新,最看重什么》的主题演讲中,阿里创新业务事业群创新投资负责人邓兆俊,以印度短视频社区产品VMate为例,分享了公司孵化一项创新业务的侧重点和对“出海”创新机遇的理解。

VMate由UC于2017年底在印度创立,是一款面向印度年轻人的短视频UGC内容社区产品,主打普通人的生活纪录和分享。

尽管印度短视频市场起步不久,但却备受中国互联网公司青睐。其大量的人口基数、低价流量套餐与重度视频消费习惯,都为短视频的快速发展奠定了基础。

邓兆俊表示,作为阿里巴巴创新事业群旗下的一款产品,阿里对于创新项目的管理,是把机会给到喜欢创新的人,通过深入、有特色的投后管理,来解决创新问题。

谈及出海项目,邓兆俊提到,VMate团队“不追求DAU”的态度,给了其在印度很大的成长空间。

此外,项目出海并非简单的模仿,而是基于当地市场的需求,从用户出发解决实际痛点,“我们不追逐风口而是去创造‘风口’,根据用户需求开展相应项目”。

谈及出海创新,邓兆俊认为有以下几点建议:

第一,寻找海外的用户价值,他们需要怎样的东西——这是最有价值的创新。

再就是反观国内已有的APP,比如在衣食住行、社交等领域,寻找印度、东南亚市场所没有的,都可以尝试发起新赛道。

第二,从已有的产品里寻找新机会。“无论是抖音还是快手,与两年前相比,其实都很不一样,它的媒体属性、社交属性都在改变,这里面也可能是机会所在之处”。

第三,寻找00后用户的消费潜力。

为了帮助创业者和投资人重新蓄力,2019年,猎云网携全新品牌“新势力(New Force Summit)”亮相。本次峰会由猎云网主办,锐视角、猎云资本、猎云财经、企业管家协办。

此次盛典上,猎云网将通过六个版块分享创业者和投资人在智能制造、文娱、零售、医疗、教育、汽车等领域的启发性的观点和行业前瞻,围绕多个维度,分享科技和产业前沿观点,探讨创新潮流趋势、把握未来新方向。

以下为邓兆俊演讲实录,猎云网整理:

大家好,我来自阿里巴巴创新业务事业群的邓兆俊。作为阿里巴巴20多个事业群之一,我们肩负着阿里巴巴创新与造风的责任。同时作为创新推进办公室的负责人,我不仅关注外部市场,在内部我也有投资孵化、投后管理的职责。所以跟刚才的创业型嘉宾相比,我们是投资人,同时也是项目管理人。

先跟大家分享下我们创新事业群的产品VMate。

简单来讲这是一款面向印度普通消费者的短视频社区产品,目前VMate的全球下载量排行第18,MAU已经达到5000万。从市场投放角度看,我们花出去的费用,可能只是竞品的几十分之一到几百分之一。

有人会问,阿里巴巴那么有钱,为什么不做投放?实际上,我们把钱花在了更重要的地方上,比如我们的地推人员与本地化的运营人员的数量是竞品的很多倍。

我们为什么这样做,而不花大把的钱买量,就在于我们的价值观。VMate是想为印度人民提供平等交流的媒体或者平台。

在我们做不到这一点之前,我们觉得,任何投放都是扩大在不清晰道路上的“加速”。虽然这种“超快感”能给我们带来一些业绩方面的收益,但其实满足不了我们真正的价值观——就是满足用户的需求。

截屏2019-12-12上午10.28.32.png

举个例子,一个叫Kajul的普通印度女孩,她在VMate上有30万的粉丝,她通过拍自己开拖拉机、下地种田这样的短视频,能给自己每个月带来一两万的人民币收入。我们知道,印度GDP是中国五分之一,印度人的平均工资是一千多人民币。

在这个GDP不高的国家里面的“下沉”市场中,一两万元人民币的收入对很多家庭来说是家庭总收入——这样的收入,Kajul在做短视频之前,是不敢想象的。所以,VMate改变了她自己家庭和她所居住的村庄,开启了印度本地人对于美好生活的向往。

可能会有人问我们,当初项目是如何立项做VMate的。

数据显示,UC在印度成为继Facebook、Google之外的第三大生态型互联网应用平台。在UC浏览器国际版中,我们做了很多文字、图片的搜索类目。我们发现,印度的多元化程度非常复杂,比如他们有40个语种,而且不同地区的方言有属于自己的语言体系。当各种各样的语言交杂在一起时,这些语言很难用统一的文字去实现人与内容之间的正常交流。

所以,我们发现信息流在那边是有局限性的。

于是,我们就选择了用短视频这种表达方式更直接的把人和内容连接在一起,至少它突破了文字的局限性。

可能有的公司选择降维打法,国内有什么,国外就做什么。当然思维方式的不一样,最后谁赢谁输也不能确定。但是我们立项是要通过当地市场的需求评估,解决用户的痛点完成VMate立项,我们现在有5000万的MAU,包括留存等数据都保持比较稳定的发展态势。

下面再简单介绍一下我们创新事业群。

除了VMate,我们还有国内首款弹唱App唱鸭,这是00后用户中一款非常火的唱歌软件,此外包括天猫精灵、夸克搜索也都是我们的产品,在其他领域,我们也还在继续探索新的赛道和产品。

为什么选择这些赛道?我们所有的创新都不是因为别人做了什么,我们就做什么,而是我们对于市场、对于用户的分析,觉得我们应该投入人力、财力去做这样的事情。

逍遥子在不同的场合说过,我们不追逐风口,我们要创造风口。当我们发现用户有新的需求,而我们的能力也可以满足用户需求后,才会启动项目。

我们的管理过程与很多投资机构不一样的是,很多投资机构是三分投,七分管。

我们是既有外部投资也有内部孵化,阿里巴巴有很多潜力型人才,我们也有相应的创新机制,一种人愿意做成熟业务,另外一种人喜欢创新,我们给机会。

第三种我们通过外部投资,来解决我们的创新的问题。但是我们也没有把这种方式提到很重要的位置,因为我们觉得把每个项目做好,大家觉得创投A轮到IPO成功概率2%,我们认为成功的数据跑起来,差不多有50%。

大家可以看到从小到大我们的管理就是OKR+PDCA一起进行,OKR是强目标管理的管理方式,可以用来管理项目的一号位,也可以用来投资,PDCA则是不停试错的过程。

有哪个项目从一开始的定位,特别是今天门槛那么低的移动互联网市场中,今天定位,半年之后就可以成,一年之后跟当初我画的蓝图一模一样?当然也有,个别的企业,包括快手、抖音都是这样的,但是大多数投的项目都是中途不停地变,又想变,又不想变的话,就是用OKR+PDCA,定一个目标,定一个标准,三个月、六个月能不能做到,做不到的话,目标定错了,我们改。

再就是做不到,团队没问题,这不是简单的换方向,从餐饮变成房地产。所以OKR非常有用。PDCA是配合OKR,OKR在一个月、两个月内改。把这个跑通了,我们投资项目成功率会高很多。

还有一个机制,大家说在阿里巴巴创新有什么样的机制激励他们?

像VMate是今年拿到阿里巴巴集团1亿美金的投资。我们很多业务在做到一定阶段之后都会分拆做到一个独立法人,独立法人有自己独立的股权。所以,与阿里巴巴的关系是投资关系。

跟大家聊一下还有哪些创新机会在哪里。

第一,出海。出海有两种思路,一是寻找海外的用户价值,他们需要怎样的产品——这是最有价值的创新。

你会发现他们缺的很多产品,我们都是已经有的。

再就是简单粗暴,把中国已经有的APP列出来,衣食住行、社交等,再把印度、东南亚市场里缺失的产品列一下,这些都可以做的。

也许一棒子打不到底,但出海是一个好方向,UC浏览器在当地的用户量就非常大。

第二,UGC社区。大家看今天的抖音、快手,与两年前的抖音、快手,其实很不一样,它的媒体属性、社交属性都在改变,这里面我们觉得也可能是机会。

第三,寻找00后用户的消费潜力。大家可以多接触一下伴随手机成长的00户,首先,他们是有一定的消费能力。第二,他们的自传播性非常强,只是我们不懂他们真正需要的是什么产品。

最后,我们做任何的立项也好,只问两个问题:你能解决用户什么痛点?用户为什么要用你的产品?

包括VMate拿到阿里投资的时候,我们做了一年,一年当中从来没有认真地汇报过任何DAU、KPI、留存,大家觉得很奇怪,不汇报DAU汇报什么。

我们汇报产品有什么样的功能,满足了印度人的什么样的需求。

谢谢大家!

转自创头条,原文链接为:http://www.ctoutiao.com/2563420.html

声明:以上内容来自于网络,如有侵权,请联系删除

]]>
15天后密码法正式施行 必备功课做完了吗?-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 距离2020年1月1日《中华人民共和国密码法》(简称“密码法”)正式施行,还剩15天。密码法都做了哪些规定,与我们个人和企业有什么关系,在新法正式施行前我们应该怎么做好准备?今天我们就来聊一聊密码法相关的那些事。

密码法最受关注的四大问题

密码法的“密码”指的是什么?
一提到密码,我们都会联想到银行密码、手机密码、支付密码、账号密码等等,但此密码并非彼密码。
密码法里的密码指的是使用特定变换对信息等进行加密保护或者安全认证的产品、技术和服务。所以对于硬件安全模块、服务器密码机、数字证书认证系统等核心功能属于加密保护或安全认证的产品都属于密码产品。
按照密码的功能形态分为核心密码、普通密码和商用密码。核心密码和普通密码是用来保护国家秘密信息,商用密码是用于保护不属于国家秘密的信息的密码,是互联网和其他行业使用最为广泛的类型。

那么重点来了,密码法跟谁有关?
一切使用加密保护、安全认证技术、产品和服务进行保护的企业及组织,尤其是影响国计民生、社会公共利益和秩序的单位,都应该合理使用密码来保障数据安全。
对于使用商用密码的企业及组织还需要开展商用密码应用安全性评估。在2019年12月1日正式实施的等保2.0中,就对网络安全第三级及以上等级保护对象做出了明确的密码应用安全性评测标准。对于可能影响国家安全的关键信息基础设施的运营者还需要按照监管要求进行审查。

“密码应用安全性评估”涉及哪些内容?
密码应用安全性评估对于网络对象采集、传输、存储的数据以及外围保护环境数据根据重要程度、类型提出了实现机密性、真实性、完整性和不可否认性的密码保护要求,围绕数据生命周期进行全方位的密码保护和安全管理。
通俗来讲,密码不仅要用在数据采集、存储、传输等所有节点,而且还要有效,不能是形式主义。

违反密码法有什么后果?
对于不使用密码的,轻则管理部门会对违规单位进行责令改正,给予警告,重则对违规单位进行数十万的罚款,对负责人进行处分和罚款,一旦构成犯罪,还将依法追究刑事责任。

阿里云进阶式数据加密能力助你做足功课


根据用户对不同数据不同安全等级的需求,阿里云提供了一整套完整的进阶式数据加密能力,以及密钥管理服务,也就是密码法中的密码管理服务,让用户可以保护好云上这个“密码本”,满足不同数据加密需求。

加密入门:可见的“默认加密”
为了更方便的让用户对低安全级别的数据进行加密保护,而避免付出额外的密钥管理开销,阿里云在密钥管理服务KMS中为用户提供了一种自动管理密钥的功能,用户只需要在KMS中选择“服务密钥”这一功能,就可以通过KMS实现数据的自动加密,不需要用户做任何操作,且密钥的任何调用情况用户都可以在操作审计产品中看到。

加密进阶:可见可控的全托管加密
如果用户对数据加密有更高需求,可以不使用KMS自动生成的服务密钥功能,而是自行在KMS中管理密钥的生命周期,包括创建、删除、禁用、启用密钥等,并且在访问控制(RAM)中自主管理密钥的授权规则。该密钥是解密数据的唯一钥匙,没有用户授权密钥,任何人无法看到数据;如果密钥被删除,包括用户在内的任何人都无法解密数据。

加密高阶:可见可控的半托管加密
比全托管加密更高级的安全能力来自于业界普遍认可的一项技术:BYOK(Bring Your Own Key)。通俗来讲就是用户可以自己生产密钥导入云上KMS托管的硬件密码机中,这个过程是单向的,密钥只能导入不能导出,除用户之外的任何第三方都无法知晓托管密码机中的内容。除此之外用户可以随时销毁云上密钥,而仍然保有密钥的生命周期管理能力,例如,用户导入密钥对数据加密后可以删掉密钥,在数据需要被解密时再重新导入相同密钥来解密即可,这为用户提供了更多的自主权利。

加密更高阶:自己写代码调用KMS
相较于前三阶均是“云产品集成加密”,从该阶加密开始,用户可以自己写代码调用KMS的API能力,更加适用于对敏感数据保护有更高要求,或者为了满足GPDR及其他法律法规要求的用户,这种加密方式可以针对特定数据实现主动加密保护。用户可以根据自身的业务场景特性和业务逻辑特性来制定不同的密钥管理策略,将加密能力嵌入到业务当中,使得安全与合规需求及业务系统紧密融合,进一步减小恶意者对敏感数据的攻击面。例如:数据库TDE加密,并不能有效防止具有数据库用户或者DBA查看数据库内的敏感数据。如果业务系统对特定的敏感数据列进行自定义加密,数据库用户或者DBA则需要进一步获取密钥的权限从而查看敏感数据。
除此之外,自定义加密的应用系统,可以更好的利用KMS内建的密钥自动轮转能力,实现密钥管理的安全策略。

加密最高阶:自己管理HSM集群和写代码
除了密钥管理服务KMS,阿里云还为用户提供了云服务器密码机实例。用户可以自己管理所需的密码机实例数量,自己做密钥机之间的密钥同步、备份、负载均衡等工作。在这个过程中,云服务商不参与任何密钥管理相关工作,用户不仅对密钥管理有完全的控制权,同时对硬件密码机也有完全的控制权,为最高阶的加密方式。
从上面可以看出,阿里云这套云上密码能力体系,不仅可以帮助用户实现数据的加密保护、数字签名的产生和验证、加密密钥的自动轮转等功能,更便捷的构建密码应用和解决方案,还能赋能云上数据安全、身份认证、区块链、DevSecOps等广泛场景。

640


云上密码能力地图

密码法的颁布只是第一步,数据安全是一个系统工程。在《密码法》的指导下,企业可以借助阿里云的技术工具和安全产品强化自身的安全体系,在保障数据安全的前提下,充分享受技术红利,促进业务的持续、稳定发展。

如果您想了解更多数据加密相关问题,可以扫描下方二维码,直连安全专家哦~

641

更多详情

]]>
阿里云Serverless应用引擎(SAE)3大核心优势全解析-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 软件发展到今,企业业务系统日趋复杂,开发一个业务系统需要掌握和关注的知识点越来越多。除实现业务逻辑本身,还需考虑很多非业务的基础技术系统:如分布式cache和队列、基础服务能力集成、容量规划、弹性伸缩等。这种情况下,研发门槛逐渐上升,效率逐渐下降。企业很难做到低成本创新、试错和快速扩展业务。

阿里云Serverless应用引擎(简称SAE)产品的出现,很好地解决了这类问题。帮助 PaaS 层用户免运维IaaS,按需使用,按量计费,提供了一系列通用能力,实现低门槛微服务/Web/多语言应用上云,有效解决成本及效率问题。

免运维、省成本是所有Serverless产品的核心优势之一,SAE除了免运维底层IaaS外,还能让用户免部署和运维微服务注册中心等组件,提供生产级别稳定可靠的微服务托管能力;免部署和运维K8s集群,零容器基础的用户也能拥抱K8s带来的技术红利。

10


很多企业在云上都会部署多套环境,存在很大的闲置浪费。使用SAE的“一键启停开发测试环境”,按需释放闲置资源,节省成本,需要使用时一键秒级拉起。后续SAE考虑基于K8s强大的编排能力,编排应用所需的DB、应用和应用的依赖,一键初始化拉起一套全新环境,以及多环境的克隆复制等。

11


云时代下弹性已成为新常态,很多业务场景无法提前预知,如天猫双11、突发事件导致社交网站瞬时过载。和传统弹性方案相比,SAE在成本和效率上都能做到极致。基于监控触发按需弹,不会出现资源浪费/不足,在效率上免去ECS扩容和ECS启动的时间,能做到秒级弹性。

12


SAE三个主要指标数据:端到端启动时长20s,满足突发场景快速扩容的需要。支持0.5core的最小规格,进一步降低用户使用成本。部署一套日常环境成本节省47%~57%。

13


据Serverless应用引擎(SAE)产品经理黛忻介绍,SAE继续探索弹性效率和用户成本的优化方案,继续将一些基础技术归纳抽象下沉到平台,让创新业务成为企业的唯一关注点。
据悉,阿里云是国内率先提供了面向应用的Serverless产品的云计算公司。截止目前,已有上百家企业通过 SAE 构建应用,实现业务的快速交付和IT成本优化。]]>
蚂蚁金服联合IDC发布《中国金融级移动应用开发平台白皮书》 金融机构加速执行移动优先战略-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 ad5d75088d8f43739ab98bd0ebc34a47

移动端成金融机构零售转型的重要载体,战略地位日益凸显
《白皮书》认为,随着IT领域的新兴技术⾰命,企业数字化转型浪潮正在不断重塑各⾏各业的运⾏格局和发展风貌。以金融业为例,利率市场化、金融脱媒以及互联⽹跨界竞争等多重因素动摇了传统金融机构的盈利基础,使中国金融市场正在自内而外地发生巨大变革。

在此背景下,金融机构纷纷开启零售转型战略,以金融科技创新为抓手,为企业发展赋能。移动端作为金融机构重要的对外渠道之一,已成为零售转型的重要载体。利用优质的移动端设计提供精细化服务,吸引更多的个人客户长期驻留,是金融机构应对市场挑战、实现长期发展的必然选择,移动优先战略成为金融机构面向未来的发展共识。

《白皮书》显示,在⾦融科技的推动下,⼀⼤批传统线下业务通过技术创新转移⾄线上运营,⽤⼾不再受到银⾏服务时间和空间的限制,随时随地的享受移动端带来的便捷性,⽤⼾体验获得了⾰命性提升;保险公司⼤⼒拓展移动渠道,通过保险移动展业,以更加便捷⾼效地⽅式实现全业务触点的销售及管理,降低获客成本;证券企业则重点利⽤新技术提升信息和数据处理的时效性,满⾜客⼾对移动端⾏情资讯的传递和承载需求。

一站式移动开发平台mPaaS,助力金融机构移动优先战略落地
《白皮书》指出,金融业务的移动化、场景化、智能化趋势,推动金融移动应用需求的爆发性增长,对金融机构围绕移动端的业务开发和保障能力提出极大挑战。金融机构迫切需要引入新一代移动设计开发思想,利用先进的移动应用开发平台实现在开发、运维、管理以及快速迭代方面的一系列变革。

蚂蚁金服移动金融技术总监祁晓龙认为,金融级移动应用开发平台应具备统一的开发框架,拥有强大的技术整合和集成能力,有助于打造基于移动中台的能力输出,满足金融行业对移动开发平台技术先进性、安全合规性和高稳定性、高可用性等一系列特殊要求。

基于对金融市场的洞察和全新用户行为的理解,蚂蚁金服移动开发平台mPaaS借助统一的客户端开发框架和蚂蚁特有的金融级移动中台能力,有效地加快研发效率,增加对APP动态管控及千人千面的数字化运营能力。同时基于“后台连接服务”构建与服务端的数据、多媒体传输通道,确保全链路的稳定、安全和高效。
f85afc744df04471a9bfdadb8bdc3a8e

移动端创新技术方面,mPaaS提供智能推荐、语音识别、图像识别、生物识别、小程序等能力,改善产品体验,助力业务创新。

安全合规方面,mPaaS提供IPv6、国密、容灾等特色行业能力,满足监管合规要求。同时辅以应用加固、安全键盘、IFAA生物认证及数据加密能力,充分保障数据在客户端本地、传输过程中的安全性。

目前mPaaS已服务中国农业银行、广发银行,华夏银行,西安银行、国寿保险等众多B端客户,为国内国际用户都带来优质的移动端体验。

蚂蚁金服全栈式金融科技体系,助力金融业全域数字化转型
科技是面向未来的核心驱动力。基于对未来的洞察和蚂蚁金融科技开放的实践深耕,蚂蚁金服在金融领域构建了一个自底向上的全栈式金融科技体系,从具有金融级别支撑能力的分布式计算平台等底层技术,到以人工智能、区块链等为代表的应用技术,再到智能风控、生物核身等金融级专有技术,以及一站式的移动开发平台mPaaS,形成完整的技术堆栈,助力金融机构快速打造新一代超级移动金融平台与大数据智能运营体系,推动金融机构转型升级。

据悉,包括蚂蚁金服移动开发平台mPaaS、分布式中间件SOFAStack、分布式关系数据库OceanBase等在内的产品和解决方案正通过阿里云新金融统一对外输出,服务各种类型的金融机构。而在未来,还会有越来越多的蚂蚁金服技术产品通过阿里云新金融对外输出。在第二十七届中国国际金融展上,这些世界级的解决方案进行了亮相,并吸引了诸多关注。

]]>
全球5G倡议 | 《5G移动无线通信技术》之三-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 第二章:如何实现海量数据的处理?

全球5G倡议

全球范围内有很多 5G 的论坛和研究项目组。2011 年欧洲第一个开展了 5G 研究 [23], 不久之后中国、韩国、日本开始了各自的研究活动。这些活动和时间表归纳在图 1.6 中。
image.png

3.1 METIS 和 5G-PPP

METIS [24] 是欧盟第一个完整的 5G 项目,并对全球的 5G 发展产生了深远的影响。 METIS 属于欧洲框架 7 项目(FP7),项目准备始于 2011 年 4 月,正式启动于 2012 年 11 月 1 日,中止于 2015 年 4 月 30 日。
METIS 项目的原始诉求是为全球的 5G 研究建立参照体系,包括确定 5G 的应用 场景、测试用例和重要性能指标。目前这些成果被商界和学术界广泛引用。其主要成 果是筛选了 5G 的主要技术元素。欧洲通过该项目在 5G 的研发方面获得了明显的领先 地位。
5G 公私合作伙伴(5G-PPP) [25] 是欧盟框架 73 项目中 5G 后续项目。欧洲的 ICT 行业和欧洲委员会(EC)于 2013 年 12 月签署了商业协议,组建 5G 基础设施公私合作项 目(5G-PPP)。该项目主要是技术研究,其 2014–2020 年预算为 14 亿欧元。欧洲委员会 和 ICT 产业各出资一半(7 亿欧元)。5G-PPP 在设备制造企业、电信运营商、服务提供商和中小企业以及研究人员之间架起了桥梁。
根据与 METIS 签署的谅解备忘录,5G-PPP 项目内 METIS-II 于 2015 年 7 月启 动。METIS-II 致力于开发设计 5G 无线接入网络,其目标是进行足够的细节研究,支撑 3GPP R14 版本的标准化工作。METIS-II 将提出技术建议,并有效地集成当前开发的 5G 技术元素以及与原有 LTE-A 技术演进的集成。为了实现这一目标,METIS-II 非常重视 和 5G-PPP 的其他项目,以及全球其他 5G 项目的合作和讨论。讨论的范围包括 5G 应用 场景和需求、重要 5G 技术元素、频谱规划和无线网络性能等。
5G-PPP 项目的目标是确保欧洲在特定领域的领先,并在这些领域开发潜在的 新的市场,例如智慧城市、电子医疗、智能交通、教育或者娱乐和媒体 [25]。5G-PPP 的终极目标是设计第五代通信网络和服务。5G-PPP 的第一个子项目开始于 2015 年 7 月。

3.2 中国:5G 推进组

IMT-2020(5G)推进组于 2013 年 2 月由中国工业和信息化部、国家发展和改革委 员会、科学技术部联合推动成立,组织国内的企业和高校等成员开展 5G 的研发和产业 推进,是聚合移动通信领域产学研用力量、推动第五代移动通信技术研究、开展国际交 流与合作的基础工作平台。

3.3 韩国:5G 论坛

韩国的 5G 论坛 [28] 也是公私合作项目,成立于 2013 年 5 月。该项目的主要目 标是发展和提出国家的 5G 战略,并对技术创新作出战略规划。成员包括 ETRI,SK Telecom,KT,LG- 爱立信和三星公司。这个论坛也对中小企业开放。其目标之一是确 保 2018 年平昌冬奥会部分 5G 实验网预商用。

3.4 日本:ARIB 2020 和未来专项

ARIB 2020 和未来专项成立于 2013 年 9 月,目的是研究面向 2020 和未来的陆地移 动通信技术,也是成立于 2006 年的先进无线通信研究委员会(ADWICS)的一个子委 员会。这个组织的目标是研究系统概念、基本功能和移动通信的分布式架构。预期输出 包括白皮书,向 ITU 及其他 5G 组织提交的文件。2014 年,该项目发布了第一个白皮书 描述了 5G 的愿景,“面向 2020 和未来的移动通信系统”[29]。

3.5 其他 5G 倡议

其他的 5G 倡议相对于上述项目在规模和影响力方面较小。其中几个是北美 4G(4G Americas)项目、Surrey 大学创新中心、纽约大学无线研究中心。

3.6 物联网的活动

全球范围内开展了大量的物联网倡议,覆盖了物联网的诸多方面。其中工业物联网 共同体(IIC) [30] 和工业 4.0[31] 是和 5G 最紧密相关的项目。IIC 成立于 2014 年,把组织 机构和必要的技术结合在一起,加速工业互联网的成长。主要目标是 [30]:

  • 为现实应用创建新的工业用例和测试床;
  • 影响全球工业互联网系统的标准化进程。

工业 4.0 是德国 2013 年发起的倡议,目的在于保持德国工业制造的竞争力和保持全 球市场领导力,致力于在产品中集成物联网和服务,特别是整个生产流程中创建网络管 理,实现智能工厂环境 [31]。

3.7标准化活动

下面简要介绍 5G 在 ITU、3GPP 和 IEEE 的标准化工作。

3.8 ITU-R

2012 年 ITU 无线通信部分(ITU-R)在 5D 工作组(WP5D)的领导下启动了“面 向 2020 和未来 IMT”的项目,提出了 5G 移动通信空中接口的要求。WP5D 制定了工作 计划、时间表、流程和交付内容。需要强调的是 WP5D 暂时使用“IMT-2020”这一术语 代表5G。根据时间表的要求,需要在2020年完成“IMT-2020技术规范”。至2015年9月, 已经完成下列三个报告。

  • 未来陆地 IMT 系统的技术趋势 [32]:这个报告介绍了 2015—2020 年陆地 IMT 系统的技术趋势,包括一系列可能被用于未来系统设计的技术。
  • 超越 2020 的 IMT 建议和愿景 [19]:该报告描述了 2020 年和未来的长期愿景,并 对未来 IMT 的开发提出了框架建议和总体目标。
  • 高于 6 GHz 的 IMT 可行性分析 [33]:这份报告提供了 IMT 在高于 6 GHz 频段部 署的可行性。该报告被 WRC 2015 参照,将新增的 400 MHz 频谱分配给IMT使用,详见第 12 章。

3.9 3GPP

3GPP 已经确认了 5G 标准化时间表,现阶段计划延续到 2020 年 [34]。5G 无线网络 的主要需求的研究项目和范围于 2015 年 12 月开始,2016 年 3 月开始相应的 5G 新的无 线接入标准。此外, 3GPP在LTE 9[35] 和GSM 36 引入了海量机器类通信的有关需求, 即增强覆盖、低功耗和低成本终端。在 LTE 系统中,机器类通信被称作 LTE-M 和 NBIoT,在 GSM 系统中被称为增强覆盖的 GSM 物联网(EC-GSM-IoT)。

3.10 IEEE

在国际电气和电子工程师协会(IEEE)中,主要负责局域网和城域网的是 IEEE 802 标准委员会。特别是负责无线个人区域网络的 IEEE 802.15 项目(WPAN) [33] 和无 线局域网(WLAN)的 IEEE 802.11 项目 [39]。IEEE 802.11 技术在最初设计时使用频段 在 2.4 GHz。后来 IEEE 802.11 开发了吉比特标准,IEEE 802.11ac 可以部署在更高的频 段,例如 5 GHz 频段,以及 IEEE 802.11ad 可以部署在 60 GHz 毫米波频段。这些系统的 商用部署始于 2013 年,可以预见,到 2019 年的今后几年采用 6 GHz 以下(例如 IEEE 802.11ax)和毫米波频段(例如 IEEE 802.11ay)的系统将会实现高达若干 Gbit/s 的速率。 IEEE 很有可能会基于其高速率技术提交 IMT-2020 的技术方案。IEEE 802.11p 是针对车 辆应用的技术,预计 2017 年之后会获得在车联网 V2V 通信领域的广泛应用。在物联网领域IEEE也表现活跃。IEEE 802.11ah 支持在 1GHz 以下频段部署覆盖增强的 Wi-Fi。 IEEE 802.15.4 标准在低速个人通信网络(LR-WPAN)较为领先。这一标准被 Zigbee 联盟进一步拓展为专用网格连接技术,并被国际自动化协会(ISA)采纳,用于协同和同 步操作,即 ISA100.11a 规范。预计 5G 系统会联合使用由 IEEE 制定的空中接口。这些 接口和 5G 之间的接口的设计需要十分仔细,包括身份管理、移动性、安全性和业务。

3.11 本书的内容介绍

5G 构成的主要目模块如图 1.7所示:无线接入、固定和原有无线接入技术(例如 LTE)、核心网、云计算、数据分析和安全性。本书涵盖的内容在图 1.7中标记为灰色, 5G 无线接入和用例在第 2 章介绍。包括 LTE 的原有系统的作用在不同的章节有简要介 绍。核心网和云计算(包括网络功能虚拟化)的简介在第 3 章介绍。数据分析和安全性超出了本书的范围。
本书内容组织如下。

  • 第 2 章总结了目前定义的 5G 用例和需求,以及 5G 的系统概念。
  • 第 3 章给出了 5G 架构需要考虑的主要问题。
  • 第 4 章讲述 5G 的重要用例之一,即机器类通信。
  • 第 5 章介绍设备和设备通信。
  • 第 6 章介绍有可能分配的从 10 GHz 到 100 GHz 大量频谱的毫米波技术,这些频 谱可以用于无线回传和接入。
  • 第 7 章简要介绍 5G 最可能采用的无线接入技术。
  • 第 8 章重点介绍 5G 的重点技术之一,即大规模 MIMO。
  • 第 9 章讨论多点协同发送,特别是 5G 如何更好地实现联合发射。
  • 第 10 章聚焦中继器和无线网络编码技术。
  • 第 11 章介绍 5G 干扰和移动管理相关的技术。
  • 第11章讨论5G频谱,特别是预期的5G频谱组成和需求,以及预期的频谱接入模式。
  • 第 13 章介绍 5G 信道模型的主要挑战和新的信道模型。
  • 第 14 章提供了 5G 仿真的指导建议,以此来统一假设条件、方法和参考用例。

image.png

]]>
蚂蚁金服 双11 Service Mesh 超大规模落地揭秘-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 点击下载《不一样的 双11 技术:阿里巴巴经济体云原生实践》

ban.jpg

本文节选自《不一样的 双11 技术:阿里巴巴经济体云原生实践》一书,点击上方图片即可下载!

作者:
黄挺,花名鲁直,蚂蚁金服微服务以及云原生方向负责人,主导蚂蚁金服的云原生落地。
雷志远,花名碧远,蚂蚁金服 RPC 框架负责人

更多云原生技术资讯可关注阿里巴巴云原生技术圈

引言

Service Mesh 是蚂蚁金服下一代架构的核心,本主题主要分享在蚂蚁金服当前的体量下,我们如何做到在奔跑的火车上换轮子,将现有的 SOA 体系快速演进至 Service Mesh 架构。聚焦 RPC 层面的设计和改造方案,分享蚂蚁金服 双11 核心应用如何将现有的微服务体系平滑过渡到 Service Mesh 架构下并降低大促成本。

蚂蚁金服每年 双11 大促会面临非常大的流量挑战,在已有 LDC 微服务架构下已支撑起弹性扩容能力。本次分享主要分为 4 部分:

  1. Service Mesh 简介;
  2. 为什么要 Service Mesh;
  3. 我们的方案是什么;
  4. 分时调度案例;

Service Mesh 简介

在讲具体的蚂蚁金服落地之前,想先和大家对齐一下 Service Mesh 的概念,和蚂蚁金服对应的产品。
这张图大家可能不陌生,这是业界普遍认可的 Service Mesh 架构,那么对应到蚂蚁金服,蚂蚁金服的 Service Mesh 也分为控制面和数据面,分别叫做 SOFAMesh 和 SOFAMosn,其中 SOFAMesh 后面会以更加开放的姿态参与到 Istio 里面去。

1.png

今天我们讲的实践主要集中在 SOFAMosn 上,以下我的分享中提到的主要就是集中在数据面上的落地,这里面大家可以看到,我们有支持 HTTP/SOFARPC/Dubbo/WebService。

为什么我们要 Service Mesh

有了一个初步的了解之后,可能大家都会有这样一个疑问,你们为什么要 Service Mesh,我先给出结论:

因为我们要解决在 SOA 下面,没有解决但亟待解决的:基础架构和业务研发的耦合,以及未来无限的对业务透明的稳定性与高可用相关诉求。

那么接下来,我们一起先看看在没有 Service Mesh 之前的状况。

在没有 Service Mesh 之前,整个 SOFAStack 技术演进的过程中,框架和业务的结合相当紧密,对于一些 RPC 层面的需求,比如流量调度,流量镜像,灰度引流等,是需要在 RPC 层面进行升级开发支持,同时,需要业务方来升级对应的中间件版本,这给我们带来了一些困扰和挑战。如图所示:

2.png

  1. 线上客户端框架版本不统一;
  2. 业务和框架耦合,升级成本高,很多需求由于在客户端无法推动,需要在服务端做相应的功能,方案不够优雅;
  3. 机器逐年增加,如果不增加机器,如何度过 双11;
  4. 在基础框架准备完成后,对于新功能,不再升级给用户的 API 层是否可行; 
  5. 流量调拨,灰度引流,蓝绿发布,AB Test 等新的诉求;

这些困扰着我们,我们知道在 SOA 的架构下,负责每个服务的团队都可以独立地去负责一个或者多个服务,这些服务的升级维护也不需要其他的团队的接入,SOA 其实做到了团队之间可以按照接口的契约来接耦。但是长期以来,基础设施团队需要推动很多事情,都需要业务团队进行紧密的配合,帮忙升级 JAR 包,基础设施团队和业务团队在工作上的耦合非常严重,上面提到的各种问题,包括线上客户端版本的不一致,升级成本高等等,都是这个问题带来的后果。

而 Service Mesh 提供了一种可能性,能够将基础设施下沉,让基础设施团队和业务团队能够解耦,让基础设施和业务都可以更加快步地往前跑。

3.png

我们的方案

说了这么多,那我们怎么解决呢?

方案一:全部迁移到 Envoy?不现实,自有协议+历史负担。
方案二:透明劫持?性能问题,且表达能力有限,运维和可监控性,风险不太可控。
方案三:自研数据面,最终我们给出的答案是 SOFAMosn。

总体

4.png

我们的 SOFAMosn 支持了 Pilot ,自有服务发现 SOFARegistry,和自有的消息组件,还有一些 DB 的组件。在产品层,提供给开发者,不同的能力,包括运维,监控,安全等能力,这个是目前我们的一个线上的状态。

SOFARegistry 是蚂蚁金服开源的具有承载海量服务注册和订阅能力的、高可用的服务注册中心,在支付宝/蚂蚁金服的业务发展驱动下,近十年间已经演进至第五代。

看上去很美好,要走到这个状态,我们要回答三个问题。

5.png

这三个问题后面,分别对应着业务的几大诉求,大家做过基础框架的应该比较有感触。

框架升级方案

准备开始升级之后,我们要分析目前我们的线上情况,而我们现在线上的情况,应用代码和框架有一定程度的解耦,用户面向的是一个 API,最终代码会被打包,在 SOFABoot 中运行起来。

SOFABoot 是蚂蚁金服开源的基于 SpringBoot 的研发框架,它在 SpringBoot 的基础上,提供了诸如 Readiness Check,类隔离,日志空间隔离等能力。在增强了 SpringBoot 的同时,SOFABoot 提供了让用户可以在 SpringBoot 中非常方便地使用 SOFA 中间件的能力。

6.png

那么,我们就可以在风险评估可控的情况下,直接升级底层的 SOFABoot,在这里,我们的 RPC 会检测一些信息,来确定当前 Pod 是否需要开启 SOFAMosn 的能力。然后我们完成如下的步骤。

7.png

这里,我们通过检测 PaaS 传递的容器标识,知道自己是否开启了 SOFAMosn,则将发布和订阅给 SOFAMosn,然后调用不再寻址,直接完成调用。

可以看到,我们通过批量的运维操作,直接修改了线上的 SOFABoot 版本,以此,来直接使得现有的应用具备了 SOFAMosn 的能力,有些同学可能会问,那你一直这么做不行吗?不行,因为这个操作时要配合流量关闭等操作来运行的,也不具备平滑升级的能力。而且直接和业务代码强相关。不适合长期操作。

这里我们来详细回答一下,为什么不采用社区的流量劫持方案?

主要的原因是一方面 iptables 在规则配置较多时,性能下滑严重。另一个更为重要的方面是它的管控性和可观测性不好,出了问题比较难排查。而 Service Mesh 从初期就把蚂蚁金服现在线上的系统全量切换 Mesh 作为目标,并不是只是跑跑 demo,所以我们对性能和运维的要求是非常高的,毕竟,技术架构升级,如果是以业务有损或者资源利用率大幅度上升,这是无论如何都不能接受的。

容器替换方案

解决了刚刚提到的第一个难题,也只是解决了可以做,而并不能做得好,更没有做得快,面对线上数十万,带着流量的业务容器, 我们如何立刻开始实现这些容器的快速稳定接入?

这么大的量,按照传统的替换接入显然是很耗接入成本的事情,于是我们选择了原地接入,我们可以来看下两者的区别
8.png

在之前,我们做一些升级操作之类的,都是需要有一定的资源 Buffer,然后批量的进行操作,替换 Buffer 的不断移动,来完成升级的操作。这就要求 PaaS 层留有非常多的 Buffer,但是在 双11 的情况下,我们要求不增加机器,并且为了一个接入 SOFAMosn 的操作,反而需要更多的钱来买资源,这岂不是背离了我们的初衷。有人可能会问,不是还是增加了内存和 CPU 吗,这是提高了 CPU 利用率。以前业务的 CPU 利用率很低。并且这个是一个类似超卖的方案。看上去分配了。实际上基本没增加。

可以看到, 通过 Paas 层,我们的 Operator 操作,直接在现有容器中注入,并原地重启,在容器级别完成升级。升级完成后,这个 Pod 就具备了 SOFAMosn 的能力。

SOFAMosn 升级方案

在快速接入的问题完成后,我们要面临第二个问题,由于是大规模的容器,所以 SOFAMosn 在开发过程中,势必会存在一些问题,出现问题,如何升级,要知道,线上几十万容器要升级一个组件的难度是很大的,因此,在版本初期,我们就考虑到 SOFAMosn 升级的方案。

9.png

能想到的最简单的方法,就是销毁容器,然后用新的来重建,但是在容器数量很多的时候,这种运维成本是不可接受的。如果销毁容器重建的速度不够快,就可能会影响业务的容量,造成业务故障。因此,我们在 SOFAMosn 层面,和 PaaS 一起,开发了无损流量升级的方案。

10.png

在这个方案中。SOFAMosn 会感知自己的状态,新的 SOFAMosn 启动会通过共享卷的 Domain Socket 来检测是否已有老的 SOFAMosn 在运行,如果有,则通知原有 SOFAMosn 进行平滑升级操作。

11.png

具体来说,SOFAMosn 启动的时候查看同 Pod 是否有运行的 SOFAMosn (通过共享卷的domain socket),如果存在,需要进入如下流程:
1.New Mosn 通知 Old Mosn,进入平滑升级流程
2.Old Mosn 把服务的 Listen Fd 传递给 New Mosn,New Mosn 接收 Fd 之后启动, 此时 Old 和 New Mosn 都正常提供服务。
3.然后 New Mosn 通知 Old Mosn,关闭 Listen Fd,然后开始迁移存量的长链接。
4.Old Mosn 迁移完成, 销毁容器。

这样,我们就能做到,线上做任意的 SOFAMosn 版本升级,而不影响老的业务,这个过程中的技术细节,不做过多介绍,之后,SOFAStack 会有更详细的分享文章。

分时调度案例

技术的变革通常一定不是技术本身的诉求,一定是业务的诉求,是场景的诉求。没有人会为了升级而升级,为了革新而革新,通常,技术受业务驱动,也反过来驱动业务。

在阿里经济体下,在不断的淘宝直播,实时红包,蚂蚁森林,各种活动的不断扩张中,给技术带了复杂了场景考验。

这个时候,业务同学往往想的是什么?我的量快撑不住了,我的代码已经最优化了,我要扩容加机器,而更多的机器付出更多的成本,面对这样的情况,我们觉得应用 Service Mesh,是一个很好的解法。通过和 JVM, 系统部的配合,利用进阶的分时调度实现灵活的资源调度,不加机器。这个可以在资源调度下有更好的效果。

12.png

首先,我们假设有两个大的资源池的资源需求情况,可以看到在 X 点的时候,资源域 A 需要更多的资源,Y 点的时候,资源域 B 需要更多的资源,总量不得增加。那当然,我们就希望能借调机器。就像下面这样。

请大家看左图。

13.png

在这个方案中, 我们需要先释放资源,然后销毁进程,然后开始重建资源,然后启动资源域 B 的资源。这个过程对于大量的机器,是很重的,而且变更就是风险,关键时候,做这种变更,很有可能带来衍生影响。

而在 SOFAMosn 中,我们有了新的解法。如右图所示,有一部分资源,一直通过超卖,运行着两种应用,但是 X 点的时候,对于资源域 A,我们通过 SOFAMosn 来将流量全部转走,这样,应用的 CPU 和内存就被限制到非常低的情况,大概保留 1% 的能力。这样,机器依然可以预热,进程也不停。

在这里。我们可以看这张图。

14.png

当需要比较大的资源调度的时候,我们推送一把开关,则资源限制打开,包活状态取消。资源域 B 瞬间可以满血复活。而资源域 A 此时进入上一个状态,CPU 和内存被限制。在这里,SOFAMosn 以一个极低的资源占用。完成流量保活的能力。使得资源的快速借调成为可能。

我们对 Service Mesh 的思考与未来

Service Mesh 在蚂蚁金服经过 2 年的沉淀,最终经过 双11 的检验,在 双11 ,我们覆盖了 200+ 的 双11 交易核心链路,Mosn 注入的容器数量达到了数十万,双11 当天处理的 QPS 达到了几千万,平均处理 RT<0.2 ms,SOFAMosn 本身在大促中间完成了数十次的在线升级,基本上达到了我们的预期,初步完成了基础设施和业务的第一步的分离,见证了 Mesh 化之后基础设施的迭代速度。

不论何种架构,软件工程没有银弹。架构设计与方案落地总是一种平衡与取舍,目前还有一些 Gap 需要我们继续努力,但是我们相信,云原生是远方也是未来,经过我们两年的探索和实践,我们也积累了丰富的经验。

我们相信,Service Mesh 可能会是云原生下最接近“银弹”的那一颗,未来 Service Mesh 会成为云原生下微服务的标准解决方案,接下来蚂蚁金服将和阿里集团一起深度参与到 Istio 社区中去,与社区一起把 Istio 打造成 Service Mesh 的事实标准。

ban.jpg

本书亮点

  • 双11 超大规模 K8s 集群实践中,遇到的问题及解决方法详述
  • 云原生化最佳组合:Kubernetes+容器+神龙,实现核心系统 100% 上云的技术细节
  • 双 11 Service Mesh 超大规模落地解决方案

阿里巴巴云原生技术圈关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

]]>
利用 FC + OSS 快速搭建 Serverless 实时按需图像处理服务-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 作者:泽尘

更多云原生技术资讯可关注阿里巴巴云原生技术圈

简介

随着具有不同屏幕尺寸和分辨率设备的爆炸式增长,开发人员经常需要提供各种尺寸的图像,从而确保良好的用户体验。目前比较常见的做法是预先为一份图像存放多份具有不同尺寸的副本,在前端根据用户设备的 media 信息来请求特定的图像副本。

预先为一份图像存放多份具有不同尺寸副本的行为,经常是通过 阿里云函数计算 FC 以及阿里云对象存储 OSS 两大产品实现的。用户事先为 FC 中的函数设置对象存储触发器,当在存储桶中创建了新对象(即 putObject 行为,此处指在 OSS bucket 中存放了图像),通过 OSS 触发器来触发函数对刚刚存放的图像进行处理,处理成不同尺寸的副本后,将这些副本存放进 OSS bucket。

上述方法的特点是预先处理,如果要处理的图像尺寸较多,那么当图像数量非常大的时候,会占用很多存储空间。假设要处理的图像尺寸数目为 x、图像数量为 y、平均每份图像的大小为 z,那么要占用的存储空间为 x y z。

动态调整图像大小
为了避免无用的图像占用存储空间,可以使用动态调整图像大小的方法。在 OSS bucket 中预先只为每份图像存放一个副本,当前端根据用户设备的 media 信息来请求特定尺寸图像副本时,再生成相关图像。

1.png

步骤:

  1. 用户通过浏览器请求 OSS bucket 中特定的图像资源,假设为 800 * 600 的 image.jpg。
  2. OSS bucket 中没有相关的资源,将该请求重定向至生成特定尺寸图像副本的 api 地址。
  3. 浏览器根据重定向规则去请求调整图像大小的 api 地址。
  4. 触发函数计算的函数来执行相关请求。
  5. 函数从 OSS bucket 中下载到原始图像 image.jpg,根据请求内容生成调整后的图像,上传至 OSS bucket 中。
  6. 将请求重定向至图像在 OSS bucket 中的位置。
  7. 浏览器根据重定向规则去 OSS bucket 中请求调整大小后的图像。

上述方法的特点是:

  1. 即时处理。
  2. 降低存储成本。
  3. 无需运维。

实践

1. 创建并配置 OSS

  • 在 OSS 控制台 中,创建一个新的 Bucket,读写权限选择公共读 (用于本教程示例,可之后更改)。

    2.png
  • 在 Bucket 的基础设置中,设置镜像回源。

    • 回源类型:重定向
    • 回源条件:HTTP 状态码 404
    • 回源地址:选择添加前后缀,并在回源域名中填写一个已接入阿里云备案的自定义域名。
    • 重定向 Code:302

3.png

2. 创建 FC 函数

  • 下载 serverless-image-on-the-fly 项目到本地

    git clone git@github.com:ChanDaoH/serverless-image-on-the-fly.git
  • 进入项目目录,执行 npm install
  • 填写 template.yml 文件中的相关内容:OSS_REGION、OSS_BUCKET_NAME、自定义域名
ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  serverless-image:
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: This is serverless-image service
      Policies:
        - AliyunOSSFullAccess
    image-resize:
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Handler: src/index.handler
        Runtime: nodejs10
        Timeout: 60
        MemorySize: 512
        CodeUri: ./
        EnvironmentVariables:
          OSS_REGION: oss-cn-shanghai # oss region, such as oss-cn-shanghai、oss-cn-hangzhou
          OSS_BUCKET_NAME: images-xxx # oss bucket name
      Events:
        httpTrigger:
          Type: HTTP
          Properties:
            AuthType: ANONYMOUS
            Methods:
              - GET
              - POST
  william.functioncompute.com: # domain name
    Type: 'Aliyun::Serverless::CustomDomain'
    Properties:
      Protocol: HTTP
      RouteConfig:
        routes:
          '/*':
            ServiceName: serverless-image
            FunctionName: image-resize

3. 测试动态调整图像

  • 在 OSS bucket 中上传一张图像,假设为 image.jpg

    4.png
  • 此时请求 https://{OSS_BUCKET_NAME}.{OSS_REGION}.aliyuncs.com/{width}*{height}/image.jpg。会有如下效果:

    1. 下载到指定 width * height 大小的 image.jpg。
    2. OSS bucket 中有 width * height 命名的目录,该目录下有 image.jpg。

5.gif

总结

我们通过 FC + OSS 搭建了一个实时按需图像处理服务,该服务拥有以下特点:

  1. 即时处理
  2. 降低存储成本
  3. 无需运维

资料

  1. 函数计算 Function Compute
  2. Aliyun Serverless VSCode 插件
  3. Fun

阿里巴巴云原生技术圈关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

]]>
Kubernetes v1.17 版本解读 | 云原生生态周报 Vol. 31-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 作者 |
徐迪、李传云、黄珂、汪萌海、张晓宇、何淋波 、陈有坤、李鹏
审核 | 陈俊

更多云原生技术资讯可关注阿里巴巴云原生技术圈

上游重要进展

1. Kubernetes v1.17 版本发布

功能稳定性是第一要务。v1.17 包含 22 个增强功能14 个增强功能已逐渐稳定,4 个增强功能已进入 beta 版,4 个增强功能已进入 alpha 版本

Major Theme

  • 云提供商标签达到 GA

这个自 1.2 版本就引入的 label,在 1.17 版本终于 GA。之前旧的 label 已经被废弃掉:以下 3 个旧的 label 已经被废弃掉了:

  • Volume Snapshot 进入 beta

在 1.12 版本中首次以 v1alpha 版本引入,在 1.13 中升级为 v2alpha(不兼容 v1alpha 版本),目前在 1.17 版本正式进入 beta 版;

从 1.14 开始迁移 alpha。

特性稳定

将 kube-scheduler  所关心的 Node 状态从 Conditions(例如:OutOfDiskMemoryPressure)转化到 Taints。Taints 成为 kube-scheduler 判断 Node 状态的唯一来源,同时用户也可以在 Pod 上通过声明 Tolerations 来容忍调度到有这些 Taints 的节点。

Pod 内所有容器共享 PID Namespace 特性 GA。该特性将方便 Pod 内进程信号传递(如 Sidecar 容器中的日志进程完成日志轮转后,通知业务容器进程使用新的日志)以及 Pod 内僵尸进程回收等。

Damoneset 的 pod 的调度从 daemonset controller 迁移到 kube-scheduler 来做调度,从而支持 PodAffnity、PodAntiAffinit 等能力。

该特性是为了支持调度感知单个 Node 上可以挂载的 Volume 个数的上限,且每个 Node 的上限可由存储插件自己动态设置。一般云厂商提供的云主机对某些存储卷(如块存储)能挂载的数量有限制,该特性支持调度器在选择 Node 时排除那些挂载的存储卷已经超过该 Node 支持的 Maximum Volume Count 的 Node 节点。

通过 CSI 实现的存储插件支持存储拓扑调度感知特性,即可以通过 Pod 被调度到的 Node 对应的拓扑位置信息(如 Node 所属的 Region/Zone/Rack 等等)决定动态创建的云存储的拓扑位置,也可以通过 StorageClass 限制动态创建的存储的拓扑位置,还可以通过 Pod 使用的 PV 的拓扑限制决定 Pod 可被调度的 Node 节点。

subPath 用在单个 Pod 多个容器或者一个容器中多个 mountPath 在共享同一个 volume 时以建子目录的方式在同一个 Volume 上做目录隔离。而 subPathExpr 字段可以从 Downward API 环境变量构造 subPath 目录名,可更加灵活地动态生成对应的子目录名。

Custom Resource 目前缺乏 default 机制,而 default 值对 API 的兼容性影响重大。这个功能通过 OpenAPI v3 的校验机制来为 CRD 添加默认值。

Lease api 进入 GA 阶段,kubelet 使用 lease api 周期性汇报心跳,相比 NodeStatus,lease 对象更小,可以降低 kube-apiserver 压力。

kubernetes-test.tar.gz 之前打包内嵌了各个平台的二进制文件。现在发行的 Kubernetes-test 包将以平台为单位,分拆成多个包。

kube-apiserver 通过增加 Bookmark 事件通知 watcher 服务器端当前最新 resourceVersion,可以降低 watcher 重启时对 kube-apiserver 造成的压力。

一致性测试框架进行修改以支持定义行为测试。行为测试是一组基于经验,代码检查,API 模型为视角的测试定义。而测试本身是具体对行为进行验证。此功能让两者进行分离。

增加 finalizer 去做 Load Balancer 类型的 Service 删除保护,确保 Service 这种资源对象在 Load Balancer 被摘除之后才能被删除。

之前多个客户端 watch 同一个对象时,需要对同一个对象序列化多次,引入该特性后,同一个对象只需要序列化一次,在 5000 个节点的测试环境中,可以减少 5% 的 CPU 和 15% 的内存消耗。

重要变化

Add IPv4/IPv6 Dual Stack Support 添加 IPv4/IPv6 双协议栈支持。即允许将 IPv4 和 IPv6 地址分配给 Pods 和服务。预计会在 1.18 版本对 kube-proxy 支持 IPv4/IPv6 双协议栈,代码正在 review 中;

其他重要特性

2. Knative变更

目前第一次启动时总是启动一个,用来检查用户代码是否正常工作,但在某些场景下不想启动任何实例。建议实现一个全局配置,并且可以在 revision 级别覆盖配置,如果不启动实例,则马上把状态设置为 ready,如果有流量过来按冷启动流程启动实例。

还没有足够的理由添加这些属性。

从 Broker/Trigger 模型中删除 ingress channel。当前 Broker 会创建 2 个 channels: trigger 和 ingress.  ingress channel 用于接收 trigger 的响应结果,然后发送给 ingress service. 但是目前看起来是额外的多了一跳,引入了延迟和可靠性的问题,比较好的方式是直接将响应结果发送给 ingress service.

开源项目推荐

1. dive

一个 docker image 分析工具,帮助快速分析各 layer 的内容,有助于减小整个镜像的大小。

2. amazon-vpc-cni-k8s

aws 上基于 ENI 的网络插件。

3. Draino

负责 cordon 和 drain 节点,提供了 dry run 模式。

4. Apache Dubbo-go

dubbo 的 golang 实现。

本周阅读推荐

  1. 《A visual guide on troubleshooting Kubernetes deployments》

文章主要讲述了如何去定位一个 deployment 无法正常工作的问题。

  1. 《Kubernetes Audit: Making Log Auditing a Viable Practice Again》

本文提出了一种 Kubernetes 自动化审计日志分析器的愿景,但这一愿景远不止于此。使用机器学习之类的工具甚至可以实时地自动检测日志中潜在的威胁。此外,以用户可理解的方式汇总审核日志中的信息,使审核员可以快速验证已识别的模式,并帮助调查其他隐藏的可疑活动。

  1. 《How Kubernetes Has Been "Transformational"  to Productivity and Culture at uSwitch》

很多人开始尝试把业务迁移到 Kubernetes 上,那么 Kubernetes 到底能带来哪些改变呢?通过 uSwitch 的这个案例研究,可以给你带来不一样的思考。

  1. 《Building Large Kubernetes Clusters》
  2. 随着集群越来越多,集群的搭建和管理是个很头疼的问题。LINE 分享了自研的一套框架 Caravan。
  3. 《Kubernetes is the future of Computing. What You Should Know About the New Trend》

越来越多的人开始使用 Kubernetes,有人说它是下一代的“操作系统”,“云计算的未来”。快通过这篇文章了解下这个大趋势吧。

阿里巴巴云原生技术圈关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

]]>
开放下载 | 《Knative 云原生应用开发指南》开启云原生时代 Serverless 之门-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 knative海报.png

点击下载《Knative 云原生应用开发指南》


自 2018 年 Knative 项目开源后,就得到了广大开发者的密切关注。Knative 在 Kubernetes 之上提供了一套完整的应用 Serverless 编排服务,让应用开发者可以不用为底层的基础设施分心,把更多的精力投入到业务逻辑上。
Knative 的一个很重要的目标就是制定云原生、跨平台的 Serverless 编排标准。它的优势在于:

  • 基于 Kubernetes 实现 Serverless 编排;
  • 基于 Istio 实现服务的接入、服务路由的管理以及灰度发布等功能。

今年 5 月份,我们推出了 Knative 系列文章,由阿里云容器平台技术专家牛秋霖(冬岛)及阿里云容器平台高级开发工程师李鹏(元毅)结合自身的实践经验,由浅入深的介绍了 Knative 的使用、剖析其内部实现。

为了进一步方便大家理解 Knative,我们整理了系列文章中的 25 篇重点内容编排成书《Knative 云原生应用开发指南》,并开放分享给大家,希望能够帮助更多技术爱好者快速掌握 Knative 的应用 Serverless 编排技能,揭开 Knative 的神秘面纱。

为什么你要读这本书?

对于开发者而言,本书可以让你快速掌握 Knative 的应用 Serverless 编排技能;对于管理者或决策者而言,可以通过本书的介绍和案例深入了解企业为什么需要应用的 Serverless 编排;如何对普通应用进行 Serverless 编排;应用编排和 IaaS 无服务器计算的关系以及为什么会是 Knative 等问题。

本书主要分为入门、进阶和实战三个部分。

  • 入门篇可以帮助你快速掌握 Knative 的核心理念和关键设计,让你对应用的云原生编排应该具备什么能力有一个清晰的认识;
  • 进阶篇会对 Knative 各大核心模块的高级功能进行更深入的介绍,剖析 Knative 是如何构建在 Kubernetes 之上的;
  • 实战篇给出了很多基于 Knative 的云原生实战,让你对 Knative 的使用有一个更直观的体感。

目录.png


《Knative 云原生应用开发指南》目录 点击可查看大图

在 All in Cloud 的时代,对云的驾驭能力已经成为企业的核心竞争力,云正在重塑企业 IT 架构。每个企业都在思考如何最大化利用“云”的能力,最大化发挥“云”的价值。而企业上云的过程中是要直接面对众多的云厂商和各种繁杂的云产品,比如最基本的 IaaS 资源,同样是 VM 在不同的云厂商就有不同的特性、不同的 OpenAPI 和不同的创建与销毁方式。

这给企业上云带来了巨大的复杂度,大大打击了企业上云的积极性。所以对于上云的企业和提供云服务的厂商而言都在摸索寻找一个折中的平衡点,既能帮助企业上云,又能帮助云厂商释放云的能力。

云原生理念的形成与完善

云原生理念是在以上过程中逐渐形成和完善的。这套理念是协调所有参与方对服务上云逐渐形成的统一标准,它可以很好地帮助企业上云、帮助云厂商释放云的能力。云原生旨在以更标准化的方式衔接云厂商和上云企业:

  • 这种方式对于企业而言降低了上云和跨云的成本,让企业始终保有和云厂商议价的能力;
  • 对于云厂商而言,因为企业跨云迁移的成本低,所以只要能提供性价比更高的云服务,就能很容易的聚集大量用户。

云原生是在不断促进整个系统的良性循环:既能让企业始终保有选择的能力,又能让优秀的云厂商快速服务更多的客户。如果客户的业务服务能像水一样低成本在不同云厂商之间流动,那么云厂商提供的服务就能像货币一样在客户之间流通。这是一个多赢的局面。

Kubernetes 已经成为分布式资源调度和资源编排的事实标准,它屏蔽了底层基础架构的差异,帮助应用轻松运行在不同的基础设施之中。

目前云原生生态已经在 Kubernetes 之上构建了大量的上层服务支撑框架。比如:服务网格 Istio、 Kubeflow 、各种上层服务的 Operator 等等。我们可以看到构建在 Kubernetes 之上的云原生操作系统的雏形开始出现,这是开发者最好的时代,极大地提升了业务创新的速度。

无服务器(Serverless)的出现

随着 Kubernetes 的普及,开发者已经不需要关心基础设施,有了更多的精力放在业务的核心逻辑上,随之而来的就是无服务器计算的出现。

无服务器首先是在 IaaS 层的变革,用户无需提前准备冗余的 IaaS 资源,只需要在使用的时候自动扩容不用的时候自动缩容。因为应用真正需要的是 IaaS 资源的按需分配按量计费,而不是长期保有 IaaS 资源。

无服务器这个词是从 Serverless 翻译过来的,其实 Serverless 除了基础 IaaS 资源的按量分配以外还有一层就是对应用的 Serverless 编排。

Knative 出现的必然性

IaaS 资源可以按需分配只是一个开始,当 IaaS 完成了 Serverless 进化以后,应用层应该如何做呢?比如:一个普通应用需要具备什么能力才能按量使用 IaaS 资源呢?对应用进行 Serverless 编排是否能保证应用可以很容易的在不同的云厂商之间跨云迁移?

Knative 就是应用 Serverless 编排的云原生解决方案。

Knative 建立在 Kubernetes 和 Istio 之上,通过 Kubernetes 的跨云能力能够让企业应用原生具备跨云迁移的能力。在多云、混合云以及云边端互通的时代,基于 Knative 的应用 Serverless 云原生编排能力可以极大降低企业上云的成本。

云原生时代,如何在云上玩转 Knative?

《Knative 云原生应用开发指南》一书中共收录了 8 篇具体的 Knative 开发实践案例,给出了很多基于 Knative 的云原生实战,借此讲述了如何正确使用 Knative 中的 Build、Serving 以及 Eventing 三大组件来发挥其作用,逐渐精简我们的代码;直观地展示了如何使用 Knative 来一步步简单高效地开发云原生应用,让你对通过  Knative 来实践 Serverless 有一个更全面的体感。

期待《Knative 云原生应用开发指南》能够帮助更多的开发者真正开启云原生时代的 Serverless 之门,轻松解决迎面难题,避免踩坑!

点击下载《Knative 云原生应用开发指南》

knative海报.png

]]>
快速搭建 Serverless 在线图片处理应用-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 作者:倚贤

首先介绍下在本文出现的几个比较重要的概念:

函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考

ImageMagick:ImageMagick 是一个用于查看、编辑位图文件以及进行图像格式转换的开放源代码软件套装。它可以读取、编辑超过100种图象格式。。参见维基百科词条

ImageMagick 是图片处理的利器,借助 ImageMagick 可以轻松实现图片的裁剪和缩放。虽然很多语言都封装了 ImageMagick 的调用库,但是把图片处理功能和核心业务功能放在同一个服务内,在软件架构上往往不适合。有如下两方面的原因:

一方面,图片处理依赖外部的 bin,已经编译好的二级制不具备可移植性,给打包发布带来了麻烦。另一方面,图片处理往往是比较耗费计算资源的,对于大多数业务系统来说图片处理属于边缘业务,而非核心业务,所以为整个服务预留较多的计算资源是不划算的。更好的选择是把图片处理类业务以微服务的形式切分出来,部署在具备弹性的底层服务之上。对于此类技术需求, Serverless 是非常切合的。

本文重点介绍如何快速地在函数计算平台上部署一个弹性高可用的图片处理服务,然后在此基础上轻松的定制化。

快速开始

下面我们借助于函数计算的应用中心,快速地将图片转换服务给部署出来。

  1. 打开函数计算 Image Resizer 应用详情页。如果您尚未开通函数计算服务可能需要先,开通服务是免费的,另外函数计算有每月免费额度,试用服务不会产生费用。


1.png

  1. 滚动到Image Resizer 应用详情页的最底部,点击“立即部署”按钮。


2.png

  1. 填写应用名称:my-image-resizer,然后点击“部署”按钮。


3.png

  1. 拷贝 HttpTriggerEndpoint 里的网址。


4.png

  1. 在浏览器里打开上面的网址,或者通过 curl 进行调用。注意:由于没有绑定域名,所以应用中心会默认下载而不是直接在浏览器里打开图片。
curl 'https://xxxxx.cn-shanghai.fc.aliyuncs.com/2016-08-15/proxy/my-image-resizer-ResizeService-5A40B5A8B981/my-image-resizer-ResizeFunction-3E71C57C0094/' --output resized.jpg

工作原理

这是一个单函数结合 Http Trigger 的应用。Http Trigger 以 HTTP GET 方法对外暴露服务,客户端传递三个请求参数:url、width 和 height。其中

  • url 表示需要进行处理的源图片地址
  • width 表示裁剪或缩放后的图片宽度
  • height 表示裁剪的图片宽度。该参数缺失时,表示采用缩放的方式调整图片。

该应用的架构图如下:

6.jpg

FC 函数接受到 HTTP 请求之后,执行如下三个步骤:

  1. 把 url 指向的图片下载下来
  2. 使用 imagemagick 进行图片转换
  3. 将图片通过 http 协议返回给客户端

上面我们通过了函数计算的应用中心快速上线了一个图片转换的服务。函数计算是按照调用次数收费的,所以上述服务即使保持在线也不会产生费用。而又因为函数计算每月有免费的额度,所以日常开发的调用也不会产生费用。

定制化开发

依赖工具

本项目是在 MacOS 下开发的,涉及到的工具是平台无关的,对于 Linux 和 Windows 桌面系统应该也同样适用。在开始本例之前请确保如下工具已经正确的安装,更新到最新版本,并进行正确的配置。

Fun 工具依赖于 docker 来模拟本地环境。

对于 MacOS 用户可以使用 homebrew 进行安装:

brew cask install docker
brew tap vangie/formula
brew install fun

Windows 和 Linux 用户安装请参考:

  1. https://github.com/aliyun/fun/blob/master/docs/usage/installation.md

安装好后,记得先执行 fun config 初始化一下配置。

注意, 如果你已经安装过了 funcraft,确保 funcraft 的版本在 3.1.3 以上。

$ fun --version
3.1.3

初始化

git clone https://github.com/vangie/fc-image-resizer
cd fc-image-resizer

安装依赖

npm install

本地运行

$ fun local start
using template: .fun/build/artifacts/template.yml
HttpTrigger httpTrigger of ResizeService/ResizeFunction was registered
        url: http://localhost:8000/2016-08-15/proxy/ResizeService/ResizeFunction
        methods: [ 'GET' ]
        authType: ANONYMOUS


function compute app listening on port 8000!

然后使用浏览器或者 curl 调试网址 http://localhost:8000/2016-08-15/proxy/ResizeService/ResizeFunction

部署

fun deploy

为了获得更好的开发体验,建议安装 Aliyun Serverless VSCode Extension

参考链接

  1. Funcraft
  2. Aliyun Serverless VSCode Extension

阿里巴巴云原生技术圈关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

]]>
容器镜像服务企业版发布,更强更安全-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800

【容器镜像是什么】

说到容器镜像,相信大家都已经很熟悉了。它是一种标准化的交付方式,将应用的代码以及代码环境依赖都打包在一起,成为一个与环境无关的交付物,可以被用在软件生命周期的任何阶段,彻底改变了传统的软件交付方式。

【容器镜像服务的数字】

在公共云上,阿里云容器镜像服务 是目前【国内最大的镜像服务】提供商。我们在阿里云全球地域提供服务,存储了【几十万】的容器镜像,支撑了【上亿】的镜像下载量,为您的应用镜像保驾护航。

【容器镜像服务-共享版】

容器镜像服务提供【公网、VPC网络、经典内网】三种访问入口,提供稳定的构建服务,支持镜像的细粒度安全扫描和便捷的镜像分享授权。此外,容器镜像无缝集成容器服务等云产品,输出云端DevOps的整套完整解决方案,帮助您提速产品的创新迭代。

目前,容器镜像服务是一个免费的公共云服务, 欢迎各位容器开发者把应用镜像托管上来,体验容器技术带来的敏捷变革。

【容器镜像服务-企业版】

容器镜像服务-企业版,具备更强的安全及镜像分发能力:适合拥有安全需求较高且拥有大规模节点的企业级客户。

在镜像安全部分,提供 [独享的OSS存储],支持镜像加密存储特性。提供VPC、公网、内网访问白名单,需要开启访问且设置白名单后,才能访问到企业版镜像。进一步保障您镜像的存储及访问的多方安全。

在镜像分发部分,支持P2P镜像加速,提供大规模集群节点的并发拉取能力,保障您业务的极速部署,解决大镜像分发难、多节点拉取慢的难题。

试用体验容器镜像产品
https://www.aliyun.com/product/acr
点击了解阿里云新品发布会
https://promotion.aliyun.com/ntms/act/cloud/product.html

]]>
产教结合、硬软一体,阿里云教育一体机发布-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 阿里云教育一体机,基于云原生开发服务(阿里云容器服务Kubernetes)和移动开发服务(EMAS),为高校学生量身定制了一系列课程及实验,将前沿科技的理论和最佳实践引入高校,以软件硬件于一体的交付方式为教育行业提供解决方案。产品旨在缩小高校在人才培养侧和市场需求侧在结构、质量、水平存在的差异。

云技能gap或将成为危机?
云计算自2006年起逐步被企业应用,为各行各业提供了业务支撑,至今IT系统云化成为了重要发展趋势。随着大型分布式系统兴起,更多的新技术不断涌现,深度学习、区块链、容器技术、无服务化、数字孪生、边缘计算及认知计算等等。
越来越多的企业尝试通过云原生技术把传统的IT‘遗产’搬移到云上,这意味着各种挑战,其中之一就是人才缺口。根据IDC发布的《2019年全球CIO议程预测》,公司亟需各类新兴技术的优秀人才,其中30%岗位在2022年前都将是空缺状态。OpsRamp曾经对百余位大中型公司的IT经理及以上级别的人进行了调查,94%认为寻找到具备需求技术和商业技能的人才并不容易, 超过30%认为如今人才池尚不能喂饱企业对云原生技术的需求。
而另一方面, 2019届毕业生预计834万人为近10年新高值,就业创业形势不可谓不严峻。离开校园走入职场,学子们面临着角色转化,需要快速跨越从课堂理论到实际运用的鸿沟。在麦可思研究院发布的就业蓝皮书报告中显示,毕业生就业满意度为67%,其中软件工程、网络工程等连续三届保持较高就业率。
云计算普惠,我们能做哪些?
阿里云教育一体机源于一个思考,我们能否将当下主流的云计算知识带进校园,并为学子们提供包含理论课程、动手实验、软件环境和硬件机器的整套‘云实验室’。

image


教育一体机硬件为标准机柜,具备两个规格半配和满配, 包含D13/12服务器5台或10台,分别可以满足30人或60人在线研发学习。
底层软件环境基于三款阿里云产品:飞天敏捷版容器平台、移动研发平台EMAS、CodePipeline。其中飞天敏捷版是国内唯一具有全商业版支持能力的容器云平台,可部署在自有数据中心、提供开放的接口、更提供了混合云管理模式,让用户轻松管理运行环境。而EMAS是阿里巴巴移动互联网近十年的技术积累,沉淀了基础设施及组件服务能力、DevOps研发支撑能力、移动App基础中间件能力以及工程理念,完整覆盖了研发、测试、发布、运维和运营五大生命周期,包括天猫、优酷、钉钉、盒马等上百款阿里巴巴APP产品均使用了EMAS。Codepipeline是一款提供持续集成/持续交付能力,并完全兼容Jenkins的能力和使用习惯的SaaS化产品。方便在云端实现从代码到应用的持续集成和交付,方便快速的对产品进行功能迭代和演进。
目前教育一体机设置了六门课程:《Andorid开发》、《移动DevOps技术》、《容器技术》、《DevOps技术》、《区块链技术》、《机器学习与深度学习》。每门课程都有理论课和实验课组成。

image


我们选取了主流的云计算技术,并贴合学生视角撰写教材,下图取自《机器学习与深度学习》一节理论课程。

image


设立实验课的初衷,是希望让学生们可以学练结合,提前熟悉企业真实环境中会使用的工具及相关流程操作。下面是《DevOps技术》的实验目录:

image


阿里云在技术领域有着近十年的积累,教育一体机基于阿里云容器、CodePipeline及EMAS三款企业级产品的强大技术支撑,提供云原生开发实验环境,并实现了硬件软件的一体化交付。
我们期待把最新的云计算技术带进高校课堂,实现课堂理论与实际运用融会贯通,为更多学子就业加码。

教育一体机发布会:点击观看直播

教育一体机专题页:把云计算技术带进校园,为学子提供云原生实验环境

点击了解阿里云新品发布会
https://promotion.aliyun.com/ntms/act/cloud/product.html

]]>
阿里云杨敬宇:四层技术构建基于城市场景的边缘计算-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 12月11日,阿里云边缘计算技术负责人杨敬宇在2019亚太内容分发大会上表示:在未来,边缘计算主要是以地市、区县为单位开展,面向城市服务的交通、医疗、健康、教育、新零售等场景提供算力基础。阿里云认为边缘计算就是城市计算,我们将围绕城市场景去建设边缘计算基础设施和灵活易用的上层操作系统。

IMG_2695.JPG

产业互联网、5G、AI与边缘计算

在过去25年,行业应用主要是集中在消费互联网领域,在技术层面大部分采用云-端二体网络架构支撑,这是一种趋于集中生产分散消费的模式。而随着5G、IoT等技术的革新,沉浸式消费体验来临,产业互联网也迎来发展机遇。计算不仅发生在中心,在远离中心靠近用户的边缘侧(如摄像头、传感器、IoT设备)也出现大量的计算需求,所以传统的云-端二体网络架构已经无法满足应用需求,信息架构需要由原来的辐射性架构演变成对等架构,来适应分散生产分散消费模式,因此边缘计算应运而生。

实际上4G网络大部分是以省为单位来构建的,固网和移动网络在省域汇聚和互访。而5G来临之后会发生很大变化。如果把通信管道比作高速公路,5G有一个非常重要的特征,它允许边缘分流,这就相当于在高速公路建服务区,也就是说通信管道上的信息流可以在旁路出来;另外, 5G网络切片云就如同高速公路上的车道,把路按速度和服务质量进行划分;同时,5G下的MEC促使固网和移动网络可以在区县一级打通,它改变了原来的互联网通信结构,为离用户更近的边缘计算基础设施提供了技术可能性。

A7467FC2-4539-4392-98B2-39A71EA67F73.png

每一次技术革命都会带来一波超级应用,边缘计算的来临,将使得万物智联带来的海量数据处理和边缘实时感知等诉求得以有效解决,进而驱动AI的应用,比如智能家居、智慧城市、自动驾驶等等场景。在大视频领域,超高清、强互动、VR/AR也会真正走进大众生活。

杨敬宇认为:产业互联网、5G、MEC为边缘计算提供了市场与技术的可能性,而AI和视频应用将是未来边缘计算第一站的落地场景。

阿里云的边缘计算到底做什么?

阿里云过去十年一直专注于云计算领域,基础设施遍布19个地理区域内56个可用区,拥有2800+ 全球CDN节点。早在2016年,阿里云就开始研发边缘计算产品和技术。2018年3月,阿里云正式宣布战略投入边缘计算技术领域,依托于云计算、大数据、人工智能、IoT等领域的先发优势,已经构建了完整的云边端一体化协同体系。通过阿里巴巴丰富的生态系统与视频处理技术、达摩院AI能力进行进一步融合,阿里云边缘计算在电商、物流、新零售、文娱、在线教育等众多领域具备丰富的商业化实践。

杨敬宇表示:当5G来临,各行业的应用架构,从硬件、芯片、网络、中间件到应用服务都将迎来变革,所有技术都要向边缘演进。而边缘计算主要是以地市、区县为单位开展的面向城市服务的交通、医疗、健康、教育的场景,阿里云认为边缘计算就是城市计算,未来也将主要围绕城市单元去开展边缘计算业务。

屏幕快照 2019-12-12 下午1.55.04.png

想要解决交通、医疗、健康、新零售这类场景的业务诉求,有两种解决思路,一种把计算设施放在商超、工厂、企业里,这种称之为重资产模式;另外一种是云模式,把计算设施放在基站以上并向企业提供服务。阿里云在布局边缘计算的时候重点依托CDN的点位优势布局基站以上的边缘计算,后续通过引入MEC资源,充分释放计算红利,让企业可以轻装上阵。目前,阿里云已经完成国内30多个省份300+边缘计算节点的全域覆盖。

边缘计算四层技术栈:硬件、操作系统、中间件、应用和服务

杨敬宇讲到:阿里云城市计算技术布局包含四层技术栈,一是边缘硬件和芯片,二是边缘计算平台或者边缘计算操作系统,三是边缘中件间,四是面向边缘的应用或者服务。

在芯片/设备方面,阿里云边缘计算采用通用芯片、专用芯片和自研芯片解决未来面向场景的边缘计算成本问题;在边缘计算平台方面,阿里云着重打造边缘操作系统,提供三种计算形态(虚机、容器、函数)和三种交付形态(Server、Serverlet、Serverless),为客户营造一个利于使用的计算环境;对于边缘中间件,阿里云要从原本“内容分发的调度”转变为“计算的调度”,同时叠加AI、存储等新技术,逐步形成面向城市应用场景的独特中间件能力;至于上层的边缘应用及服务,则需要结合阿里巴巴集团商业生态和垂直行业伙伴共同推动技术进步。

未来阿里云边缘计算操作系统会把解决计算在哪里、如何简化计算的复杂度、如何更便捷地运维分布式计算资产等问题会作为核心目标,客户的开发人员只需要简单地调用接口,就可以使用广泛地使用边缘计算策略,而不用担心部署和计算在哪里的问题。杨敬宇认为未来边缘计算服务提供商一定是来解决融合、开放、集成、按需的问题,更高层次的赋能客户。各种产业应用发展起来,应用层不应该关心底层细节,不然整个发展会有大的掣肘。

屏幕快照 2019-12-12 下午1.51.47.png

同时,阿里云边缘计算也不是孤立的,它会和云、端形成一体化的协同模式,同时开放API,努力赋能上层应用生态,与合作伙伴一同推进产业发展。

边缘计算在新零售、城市大脑场景的应用实践

过去一年,阿里云和盒马在边缘计算领域做了很多尝试。通过将摄像头、传感器接入边缘节点进行实时的视频结构化和数据汇总分析,盒马门店实现了生产安全监控、防盗损、门店督导的新效能,提升了生产安全和规范性。边缘计算可以为门店、物流点提供防盗损安防视频解决方案,低成本接入不同厂商设备,提供实时预览、录制回看、截图、分析等能力,实现了视频安防云联网,提高监管人员工作效率,促进生产安全,减少盗损资产损失,同时边缘计算提供的高性价比视频AI计算能力,支持计算资源弹性扩容满足业务突发增长,降低了本地盒子或一体机方案带来的大量本地部署、运维和管理成本。

屏幕快照 2019-12-12 下午1.56.49.png

在城市大脑中,边缘计算也可以发挥重大作用。未来城市中存在大量的摄像头、传感器,如何把这些数据及时分析,对城市治理形成帮助是一个非常大的命题。比如,在市政、交通场景中,把从学校、餐饮、医院的数千万摄像头采集的视频汇聚、传输到城市边缘计算平台,数据在边缘节点进行有效收敛、AI及结构化处理,关键性数据再回传到中心云。这种计算下沉边缘的模式相比直接上公有云可以很好节省回源带宽,相比专有云可以提升交付效率和降低运营成本。

屏幕快照 2019-12-12 下午1.52.57.png

综上,边缘计算具有更靠近数据源,传输成本低、低时延、体验更佳、轻资产运营等特点。基于阿里云在边缘计算领域先发优势以及创新性产品技术部署,边缘节点服务(ENS)已实现终端接入延迟低至5毫秒,为用户带来了综合成本30%的减少、运维效率50%的提升。

]]>
有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 更多云原生技术资讯可关注阿里巴巴云原生技术圈

Puppeteer 是什么?

puppeteer 官网的介绍如下:
Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.

通俗描述就是:Puppeteer 可以将 Chrome 或者 Chromium 以无界面的方式运行(当然也可以运行在有界面的服务器上),然后可以通过代码控制浏览器的行为,即使是非界面的模式运行,Chrome 或 Chromium 也可以在内存中正确渲染网页的内容。
那么 Puppeteer 能做什么呢?

  • 生成网页截图或者 PDF
  • 抓取 SPA(Single-Page Application) 进行服务器渲染(SSR)
  • 高级爬虫,可以爬取大量异步渲染内容的网页
  • 模拟键盘输入、表单自动提交、登录网页等,实现 UI 自动化测试
  • 捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题

本文选择截图场景作为演示。

废话不多说了,我们直接给大家介绍下如何用函数计算产品来快速部署一个 Puppeteer Web 应用。

如何快速部署一个分布式 Puppeteer Web 应用?

为了快速部署分布式 Puppeteer Web 应用,本文以函数计算服务为例来做展示。

函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考

有了函数计算服务,我们这里目标是搭建一个分布式应用,但做的事情其实很简单,那就是写好业务代码,部署到函数计算,仅此而已。

使用函数计算后,我们的系统架构图如下:

1.png

效果演示

可以直接通过以下链接查看效果:
https://1911504709953557.cn-hangzhou.fc.aliyuncs.com/2016-08-15/proxy/puppeteer-test/html2png/?url=https://www.aliyun.com/product/fc
PS:第一次请求可能会有几秒的冷启动时间,通过使用预留模式可以完全去除冷启动,这题超纲,下次再讲。

搭建步骤步骤:

整体流程如下图所示:

2.png

其中,需要我们操作的只有 Fun Init、Fun Install 以及 Fun Deploy 命令,每个的步骤内容都会由这三个命令自动完成。

1. 工具安装

安装 Fun 工具

建议直接从这里下载二进制可执行程序,解压后即可直接使用。下载地址

安装 Docker
可以按照这里介绍的方法进行安装。

2. 初始化项目:

通过 Fun 工具,使用下面的命令可以快速初始化一个 Puppeteer Web 应用的脚手架:

fun init -n puppeteer-test http-trigger-node-puppeteer

其中 -n puppeteer-test  表示初始化项目的目录名称, http-trigger-node-puppeteer  表示要使用的模板名称,可以省略该名称,省略后,可以从终端提示的列表中自行选择需要的模板。
执行完毕后,可以看到如下的目录结构:

.
├── index.js
├── package.json
└── template.yml

相比较于传统的 puppeteer 应用,这里仅仅多了一个 template.yml 文件,用于描述函数计算的资源。
而 index.js 就是我们的业务代码了,可以按照 Puppeteer 官方帮助文档的要求书写自己的业务代码,这里不再重复阐述,核心代码如下:

const browser = await puppeteer.launch({
  headless: true,
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
  ]
});
const page = await browser.newPage();
await page.emulateTimezone('Asia/Shanghai');
await page.goto('https://www.baidu.com', {
  'waitUntil': 'networkidle2'
});
await page.screenshot({ path: '/tmp/example', fullPage: true, type: 'png' });
await browser.close();

package.json 内容如下:

{
  ... ...
  "dependencies": {
    "puppeteer": "^2.0.0"
  },
  ... ...
}

可以看到,在 package.json 中声明了 puppeteer 的依赖。这个也是我们使用 node 开发时的标准做法,并无特别之处。

3. 一键安装依赖

puppeteer 的安装,即使是在传统的 linux 机器上,也不是那么的轻松。因为 puppeteer 本身依赖了非常多的系统库,要安装哪些系统库、如何安装这些系统库成了一个比较头痛的问题。

好在函数计算命令行工具 Fun 已经集成了 Puppeteer 的解决方案,只要 package.json 中包含了 puppeteer 依赖,然后使用 fun install -d 即可一键安装所有系统依赖。

fun install -d

4. 本地运行、调试函数

Puppeteer 的本地运行、调试方法与这里介绍的完全一致,我们就不再重复介绍。我们这里只演示下运行效果:

4.gif

5. 一键部署应用

基本上所有的 FaaS 平台为了减小应用的冷启动,都会设置代码包的限制,函数计算也不例外。而 puppeteer 自身已经达到了 350M 左右,连同其系统依赖已经达到了 450M。如何将 450M 体积的函数部署到 FaaS 平台是一个比较头痛而且繁琐的问题。

函数计算的命令行工具 Fun 现在原生支持了这种大依赖部署(3.1.1 版本仅支持 node runtime)。不需要任何额外操作,仅仅执行 fun deploy:

$ fun deploy

fun 会自动完成依赖的部署。而当检测到打包的依赖超过了平台的限制时,会进入到配置向导,帮助用户自动化地配置。

我们这里推荐的路径是当提示是否由 Fun 自动帮助 NAS 管理是,输入 yes,然后提示提示是否使用 NasConfig: Auto 自动处理 NAS 时,也选择是,之后就不需要做其他的事情,等待函数部署成功即可。

5.png

如果有其他的需求,比如想使用自己已经存在的 NAS 服务,可以在提示使用 NasConfig: Auto 时,输入 no,这样就会进入到相应的流程。更详细的说明,请参考下面的 FAQ。

FAQ

在安装 puppeteer 时,Fun 都做了哪些事情?

puppeteer 本身是一个 npm 包,它的安装是非常简单的,通过 npm install 即可。这里的问题在于,puppeteer 依赖了 chromium,而 chromium 又依赖一些系统库。所以 npm install 后,还会触发下载 chromium 的操作。这里用户经常遇到的问题,主要是:

  1. 由于 chromium 的体积比较大,所以经常遇到网络问题导致下载失败。
  2. npm 仅仅只下载 chromium,chromium 依赖的系统库并不会自动安装。用户还需要自行查找缺失的依赖进行安装。

Fun 做的优化主要是:

  1. 通过检测网络环境,对于国内用户,会帮助配置淘宝 NPM 镜像实现加速下载的效果。
  2. 自动为用户安装 chromium 所缺失的依赖库。

Fun 是如何把大依赖部署到函数计算的?不是有代码包大小的限制吗?

基本上所有的 FaaS 为了优化函数冷启动,都会加入函数代码包大小的限制。函数计算也不例外。但是,Fun 通过内置 NAS(阿里云文件存储) 解决方案,可以一键帮用户创建、配置 NAS,并上传依赖到 NAS 上。而函数计算在运行时,可以自动从 NAS 读取到函数依赖。

为了帮助用户自动化地完成这些操作,Fun 内置了一个向导(3.1.1 版本仅支持 node,后续会支持更多,欢迎 github issue 提需求),在检测到代码体积大小超过平台限制时,会提示是否由 Fun 将其改造成 NAS 的方案,整个向导的逻辑如下:

  1. 询问是否使用 Fun 来自动化的配置 NAS 管理依赖?(如果回答是,则进入向导,回答否,则继续发布流程)
  2. 检测用户的 yml 中是否已经配置了 NAS
  3. 如果已经配置,则提示用户选择已经配置的 NAS 存储函数依赖
  4. 如果没有配置,则提示用户是否使用NasConfig: Auto自动创建 NAS 配置
  5. 如果选择了是,则帮助用户自动配置 nas、vpc 资源。
  6. 如果选择了否,则列出用户当前 NAS 控制台上已经有的 NAS 资源,让用户选择
  7. 无论上面使用哪种方式,最终都会在 template.yml 生成 NAS 以及 VPC 相关的配置
  8. 根据语言检测,比如 node runtime,会将 node_modules 以及 .fun/root 目录映射到 nas 目录(通过 .nas.yml 实现)
  9. 自动执行 fun nas sync 帮用户把本地的依赖上传到 NAS 服务
  10. 自动执行 fun deploy,帮用户把代码上传到函数计算
  11. 提示帮助信息,对于 HTTP Trigger 的,提示函数的 Endpoint,直接打开浏览器访问即可看到效果

是否可以指定 puppeteer 的版本?

可以的,只需要修改 package.json 中的 puppeteer 的版本,重新安装即可。

函数计算实例中的时区采用的 UTC,是否有办法改为北京时间?

某些网页的显示效果是和时区挂钩的,时区不同,可能会导致显示的内容有差异。使用本文介绍的方法,可以非常容易的使用 puppeteer 的最新版本,而在 puppeteer 的最新版本 2.0 提供了一个新的 API page.emulateTimezone(timezoneId) , 可以非常容易的修改时区。

如果 Puppeteer 后续版本更新后,依赖更多的系统依赖,本文介绍的方法还适用吗?

Fun 内置了 .so 缺失检测机制,当在本地调试运行时,会智能地根据报错识别出缺失的依赖库,然后精准地给出安装命令,可以做到一键安装。

如果添加了新的依赖,如何更新?

如果添加了新的依赖,比如 node_modules 目录添加了新的依赖库,只需要重新执行 fun nas sync 进行同步即可。

如果修改了代码,只需要使用 fun deploy 重新部署即可。由于大依赖和代码通过 NAS 进行了分离,依赖通常不需要频繁变化,所以调用的频率比较低,而 fun deploy 的由于没有了大依赖

除了本文介绍的方法还有哪些方法可以一键安装 puppeteer?

Fun 提供了非常多的依赖安装方式,除了本文介绍的将依赖直接声明在 package.json 中,然后通过 fun install -d 的方式安装外,还有很多其他方法,他们均有各自适用的场景:

  1. 命令式安装。比如 fun install -f functionName -p npm puppeteer。这种安装方式的好处是即使对 fun 不了解的用户也可以傻瓜式的使用。
  2. 声明式安装。这种安装方式的好处是提供了类 Dockerfile 的体验,Dockerfile 的大部分指令在这里都是可以直接使用的。通过这种方式声明的依赖,可以通过直接提交到版本仓库。他人拉取代码后,也可以一键安装所有依赖。
  3. 交互环境安装。这种安装方式的好处是提供了类似传统物理机的安装体验。在交互环境中,大部分 linux 命令都是可以使用的,而且可以不断试错。

总结

本文介绍了一种比较简单易行地从零开始搭建分布式 Puppeteer Web 服务的方法。利用该方法,可以做到不需要关心如何安装依赖、也不需要关系如何上传依赖,顺滑地完成部署。

部署完成后,即可享受函数计算带来的优势,即:

  • 无需采购和管理服务器等基础设施,只需专注业务逻辑的开发,可以大幅缩短项目交付时间和人力成本
  • 提供日志查询、性能监控、报警等功能快速排查故障
  • 免运维,毫秒级别弹性伸缩,快速实现底层扩容以应对峰值压力,性能优异
  • 成本极具竞争力

阿里巴巴云原生技术圈关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

]]>
权威发布 | 阿里云分析型数据库AnalyticDB 荣膺中国信通院大数据产品评测双料认证-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 大会汇集了国内外知名机构的数据资产管理领军专家,对政务、工业、金融等领域的数据资产管理问题展开深入探讨,并对中国信通院第九批大数据产品能力评测结果进行了公布和证书颁发。

其中阿里云分析型数据库产品 AnalyticDB 获得了分析型数据库基础能力和性能双料认证。尤其在大规模性能认证方面,本次评测采用了全球最大规模的 TPC-DS 100TB 测试标准,阿里云 AnalyticDB 完成了 640 节点的分布式分析型数据库性能测试,是迄今为止通过信通院评测认证的最大规模分布式分析型数据库集群,综合评测结果同领域领先。
1576067725915-db0eb348-d8bd-487b-961c-c7e48a220a1a.png
1576067725814-5fa96c83-9b95-4c51-9501-a5802f67d2e8.jpeg

随着业务和技术的变化演进,传统数据仓库方案在支撑企业业务上遇到一系列问题。
1576133794736-d945d01e-1102-4ba2-be8e-7d26c8ad82dc.png

相比较传统大数据产品 阿里云 AnalyticDB 具有更多优点。

1,扩展能力强,AnalyticDB 是 MPP架构的分布式集群数据库,摆脱单机处理瓶颈。

2,使用简单, AnalyticDB 支持SQL 2003,兼容MySQL,Oracle语法和支持PL/SQL存储过程,触发器,支持标准数据库事务。

3,支持场景丰富,AnalyticDB 通过行存储、列存储、多种分区表和索引等机制,可以支持海量数据的在线交付分析,也支持ETL批处理任务。

4,实时性更强,相比离线数仓方案,报表数据延时从天级别缩短至秒级,数据实时性高。

5,高可用,服务秒级恢复,AZ内/跨AZ部署,自动故障检测、摘除和副本重搭。

6,更安全,具有更完善和细化的权限体系模型,白名单和集群级别RAM控制

当前AnalyticDB For PostgreSQL正在进行 6.0 新版本的公测,6.0 版本大幅提升并发事务处理能力,更好的满足实时数仓场景,同时通过事务锁等优化,完备支持HTAP业务,在既有JSON类型上,支持JSONB存储格式,实现高性能的JSON数据处理及更丰富的JSON函数等特性。
1576133854036-b8aaa587-fcd1-4515-b1be-21081ab5d10d.png

阿里云 AnalyticDB 广泛应用于企业实时数仓构建,如电商&新零售大数据运营支撑平台,用户将平台业务线上、线下各渠道的行为数据清洗沉淀到实时数仓,通过数仓提供在线客户标签和用户群体分析能力,圈选目标客户,进行针对性的广告投放和营销活动。

1576067725798-a59bc30b-0437-42d1-87f2-8c9f894eb6f9.png

AnalyticDB 6.0 (事务增强版)火热公测中!限时免费,立即查看]]> 如何在 PyFlink 1.10 中自定义 Python UDF? Mon, 16 Dec 2019 05:35:02 +0800 作者:孙金城(金竹)

我们知道 PyFlink 是在 Apache Flink 1.9 版新增的,那么在 Apache Flink 1.10 中 Python UDF 功能支持的速度是否能够满足用户的急切需求呢?

图片1.gif

Python UDF 的发展趋势

直观的判断,PyFlink Python UDF 的功能也可以如上图一样能够迅速从幼苗变成大树,为啥有此判断,请继续往下看…

Flink on Beam

我们都知道有 Beam on Flink 的场景,就是 Beam 支持多种 Runner,也就是说 Beam SDK 编写的 Job 可以运行在 Flink 之上。如下图所示:

2.jpg

上面这图是 Beam Portability Framework 的架构图,他描述了 Beam 如何支持多语言,如何支持多 Runner,单独说 Apache Flink 的时候我们就可以说是 Beam on Flink,那么怎么解释 Flink on Beam 呢?

3.jpg

在 Apache Flink 1.10 中我们所说的 Flink on Beam 更精确的说是 PyFlink on Beam Portability Framework。我们看一下简单的架构图,如下:

4.jpg

Beam Portability Framework 是一个成熟的多语言支持框架,框架高度抽象了语言之间的通信协议(gRPC),定义了数据的传输格式(Protobuf),并且根据通用流计算框架所需要的组件,抽象个各种服务,比如 DataService,StateService,MetricsService 等。在这样一个成熟的框架下,PyFlink 可以快速的构建自己的 Python 算子,同时重用 Apache Beam Portability Framework 中现有 SDK harness 组件,可以支持多种 Python 运行模式,如:Process,Docker,etc.,这使得 PyFlink 对 Python UDF 的支持变得非常容易,在 Apache Flink 1.10 中的功能也非常的稳定和完整。那么为啥说是 Apache Flink 和 Apache Beam 共同打造呢,是因为我发现目前 Apache Beam Portability Framework 的框架也存在很多优化的空间,所以我在 Beam 社区进行了优化讨论,并且在 Beam 社区也贡献了 20+ 的优化补丁

概要了解了 Apache Flink 1.10 中 Python UDF 的架构之后,我们还是切入的代码部分,看看如何开发和使用 Python UDF。

如何定义 Python UDF

在 Apache Flink 1.10 中我们有多种方式进行 UDF 的定义,比如:

  • Extend ScalarFunction, e.g.:
class HashCodeMean(ScalarFunction):
   def eval(self, i, j):
       return (hash(i) + hash(j)) / 2
  • Lambda Functio
lambda i, j: (hash(i) + hash(j)) / 2
  • Named Function
def hash_code_mean(i, j):
   return (hash(i) + hash(j)) / 2
  • Callable Function
class CallableHashCodeMean(object):
   def __call__(self, i, j):
       return (hash(i) + hash(j)) / 2

我们发现上面定义函数除了第一个扩展 ScalaFunction 的方式是 PyFlink 特有的,其他方式都是 Python 语言本身就支持的,也就是说,在 Apache Flink 1.10 中 PyFlink 允许以任何 Python 语言所支持的方式定义 UDF。

如何使用 Python UDF

那么定义完 UDF 我们应该怎样使用呢?Apache Flink 1.10 中提供了 2 种 Decorators,如下:

  • Decorators - udf(), e.g. :
udf(lambda i, j: (hash(i) + hash(j)) / 2,
      [for input types], [for result types])
  • Decorators - @udf, e.g. :
@udf(input_types=..., result_type=...) 
     def hash_code_mean(…):
               return …

然后在使用之前进行注册,如下:

st_env.register_function("hash_code", hash_code_mean)

接下来就可以在 Table API/SQL 中进行使用了,如下:

my_table.select("hash_code_mean(a, b)").insert_into("Results")

目前为止,我们已经完成了 Python UDF 的定义,声明和注册了。接下来我们还是看一个完整的示例吧:)

案例描述

  • 需求

假设苹果公司要统计该公司产品在双 11 期间各城市的销售数量和销售金额分布情况。

  • 数据格式

每一笔订单是一个字符串,字段用逗号分隔, 例如:

ItemName, OrderCount, Price, City
-------------------------------------------
iPhone 11, 30, 5499, Beijingn
iPhone 11 Pro,20,8699,Guangzhoun

案例分析

根据案例的需求和数据结构分析,我们需要对原始字符串进行结构化解析,那么需要一个按“,”号分隔的 UDF(split) 和一个能够将各个列信息展平的 DUF(get)。同时我们需要根据城市进行分组统计。

核心实现

UDF 定义

  • Split UDF
@udf(input_types=[DataTypes.STRING()],
           result_type=DataTypes.ARRAY(DataTypes.STRING()))
  def split(line):
       return line.split(",")
  • Get UDF
@udf(input_types=[DataTypes.ARRAY(DataTypes.STRING()), DataTypes.INT()], result_type=DataTypes.STRING())
def get(array, index):
       return array[index]

注册 UDF

  • 注册 Split UDF
t_env.register_function("split", split)
  • 注册 Get UDF
t_env.register_function("get", get)

核心实现逻辑

如下代码我们发现核心实现逻辑非常简单,只需要对数据进行解析和对数据进行集合计算:

t_env.from_table_source(SocketTableSource(port=9999))        .alias("line")        .select("split(line) as str_array")        .select("get(str_array, 3) as city, "                     "get(str_array, 1).cast(LONG) as count, "                     "get(str_array, 2).cast(LONG) as unit_price")        .select("city, count, count * unit_price as total_price")       
        .group_by("city")        .select("city, sum(count) as sales_volume, sum(total_price)   
         as sales")
       .insert_into("sink")
t_env.execute("Sales Statistic")

上面的代码我们假设是一个 Socket 的 Source,Sink 是一个 Chart Sink,那么最终运行效果图,如下:

5.jpg

我总是认为在博客中只是文本描述而不能让读者真正的在自己的机器上运行起来的博客,不是好博客,所以接下来我们看看按照我们下面的操作,是否能在你的机器上也运行起来?:)

环境

因为目前 PyFlink 还没有部署到 PyPI 上面,在 Apache Flink 1.10 发布之前,我们需要通过构建 Flink 的 master 分支源码来构建运行我们 Python UDF 的 PyFlink 版本。

源代码编译

在进行编译代码之前,我们需要你已经安装了 JDK8Maven3x

  • 下载解压
tar -xvf apache-maven-3.6.1-bin.tar.gz
mv -rf apache-maven-3.6.1 /usr/local/
  • 修改环境变量(~/.bashrc)
MAVEN_HOME=/usr/local/apache-maven-3.6.1
export MAVEN_HOME
export PATH=${PATH}:${MAVEN_HOME}/bin

除了 JDK 和 MAVEN 完整的环境依赖性如下:

  • JDK 1.8+ (1.8.0_211)
  • Maven 3.x (3.2.5)
  • Scala 2.11+ (2.12.0)
  • Python 3.6+ (3.7.3)
  • Git 2.20+ (2.20.1)
  • Pip3 19+ (19.1.1)

我们看到基础环境安装比较简单,我这里就不每一个都贴出来了。如果大家有问题欢迎邮件或者博客留言。

  • 下载 Flink 源代码:
git clone https://github.com/apache/flink.git
  • 编译
cd flink
mvn clean install -DskipTests
...
...
[INFO] flink-walkthrough-datastream-scala ................. SUCCESS [  0.192 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  18:34 min
[INFO] Finished at: 2019-12-04T23:03:25+08:00
[INFO] ------------------------------------------------------------------------
  • 构建 PyFlink 发布包
cd flink-python; python3 setup.py sdist bdist_wheel
...
...
adding 'apache_flink-1.10.dev0.dist-info/WHEEL'
adding 'apache_flink-1.10.dev0.dist-info/top_level.txt'
adding 'apache_flink-1.10.dev0.dist-info/RECORD'
removing build/bdist.macosx-10.14-x86_64/wheel
  • 安装 PyFlink(PyFlink 1.10 需要 Python3.6+)
pip3 install dist/*.tar.gz
...
...
Successfully installed apache-beam-2.15.0 apache-flink-1.10.dev0 avro-python3-1.9.1 cloudpickle-1.2.2 crcmod-1.7 dill-0.2.9 docopt-0.6.2 fastavro-0.21.24 future-0.18.2 grpcio-1.25.0 hdfs-2.5.8 httplib2-0.12.0 mock-2.0.0 numpy-1.17.4 oauth2client-3.0.0 pbr-5.4.4 protobuf-3.11.1 pyarrow-0.14.1 pyasn1-0.4.8 pyasn1-modules-0.2.7 pydot-1.4.1 pymongo-3.9.0 pyyaml-3.13 rsa-4.0

也可以查看一下,我们核心需要 apache-beam 和 apache-flink,如下命令:

jincheng:flink-python jincheng.sunjc$ pip3 list
Package                       Version  
----------------------------- ---------
alabaster                     0.7.12   
apache-beam                   2.15.0   
apache-flink                  1.10.dev0
atomicwrites                  1.3.0

如上信息证明你我们所需的 Python 依赖已经没问题了,接下来回过头来在看看如何进行业务需求的开发。

PyFlinlk 的 Job 结构

6.jpg

一个完成的 PyFlink 的 Job 需要有外部数据源的定义,有业务逻辑的定义和最终计算结果输出的定义。也就是 Source connector, Transformations, Sink connector,接下来我们根据这个三个部分进行介绍来完成我们的需求。

Source Connector

我们需要实现一个 Socket Connector,首先要实现一个 StreamTableSource, 核心代码是实现 getDataStream,代码如下:

@Override
  public DataStream<Row> getDataStream(StreamExecutionEnvironment env) {
    return env.socketTextStream(hostname, port, lineDelimiter, MAX_RETRY)
      .flatMap(new Spliter(fieldNames.length, fieldDelimiter, appendProctime))
      .returns(getReturnType());
  }

上面代码利用了 StreamExecutionEnvironment 中现有 socketTextStream 方法接收数据,然后将业务订单数据传个一个 FlatMapFunction, FlatMapFunction 主要实现将数据类型封装为 Row,详细代码查阅 Spliter

同时,我们还需要在 Python 封装一个 SocketTableSource,详情查阅 socket_table_source.py

Sink Connector

我们预期要得到的一个效果是能够将结果数据进行图形化展示,简单的思路是将数据写到一个本地的文件,然后在写一个 HTML 页面,使其能够自动更新结果文件,并展示结果。所以我们还需要自定义一个 Sink 来完成该功能,我们的需求计算结果是会不断的更新的,也就是涉及到 Retraction(如果大家不理解这个概念,可以查阅我以前的博客),目前在 Flink 里面还没有默认支持 Retract 的 Sink,所以我们需要自定义一个 RetractSink,比如我们实现一下 CsvRetractTableSink。

CsvRetractTableSink 的核心逻辑是缓冲计算结果,每次更新进行一次全量(这是个纯 demo,不能用于生产环境)文件输出。源代码查阅 CsvRetractTableSink

同时我们还需要利用 Python 进行封装,详见 chart_table_sink.py。

在 chart_table_sink.py 我们封装了一个 http server,这样我们可以在浏览器中查阅我们的统计结果。

业务逻辑

完成自定义的 Source 和 Sink 之后我们终于可以进行业务逻辑的开发了,其实整个过程自定义 Source 和 Sink 是最麻烦的,核心计算逻辑似乎要简单的多。

  • 设置 Python 版本(很重要)

如果你本地环境 python 命令版本是 2.x,那么需要对 Python 版本进行设置,如下:

t_env.get_config().set_python_executable("python3")

PyFlink 1.10 之后支持 Python 3.6+ 版本。

  • 读取数据源

PyFlink 读取数据源非常简单,如下:

...
...
t_env.from_table_source(SocketTableSource(port=9999)).alias("line")

上面这一行代码定义了监听端口 9999 的数据源,同时结构化 Table 只有一个名为 line 的列。

  • 解析原始数据

我们需要对上面列进行分析,为了演示 Python UDF,我们在 SocketTableSource中并没有对数据进行预处理,所以我们利用上面 UDF 定义 一节定义的 UDF,来对原始数据进行预处理。

...
...
.select("split(line) as str_array")        
.select("get(str_array, 3) as city, " "get(str_array, 1).cast(LONG) as count, " "get(str_array, 2).cast(LONG) as unit_price")        
.select("city, count, count * unit_price as total_price")
  • 统计分析

核心的统计逻辑是根据 city 进行分组,然后对 销售数量和销售金额进行求和,如下:

...
...
.group_by("city")
.select("city, sum(count) as sales_volume, sum(total_price)   
         as sales")
  • 计算结果输出

计算结果写入到我们自定义的 Sink 中,如下:

...
...
.insert_into("sink")
from pyflink.datastream import StreamExecutionEnvironment
from pyflink.demo import ChartConnector, SocketTableSource
from pyflink.table import StreamTableEnvironment, EnvironmentSettings, DataTypes
from pyflink.table.descriptors import Schema
from pyflink.table.udf import udf

env = StreamExecutionEnvironment.get_execution_environment()
t_env = StreamTableEnvironment.create(
    env,
    environment_settings=EnvironmentSettings.new_instance().use_blink_planner().build())
t_env.connect(ChartConnector())
    .with_schema(Schema()
                 .field("city", DataTypes.STRING())
                 .field("sales_volume", DataTypes.BIGINT())
                 .field("sales", DataTypes.BIGINT()))
    .register_table_sink("sink")


@udf(input_types=[DataTypes.STRING()],
     result_type=DataTypes.ARRAY(DataTypes.STRING()))
def split(line):
    return line.split(",")


@udf(input_types=[DataTypes.ARRAY(DataTypes.STRING()), DataTypes.INT()],
     result_type=DataTypes.STRING())
def get(array, index):
    return array[index]

t_env.get_config().set_python_executable("python3")

t_env.register_function("split", split)
t_env.register_function("get", get)
t_env.from_table_source(SocketTableSource(port=6666))
    .alias("line")
    .select("split(line) as str_array")
    .select("get(str_array, 3) as city, "
            "get(str_array, 1).cast(LONG) as count, "
            "get(str_array, 2).cast(LONG) as unit_price")
    .select("city, count, count * unit_price as total_price")
    .group_by("city")
    .select("city, "
            "sum(count) as sales_volume, "
            "sum(total_price) as sales")
    .insert_into("sink")

t_env.execute("Sales Statistic")

上面代码中大家会发现一个陌生的部分,就是 from pyflink.demo import ChartConnector, SocketTableSource. 其中 pyflink.demo 是哪里来的呢?其实就是包含了上面我们介绍的 自定义 Source/Sink(Java&Python)。下面我们来介绍如何增加这个 pyflink.demo 模块。

安装 pyflink.demo

为了大家方便我把自定义 Source/Sink(Java&Python)的源代码放到了这里 ,大家可以进行如下操作:

  • 下载源码
git clone https://github.com/sunjincheng121/enjoyment.code.git
  • 编译源码
cd enjoyment.code/PyUDFDemoConnector/; mvn clean install
  • 构建发布包
python3 setup.py sdist bdist_wheel
...
...
adding 'pyflink_demo_connector-0.1.dist-info/WHEEL'
adding 'pyflink_demo_connector-0.1.dist-info/top_level.txt'
adding 'pyflink_demo_connector-0.1.dist-info/RECORD'
removing build/bdist.macosx-10.14-x86_64/wheel
  • 安装 Pyflink.demo
pip3 install dist/pyflink-demo-connector-0.1.tar.gz
...
...
Successfully built pyflink-demo-connector
Installing collected packages: pyflink-demo-connector
Successfully installed pyflink-demo-connector-0.1

出现上面信息证明已经将 PyFlink.demo 模块成功安装。接下来我们可以运行我们的示例了 :)

运行示例

示例的代码在上面下载的源代码里面已经包含了,为了简单,我们利用 PyCharm 打开enjoyment.code/myPyFlink。同时在 Terminal 启动一个端口:

nc -l 6666

启动 blog_demo,如果一切顺利,启动之后,控制台会输出一个 web 地址,如下所示:

7.jpg

我们打开这个页面,开始是一个空白页面,如下:

8.png

我们尝试将下面的数据,一条,一条的发送给 Source Connector:

iPhone 11,30,5499,Beijing
iPhone 11 Pro,20,8699,Guangzhou
MacBook Pro,10,9999,Beijing
AirPods Pro,50,1999,Beijing
MacBook Pro,10,11499,Shanghai
iPhone 11,30,5999,Shanghai
iPhone 11 Pro,20,9999,Shenzhen
MacBook Pro,10,13899,Hangzhou
iPhone 11,10,6799,Beijing
MacBook Pro,10,18999,Beijing
iPhone 11 Pro,10,11799,Shenzhen
MacBook Pro,10,22199,Shanghai
AirPods Pro,40,1999,Shanghai

当输入第一条订单 iPhone 11,30,5499,Beijing,之后,页面变化如下:

9.jpg

随之订单数据的不断输入,统计图不断变化。一个完整的 GIF 演示如下:

更新.gif

小结

本篇从架构到 UDF 接口定义,再到具体的实例,向大家介绍了在 Apache Flink 1.10 发布之后,如何利用 PyFlink 进行业务开发,其中 用户自定义 Source 和 Sink部分比较复杂,这也是目前社区需要进行改进的部分(Java/Scala)。真正的核心逻辑部分其实比较简单,为了大家按照本篇进行实战操作有些成就感,所以我增加了自定义 Source/Sink 和图形化部分。但如果大家想简化实例的实现也可以利用 Kafka 作为 Source 和 Sink,这样就可以省去自定义的部分,做起来也会简单一些。

查看原文可点击:原文链接

]]>
阿里云荣获最佳智能边缘计算技术创新平台 Mon, 16 Dec 2019 05:35:02 +0800 12月11日, 2019亚太内容分发大会暨CDN峰会在广州如期召开,大会围绕“边缘计算”为主题,探讨新技术下,全球互联网产业发展趋势。会上,国内第一,全球前三的阿里云凭借在边缘计算领先的技术布局与创新方案,荣获“最佳智能边缘计算技术创新平台”奖项。

a6de9f2f4263ce322fef4b81d8e97260 (1).jpg

边缘计算因5G万物智联的快速发展而备受关注。据Gartner预测,2021年将有40%的大型企业在项目中纳入边缘计算原则。阿里云是国内最早布局边缘计算的科技公司,早在2016年就开始研发相关产品和技术。2018年3月,阿里云正式宣布战略投入边缘计算技术领域,将云计算、大数据、人工智能的优势拓展到更靠近端的边缘计算上,打造云、边、端一体化的协同计算体系。目前,阿里云已经完成国内30多个省份300+边缘计算节点的全域覆盖。

早在2018年4月,阿里云在业界率先推出边缘节点服务(Edge Node Service, ENS),首次将计算推进至用户100公里的边缘。

2019年1月,边缘节点服务(ENS)正式步入2.0时代,阿里云引入MEC资源,将飞天算力调度、容器、函数、安全、大数据与AI等技术能力进一步融合释放,建立了“融合、开放、联动”的边缘计算平台,将计算能力进一步推进至用户10公里生活圈。

在2019年7月,阿里云发布国内首个全域边缘节点服务,300+边缘节点算力基本覆盖全国省会城市三大运营商与热门地区的三线城市,自此阿里云边缘计算正式宣告进入“无处不在”的全新篇章。

通过上千个CDN节点,阿里云建立了标准、安全、多租户的边缘基础设施底座。同时,这也是阿里云第一次把飞天技术轻量化落地到大量的边缘节点上,借助飞天十年技术沉淀,实现性能优秀、稳定可靠的边缘计算能力,有效降低用户计算时延和成本。

此外,阿里云在边缘智能视频接入、边缘存储以及自动化运维等众多技术领域,不断寻求突破性技术进展。例如,陆续推出了云边统一的边缘K8s和容器解决方案,赋能开发者DevOps轻松落地,统一进行资源管理与调度、镜像分发、自助运维和云端监控,极大简化了运维工作复杂度。

基于阿里云在边缘计算领域先发优势以及创新性产品技术部署,边缘节点服务(ENS)已实现终端接入延迟低至5毫秒,为用户带来综合成本30%的减少,运维效率50%的提升。

作为整个边缘技术栈腰部力量,阿里云一直在积极推进边缘计算技术标准化建设与产业上下游创新合作。2018年12月,阿里云联合中国电子技术标准化研究院发布中国首份《边缘云计算技术及标准化白皮书》,明确定义未来“边缘云计算”的技术特点与行业标准。2019年9月,阿里云牵头编制《信息技术 云计算 边缘云计算通用技术要求(征求意见稿)》,用于指导“边缘云计算”技术和产品研发、服务交付,再次助推边缘云产业标准化建设。在产业合作方面,阿里云与各大运营商进行多项试点合作,推进5G移动边缘计算(MEC)、虚拟化vCDN网络架构、边缘智能等领域建设,携手运营商实现共赢。

点击了解获奖的边缘节点服务ENS

]]>
DataV、语雀、imgcook、菜鸟IoT等前沿产品齐聚 D2 ,现场展台等你来体验! Mon, 16 Dec 2019 05:35:02 +0800 第十四届D2前端技术论坛即将在杭州和达希尔顿逸林酒店举办!除了有干货满满、大佬云集的会场和 D2 之夜,我们还提供了多个线下互动展台,在这里你将直接体验来自阿里内外前沿的技术产品,内容丰富:覆盖前端智能化、数据可视化、3D游戏引擎等,形式多样:现场手绘实时生成数据大屏?跟随人体舞动的蚂蚁公仔?各种黑科技助力前端降本提效,还怕产品经理改需求?另外,展台不仅有相关的技术同学交流技术、答疑解惑,还准备了丰富的现场礼品等你领取,欢迎来体验! 先让我们跟着视频一睹为快吧!

精彩视频点击此处查看

数据可视化-DataV

展台介绍:DataV 数据可视化产品是阿里云上一款专注于数据可视化交互界面搭建的技术产品。从2011年内部孵化第一款数据可视化组件库datav.js到搭建第一块双十一媒体数据大屏,DataV数据可视化团队一直希望通过技术工具让更多人体会到与数据互动的轻松和乐趣,真正享受到这个数据时代所带来的全新机会。
DataV数据可视化产品从电商领域起步,致力于给更多场景带来数据可视化的技术体验。无论在零售、物流、电力、水利、环保、还是交通领域,通过交互式实时数据可视化视屏墙来帮助业务人员发现、诊断业务问题,越来越成为大数据解决方案中不可或缺的一环。DataV团队也在与更多领域的碰撞中,希望通过在三维引擎、可视化数据服务、搭建工具三个技术点的不断探索,去实现物理世界数字重现、数据智能可见可信、可视应用智能搭建三个目标,利用数据可视化技术为大数据建设的最后一公里铺平道路。
礼品信息:蚂蚁公仔、贴纸等

image.png

前端智能化-imgcook

展台介绍:imgcook专注以 Sketch、PSD、静态图片等形式的视觉稿作为输入,通过智能化技术一键生成可维护的前端代码,包含视图代码、数据字段绑定、组件代码、部分业务逻辑代码等。
我们期望 imgcook (图像大厨) 能够利用智能化手段,成为一位 P5 级别的前端工程师,在对设计稿轻约束的前提下实现高度还原,释放前端生产力,助力前端与设计师高效协作,让您关注更具挑战性的事情!官网:https://www.imgcook.com
礼品信息:淘宝购物袋、贴纸

image.png

云端知识库-语雀:

展台介绍:语雀是一个专业的云端知识库,孵化自 蚂蚁金服 ,是 体验科技 理念下的一款创新产品,已是10万阿里员工进行文档编写、知识沉淀的标配。通过丰富的应用场景,结构化知识库及专业的编辑器,为个人,团队及企业提供与众不同的高效知识管理,打造轻松流畅的工作协同体验。
语雀诞生伊始,只是希望能给工程师提供一个好用的工具用来写技术文档,达成「用Markdown写文档」这个小目标。但在产品研发的过程中,我们发现其实身边的每个人、每个团队、每个组织都有很多知识,但一直以来缺少一个好用的工具让这些知识不只是留在每个人的大脑或电脑里,还可以被记录、分享和交流。
所以,带着这颗初心,我们觉得语雀不应止步于服务工程师,应该致力于为每个想表达所思所想的人提供一款顺手的工具,让知识能得以记录和传播,让人们可以在「语雀」中平等快乐地创作和交流知识,让再小的个体也可以拥有自己的知识库。
礼品信息:语雀礼品及周边

image.png

前端数智化-菜鸟

展台介绍:看2019双11逍遥子钦点的IoT设备,菜鸟如何利用IoT技术降低物流实操环节90%硬件成本。IoT如何助力数字孪生? 前端同学如何帮助新硬件快速落地?菜鸟展台带你领略物流行业的IoT。
礼品信息:LEMO纪念记事本

image.png

Web3D引擎-Oasis 3D

展台介绍:Oasis 3D 是一个面向前端工程师的3D 综合性解决方案,包含对移动端友好的 Web 3D 引擎和基于 ESC 架构的 3D 内容编辑器。目前应用场景涵盖阿里经济体内的H5 互动游戏、工业产品渲染、数据可视化等领域。Oasis 3D 的使命是把 3D 开发的荒漠变成绿洲,让每个前端工程师都能轻松开发专业的 3D 应用,让 Web 世界也能达到影视级的绚丽多姿。
礼品信息:
展台提供了两款由Oasis 3D开发的互动游戏:“太空跑酷”和“吸金大法”,供大家现场把玩,排名靠前的同学将有机会获得蚂蚁公仔等精美礼物。

image.png

Serveless-织云

展台介绍:“织云”是一个可视化服务编排平台,通过可视化编排的方式快速将业务需求转换为技术需求,在几分钟内构建可调用接口。依托于集团的Faas平台,提供了强大的接口能力,确保接口按照预期执行。
我们的目标是利用可视化编排的方式,沉淀已有的服务和能力,最终实现产品能够自主编排业务逻辑,将前端从复杂的逻辑代码中解放出来。
礼品信息:技术贴纸及徽章小礼品

image.png

图灵

展台介绍:图灵教育是国内计算机图书领域的高端品牌之一,策划出版了众多高质量的科技图书。
礼品信息:现场参与图灵展位集赞互动,有机会免费领取图书。

image.png

阿里云开发者社区

展台介绍:阿里云开发者社区汇聚了阿里巴巴集团技术专家和百万开发者用户,在微信、微博、钉钉、知乎等多个平台拥有官方账号@阿里技术 及数万成员规模的社群,面向全球开发者分享技术干货,帮助技术人不断成长进步。现场找到我们,拿独家技术干货合集,领取开发者社区周边礼品,加入前端技术钉群,与阿里前端专家切磋交流。
礼品信息: 贴纸及社区周边小礼品

image.png

掘金

展台介绍:掘⾦是⼀个帮助开发者成⻓的社区,是⼀款⾯向开发者的基于数据挖掘技术的个性化推荐引擎产品,它为每⼀位技术⼈才推荐有学习价值的个性化技术内容。最终链接技术内容、技术⼈才与技术服务企业。
⾃ 2015 年 8 ⽉上线 4 年以来,掘⾦有三端产品,每⽉服务超过 1500 万开发者阅读消费技术内容,移动应⽤超过 100 万⼈,并已经积累了超过 1.5 亿条技术内容兴趣数据。
⽤⼾可以通过掘⾦分享最新的技术内容、赞赏好内容、收录⾃⼰喜爱的内容到收藏集、关注感兴趣技术标签和专栏作者。⽽掘⾦会不断根据⽤⼾的⾏为数据为⽤⼾推荐个性化的内容,帮助开发者更⾼效的分享、学习和成⻓。为了更好的服务开发者,我们也推出了掘⾦⼩册、掘⾦翻译计划、掘⾦沸点等拳头产品。期待D2的参会者和掘友们来掘⾦展台会⾯!更多掘⾦周边正在等着你〜
礼品信息:掘金周边、卫衣、鼠标垫、笔记本、贴纸、礼品卡

image.png

展台活动时间8:00~18:00,欢迎提前签到去现场体验,期待在D2与你相见!

]]>
​Lindorm/HBase增强版技术解密|每秒7亿次请求,阿里新一代数据库如何支撑? Mon, 16 Dec 2019 05:35:02 +0800 HBase用户福利:9.9元用半年HBase,学习测试两不误

新用户9.9元即可使用6个月云数据库HBase,更有低至1元包年的入门规格供广大HBase爱好者学习研究,更多内容请参考链接

前言

2684亿!天猫双十一再次创造了历史。阿里CTO行癫自豪地向媒体宣布:不是任何一朵云都撑得住双11!阿里云和其他云都不一样,从第一行代码写起,构建了中国唯一自研的云操作系统飞天!

而Lindorm(注:Lindorm是阿里内部HBase分支的别称,在阿里云上对外售卖的版本叫做HBase增强版,之后文中出现的HBase增强版和Lindorm都指同一个产品),就是云操作系统飞天中面向大数据存储处理的重要组成部分。Lindorm是基于HBase研发的、面向大数据领域的分布式NoSQL数据库,集大规模、高吞吐、快速灵活、实时混合能力于一身,面向海量数据场景提供世界领先的高性能、可跨域、多一致、多模型的混合存储处理能力。目前,Lindorm已经全面服务于阿里经济体中的大数据结构化、半结构化存储场景。

2019年以来,Lindorm已经服务了包括淘宝、天猫、蚂蚁、菜鸟、妈妈、优酷、高德、大文娱等数十个BU,在今年的双十一中,Lindorm峰值请求达到了7.5亿次每秒,天吞吐22.9万亿次,平均响应时间低于3ms,整体存储的数据量达到了数百PB。

这些数字的背后,凝聚了HBase&Lindorm团队多年以来的汗水和心血。Lindorm脱胎于HBase,是团队多年以来承载数百PB数据,亿级请求量,上千个业务后,在面对规模成本压力,以及HBase自身缺陷下,全面重构和引擎升级的全新产品。相比HBase,Lindorm无论是性能,功能还是可用性上,都有了巨大飞跃。本文将从功能、可用性、性能成本、服务生态等维度介绍Lindorm的核心能力与业务表现,最后分享部分我们正在进行中的一些项目。更多技术细节大家可关注大数据NoSQL圈子中各个细分主题的技术分享。

极致优化,超强性能

Lindorm比HBase在RPC、内存管理,缓存、日志写入等方面做了深度的优化,引入了众多新技术,大幅提升了读写性能,在相同硬件的情况下,吞吐可达到HBase的5倍以上,毛刺更是可以达到HBase的1/10。这些性能数据,并不是在实验室条件下产生的,而是在不改动任何参数的前提下,使用开源测试工具YCSB跑出来的成绩。我们把测试的工具和场景都公布在阿里云的帮助文件中,任何人都可以依照指南自己跑出一样的结果。
image.png
取得这么优异的性能的背后,是Lindorm中积攒多年的“黑科技”,下面,我们简单介绍下Lindorm内核中使用到的部分“黑科技”。

Trie Index

Lindorm 的文件LDFile(类似HBase中的HFile)是只读 B+ 树结构,其中文件索引是至关重要的数据结构。在 block cache 中有高优先级,需要尽量常驻内存。如果能降低文件索引所占空间大小,我们可以节省 block cache 中索引所需要的宝贵内存空间。或者在索引空间不变的情况下,增加索引密度,降低 data block 的大小,从而提高性能。而HBase中的索引block中存的是全量的Rowkey,而在一个已经排序好的文件中,很多Rowkey都是有共同前缀的。数据结构中的Trie (前缀树) 结构能够让共同前缀只存一份,避免重复存储带来的浪费。但是传统前缀树结构中,从一个节点到下一个节点的指针占用空间太多,整体而言得不偿失。这一情况有望用 Succinct Prefix Tree 来解决。SIGMOD2018年的最佳论文 Surf 中提出了一种用 Succinct Prefix Tree 来取代 bloom filter,并同时提供 range filtering 的功能。我们从这篇文章得到启发,用 Succinct Trie 来做 file block index。
image.png
我们在线上的多个业务中使用了Trie index实现的索引结构。结果发现,各个场景中,Trie index可以大大缩小索引的体积,最多可以压缩12倍的索引空间!节省的这些宝贵空间让内存Cache中能够存放更多的索引和数据文件,大大提高了请求的性能。
image.png

ZGC加持,百GB堆平均5ms暂停

ZGC(Powerd by Dragonwell JDK)是下一代Pauseless GC算法的代表之一,其核心思想是Mutator利用内存读屏障(Read Barrier)识别指针变化,使得大部分的标记(Mark)与合并(Relocate)工作可以放在并发阶段执行。
这样一项实验性技术,在Lindorm团队与AJDK团队的紧密合作下,进行了大量的改进与改造工作。使得ZGC在Lindorm这个场景上实现了生产级可用,
主要工作包括:

  1. Lindorm内存自管理技术,数量级减少对象数与内存分配速率。(比如说阿里HBase团队贡献给社区的CCSMap)
  2. AJDK ZGC Page缓存机制优化(锁、Page缓存策略)
  3. AJDK ZGC 触发时机优化,ZGC无并发失败
    AJDK ZGC在Lindorm上稳定运行两个月,并顺利通过双十一大考。其JVM暂停时间稳定在5ms左右,最大暂停时间不超过8ms。ZGC大大改善了线上运行集群的RT与毛刺指标,平均RT优化15%~20%,P999 RT减少一倍。在今年双十一蚂蚁风控集群中,在ZGC的加持下,P999时间从12ms降低到了5ms。

image.png
注:图中的单位应该为us,平均GC在5ms

LindormBlockingQueue

image.png
上图是HBase中的RegionServer从网络上读取RPC请求并分发到各个Handler上执行的流程。HBase中的RPC Reader从Socket上读取RPC请求放入BlockingQueue,Handler订阅这个Queue并执行请求。而这个BlockingQueue,HBase使用的是Java原生的JDK自带的LinkedBlockingQueue。LinkedBlockingQueue利用Lock与Condition保证线程安全与线程之间的同步,虽然经典易懂,但当吞吐增大时,这个queue会造成严重的性能瓶颈。因此在Lindorm中全新设计了LindormBlockingQueue,将元素维护在Slot数组中。维护head与tail指针,通过CAS操作对进队列进行读写操作,消除了临界区。并使用Cache Line Padding与脏读缓存加速,同时可定制多种等待策略(Spin/Yield/Block),避免队列为空或为满时,频繁进入Park状态。LindormBlockingQueue的性能非常突出,相比于原先的LinkedBlockingQueue性能提升4倍以上。
image.png

VersionBasedSynchronizer

image.png
LDLog是Lindorm中用于系统failover时进行数据恢复时的日志,以保障数据的原子性和可靠性。在每次数据写入时,都必须先写入LDLog。LDLog写入成功之后,才可以进行后续的写入memstore等操作。因此Lindorm中的Handler都必须等待WAL写入完成后再被唤醒以进行下一步操作,在高压条件下,无用唤醒会造成大量的CPU Context Switch造成性能下降。针对这个问题,Lindorm研发了基于版本的高并发多路线程同步机制(VersionBasedSynchronizer)来大幅优化上下文切换。VersionBasedSynchronizer的主要思路是让Handler的等待条件被Notifier感知,减少Notifier的唤醒压力。经过模块测试VersionBasedSynchronizer的效率是JDK自带的ObjectMonitor和J.U.C(java util concurrent包)的两倍以上。
image.png

全面无锁化

HBase内核在关键路径上有大量的锁,在高并发场景下,这些锁都会造成线程争抢和性能下降。Lindorm内核对关键链路上的锁都做了无锁化处理,如MVCC,WAL模块中的锁。另外,HBase在运行过程中会产生的各种指标,如qps,rt,cache命中率等等。而在记录这些Metrics的“不起眼”操作中,也会有大量的锁。面对这样的问题,Lindorm借鉴了tcmalloc的思想,开发了LindormThreadCacheCounter,来解决Metrics的性能问题。
image.png

Handler协程化

在高并发应用中,一个RPC请求的实现往往包含多个子模块,涉及到若干次IO。这些子模块的相互协作,系统的ContextSwitch相当频繁。ContextSwitch的优化是高并发系统绕不开的话题,各位高手都各显神通,业界有非常多的思想与实践。其中coroutine(协程)和SEDA(分阶段事件驱动)方案是我们着重考察的方案。基于工程代价,可维护性,代码可读性三个角度考虑,Lindorm选择了协程的方式进行异步化优化。我们利用了阿里JVM团队提供的Dragonwell JDK内置的Wisp2.0功能实现了HBase Handler的协程化,Wisp2.0开箱即用,有效地减少了系统的资源消耗,优化效果比较客观。

全新Encoding算法

从性能角度考虑,HBase通常需要将Meta信息装载进block cache。如果将block大小较小,Meta信息较多,会出现Meta无法完全装入Cache的情况, 性能下降。如果block大小较大,经过Encoding的block的顺序查询的性能会成为随机读的性能瓶颈。针对这一情况,Lindorm全新开发了Indexable Delta Encoding,在block内部也可以通过索引进行快速查询,seek性能有了较大提高。Indexable Delta Encoding原理如图所示:
image.png
通过Indexable Delta Encoding, HFile的随机seek性能相对于使用之前翻了一倍,以64K block为例,随机seek性能基本与不做encoding相近(其他encoding算法会有一定性能损失)。在全cache命中的随机Get场景下,相对于Diff encoding RT下降50%

其他

相比社区版HBase,Lindorm还有多达几十项的性能优化和重构,引入了众多新技术,由于篇幅有限,这里只能列举一部分,其他的核心技术,比如:

丰富的查询模型,降低开发门槛

原生的HBase只支持KV结构的查询,虽然简单,但是在面对各项业务的复杂需求时,显的有点力不从心。因此,在Lindorm中,我们针对不同业务的特点,研发了多种查询模型,通过更靠近场景的API和索引设计,降低开发门槛。

WideColumn 模型(原生HBase API)

WideColumn是一种与HBase完全一致的访问模型和数据结构,从而使得Lindrom能100%兼容HBase的API。用户可以通过Lindorm提供的高性能原生客户端中的WideColumn API访问Lindorm,也可以通过alihbase-connector这个插件,使用HBase客户端及API(无需任何代码改造)直接访问Lindorm。同时,Lindorm使用了轻客户端的设计,将大量数据路由、批量分发、超时、重试等逻辑下沉到服务端,并在网络传输层做了大量的优化,使得应用端的CPU消耗可以大大节省。像下表中,相比于HBase,使用Lindorm后的应用侧CPU使用效率提升60%,网络带宽效率提升25%。
image.png
注:表中的客户端CPU代表HBase/Lindorm客户端消耗的CPU资源,越小越好.
在HBase原生API上,我们还独家支持了高性能二级索引,用户可以使用HBase原生API写入数据过程中,索引数据透明地写入索引表。在查询过程中,把可能全表扫的Scan + Filter大查询,变成可以先去查询索引表,大大提高了查询性能。关于高性能原生二级索引,大家可以参考高性能原生二级索引一文。

TableService模型(SQL、二级索引)

HBase中只支持Rowkey这一种索引方式,对于多字段查询时,通常效率低下。为此,用户需要维护多个表来满足不同场景的查询需求,这在一定程度上既增加了应用的开发复杂性,也不能很完美地保证数据一致性和写入效率。并且HBase中只提供了KV API,只能做Put、Get、Scan等简单API操作,也没有数据类型,所有的数据都必须用户自己转换和储存。对于习惯了SQL语言的开发者来说,入门的门槛非常高,而且容易出错。

为了解决这一痛点,降低用户使用门槛,提高开发效率,在Lindorm中我们增加了TableService模型,其提供丰富的数据类型、结构化查询表达API,并原生支持SQL访问和全局二级索引,解决了众多的技术挑战,大幅降低普通用户的开发门槛。通过SQL和SQL like的API,用户可以方便地像使用关系数据库那样使用Lindorm。下面是一个Lindorm SQL的简单示例。

 -- 主表和索引DDL
create table shop_item_relation (
    shop_id varchar,
    item_id varchar,
    status varchar
constraint primary key(shop_id, item_id)) ; 

create index idx1 on shop_item_relation (item_id) include (ALL);   -- 对第二列主键建索引,冗余所有列
create index idx2 on shop_item_relation (shop_id, status) include (ALL);  -- 多列索引,冗余所有列

-- 写入数据,会同步更新2个索引
upsert into shop_item_relation values('shop1', 'item1',  'active');
upsert into shop_item_relation values('shop1', 'item2',  'invalid');

-- 根据WHERE子句自动选择合适的索引执行查询
select * from shop_item_relation where item_id = 'item2';  -- 命中idx1
select * from shop_item_relation where shop_id = 'shop1' and status = 'invalid'; -- 命中idx2

相比于关系数据库的SQL,Lindorm不具备多行事务和复杂分析(如Join、Groupby)的能力,这也是两者之间的定位差异。

相比于HBase上Phoenix组件提供的二级索引,Lindorm的二级索引在功能、性能、稳定性上远远超过Phoenix,下图是一个简单的性能对比。
image.png
image.png
注:该模型已经在阿里云HBase增强版上内测,感兴趣的用户可以联系云HBase答疑钉钉号或者在阿里云上发起工单咨询。

FeedStream模型

注:该模型已经在阿里云HBase增强版上内测,感兴趣的用户可以联系云HBase答疑钉钉号或者在阿里云上发起工单咨询。
现代互联网架构中,消息队列承担了非常重要的职责,可以极大的提升核心系统的性能和稳定性。其典型的应用场景有包括系统解耦,削峰限流,日志采集,最终一致保证,分发推送等等。

常见的消息队列包括RabbitMq,Kafka以及RocketMq等等。这些数据库尽管从架构和使用方式和性能上略有不同,但其基本使用场景都相对接近。然而,传统的消息队列并非完美,其在消息推送,feed流等场景存在以下问题:

  • 存储:不适合长期保存数据,通常过期时间都在天级
  • 删除能力: 不支持删除指定数据entry
  • 查询能力:不支持较为复杂的查询和过滤条件
  • 一致性和性能难以同时保证:类似于Kafka之类的数据库更重吞吐,为了提高性能存在了某些状况下丢数据的可能,而事务处理能力较好的消息队列吞吐又较为受限。
  • Partition快速拓展能力:通常一个Topc下的partition数目都是固定,不支持快速扩展。
  • 物理队列/逻辑队列:通常只支持少量物理队列(如每个partition可以看成一个队列),而业务需要的在物理队列的基础上模拟出逻辑队列,如IM系统中为每个用户维护一个逻辑上的消息队列,用户往往需要很多额外的开发工作。
    针对上述需求,Lindorm推出了队列模型FeedStreamService,能够解决海量用户下的消息同步,设备通知,自增ID分配等问题。

image.png
FeedStream模型在今年手机淘宝消息系统中扮演了重要角色,解决了手机淘宝消息推送保序,幂等等难题。在今年双十一中,手淘的盖楼和回血大红包推送都有Lindorm的身影。手淘消息的推送中,峰值超过了100w/s,做到了分钟级推送全网用户。
image.png
注:该模型已经在阿里云HBase增强版上内测,感兴趣的用户可以联系云HBase答疑钉钉号或者在阿里云上发起工单咨询。

全文索引模型

虽然Lindorm中的TableService模型提供了数据类型和二级索引。但是,在面对各种复杂条件查询和全文索引的需求下,还是显得力不从心,而Solr和ES是优秀的全文搜索引擎。使用Lindorm+Solr/ES,可以最大限度发挥Lindorm和Solr/ES各自的优点,从而使得我们可以构建复杂的大数据存储和检索服务。Lindorm内置了外部索引同步组件,能够自动地将写入Lindorm的数据同步到外部索引组件如Solr或者ES中。这种模型非常适合需要保存大量数据,而查询条件的字段数据仅占原数据的一小部分,并且需要各种条件组合查询的业务,例如:

  • 常见物流业务场景,需要存储大量轨迹物流信息,并需根据多个字段任意组合查询条件
  • 交通监控业务场景,保存大量过车记录,同时会根据车辆信息任意条件组合检索出感兴趣的记录
  • 各种网站会员、商品信息检索场景,一般保存大量的商品/会员信息,并需要根据少量条件进行复杂且任意的查询,以满足网站用户任意搜索需求等。
    image.png

全文索引模型已经在阿里云上线,支持Solr/ES外部索引。目前,索引的查询用户还需要直接查询Solr/ES再来反查Lindorm,后续我们会用TableService的语法把查询外部索引的过程包装起来,用户全程只需要和Lindorm交互,即可获得全文索引的能力。

更多模型在路上

除了上述这些模型,我们还会根据业务的需求和痛点,开发更多简单易用的模型,方便用户使用,降低使用门槛。像时序模型,图模型等,都已经在路上,敬请期待。

零干预、秒恢复的高可用能力

从一个婴儿成长为青年,阿里HBase摔过很多次,甚至头破血流,我们在客户的信任之下幸运的成长。在9年的阿里应用过程中,我们积累了大量的高可用技术,而这些技术,都应用到了HBase增强版中。

MTTR优化

HBase是参照Gooogle著名论文BigTable的开源实现,其中最核心特点是数据持久化存储于底层的分布式文件系统HDFS,通过HDFS对数据的多副本维护来保障整个系统的高可靠性,而HBase自身不需要去关心数据的多副本及其一致性,这有助于整体工程的简化,但也引入了"服务单点"的缺陷,即对于确定的数据的读写服务只有发生固定的某个节点服务器,这意味着当一个节点宕机后,数据需要通过重放Log恢复内存状态,并且重新派发给新的节点加载后,才能恢复服务。当集群规模较大时,HBase单点故障后恢复时间可能会达到10-20分钟,大规模集群宕机的恢复时间可能需要好几个小时!而在Lindorm内核中,我们对MTTR(平均故障恢复时间)做了一系列的优化,包括故障恢复时先上线region、并行replay、减少小文件产生等众多技术。将故障恢复速度提升10倍以上!基本上接近了HBase设计的理论值。
## 可调的多一致性
在原来的HBase架构中,每个region只能在一个RegionServer中上线,如果这个region server宕机,region需要经历Re-assgin,WAL按region切分,WAL数据回放等步骤后,才能恢复读写。这个恢复时间可能需要数分钟,对于某些高要求的业务来说,这是一个无法解决的痛点。另外,虽然HBase中有主备同步,但故障下只能集群粒度的手动切换,并且主和备的数据只能做到最终一致性,而有一些业务只能接受强一致,HBase在这点上望尘莫及。

Lindorm内部实现了一种基于Shared Log的一致性协议,通过分区多副本机制达到故障下的服务自动快速恢复的能力,完美适配了存储分离的架构, 利用同一套体系即可支持强一致语义,又可以选择在牺牲一致性的前提换取更佳的性能和可用性,实现多活,高可用等多种能力。
在这套架构下,Lindorm拥有了以下几个一致性级别,用户可以根据自己的业务自由选择一致性级别:

一致性等级(由低到高) 读写一致保障 可用性能力
Eventual Consistency(EC) 数据写入后,可能需要一段时间(毫秒级)后才能被读到; 读写可规避任何hang及毛刺;宕机读写恢复10毫秒;
Basic Consistency(BC) 数据写入后,绝大多数(99.99%+)下,可以立即被读到,小概率下需要一段时间(毫秒级)后可以被读到 读写不能规避hang及毛刺;宕机读写恢复10毫秒;
TimeStamp Consistency(TC) 数据写入后,100%可以立即被读到 写可规避任何hang及毛刺;读有额外开销;宕机写恢复10毫秒;宕机读恢复30秒;
Strong Consistency(SC) 数据写入后,100%可以立即被读到 N/A

注:该功能暂时未在阿里云HBase增强版上对外开放

客户端高可用切换

虽然说目前HBase可以组成主备,但是目前市面上没有一个高效地客户端切换访问方案。HBase的客户端只能访问固定地址的HBase集群。如果主集群发生故障,用户需要停止HBase客户端,修改HBase的配置后重启,才能连接备集群访问。或者用户在业务侧必须设计一套复杂地访问逻辑来实现主备集群的访问。阿里HBase改造了HBase客户端,流量的切换发生在客户端内部,通过高可用的通道将切换命令发送给客户端,客户端会关闭旧的链接,打开与备集群的链接,然后重试请求。
image.png
如果需要使用此项功能,请参考高可用帮助文档

云原生,更低使用成本

Lindorm从立项之初就考虑到上云,各种设计也能尽量复用云上基础设施,为云的环境专门优化。比如在云上,我们除了支持云盘之外,我们还支持将数据存储在OSS这种低成本的对象存储中减少成本。我们还针对ECS部署做了不少优化,适配小内存规格机型,加强部署弹性,一切为了云原生,为了节省客户成本。

ECS+云盘的极致弹性

目前Lindorm在云上的版本HBase增强版均采用ECS+云盘部署(部分大客户可能采用本地盘),ECS+云盘部署的形态给Lindorm带来了极致的弹性。
image.png
最开始的时候,HBase在集团的部署均采用物理机的形式。每个业务上线前,都必须先规划好机器数量和磁盘大小。在物理机部署下,往往会遇到几个难以解决的问题:

  • 业务弹性难以满足:当遇到业务突发流量高峰或者异常请求时,很难在短时间内找到新的物理机扩容,
  • 存储和计算绑定,灵活性差:物理机上CPU和磁盘的比例都是一定的,但是每个业务的特点都不一样,采用一样的物理机,有一些业务计算资源不够,但存储过剩,而有些业务计算资源过剩,而存储瓶颈。特别是在HBase引入混合存储后,HDD和SSD的比例非常难确定,有些高要求的业务常常会把SSD用满而HDD有剩余,而一些海量的离线型业务SSD盘又无法利用上。
  • 运维压力大:使用物理机时,运维需要时刻注意物理机是否过保,是否有磁盘坏,网卡坏等硬件故障需要处理,物理机的报修是一个漫长的过程,同时需要停机,运维压力巨大。对于HBase这种海量存储业务来说,每天坏几块磁盘是非常正常的事情。

而当Lindorm采用了ECS+云盘部署后,这些问题都迎刃而解。ECS提供了一个近似无限的资源池。当面对业务的紧急扩容时,我们只需在资源池中申请新的ECS拉起后,即可加入集群,时间在分钟级别之内,无惧业务流量高峰。配合云盘这样的存储计算分离架构。我们可以灵活地为各种业务分配不同的磁盘空间。当空间不够时,可以直接在线扩缩容磁盘。同时,运维再也不用考虑硬件故障,当ECS有故障时,ECS可以在另外一台宿主机上拉起,而云盘完全对上层屏蔽了坏盘的处理。极致的弹性同样带来了成本的优化。我们不需要为业务预留太多的资源,同时当业务的大促结束后,能够快速地缩容降低成本。
image.png

一体化冷热分离

在海量大数据场景下,一张表中的部分业务数据随着时间的推移仅作为归档数据或者访问频率很低,同时这部分历史数据体量非常大,比如订单数据或者监控数据,降低这部分数据的存储成本将会极大的节省企业的成本。如何以极简的运维配置成本就能为企业极大降低存储成本,Lindorm冷热分离功能应运而生。Lindorm为冷数据提供新的存储介质,新的存储介质存储成本仅为高效云盘的1/3。

Lindorm在同一张表里实现了数据的冷热分离,系统会自动根据用户设置的冷热分界线自动将表中的冷数据归档到冷存储中。在用户的访问方式上和普通表几乎没有任何差异,在查询的过程中,用户只需配置查询Hint或者TimeRange,系统根据条件自动地判断查询应该落在热数据区还是冷数据区。对用户而言始终是一张表,对用户几乎做到完全的透明。详细介绍请参考云栖社区文《面向海量数据的极致成本优化-云HBase的一体化冷热分离
image.png

ZSTD-V2,压缩比再提升100%

早在两年前,我们就把集团内的存储压缩算法替换成了ZSTD,相比原来的SNAPPY算法,获得了额外25%的压缩收益。今年我们对此进一步优化,开发实现了新的ZSTD-v2算法,其对于小块数据的压缩,提出了使用预先采样数据进行训练字典,然后用字典进行加速的方法。我们利用了这一新的功能,在Lindorm构建LDFile的时候,先对数据进行采样训练,构建字典,然后在进行压缩。在不同业务的数据测试中,我们最高获得了超过原生ZSTD算法100%的压缩比,这意味着我们可以为客户再节省50%的存储费用!
image.png
关于HBase Serverless的介绍和使用,可以参考《[1元包月,阿里云HBase Serverless开启大数据学习与测试的新时代
](https://developer.aliyun.com/article/719206)》一文。

面向大客户的安全和多租户能力

Lindorm引擎内置了完整的用户名密码体系,提供多种级别的权限控制,并对每一次请求鉴权,防止未授权的数据访问,确保用户数据的访问安全。同时,针对企业级大客户的诉求,Lindorm内置了Group,Quota限制等多租户隔离功能,保证企业中各个业务在使用同一个HBase集群时不会被相互影响,安全高效地共享同一个大数据平台。

用户和ACL体系

Lindorm内核提供一套简单易用的用户认证和ACL体系。用户的认证只需要在配置中简单的填写用户名密码即可。用户的密码在服务器端非明文存储,并且在认证过程中不会明文传输密码,即使验证过程的密文被拦截,用以认证的通信内容不可重复使用,无法被伪造。
Lindorm中有三个权限层级。Global,Namespace和Table。这三者是相互覆盖的关系。比如给user1赋予了Global的读写权限,则他就拥有了所有namespace下所有Table的读写权限。如果给user2赋予了Namespace1的读写权限,那么他会自动拥有Namespace1中所有表的读写权限。

Group隔离

当多个用户或者业务在使用同一个HBase集群时,往往会存在资源争抢的问题。一些重要的在线业务的读写,可能会被离线业务批量读写所影响。而Group功能,则是HBase增强版(Lindorm)提供的用来解决多租户隔离问题的功能。
通过把RegionServer划分到不同的Group分组,每个分组上host不同的表,从而达到资源隔离的目的。
image.png
例如,在上图中,我们创建了一个Group1,把RegionServer1和RegionServer2划分到Group1中,创建了一个Group2,把RegionServer3和RegionServer4划分到Group2。同时,我们把Table1和Table2也移动到Group1分组。这样的话,Table1和Table2的所有region,都只会分配到Group1中的RegionServer1和RegionServer2这两台机器上。同样,属于Group2的Table3和Table4的Region在分配和balance过程中,也只会落在RegionServer3和RegionServer4上。因此,用户在请求这些表时,发往Table1、Table2的请求,只会由RegionServer1和RegionServer2服务,而发往Table3和Table4的请求,只会由RegionServer3和RegionServer4服务,从而达到资源隔离的目的。

Quota限流

Lindorm内核中内置了一套完整的Quota体系,来对各个用户的资源使用做限制。对于每一个请求,Lindorm内核都有精确的计算所消耗的CU(Capacity Unit),CU会以实际消耗的资源来计算。比如用户一个Scan请求,由于filter的存在,虽然返回的数据很少,但可能已经在RegionServer已经消耗大量的CPU和IO资源来过滤数据,这些真实资源的消耗,都会计算在CU里。在把Lindorm当做一个大数据平台使用时,企业管理员可以先给不同业务分配不同的用户,然后通过Quota系统限制某个用户每秒的读CU不能超过多少,或者总的CU不能超过多少,从而限制用户占用过多的资源,影响其他用户。同时,Quota限流也支持Namesapce级别和表级别限制。

最后

全新一代NoSQL数据库Lindorm是阿里巴巴HBase&Lindorm团队9年以来技术积累的结晶,Lindorm在面向海量数据场景提供世界领先的高性能、可跨域、多一致、多模型的混合存储处理能力。对焦于同时解决大数据(无限扩展、高吞吐)、在线服务(低延时、高可用)、多功能查询的诉求,为用户提供无缝扩展、高吞吐、持续可用、毫秒级稳定响应、强弱一致可调、低存储成本、丰富索引的数据实时混合存取能力。Lindorm已经成为了阿里巴巴大数据体系中的核心产品之一,成功支持了集团各个BU上千个业务,也多次在天猫双十一“技术大团建”中经受住了考验。阿里CTO行癫说过,阿里的技术都应该通过阿里云输出,去普惠各行各业数百万客户。因此Lindorm从今年开始,已经在阿里云上以“HBase增强版”的形式,以及在专有云中对外输出,让云上的客户能够享受到阿里巴巴的技术红利,助力业务腾飞!

文中所涉及到的技术文章汇总

本文是一篇综述,具体的技术细节大家可以参考阿里云开发社区的文章

HBase用户福利

新用户9.9元即可使用6个月云数据库HBase,更有低至1元包年的入门规格供广大HBase爱好者学习研究,更多内容请参考链接

]]>
Flink Batch SQL 1.10 实践 Mon, 16 Dec 2019 05:35:02 +0800 作者:李劲松(之信)

Flink作为流批统一的计算框架,在1.10中完成了大量batch相关的增强与改进。1.10可以说是第一个成熟的生产可用的Flink Batch SQL版本,它一扫之前Dataset的羸弱,从功能和性能上都有大幅改进,以下我从架构、外部系统集成、实践三个方面进行阐述。

架构

Stack

图片 1.png

首先来看下stack,在新的Blink planner中,batch也是架设在Transformation上的,这就意味着我们和Dataset完全没有关系了:

  1. 我们可以尽可能的和streaming复用组件,复用代码,有同一套行为。
  2. 如果想要Table/SQL的toDataset或者fromDataset,那就完全没戏了。尽可能的在Table的层面来处理吧。
  3. 后续我们正在考虑在DataStream上构建BoundedStream,给DataStream带来批处理的功能。

网络模型

图片 2.png

Batch模式就是在中间结果落盘,这个模式和典型的Batch处理是一致的,比如MapReduce/Spark/Tez。

Flink以前的网络模型也分为Batch和Pipeline两种,但是Batch模式只是支持上下游隔断执行,也就是说资源用量可以不用同时满足上下游共同的并发。但是另外一个关键点是Failover没有对接好,1.9和1.10在这方面进行了改进,支持了单点的Failover。

建议在Batch时打开:

jobmanager.execution.failover-strategy = region

为了避免重启过于频繁导致JobMaster太忙了,可以把重启间隔提高:

restart-strategy.fixed-delay.delay = 30 s

Batch模式的好处有:

  • 容错好,可以单点恢复
  • 调度好,不管多少资源都可以运行
  • 性能差,中间数据需要落盘,强烈建议开启压缩
    taskmanager.network.blocking-shuffle.compression.enabled = true

Batch模式比较稳,适合传统Batch作业,大作业。

图片 3.png

Pipeline模式是Flink的传统模式,它完全和Streaming作业用的是同一套代码,其实社区里Impala和Presto也是类似的模式,纯走网络,需要处理反压,不落盘,它主要的优缺点是:

  • 容错差,只能全局重来
  • 调度差,你得保证有足够的资源
  • 性能好,Pipeline执行,完全复用Stream,复用流控反压等功能。

有条件可以考虑开启Pipeline模式。

调度模型

Flink on Yarn支持两种模式,Session模式和Per job模式,现在已经在调度层次高度统一了。

  1. Session模式没有最大进程限制,当有Job需要资源时,它就会去Yarn申请新资源,当Session有空闲资源时,它就会给Job复用,所以它的模型和PerJob是基本一样的。
  2. 唯一的不同只是:Session模式可以跨作业复用进程。

另外,如果想要更好的复用进程,可以考虑加大TaskManager的超时释放:
resourcemanager.taskmanager-timeout = 900000

资源模型

先说说并发:

  1. 对Source来说:目前Hive的table是根据InputSplit来定需要多少并发的,它之后能Chain起来的Operators自然都是和source相同的并发。
  2. 对下游网络传输过后的Operators(Tasks)来说:除了一定需要单并发的Task来说,其它Task全部统一并发,由table.exec.resource.default-parallelism统一控制。

我们在Blink内部实现了基于统计信息来推断并发的功能,但是其实以上的策略在大部分场景就够用了。

Manage内存

图片 4.png

目前一个TaskManager里面含有多个Slot,在Batch作业中,一个Slot里只能运行一个Task (关闭SlotShare)。

对内存来说,单个TM会把Manage内存切分成Slot粒度,如果1个TM中有n个Slot,也就是Task能拿到1/n的manage内存。

我们在1.10做了重大的一个改进就是:Task中chain起来的各个operators按照比例来瓜分内存,所以现在配置的算子内存都是一个比例值,实际拿到的还要根据Slot的内存来瓜分。

这样做的一个重要好处是:

  1. 不管当前Slot有多少内存,作业能都run起来,这大大提高了开箱即用。
  2. 不管当前Slot有多少内存,Operators都会把内存瓜分干净,不会存在浪费的可能。

当然,为了运行的效率,我们一般建议单个Slot的manage内存应该大于500MB。

另一个事情,在1.10后,我们去除了OnHeap的manage内存,所以只有off-heap的manage内存。

外部系统集成

Hive

强烈推荐Hive Catalog + Hive,这也是目前批处理最成熟的架构。在1.10中,除了对以前功能的完善以外,其它做了几件事:

  1. 多版本支持,支持Hive 1.X 2.X 3.X
  2. 完善了分区的支持,包括分区读,动态/静态分区写,分区统计信息的支持。
  3. 集成Hive内置函数,可以通过以下方式来load:
    a)TableEnvironment.loadModule("hiveModule",new HiveModule("hiveVersion"))
  4. 优化了ORC的性能读,使用向量化的读取方式,但是目前只支持Hive 2+版本,且要求列没有复杂类型。有没有进行过优化差距在5倍量级。

兼容Streaming Connectors

得益于流批统一的架构,目前的流Connectors也能在batch上使用,比如HBase的Lookup和Sink、JDBC的Lookup和Sink、Elasticsearch的Sink,都可以在Batch无缝对接使用起来。

实践

SQL-CLI

在1.10中,SQL-CLI也做了大量的改动,比如把SQL-CLI做了stateful,里面也支持了DDL,还支持了大量的DDL命令,给SQL-CLI暴露了很多TableEnvironment的能力,这让用户可以方便得多。后续,我们也需要对接JDBC的客户端,让用户可以更好的对接外部工具。但是SQL-CLI仍然待继续改进,比如目前仍然只支持Session模式,不支持Per Job模式。

编程方式

TableEnvironment tEnv = TableEnvironment.create(EnvironmentSettings
  .newInstance()
  .useBlinkPlanner()
  .inBatchMode()
  .build());

老的BatchTableEnv因为绑定了Dataset,而且区分Java和Scala,是不干净的设计方式,所以Blink planner只支持新的TableEnv。

TableEnv注册的source, sink, connector, functions,都是temporary的,重启之后即失效了。如果需要持久化的object,考虑使用HiveCatalog。

tEnv.registerCatalog(“hive”, hiveCatalog);
tEnv.useCatalog(“hive”);

可以通过tEnv.sqlQuery来执行DML,这样可以获得一个Table,我们也通过collect来获得小量的数据:

Table table = tEnv.sqlQuery(“SELECT COUNT(*) FROM MyTable”);
List<Row> results = TableUtils.collectToList(table);
System.out.println(results);

可以通过tEnv.sqlUpdate来执行DDL,但是目前并不支持创建hive的table,只能创建Flink类型的table:

tEnv.sqlUpdate(
   "CREATE TABLE myResult (" +
      "  cnt BIGINT"
      ") WITH (" +
      "  'connector.type'='jdbc'," 
         ……
      ")");

可以通过tEnv.sqlUpdate来执行insert语句,Insert到临时表或者Catalog表中,比如insert到上面创建的临时JDBC表中:

tEnv.sqlUpdate(“INSERT INTO myResult SELECT COUNT(*) FROM MyTable”);
tEnv.execute(“MyJob”);

当结果表是Hive表时,可以使用Overwrite语法,也可以使用静态Partition的语法,这需要打开Hive的方言:

tEnv.getConfig().setSqlDialect(SqlDialect.HIVE);

结语

目前Flink batch SQL仍然在高速发展中,但是1.10已经是一个可用的版本了,它在功能上、性能上都有很大的提升,后续还有很多有意思的features,等待着大家一起去挖掘。

]]>
鹿班|一人设计10亿图片,这个“设计师”如何演进? Mon, 16 Dec 2019 05:35:02 +0800 image.png
作者| 鲍军(推开)
出品|阿里巴巴新零售淘系技术部

本文内容提炼:
1、如何建立图片数据与用户注意力之间的连接?
2、如何进行结构化规模化的图片生产?

2019 年双十一期间,鹿班面向集团电商场景输送了 10亿 规模的图片。从提升公域流量效率,到商家私域的表达赋能,随着场景的细分,分人群精细化运营的需求提出,对图片结构化生产,规模化生产在量和质上的要求不断提高。图像生成技术也在不断的演进,本篇将围绕鹿班最近一年的在生成能力上演进以及实践做展开,欢迎探讨交流。

image.png

上图是我们有过采访的在平台上卖姜茶的店铺的图片运营经验,可以看到不同场景下的商品图文,在内容和形式是极具多样性,这种多样性不同于海量商品的个性化多样性,这种多样性是对 C 端用户注意力更加精细的吸引,这种多样性是对 B 端商家运营能力的一个新命题。

那么如何满足这种多样性生产?如何建立图片数据与用户注意力之间的连接?如何对商家赋能?下面我会从图片生产的视角切入,尝试回答以上问题。

生产标准-图片结构化

在 C 端的商品分发链路上,得益于结构化的标准定义,使得商品的数据和特征可以被高效的传递收集处理,从而给予模型和算法充分的施展空间。

当尝试将商品图片的数据作为一个整体进特征提取计算时,无论是低层次的显示特征还是高维的语义隐式特征在基于深度神经网络处理后都变成了一个概率问题,但实际我们更希望把概率转换为确定性输入从而更准确的挖掘图片特征与用户行为之间的关联关系。

image.png

电商的图片生产除了最开始的拍摄外,更多的会依赖后期的图像处理软件,比如PS(photoshop)进行图文的创作编辑,根据图像处理软件的图层划分标准,我们对图片进行结构化的分层定义。给图片引入图层(layer)属性,从结构、色彩、文字(内容)三个维度对一张图片进行结构化的描述。通过结构化使得图片自身的属性特征可以被高效准确的传递收集处理,进而使得后续的生成加工成为可能。

image.png

为了标准的执行,我们面向商家设计师开发了配套的生产工具,在保持设计师工作流程不变化的前提下,将原来非结构化的单张图片转换为自描述的 DSL 结构化数据,从而在生产的源头保证了图片数据结构化的执行实施。

生产工序-流程编排

当图片有了结构化的定义后,我们将图片的生成转换为成基于人机协作的数据匹配排序问题。为什么是匹配排序?

我们积累了大量的设计数据,相比之前非结构化的设计创意,通过图片结构化我们可以将设计精确解构到每一个图层,每一个元素,每一个文字。进而沉淀了可复用的数据资产。根据用户喜好,商品属性进行图片表达的好中选优,这就转化为一个数据匹配问题。

数据匹配包含两个部分:一是由设计师创作的面向特定场景或商品表达的设计数据,我们称之为模板;二是由用户属性数据以及在浏览商品图片过程中产生的的收藏、点击、购买等用户行为数据。

对于的匹配排序有两层,首先是商品图片和模板的匹配,这层通过定义设计约束进行参数化的求解实现匹配。

比如基于模板的背景色约束商品图片主色区间,根据模板结构布局约束商品图片主体形状等。通过图像检测/识别算法在线提取商品主体的图片特征,结合离线计算的模板特征进行匹配计算。

然后是用户特征与图片特征的匹配计算,在建模时我们把数据划分成三个特征组,分别是用户特征组,商品特征组合和图片特征组,通过 embedding 变换对得到特征向量进行两两交叉预测建模,之所以采用两两分别组合而不采用三组向量联合建模的原因是考虑到对于电商场景,商品特征与用户特征之间的信号更强,如果联合建模训练会导致图片的行为的关系不能有效的被学习到,而通过两两交叉建模,可以针对性的做预测结果的加权。

问题定义清楚后我们依然要面对来自业务的复杂性和快速响应问题,为此我们定义了生产 pipline,将生产流程与生产能力分而治之。面对复杂业务需求提供生产流程编排能力,为提高响应速度提供可插拔的生产算子模型。

image.png

► 生产流程-节点编排

将图片设计生产的理念流程化,流程系统化。通过工作流引擎实现生产节点的编排管理,从而让业务方可以灵活的按需求进行生产线的定义组装,满足多场景的生产需求。

► 生产能力-可插拔算子

算子定义了统一的输入输出以及必要的context,通过对约定输入的计算处理完成效果实现。
图像类算子:图像分割,主体识别,OCR,显著性检测等。
文本类算子:短标题生成,文字效果增强等。
规则类算子:人工干预,流程控制等。

► 通过这套生成引擎,白盒化的对生成能力进行分制管理,面向二方能力的开放友好,同时满足业务集成的灵活性。目前线上共管理了10个核心场景,33个生产节点,47种算子能力,通过编排组合实现了10亿规模图片的分场景矩阵式生成。

生产工艺-图文渲染

如果说生产架构解决了宏观的生产工序问题,那么渲染就是面向微观的工艺问题。

渲染首先要解决的是效果统一,除了直接通过服务端渲染图片以外,在商家侧需要所见即所得的二次编辑能力,也就是对于同一套 DSL 数据协议,在前后端需保证渲染效果统一,为此我们构建了前后端同构的渲染方案,开发了基于 canvas 的画布引擎,在前端通过 UI 的包装提供图片可视化编辑能力;在云端通过 puppeteer 无头浏览器加载 canvas 画布引擎实现图片生产。

image.png

其次渲染需要保证对视觉设计的还原能力,尤其是文字渲染效果。前端渲染对丰富文字效果的支持由于字体库安装问题很难完成,同时后端也缺乏对文字效果的标准协议定义。而有了同构的渲染能力后,我们可以将前端协议的优势与后端字体库的优势结合,灵活的完成视觉还原。

image.png

淘宝首焦 banner 场景下,单字单样式的模板较普通模板在 AB 分桶试验下点击率平均提升约 13% 。

生产保障-性能优化

在 10亿 量级的规模下,如果没有高性能的工程保障,一切效果的提升都是零,双十一期间鹿班的平均合图 RT<5ms ,从 DSL 解析到 OSS 上行链路完成平均 RT<200ms ,在没有增加机器资源的情况下,实现了相较于去年的整体系统吞吐性能提升 50% 。整个后端引擎分为两部分:

image.png

渲染:将结构化的 layer 数据转换为独立的图片数据流。不同类型图层转换交由对应的 handler 处理。执行并行化渲染。

合图:将渲染得到的多个图层数据进行图像合并计算,经过编码压缩,图片上传,得到成图。

性能优化主要分以下几点:

  • 图层拉取并行化,本地采用 LRU-K 主动缓存,减少 tfs 拉图消耗。
  • GPU 显存主动调度管理,对显存预先分段分片,减少频繁显存的申请分配与释放消耗。
  • jpg 编码优化,通过 SIMD 进行加速,软编码的平均耗时由 70ms 下降至 20ms 。

未来展望

图片作为商品信息展示的重要载体,无论是在公域的搜索推荐还是私域的店铺详情都承担着传递商家意图与帮助消费者决策的双重作用。

对于商家:通过技术与数据赋能商家在图片生产上的持续优化,让结构化的图片能够更好的被机器理解,更高效的分发。同时增加商家的运营抓手。
对于消费者:利用更多维的图片特征获得对受众更泛化更精细的刻画能力,更好的满足甚至激发用户兴趣。

We are hiring

淘系技术部依托淘系丰富的业务形态和海量的用户,我们持续以技术驱动产品和商业创新,不断探索和衍生颠覆型互联网新技术,以更加智能、友好、普惠的科技深度重塑产业和用户体验,打造新商业。我们不断吸引用户增长、机器学习、视觉算法、音视频通信、数字媒体、移动技术、端侧智能等领域全球顶尖专业人才加入,让科技引领面向未来的商业创新和进步。
请投递简历至邮箱:ruoqi.zlj@taobao.com
了解更多职位详情:2684亿成交!每秒订单峰值54.4W!这样的团队你想加入吗?

更多技术干货,关注「淘系技术」微信公众号。
image.png

]]>
阿里经济体大数据平台的建设与思考 Mon, 16 Dec 2019 05:35:02 +0800 本文内容根据演讲视频以及PPT整理而成。

双十一!=11.11
首先从双11说起,双11已经成为阿里巴巴最大的单日促销活动。双11活动可能对于消费者而言只是一天而已,但是对于阿里巴巴和数百万商家而言,却是一个非常长线的工作。站在阿里巴巴的角度来看双11,其实无论是从业务线还是技术线,背后都存在着很多的思考。
image.png

从“人、货、场”的角度看待双11。首先,对于“人”而言,双11需要回答什么样的消费者会看什么样的商品,以及每个人看到的商品是什么样子的。“货”则是对于商家而言的,商家需要知道在这次双11中,什么样的商品才能成为尖货,以及需要提前多久准备多少货才是最合适的。“场”的概念则更偏重于物流,比如需要提前将什么货物铺在什么地方才能够达到最优的物流执行效率。在“人、货、场”的背后存在两件事情,他们才是电商竞争力的关键。第一件事情就是供应链,如果能够提前长周期地布局供应链,包括柔性、精细化的供应链,对于商家双11大促和成本的降低将会产生非常大的作用。另外一件事情就是物流,前几年的时候每到双11物流就会爆仓,而最近几年虽然成交量在不断上涨,但是却没有再出现物流爆仓的情况。这背后的原因是阿里巴巴联合商家已经把消费者可能购买的商品布局到当地的本地仓库中了。而所有的这些工作其实都是千万级别商品和十亿级的消费者的匹配的问题。
image.png

而从技术的角度来看,在这背后其实就是大数据和AI能力的竞争。双11竞争的是企业是否具有足够多的数据、足够强的算力、足够好的算法,指导什么样的消费者在什么样的风格、类目以及价格区间上看到商品;对于商家而言,什么样的货品才能够成为尖货,需要准备多少货才是合适的;对于供应链而言,需要怎样布局才能够达成成本的最优,将货物放在那个货场才能够距离消费者更近。这就是阿里所提的A+B+C概念,这里的A指的是Algorithm算法,B指的是Big Data大数据,C就是Computing计算,也就是说是否有足够多的数据、足够好的算法以及足够便宜的计算力。因此,双11的竞争,从技术角度来看,就是一个公司的大数据和AI能力的竞争

下图展示的双11单日处理数据量的统计情况。从2015年到2019年,双11单日数据处理量大约增长了70%左右,但是这样的数据量不只是在双11当天才需要处理的,实际上从9月下旬到双11当天,每一天都需要处理如此之多的数据。运营同学、分析同学以及商家就在这些数据里面运行非常精细的算法,实现数据挖掘和信息处理,通过这种方式助力双11,这样才能使得双11当天实现最优的匹配。
image.png

从技术的角度来看,双11的成功有三个必要条件,即超大规模数据,低成本算力,以及数据上的快速迭代。最后这个条件要划重点,如何使上万名算法工程师和数据工程师在数据上实现快速迭代与前面数据以及算力同样关键。海量数据上的快速迭代能力,本质是数据中台和数据开发平台的能力。

飞天大数据平台整体架构

如下图所示的是从阿里巴巴的角度看的整个飞天大数据平台的布局。从左侧看起,阿里巴巴主线数仓在MaxCompute上,目前在全球10个数据中心具有超过10万台的规模,阿里巴巴几乎所有的数据都存储在这里面。MaxCompute支撑了一套自研的SQL引擎,同时也支持Spark等开源的计算能力。除了主线数仓和大数据计算之外,阿里巴巴还有基于Flink的流计算系统。对于云上业务则有基于Hadoop的完整的EMR解决方案提供给客户。下图中左边的三部分叫做Basic Engine,也就是基础计算引擎。右边的引擎则包括PAI机器学习平台等,之所以左边和右边引擎割裂开,是因为两者不属于同等层面的关系,比如PAI的作业可以跑在MaxCompute上面也可以跑在Flink和EMR上面。除了PAI之外,阿里巴巴大数据平台还包括Hologres、图计算引擎Graph Compute以及Elasticsearch等。中间则是使用DataWorks贯穿起来的一体化大数据开发平台,包括大数据的开发以及数据Pipeline的建立也都整合在一个体系内。
image.png

接下来以 MaxCompute 为例为大家介绍阿里经济体大数据平台的建设与思考。

飞天平台发展历程

从2002年开始,阿里所有的数据都存储在Oracle数据库里面。因为电商类业务最初都是记账类的,那时候所有的数据都在Oracle里面,当时阿里拥有整个亚洲最大的Oracle集群。而在后来发现Oracle无法支撑计算力的提升之后,阿里巴巴就迁移到了Greenplum上。Greenplum采用分布式架构,最高能够扩展到PB级别,但是不到一年的时间,Greenplum却也无法满足阿里业务的发展了。因此,在2008年的时候,阿里巴巴启动了Hadoop集群,这是阿里最早在大数据方面的探索。2009年阿里云成立,建立了飞天品牌,当时考虑是否自建一套飞天系统,所以大数据引擎、分布式存储和分布式调度一起作为三条主线一起启动。在2010年,阿里发布了存储计算的MaxCompute 1.0体系,对应的底盘叫做盘古存储,中间使用伏羲调度,最早支持蚂蚁金服的小微贷业务。在2013年,阿里开始在规模和扩展性上做到一定的量级,大约5千台服务器的级别,并在这个关键点上启动了阿里内部非常关键的项目“登月”,也就是将阿里巴巴所有的数据都集中到一个体系上来。因此当时存在非常大的讨论就是到底使用Hadoop还是使用自研的盘古 + MaxCompute体系,最终决定了使用自研体系。从2013年到2015年实现了完整的“登月”过程。2015年,阿里使用MaxCompute全面替换Hadoop,基于MaxCompute和DataWorks构建了完整的阿里数据中台。在2017年的时候,阿里巴巴认为需要进行引擎的迭代了,因此发布了MaxCompute 2.0版本,将整个核心引擎实现了重构。当时在扩展性上,单集群能够达到万台,全球有超过10个数据中心。最近,阿里巴巴在MaxCompute方面所做的工作包括性能的提升,以及在中台的基础之上演进自动中台或者说是自动数仓。
image.png

因此,飞天平台的发展历程可以用几句话来总结:第一,回首过去10年的发展,其实是阿里巴巴对于数据规模和低成本算力的持续追求。第二,从开源到自研的演进,而如今又从自研向开源方向演进,比如Flink的发展。第三,从最早的数据库走向数据仓库,走向了数据中台,再走向自动数仓。第四,数据湖开始的时候选择了Hadoop体系,而如今需要考虑如何将数据湖和数据仓库很好地融合在一起。

企业级计算平台的核心问题

对于企业级计算平台而言,往往会遇到很多问题。第一个问题很简单,但是也很常见,那就是需要可靠的数据交汇点,这里的可靠就是100%万无一失,并且需要保证数据存储在机房里面就不会丢失。第二个需要考虑高性能和低成本,这里除了引擎本身的性能优化之外,还需要考虑存储第三个问题是如何做数据管理、共享与安全性第四个问题则是企业级能力,比如如何做企业级自动化运维。第五个问题是需要支撑统一而丰富的运算能力,包括批处理、流处理、机器学习、图计算、交互计算等能力。第六个问题是如何拥抱和融合各种生态,包括自主系统与生态的融合,数据湖和数据仓库的融合等。第七个问题比较简单,就是开发语言与效率。第八个问题就是弹性能力与扩展性。最后一个问题就是大数据系统如何更好地支撑AI能力,同时是否能够利用AI能力优化大数据系统。
image.png

有关性能/效率(成本)优化

阿里巴巴在性能和效率方面所面临的挑战可以总结为以下4点

1.当规模超过1万台时成本会持续增长,因此云上大规模客户对于成本的要求非常关键。
2.阿里巴巴数据和计算力的增长非常迅速,从双11来看,每年数据处理量的增速为70%左右,但是硬件投入不可能达到70%,这样的成本是无法承受的,因此需要打破数据和计算量线性增长之间的关系。
3.目前,技术发展进入了开源软件盲区,因为一般而言,开源软件无法满足超大规模的应用需要,因此需要解决这个问题。
4.之前发现了非常多的小集群,但是他们之间的负载无法实现均衡,因此需要解决多集群整体利用率不够高的问题。

image.png

针对以上问题和挑战,可以从计算、存储以及资源方面进行优化,这里重点分享资源优化中的一部分,那就是混部。这里需要说明的是阿里巴巴在考虑资源优化的时候,并不考虑单作业的成本和效率,而关心整个集群的利用率的提升,将集群利用率提高到60%以上是阿里巴巴的强优化目标。

在双11当天,流量刚开始的时候会出现一个尖峰,这个尖峰可能一年就出现一次。大概到2点多钟的时候,流量会跌倒一个低谷,因为大家第一波抢购完成之后就睡觉了,等大家起床之后又会出现流量上升。那么,阿里巴巴需要准备多少台服务器才能满足需求呢?如果按照峰值准备,那么将会有一半的服务器总会处于空闲。如果按照均值进行规划,就会发现在峰值时用户无法提交请求,双11的体验就会很差。
image.png

针对于双11的现状,阿里实现了两套混合部署的体系,第一套体系叫做离线和在线混合部署,第二套体系叫做在线和离线混合部署。比如大数据与AI计算服务和在线计算在离线计算规模上各不相同,对于电商服务而言,白天可能比较空闲,而大数据服务则是一直都很繁忙,因此在白天的时候,可以将一些大数据的计算弹到电商的集群上来,利用电商的部分CPU计算资源。而在双11,大数据业务需要快速回退,这里的回退指的不是几台机器的回退,而是数万台机器的回退,来支撑电商的流量洪峰。大数据和AI计算使用电商资源的混合部署是每天都会发生的,而电商使用大数据的资源则只在每年的双11和双12发生,每次只要两个小时,但是这两个小时的弹性却会为阿里巴巴节省数十亿的成本。混部这件事情绝不是将一些Workload放在一起就能解决问题了,因为总会遇到一些问题,比如如何做资源规划?这里不仅是在线集群的资源规划问题,而是阿里巴巴整个经济体的资源规划问题。因为不同负载对SLA要求不同,因此需要同时满足隔离和共享之间的矛盾?此外,大数据计算强依赖存储,这种情况下需要推的就是存储和计算分离的架构,而在存储与计算分离的背后是极高的网络带宽挑战。

资源利用率优化–离线与在线混布

如下图所示的是资源调度模拟图。Sigma是在线容器调度器,基本上所有的在线系统全部都实现了容器化,所有的容器系统都通过Sigma调度。伏羲是大数据和AI的调度器,主力计算力都通过伏羲进行调度。两套调度器都看到一套资源的View,相当于能够看到哪部分资源是空的,可以调入和调出。底层有两套Agent,这两套Agent负责在拿到资源之后向下做资源申请和管理。Sigma后续可能会延续到Kubernetes平台上,目前是使用Docker完成的。这里并没有试图去合成一个中央调度器来实现所有的调度工作,而是以在线和离线分开来做调度的。从半动态资源调度策略起步,保持两边调度系统改动最小,从而实现快速升降级和迭代。
image.png

在思考层面,有几个关键点,其中一个是存储和计算分离,特别是想要利用大规模电商资源实现弹性的时候,一定要做存储和计算分离。因此,在阿里巴巴内部有一个项目叫做“天下无盘”,也就是说所有的计算都可以和存储分开,而不依赖于本地存储。因为会涉及到数十万台机器的调度,因此需要有统一高效的部署运维平台,一定需要一键部署,自动检测与回滚,高效版本分发等能力。在资源管理层,因为不同的应用具有不同的SLA要求,因此将资源分为了S10-S20-S30三个等级。隔离能力绝对不仅仅是CPU的隔离,这里面包括IO、网络、内存等各个方面的隔离。对于大量的改动而言,阿里巴巴实现了定制版本的内核AliKernel,将这些改动全部放在AliKernel里面。以上这些关键点实现之后,基本上就能够实现比较完善的电商混部。

有关数据仓库与数据湖

其实Hadoop本身就是一个数据湖体系,其拥有一套统一的存储架构,上面运行多套引擎。Hadoop基本满足数据湖所有的定义,比如HDFS存储的数据几乎不要求是完全建模的,可以不建模,并且能够是Schema-On-Read的,可以在读取到时候动态解析Schema。因为是开放架构,因此可以运行所有引擎,但是从另外一个层面上讲解,因为存储是开放的,因此难以做全面优化。在成本方面,对于数据湖而言,比较容易启动。其难点在于维护成本比较高,比如最经典的小文件问题。对于数据使用而言,往往难以实现很高的质量以及可维护性。从另外一个角度来看,包括阿里在内的很多企业都在做数据仓库,之所以做这件事情是因为在数据仓库中,数据进来都是Fully modelled的,那么表和数据都是事先定义好的。正因为是Fully modelled的,因此通常只存储结构化和非结构化的数据,而这样会造成数据存储灵活性的问题。而因为采用了一体的概念,那么并不是所有引擎都适合运行在这套系统里面。但是一体化架构更容易实现优化,存储更容易为上层计算进行优化,这里的成本就是数据仓库可能不好建设,因为对于数据写入以及维护等要求较高。但是一旦数据仓库做成,就更容易实现Fully managed。对于数据使用而言,往往能够实现较高的数据质量,并且易于使用。
image.png

那么将核心数据全部放在数据仓库上是否可以行,显然是可行的,并且包括阿里巴巴在内的很多企业也都是这么做的。如果只用数据湖来做,是否可行,答案也是可行的,其实很多公司也是这么做的。那么能否将两者结合起来呢?也是可行的。业界也有很多尝试,并且是双向的,数据湖架构能够看到数据仓库的优势,因此向着数据仓库演进比如Hadoop + HMS,可以认为是增强版HMS的Netflix Iceberg以及Spark DeltaLake。而数据仓库系统也能够看到数据湖的灵活性,也在向着数据湖发展,比如Redshift和Snowflake,因此演进是双向的。

有关数据仓库与数据湖–阿里大数据平台的演进

阿里巴巴在2013年到2015年的时候看到了Hadoop体系的一些问题,比如扩展性、性能、安全性、稳定性以及代码可控性。因此,阿里做了Hadoop到MaxCompute的迁移,相当于对于数据湖场景做了主线数仓,那个时候就已经开始有能力构建阿里的数据中台,开始构建数据建模、数据血缘、数据治理以及标签体系等。
image.png

阿里巴巴构建完数据中台之后,在2016年到2018年的时候对于主线的数据仓库平台中做了两个项目,分别是联合计算平台和逻辑数据湖。联合计算平台使得数据能支持多种引擎,在MaxCompute平台上封装了“丘比特”,将数据的资源层封装成了Yarn和Kubernetes平台,将数据存储层抽象了一套IO接口,将元数据系统抽象出来一套系统,可以对接Spark、Flink等开源引擎。丘比特平台所能实现的是Spark和Flink不需要修改代码,只需要替换一些Jar包就能够在MaxCompute平台上使用资源跑数据,相当于在数仓的基础之上向上扩展了对于引擎的支持。另外一件事情就是做了外表能力,所谓逻辑数据湖则实现了与其他存储打通,不是把数据汇聚,因为计算下推比数据上移更高效。
image.png

在2019年,阿里巴巴看到了实现逻辑数据湖潜在的问题,这对于用户而言是非常困难的,特别是具有海量数据的时候。另外一点,云上客户给阿里的反馈是手里已经有了200台机器的Hadoop体系了,并且希望使用阿里的数仓架构和中台架构提升业务能力,如何实现两条线和谐发展呢?因此,阿里巴巴正在着手实现所谓的“湖仓一体”,也就是将数据仓库和数据湖融合在一起。除了打通数据湖和数据仓库的网络之外,阿里巴巴还实现了元数据的打通,当希望对两边的数据做Join计算的时候不需要建立外表,目前这套架构正在试用中。

image.png




更多阿里巴巴大数据计算技术和产品信息,可点击链接加入 MaxCompute开发者社区2群
https://h5.dingtalk.com/invite-page/index.html?bizSource=____source____&corpId=dingb682fb31ec15e09f35c2f4657eb6378f&inviterUid=E3F28CD2308408A8&encodeDeptId=0054DC2B53AFE745
或扫码加入
image

]]>
从业务需求到能力扩展 | 阿里云Elasticsearch向量检索能力的创变 Mon, 16 Dec 2019 05:35:02 +0800 阿里云 Elasticsearch 目前是公有云营收增长最快的大数据产品之一。随着客户数的增长,我们发现随着AI技术的不断普及,针对向量检索场景的需求量在逐步提升。从人脸识别、音/视频识别到商品智能推荐等场景,技术上都离不开向量检索的能力作为支撑,而本片文章从构思到实践为您全面了解阿里云 Elasticsearch 的向量检索能力。

本文字数:1874
阅读时间:约3~5分钟

您将获得
1、阿里云 Elasticsearch 向量检索能力的演变过程
2、如何使用向量检索
3、未来阿里云 Elasticsearch 的探索之路

以下是正文


一、创意的诞生

阿里云 Elasticsearch 是目前公有云营收增长最快的大数据产品之一。随着客户数的增长,我们发现随着 AI 技术的不断普及,针对向量检索场景的需求量在逐步提升。比如人脸识别、音/视频识别、商品智能推荐等场景,技术上都离不开向量检索的能力作为支撑。以某专有云客户为例,客户的场景是视频安全监控,摄像头每天会产生500万帧采样图片,每个月产生TB级的向量数据,业务上需要实时对这些视频采样数据进行图片比对搜索。该客户属于典型的时序+向量检索的场景,而时序分析场景刚好是 Elasticsearch 最擅长的部分,那么我们能否在Elasticsearch现有能力的基础上补充向量检索的支持能力呢?基于这个朴素的想法,我们开始了与阿里巴巴达摩院向量检索团队的合作,希望借助达摩院自研的向量检索引擎补充阿里云 Elasticsearch 在向量检索方面的能力,一站式解决云上用户全文检索、时序分析及向量检索的需求。

简单介绍一下阿里云 Elasticsearch 使用的 Proxima 向量引擎库:阿里巴巴达摩院提供的 Proxima 向量检索引擎是一个运用于大数据下,实现向量近邻搜索的高性能软件库,能够提供业内性能和效果领先的基础方法模块,支持图像搜索、视频指纹、人脸识别、语音识别和商品推荐等各种场景。同时,引擎对向量检索的一些基础能力,如聚类、距离计算、高并发、Cache 等做了深层次的优化。

目前 Proxima 向量检索库在阿里集团覆盖的生产业务如图所示:
image.png

二、优选在线方案

如何将 Proxima 引擎库集成到阿里云 Elasticsearch 生态中,有两个方向摆在我们眼前:一种是最直观也是最简单的离线方案,也是集团内其它兄弟团队大部分采用的方案,依赖独立的离线资源做索引全量 Build;另一种是在线方案,也是无缝对接 Elasticsearch 现有能力、易用性最好的方案,但写入性能和存储相对会有一些Overhead。两种方案优劣势对比如下:
image.png

考虑到云上客户大多数对弹性和稳定性要求比较高,我们最终选择了易用性、稳定性更好的在线方案。

三、详解设计方案

在确定在线方案的前提下,如何能满足 Proxima 向量索引和 Elasticsearch 原生索引无缝集成呢?答案是利用 Lucene的 Codec 扩展机制。Codec 可以理解为 Lucene 索引文件格式的一种协议,用户只要实现对应的写入/读取的业务流程,即可自定义正排、倒排、StoreFields 等不同索引的具体实现。在阿里云 Elasticsearch 的实现中,我们包装并扩展了Lucene 的 Latest Codec,当向量数据写入es的某个字段时,前期流程跟原生的流程一致,先放入 indexBuffer 中;等内部发起 Refresh 时,调用底层的 Proxima 库,消费向量数据构建出 Proxima 的向量索引。

查询的时候,由于向量索引和原生索引一样都是 Segment 粒度生成,所以我们只要很轻量的实现向量 Segment 对应的 Weight 和 Scorer即可。具体的,当查询到了 BuildScorer 阶段,我们利用底层 Proxima 库加载当前 Segment的向量索引文件,通过 Native 方法查询出TopN的 id 和 Score 后,通过docID和分数生成当前 Segment 的 Scorer,交给indexSearcher继续执行上层的求交/求并操作即可。
image.png
基于 Codec 机制,向量索引已经可以被 Lucene 当成普通索引来管理,这对上层的 Elasticsearch 来说是完全透明的,所以可以实现不修改上层业务的前提下,兼容 Elasticsearch 所有上层的分布式文件操作;所有扩副本、本地 Failover 、阿里云快照备份/恢复等功能都与原生普通索引无异。因此大大提高了索引的稳定性,降低了用户的使用成本。

四、性能与效果评测

以下是阿里云Elasticsearch 6.7.0版本环境实测数据,机器配置为数据节点16c64g*2 + 100G ssd云盘,数据集为Sift128维 Float 向量(http://corpus-texmex.irisa.fr/),数据总量为2千万。索引配置全部是默认参数。
image.png

五、使用说明

5.1、创建索引

PUT test
{
  "settings": {
    "index.codec": "proxima",
    "index.vector.algorithm": "hnsw" # 可选值: hnsw/linear
  },
  "mappings": {
    "_doc": {
      "properties": {
        "feature": {
          "type": "proxima_vector", # 向量字段
          "dim": 2 # 向量维度,支持1~2048维
        },
        "id": {
          "type": "keyword"
        }
      }
    }
  }
}

5.2 添加文档

​
POST test/_doc
{
  "feature": [1.0, 2.0], # float数组,数组长度必须与mapping指定的dim保持一致
  "id": 1
}

5.3 检索

GET test/_search
{
  "query": {
    "hnsw": {  # 与创建索引时指定的algorithm一致
      "feature": {
        "vector": [1.5, 2.5], # float数组,数组长度必须与mapping指定的dim保持一致
        "size": 10 # 指定召回的topN
      }
    }
  }
}

六、总结展望

阿里云 Elasticsearch 始终致力于为云上用户提供一站式的高性能、低成本的大数据检索分析服务。向量检索引擎是我们在人工智能领域迈出的第一步,后续的发力点还有很多,比如支持更丰富的近似算法、支持离线训练、硬件加速等,有很多有意思的方向等待我们一起探索。目前阿里云ES向量检索引擎即将在下一版本上线公有云,有需求接入的用户可以提前提工单给我们沟通使用场景,感谢大家的支持。

目前商业版的6.7和7.4版本,可以使用向量检索

购买实例,请点击
进一步了解产品,请点击

加入我们

9.png

]]>
首月99元,3分钟入门DataWorks(标准版)强大功能! Mon, 16 Dec 2019 05:35:02 +0800 DataWorks作为飞天大数据平台操作系统,对接各种大数据计算引擎,以all in one box的方式提供专业高效、安全可靠的全域智能大数据平台,高效率完成数据全链路研发流程,建设企业数据治理体系。
从2009年飞天大数据平台写下第一行代码开始,DataWorks历经10年发展,形成一套成熟的产品功能体系,满足企业数据中台搭建需求。在阿里巴巴内部,每天有数万数据/算法开发工程师正在使用DataWorks,现在仅需99元你就可以体验到DataWorks标准版的强大功能!

image.png

本次活动持续到2019年12月31日,购买任意Region的DataWorks增值版本-标准版,均能享受首月99元优惠活动,体验6大专属场景。活动结束后恢复原价2500元/月。

购买地址:
https://common-buy.aliyun.com/?spm=a2c0j.8205274.1252641.124455.5712154d23aYu2&commodityCode=dide_pre#/buy

功能场景介绍:

功能场景一:智能监控提高生产力,一种优雅的告警处理方式

场景描述:任务工作流节点多,每个任务监控规则多,每个监控规则变化多,人肉维护就像网络工程师理网线,恨不得一刀剪干净。

a94b5df668ab47f2be0ed5f0f8ff1418.png
]]> ES7、ES8、ES9、ES10新特性大盘点 Mon, 16 Dec 2019 05:35:02 +0800

作者: 前端工匠 公号 / 浪里行舟君

前言

从 ECMAScript 2016(ES7)开始,版本发布变得更加频繁,每年发布一个新版本,好在每次版本的更新内容并不多,本文会细说这些新特性,尽可能和旧知识相关联,帮你迅速上手这些特性。
image.png

ES7新特性

1.Array.prototype.includes()方法
在ES6中我们有String.prototype.includes()可以查询给定字符串是否包含一个字符,而在 ES7 中,我们在数组中也可以用 Array.prototype.includes 方法来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回true,否则返回false。

const arr = [1, 3, 5, 2, '8', NaN, -0]
arr.includes(1) // true
arr.includes(1, 2) // false 该方法的第二个参数表示搜索的起始位置,默认为0
arr.includes('1') // false
arr.includes(NaN) // true
arr.includes(+0) // true

在ES7之前想判断数组中是否包含一个元素,有如下两种方法,但都不如includes来得直观:

  • indexOf()
    indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
if (arr.indexOf(el) !== -1) {
  // ...
}

不过这种方法有两个缺点,一是不够语义化,要先找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。

[NaN].indexOf(NaN)// -1
  • find() 和 findIndex()

数组实例的find方法,用于找出第一个符合条件的数组成员。另外,这两个方法都可以发现NaN,弥补了数组的indexOf方法的不足。

[1, 4, -5, 10].find((n) => n < 0) // -5
[1, 5, 10, 15].findIndex(function(value) {
  return value > 9;
}) // 2
[NaN].findIndex(y => Object.is(NaN, y)) // 0

Array.prototype.includes()的支持情况:

2.求幂运算符**
在ES7中引入了指数运算符,具有与Math.pow()等效的计算结果

console.log(2**10);// 输出1024zhicc
console.log(Math.pow(2, 10)) // 输出1024

求幂运算符的支持情况:
image.png

ES8新特性

1.Async/Await
我们都知道使用Promise能很好地解决回调地狱的问题,但如果处理流程比较复杂的话,那么整段代码将充斥着then,语义化不明显,代码不能很好地表示执行流程,那有没有比Promise更优雅的异步方式呢?

假如有这样一个使用场景:需要先请求a链接,等返回信息之后,再请求b链接的另外一个资源。下面代码展示的是使用fetch来实现这样的需求,fetch被定义在window对象中,它返回的是一个Promise对象

fetch('https://blog.csdn.net/')
  .then(response => {
    console.log(response)
    return fetch('https://juejin.im/')
  })
  .then(response => {
    console.log(response)
  })
  .catch(error => {
    console.log(error)
  })

虽然上述代码可以实现这个需求,但语义化不明显,代码不能很好地表示执行流程。基于这个原因,ES8引入了async/await,这是JavaScript异步编程的一个重大改进,提供了在不阻塞主线程的情况下使用同步代码实现异步访问资源的能力,并且使得代码逻辑更加清晰。

async function foo () {
  try {
    let response1 = await fetch('https://blog.csdn.net/')
    console.log(response1)
    let response2 = await fetch('https://juejin.im/')
    console.log(response2)
  } catch (err) {
    console.error(err)
  }
}
foo()

通过上面代码,你会发现整个异步处理的逻辑都是使用同步代码的方式来实现的,而且还支持try catch来捕获异常,这感觉就在写同步代码,所以是非常符合人的线性思维的。需要强调的是,await 不可以脱离 async 单独使用,await 后面一定是Promise 对象,如果不是会自动包装成Promise对象。

根据MDN定义,async是一个通过异步执行并隐式返回Promise作为结果的函数

async function foo () {
  return '浪里行舟'
}
foo().then(val => {
  console.log(val) // 浪里行舟
})

上述代码,我们可以看到调用async 声明的foo 函数返回了一个Promise对象,等价于下面代码:

async function foo () {
  return Promise.resolve('浪里行舟')
}
foo().then(val => {
  console.log(val) // 浪里行舟
})

Async/Await的支持情况:
image.png

2.Object.values(),Object.entries()
ES5 引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。ES8引入了跟Object.keys配套的Object.values和Object.entries,作为遍历一个对象的补充手段,供for...of循环使用。

Object.values方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。

const obj = { foo: 'bar', baz: 42 };
Object.values(obj) // ["bar", 42]
const obj = { 100: 'a', 2: 'b', 7: 'c' };
Object.values(obj) // ["b", "c", "a"]

需要注意的是,如果属性名为数值的属性,是按照数值大小,从小到大遍历的,因此返回的顺序是b、c、a。

Object.entries()方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。这个特性我们后面介绍ES10的Object.fromEntries()还会再提到。

const obj = { foo: 'bar', baz: 42 };
Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]
const obj = { 10: 'xxx', 1: 'yyy', 3: 'zzz' };
Object.entries(obj); // [['1', 'yyy'], ['3', 'zzz'], ['10': 'xxx']]

Object.values()与Object.entries()兼容性一致,下面以Object.values()为例:
image.png

3.String padding
在ES8中String 新增了两个实例函数 String.prototype.padStart 和 String.prototype.padEnd,允许将空字符串或其他字符串添加到原始字符串的开头或结尾。我们先看下使用语法:

String.padStart(targetLength,[padString])
  • targetLength(必填):当前字符串需要填充到的目标长度。如果这个数值小于当前字符串的长度,则返回当前字符串本身。
  • padString(可选):填充字符串。如果字符串太长,使填充后的字符串长度超过了目标长度,则只保留最左侧的部分,其他部分会被截断,此参数的缺省值为 " "。
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'

有时候我们处理日期、金额的时候经常要格式化,这个特性就派上用场:

'12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

String padding的支持情况:
image.png

4.Object.getOwnPropertyDescriptors()
ES5的Object.getOwnPropertyDescriptor()方法会返回某个对象属性的描述对象(descriptor)。ES8 引入了Object.getOwnPropertyDescriptors()方法,返回指定对象所有自身属性(非继承属性)的描述对象。

const obj = {
  name: '浪里行舟',
  get bar () {
    return 'abc'
  }
}
console.log(Object.getOwnPropertyDescriptors(obj))

得到如下结果:
image.png
该方法的引入目的,主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。我们来看个例子:

const source = {
  set foo (value) {
    console.log(value)
  },
  get bar () {
    return '浪里行舟'
  }
}
const target1 = {}
Object.assign(target1, source)
console.log(Object.getOwnPropertyDescriptor(target1, 'foo'))

返回如下结果:
image.png

上面代码中,source对象的foo属性的值是一个赋值函数,Object.assign方法将这个属性拷贝给target1对象,结果该属性的值变成了undefined。这是因为Object.assign方法总是拷贝一个属性的值,而不会拷贝它背后的赋值方法或取值方法

这时Object.getOwnPropertyDescriptors()方法配合Object.defineProperties()方法,就可以实现正确拷贝。

const source = {
  set foo (value) {
    console.log(value)
  },
  get bar () {
    return '浪里行舟'
  }
}
const target2 = {}
Object.defineProperties(target2, Object.getOwnPropertyDescriptors(source))
console.log(Object.getOwnPropertyDescriptor(target2, 'foo'))

返回如下结果:
image.png

Object.getOwnPropertyDescriptors()的支持情况:
image.png

ES9新特性

1.for await of
for of方法能够遍历具有Symbol.iterator接口的同步迭代器数据,但是不能遍历异步迭代器。ES9新增的for await of可以用来遍历具有Symbol.asyncIterator方法的数据结构,也就是异步迭代器,且会等待前一个成员的状态改变后才会遍历到下一个成员,相当于async函数内部的await。现在我们有三个异步任务,想要实现依次输出结果,该如何实现呢?

// for of遍历
function Gen (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(time)
    }, time)
  })
}
async function test () {
  let arr = [Gen(2000), Gen(100), Gen(3000)]
  for (let item of arr) {
    console.log(Date.now(), item.then(console.log))
  }
}
test()

得到如下结果:
image.png

上述代码证实了for of方法不能遍历异步迭代器,得到的结果并不是我们所期待的,于是for await of就粉墨登场啦!

function Gen (time) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      resolve(time)
    }, time)
  })
}
async function test () {
  let arr = [Gen(2000), Gen(100), Gen(3000)]
  for await (let item of arr) {
    console.log(Date.now(), item)
  }
}
test()
// 1575536194608 2000
// 1575536194608 100
// 1575536195608 3000

使用for await of遍历时,会等待前一个Promise对象的状态改变后,再遍历到下一个成员。

异步迭代器的支持情况:
image.png

2.Object Rest Spread
ES6中添加的最意思的特性之一是spread操作符。你不仅可以用它替换cancat()和slice()方法,使数组的操作(复制、合并)更加简单,还可以在数组必须以拆解的方式作为函数参数的情况下,spread操作符也很实用。

const arr1 = [10, 20, 30];
const copy = [...arr1]; // 复制
console.log(copy);    // [10, 20, 30]
const arr2 = [40, 50];
const merge = [...arr1, ...arr2]; // 合并
console.log(merge);    // [10, 20, 30, 40, 50]
console.log(Math.max(...arr));    // 30 拆解

ES9通过向对象文本添加扩展属性进一步扩展了这种语法。他可以将一个对象的属性拷贝到另一个对象上,参考以下情形:

const input = {
  a: 1,
  b: 2,
  c: 1
}
const output = {
  ...input,
  c: 3
}
console.log(output) // {a: 1, b: 2, c: 3}

上面代码可以把 input 对象的数据都添加到 output 对象中,需要注意的是,如果存在相同的属性名,只有最后一个会生效

const input = {
  a: 1,
  b: 2
}
const output = {
  ...input,
  c: 3
}
input.a='浪里行舟'
console.log(input,output) // {a: "浪里行舟", b: 2} {a: 1, b: 2, c: 3}

上面例子中,修改input对象中的值,output并没有改变,说明扩展运算符拷贝一个对象(类似这样obj2 = {...obj1}),实现只是一个对象的浅拷贝。值得注意的是,如果属性的值是一个对象的话,该对象的引用会被拷贝:

const obj = {x: {y: 10}};
const copy1 = {...obj};    
const copy2 = {...obj}; 
obj.x.y='浪里行舟'
console.log(copy1,copy2) // x: {y: "浪里行舟"} x: {y: "浪里行舟"}
console.log(copy1.x === copy2.x);    // → true

copy1.x 和 copy2.x 指向同一个对象的引用,所以他们严格相等。

我们再来看下 Object rest 的示例:

const input = {
  a: 1,
  b: 2,
  c: 3
}
let { a, ...rest } = input
console.log(a, rest) // 1 {b: 2, c: 3}

当对象 key-value 不确定的时候,把必选的 key 赋值给变量,用一个变量收敛其他可选的 key 数据,这在之前是做不到的。注意,rest属性必须始终出现在对象的末尾,否则将抛出错误。

Rest与Spread兼容性一致,下列以spread为例:
image.png

3.Promise.prototype.finally()
Promise.prototype.finally() 方法返回一个Promise,在promise执行结束时,无论结果是fulfilled或者是rejected,在执行then()和catch()后,都会执行finally指定的回调函数。

fetch('https://www.google.com')
  .then((response) => {
    console.log(response.status);
  })
  .catch((error) => { 
    console.log(error);
  })
  .finally(() => { 
    document.querySelector('#spinner').style.display = 'none';
  });

无论操作是否成功,当您需要在操作完成后进行一些清理时,finally()方法就派上用场了。这为指定执行完promise后,无论结果是fulfilled还是rejected都需要执行的代码提供了一种方式,避免同样的语句需要在then()和catch()中各写一次的情况

Promise.prototype.finally()的支持情况:
image.png

4.新的正则表达式特性
ES9为正则表达式添加了四个新特性,进一步提高了JavaScript的字符串处理能力。这些特点如下:

  • s (dotAll) 标志
  • 命名捕获组
  • Lookbehind 后行断言
  • Unicode属性转义

(1)s(dotAll)flag
正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是有两个例外。一个是四个字节的 UTF-16 字符,这个可以用u修饰符解决;另一个是行终止符,如换行符(n)或回车符(r),这个可以通过ES9的s(dotAll)flag,在原正则表达式基础上添加s表示:

console.log(/foo.bar/.test('foonbar')) // false
console.log(/foo.bar/s.test('foonbar')) // true

那如何判断当前正则是否使用了 dotAll 模式呢?

const re = /foo.bar/s // Or, `const re = new RegExp('foo.bar', 's');`.
console.log(re.test('foonbar')) // true
console.log(re.dotAll) // true
console.log(re.flags) // 's'

(2)命名捕获组
在一些正则表达式模式中,使用数字进行匹配可能会令人混淆。例如,使用正则表达式/(d{4})-(d{2})-(d{2})/来匹配日期。因为美式英语中的日期表示法和英式英语中的日期表示法不同,所以很难区分哪一组表示日期,哪一组表示月份:

const re = /(d{4})-(d{2})-(d{2})/;
const match= re.exec('2019-01-01');
console.log(match[0]);    // → 2019-01-01
console.log(match[1]);    // → 2019
console.log(match[2]);    // → 01
console.log(match[3]);    // → 01

ES9引入了命名捕获组,允许为每一个组匹配指定一个名字,既便于阅读代码,又便于引用。

const re = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/;
const match = re.exec('2019-01-01');
console.log(match.groups);          // → {year: "2019", month: "01", day: "01"}
console.log(match.groups.year);     // → 2019
console.log(match.groups.month);    // → 01
console.log(match.groups.day);      // → 01

上面代码中,“命名捕获组”在圆括号内部,模式的头部添加“问号 + 尖括号 + 组名”(?),然后就可以在exec方法返回结果的groups属性上引用该组名。

命名捕获组也可以使用在replace()方法中,例如将日期转换为美国的 MM-DD-YYYY 格式:

const re = /(?<year>d{4})-(?<month>d{2})-(?<day>d{2})/
const usDate = '2018-04-30'.replace(re, '$<month>-$<day>-$<year>')
console.log(usDate) // 04-30-2018

(3)Lookbehind 后行断言
JavaScript 语言的正则表达式,只支持先行断言,不支持后行断言,先行断言我们可以简单理解为"先遇到一个条件,再判断后面是否满足",如下面例子:

let test = 'hello world'
console.log(test.match(/hello(?=sworld)/))
// ["hello", index: 0, input: "hello world", groups: undefined]

但有时我们想判断前面是 world 的 hello,这个代码是实现不了的。在 ES9 就支持这个后行断言了:

let test = 'world hello'
console.log(test.match(/(?<=worlds)hello/))
// ["hello", index: 6, input: "world hello", groups: undefined]

(?<…)是后行断言的符号,(?..)是先行断言的符号,然后结合 =(等于)、!(不等)、1(捕获匹配)。

(4)Unicode属性转义
ES2018 引入了一种新的类的写法p{...}和P{...},允许正则表达式匹配符合 Unicode 某种属性的所有字符。比如你可以使用p{Number}来匹配所有的Unicode数字,例如,假设你想匹配的Unicode字符㉛字符串:

const str = '㉛';
console.log(/d/u.test(str));    // → false
console.log(/p{Number}/u.test(str));     // → true

同样的,你可以使用p{Alphabetic}来匹配所有的Unicode单词字符:

const str = 'ض';
console.log(/p{Alphabetic}/u.test(str));     // → true
// the w shorthand cannot match ض
console.log(/w/u.test(str));    // → false

同样有一个负向的Unicode属性转义模板 P{...}

console.log(/P{Number}/u.test('㉛'));    // → false
console.log(/P{Number}/u.test('ض'));    // → true
console.log(/P{Alphabetic}/u.test('㉛'));    // → true
console.log(/P{Alphabetic}/u.test('ض'));    // → false

除了字母和数字之外,Unicode属性转义中还可以使用其他一些属性。

以上这几个特性的支持情况:
image.png

ES10新特性

1.Array.prototype.flat()
多维数组是一种常见的数据格式,特别是在进行数据检索的时候。将多维数组打平是个常见的需求。通常我们能够实现,但是不够优雅。

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。

newArray = arr.flat(depth) 
// depth是指定要提取嵌套数组的结构深度,默认值为 1

接下来我们看两个例子:

const numbers1 = [1, 2, [3, 4, [5, 6]]]
console.log(numbers1.flat())// [1, 2, 3, 4, [5, 6]]
const numbers2 = [1, 2, [3, 4, [5, 6]]]
console.log(numbers2.flat(2))// [1, 2, 3, 4, 5, 6]

上面两个例子说明flat 的参数没有设置,取默认值 1,也就是说只扁平化第一级;当 flat 的参数大于等于 2,返回值就是 [1, 2, 3, 4, 5, 6] 了。

Array.prototype.flat的支持情况:
image.png

2.Array.prototype.flatMap()
有了flat方法,那自然而然就有Array.prototype.flatMap方法,flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。从方法的名字上也可以看出来它包含两部分功能一个是 map,一个是 flat(深度为1)。

let arr = [1, 2, 3]
console.log(arr.map(item => [item * 2]).flat()) // [2, 4, 6]
console.log(arr.flatMap(item => [item * 2])) // [2, 4, 6]

实际上flatMap是综合了map和flat的操作,所以它也只能打平一层

Array.prototype.flatmap的支持情况:
image.png

3.Object.fromEntries()
Object.fromEntries 这个新的API实现了与 Object.entries 相反的操作。这使得根据对象的 entries 很容易得到 object。

const object = { x: 23, y:24 };
const entries = Object.entries(object); // [['x', 23], ['y', 24]]
const result = Object.fromEntries(entries); // { x: 23, y: 24 }

ES2017引入了Object.entries, 这个方法可以将对象转换为数组,这样对象就可以使用数组原型中的众多内置方法,比如map, filter、reduce,举个例子,我们想提取下列对象obj中所有value大于21的键值对,如何操作呢?

// ES10之前
const obj = {
  a: 21,
  b: 22,
  c: 23
}
console.log(Object.entries(obj)) // [['a',21],["b", 22],["c", 23]]
let arr = Object.entries(obj).filter(([a, b]) => b > 21) // [["b", 22],["c", 23]]
let obj1 = {}
for (let [name, age] of arr) {
  obj1[name] = age
}
console.log(obj1) // {b: 22, c: 23}

上例中得到了数组arr,想再次转化为对象,就需要手动写一些代码来处理,但是有了Object.fromEntries()就很容易实现

// 用Object.fromEntries()来实现
const obj = {
  a: 21,
  b: 22,
  c: 23
}
let res = Object.fromEntries(Object.entries(obj).filter(([a, b]) => b > 21))
console.log(111, res) // {b: 22, c: 23}

Object.fromEntries()的支持情况:
image.png

4.String.trimStart 和 String.trimEnd
移除开头和结尾的空格,之前我们用正则表达式来实现,现在ES10新增了两个新特性,让这变得更简单!

trimStart() 方法从字符串的开头删除空格,trimLeft()是此方法的别名。

let str = ' 前端工匠 '
console.log(str.length) // 6
str = str.trimStart()
console.log(str.length) // 5
let str1 = str.trim() // 清除前后的空格
console.log(str1.length) // 4
str.replace(/^s+/g, '') // 也可以用正则实现开头删除空格

trimEnd() 方法从一个字符串的右端移除空白字符,trimRight 是 trimEnd 的别名。

let str = ' 浪里行舟 '
console.log(str.length) // 6
str = str.trimEnd()
console.log(str.length) // 5
let str1 = str.trim() //清除前后的空格
console.log(str1.length) // 4
str.replace(/s+$/g, '') // 也可以用正则实现右端移除空白字符

String.trimStart和String.trimEnd 两者兼容性一致,下图以trimStart为例:
image.png

5.String.prototype.matchAll
如果一个正则表达式在字符串里面有多个匹配,现在一般使用g修饰符或y修饰符,在循环里面逐一取出。

function collectGroup1 (regExp, str) {
  const matches = []
  while (true) {
    const match = regExp.exec(str)
    if (match === null) break
    matches.push(match[1])
  }
  return matches
}
console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`))
// [ 'foo', 'bar', 'baz' ]

值得注意的是,如果没有修饰符 /g, .exec() 只返回第一个匹配。现在通过ES9的String.prototype.matchAll方法,可以一次性取出所有匹配。

function collectGroup1 (regExp, str) {
  let results = []
  for (const match of str.matchAll(regExp)) {
    results.push(match[1])
  }
  return results
}
console.log(collectGroup1(/"([^"]*)"/g, `"foo" and "bar" and "baz"`))
// ["foo", "bar", "baz"]

上面代码中,由于string.matchAll(regex)返回的是遍历器,所以可以用for...of循环取出。

String.prototype.matchAll的支持情况:
image.png

6.try…catch
在ES10中,try-catch语句中的参数变为了一个可选项。以前我们写catch语句时,必须传递一个异常参数。这就意味着,即便我们在catch里面根本不需要用到这个异常参数也必须将其传递进去

// ES10之前
try {
  // tryCode
} catch (err) {
  // catchCode
}

这里 err 是必须的参数,在 ES10 可以省略这个参数:

// ES10
try {
  console.log('Foobar')
} catch {
  console.error('Bar')
}

try…catch的支持情况:
image.png

7.BigInt
JavaScript 所有数字都保存成 64 位浮点数,这给数值的表示带来了两大限制。一是数值的精度只能到 53 个二进制位(相当于 16 个十进制位),大于这个范围的整数,JavaScript 是无法精确表示的,这使得 JavaScript 不适合进行科学和金融方面的精确计算。二是大于或等于2的1024次方的数值,JavaScript 无法表示,会返回Infinity。

// 超过 53 个二进制位的数值,无法保持精度
Math.pow(2, 53) === Math.pow(2, 53) + 1 // true
// 超过 2 的 1024 次方的数值,无法表示
Math.pow(2, 1024) // Infinity

现在ES10引入了一种新的数据类型 BigInt(大整数),来解决这个问题。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。

创建 BigInt 类型的值也非常简单,只需要在数字后面加上 n 即可。例如,123 变为 123n。也可以使用全局方法 BigInt(value) 转化,入参 value 为数字或数字字符串。

const aNumber = 111;
const aBigInt = BigInt(aNumber);
aBigInt === 111n // true
typeof aBigInt === 'bigint' // true
typeof 111 // "number"
typeof 111n // "bigint"

如果算上 BigInt,JavaScript 中原始类型就从 6 个变为了 7 个。

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Symbol (new in ECMAScript 2015)
  • BigInt (new in ECMAScript 2019)
    BigInt的支持情况:

image.png

8.Symbol.prototype.description
我们知道,Symbol 的描述只被存储在内部的 [[Description]],没有直接对外暴露,我们只有调用 Symbol 的 toString() 时才可以读取这个属性:

Symbol('desc').description;  // "desc"
Symbol('').description;      // ""
Symbol().description;        // undefined

Symbol.prototype.description的支持情况:
image.png

9.Function.prototype.toString()
ES2019中,Function.toString()发生了变化。之前执行这个方法时,得到的字符串是去空白符号的。而现在,得到的字符串呈现出原本源码的样子:

function sum(a, b) {
  return a + b;
}
console.log(sum.toString());
// function sum(a, b) {
//  return a + b;
// }

Function.prototype.toString()的支持情况:
image.png

]]>
大数据面前,统计学的价值在哪里 Mon, 16 Dec 2019 05:35:02 +0800 1 统计学对大数据的意义

很高兴有这样一个机会,我能与大家在这里做一些关于统计学与大数据的交流,与大家分享一些观点。
在讲大数据之前,我们首先来看看什么是数据。很长一段时间里,大家对数据的理解,可能只是停留在阿拉伯数字这个层面。近些年来,大家开始讲大数据。结果有人就开始好奇了:这个大数据和我们之前说的数据有什么关系呢?

阿拉伯数字是不是数据呢?当然是数据。大数据是不是数据呢?当然也还是数据。不过,现在我们对数据的理解要广泛得多了。凡是可以被数据化的信息载体,我们都可以认为是数据。比如说,我们接触的文本,包括平时看到的一些文字,现在我们都可以把它量化。我们看到的图片、视频和音频,现在也都可以量化。包括阿拉伯数字、文本、图片、视频和音频,我们都称之为数据。现在我们理解的数据,从来源上来说更加广泛了,从类型上说变得很复杂了。这些不同来源、类型复杂的数据组合在一起,达到一定的体量之后,就可以认为是一个大数据了。

现在我们来说一下统计学,统计学是什么呢?首先,从学科定位上说,统计学已经被列为一级学科了。这一点和数学、法学等都一样了。大不列颠百科全书对统计学有个定义,说这是一门收集数据、分析数据的科学和艺术。定义中提到统计学是一门科学,这个容易理解。那为什么说统计学是一门艺术呢?这个问题,就和我今天主要回答的一个问题很有关系。顺便说一句,现在美国很多高校的统计系,它并不设在理学院下面,而是设在艺术学院下面。

今天我主要回答一个问题:在大数据时代,我们究竟是否需要基于抽样的统计学?

有些人认为,现在计算机科学非常发达,可以收集海量的数据。为了特定的研究目的,我们现在甚至有能力通过计算机技术收集与特定的研究目的相关的全部数据。今天,基于抽样的统计学就没有那么重要了,甚至都不在被需要了。事实真的是这样吗?

2 统计学是一门收集数据的艺术

既然统计学被认为是一门收集数据、分析数据的科学和艺术。我们暂时不谈科学,先来看看统计学为什么被认为是一门收集数据的艺术。

我们来看第一个案例。这个案例是希望调查15个国家的国民的诚实情况。调查人员想要知道,哪些国家的国民最倾向于撒谎,哪些国家的国民很诚实。如果直接去问被调查的人员:“您是否撒过谎?”十之八九,是问不到真实答案的。如果被调查人员以前撒过谎,也不在乎多撒这个谎了。被调查人员可能出于不同的动机,不愿意给出真实答案。那么,调查数据怎么得来呢?这显然不是简单地通过计算机技术、通过某些爬虫软件就容易收集到适合研究目的相关数据的。
如何利用统计学方法来收集数据呢?这就需要统计学的智慧了。调查人员设计了两组实验。

调查人员先从每一个国家找1000人参与测试,15个国家一共找了15000人,找这么多不同国家的人来面对面调查,这是非常困难的,所以调查人员通过互联网找到了这15个国家共计15000人。两组实验都是在互联网上进行的。

在第一组中,他们先做了一个测试,请受调查者在家里抛硬币,硬币有正反两面,调查者事先规定,受调查者抛硬币之后要告诉我结果,如果硬币正面朝上,我就奖励你十块钱,如果反面朝上,我就不给你奖励。这个调查不需要提供你抛硬币的证据,只是由你告诉调查者,抛硬币的结果。这也就是说,受调查者有没有撒谎,只有他自己知道。

这个最后的结果,实际上调查者是有参照的。因为,每个国家有1000人参与测试。正常情况下,1000次抛硬币的结果,应该是500次左右正面朝上。某个国家参与实验的1000个人之中,如果有900个人声称自己抛出来的硬币正面朝上,甚至1000人声称抛出来硬币正面朝上。那么,很大概率就是其中有人撒谎了。这是第一组实验。

第一组的实验有价值,但是它也不一定能够全面反映真实的情况,所以调查人员还有第二组实验。

第二组实验,是要求受调查者回答五个问题。这五个问题在回答之前,需要受调查者承诺,他不能为了答题去查阅任何资料,不能去寻求任何帮助,也就是说,看了这五个问题之后,受调查者需要立即给出答案。调查者承诺,如果五个问题中,回答对了四个以上,就奖励给受访者十块钱,如果答对三个或者三个以下,就没有奖励。

而这五个问题中,其中有三个问题特别简单,类似于像1+1等于几这种问题。另外两个问题则非常生僻。如果受调查者不去查阅资料或咨询他人的话,基本是不太可能回答出来的。因此,如果有受调查者答对了这两道难题,十有八九就说明他违反了自己事先承诺的“不去查阅资料寻求帮助”,由此可以推论他在这件事情上不诚实。

然后统计人员通过这两组实验结果,互相验证。这两组数据收集的过程都非常恰当地体现了统计学在收集数据方面的智慧。

所以说,即使在大数据时代,不是说有了计算机,有了爬虫技术,我们就能收集到适合研究目的的所有数据。统计学是一个收集数据的艺术,针对特定的研究目的,设计非常漂亮的数据收集方案,就是一个非常艺术的收集数据的过程了

我们再举一个例子。这是最近美国麻省理工刚刚完成的一个实验,大致在2018年左右完成的,实验结果也公布出来了。目的是想了解大家目前的婚姻观念,100人受到邀请来到一个封闭的场所参与这个实验。参加实验时,每人都会被贴上一个编号。男的编号是单数一三五七九,女的编号是双数二四六八十,以此类推。参与实验的这100人不知道自己的编号,也不知道究竟有多少人参加了这次实验。换句话说,他们不知道参加这次实验的正好是50个男人和50个女人,受访者仅仅知道,这次实验有很多人参加。

在这里统计人员采取了一点小花招,就是当受访者进门的时候,把编号贴在受访者后背上,受访者知道自己有编号,但是不知道自己的编号是多少,不过他能够看到别人后背上的编号。实验规则说,允许100人中的任何两个人进行交谈,除了不能告诉对方他的后背编号是多少,其他话题都可以谈。

然后实验者把这100人带到一个很小的一个房间里,宣布给大家5分钟时间,在这5分钟内,大家自行配对,每人只能配一名异性。5分钟结束之后,如果配对成功了,两个人背后的数字加起来乘以十,就是两人能够拿到的奖金。也就是说,如果编号是100的那个女性找到了那个编号为99的男性,那么两人就可以拿到(100+99)×10的奖金,也就是1990美元,这笔钱已经很可观了。但是如果你是一个编号为2的女性,而你找到的是那个编号为1的男性,那么你俩只能得到(1+2)×10也就是30美元,你俩用这奖金一起吃顿饭都不一定够。但是5分钟之后,如果还没有配对成功的话,你就连一美分都拿不到。因此,参加者必须在5分钟之内,在一个很小的拥挤空间内,尽快找到愿意跟自己配对的那个人。而且在这个过程中,要尽可能让自己的奖金数额变得很大。

实验人员之所以把100人故意安排在非常拥挤的小房间内,就是考虑到,一方面要让大家能够很快速地看到一些人的编号,另一方面又能保证一个人不可能看到所有人的编号。在人挤人的情况下,有些编号是肯定看不到的。

3 实验开始了

一些人很快就发现,自己连续跟别人配对三四次,大家都拒绝他。这很可能说明,自己后背的编号数字不够大,别人不感兴趣。于是这其中就有人采取了应对策略,他跟别人讲,如果你愿意跟我配对的话,那我愿意把奖金全部给你,反正我数字也不大,所以我的钱不要了。还有人说,只要你这次跟我配对成功了,我们出去以后,我再单独请你吃顿饭。

另外还有一些人,虽然他不知道自己后背的编号,但是他发现有很多人过来找他,所以他很快就意识到,自己后背的编号很可能很大,但具体多大,他并不知道。而且要尽可能让两个人组合出来的数字变得很大。于是他很快就把眼前这批他能看到数字的人拒绝掉了,因为他理所当然地认为接下来肯定还有更大的编号,但是他并不知道最大的编号是多少,同时他还必须要在5分钟内快速决定跟谁配对。

这个实验的结果是,编号99的男性并没有与编号100的女性配对成功。那位编号100的女性,找到的是编号八十几的一位男性。那些数字在中间的人,大体都配对了跟自己差不多的另一个人。这个结果,很符合中国的一种传统思想,也就是门当户对。

我们现在来看这个实验的结果,它基本上跟中国男女婚姻观念的现实比较类似。比如说,实验者因为自己编号小,就让渡自己的奖金给对方甚至于承诺事后请对方吃饭,以求得成功配对,这个跟现实中“我的个人条件差一些,但是我父母同意我们两个结婚之后送给我们一套房子”的承诺是类似的。而且我们在生活中也发现,一些最优秀的男性女性,他们身边不乏追求者,但是他们并没有找到自己的“最佳匹配对象”。

这个数据的收集过程也是非常漂亮的。
数据并不是越多越好

统计本身是一门收集数据的科学,但是数据是不是越多越好呢?很难说。

历史上有一个非常有名的例子。大约500年之前,丹麦有一个天文学家叫第谷,他从当时的丹麦国王那里要了一笔钱,建了一个实验室。第谷天天去观察每颗行星的运动轨迹,并且每天记录下来。于是第谷观察了20年,记录了大量的数据。不过,这个数据太多了,第谷花了大量时间、精力来分析这个数据,但没有发现任何规律。

这时候,一个叫开普勒的人出现了。开普勒认为,第谷每天去观测,一年365天每一颗行星都会有365个数据,这样20年观测记录积累下来,要分析处理的数据就太多了,而且那个时候的数据分析只能依靠手工计算,这个处理工作量实在太大了。于是开普勒就说,能不能每年只给我一个数据,比如说你可以只告诉我每年的1月1日,地球在什么位置,土星在什么位置,太阳在什么位置,等等。这样20年的观测数据筛选之后,每一颗行星的数据就只有20个了。开普勒知道,地球每隔365天会回到同一个位置,然后他把地球的位置固定,再分析其他行星跟地球的相对位置。开普勒通过固定地球的位置,对其他行星位置20年的数据进行分析,就成功得到了其他行星的运行轨迹。此后开普勒就发现,如果地球位置不变的话,那么其他行星的20年运行轨迹画出来之后,这些行星都是围着太阳运转,运行轨迹都是椭圆形的。由此开普勒发现了行星运动的规律。

从这个天文学上的著名案例,我们可以看出来,数据太多可能会导致信息量变得巨大,反而增加寻找到规律的难度。从而需要通过科学的方法简化数据。

关于这方面的案例还有不少。比如说美国总统富兰克林·罗斯福。他是美国历史上唯一一位连任四届的总统。1932年的时候他第一次当总统,当时美国和许多国家正在遭受经济危机,罗斯福面临的压力也很大。因此到了1936年罗斯福想竞选自己的第二任总统的时候,美国许多人预测罗斯福很难连任。那一次,罗斯福的主要竞选对手是兰登。当时就有两个机构在预测总统选举结果,其中一个是《文学文摘》杂志,它在当时是一个非常有影响力的刊物,因为这个杂志此前几次对总统选举结果的预测都成功了。到了1936年美国总统选举的时候,文学文摘搞了一个大的调查统计,它调查了240万人。具体方式就是在杂志里面夹上关于总统选举的调查问卷,然后收集反馈。其实当时文学文摘调查的还不止240万人,还要更多,只不过最后收回来的有效问卷是240万份。正是根据这个调查结果,文学文摘宣布他们预测兰登将战胜罗斯福赢得大选。

而当时还有一个机构,准确地说是一个年轻人,叫盖洛普,他的预测结果跟文学文摘的预测正好相反。起初盖洛普做这类调查统计,是因为他的母亲要竞选众议员,他是给他母亲帮忙,于是就在经费不多的情况下做了对较小人群的相关调查,然后这个调查结果很成功,他母亲当上了众议员。接下来他就想调查一下,罗斯福和兰登谁会赢得1936年竞选。但是他比不了文学文摘的财大气粗,所以他只调查了5000个人,根据这5000人的调查结果,盖洛普预测罗斯福当选。
结果罗斯福果然成功连任总统,盖洛普的预测胜利了。

这个选举结果出来之后,对《文学文摘》杂志的声誉造成了巨大的冲击:毕竟文学文摘调查了240万人,最后却发布了一个错误的预测,而盖洛普只调查了5000人,发布的预测却是正确的。结果,文学文摘因为这个事情后来就关门倒闭了。而那个年轻人盖洛普,就此成立了一个民意调查公司,也就是现在的盖洛普咨询公司。

这是事情的结果。那么为什么调查了5000人的预测,要比调查240万人的结果更准确呢?我们先不说240万这种海量数据,它在规模变大以后会带来计算效率的下降,我们也不提这类海量收集数据会导致成本居高不下的问题。根本的原因,是当时文学文摘通过杂志夹带问卷进行调查的这种方式。因为当初问卷是夹在杂志中发放的,所以文学文摘收集来的240万份有效问卷,实际面对的都是订阅了这份期刊的用户。那么,当时什么样的家庭会订阅这样的杂志呢?一般来说都是家境比较好的家庭,所以,文学文摘虽然号称调查了240万人之多,但是它调查的主要群体,是当时美国国内相对而言有钱的那部分人。而穷人群体的意见,它这个调查实际并没有覆盖到。

数据的量多不一定就代表准确,收集来的数据质量好、有代表性,才有可能分析出准确的结果。

4 统计学是一门分析数据的艺术

前面举了一些例子,提醒我们需要非常小心地设计方案收集数据。数据收集上来之后,我们还要做数据分析。按照前面大不列颠百科全书的说法,统计学同样是一门分析数据的艺术。

讲到数据分析,在这里我只讲两个基本概念:相关与因果。为什么讲这两个概念呢?这是因为人们常常混淆这两个概念,常常会把相关关系误以为是因果关系。在许多科学研究和政策问题评价中,我们更关心因果关系。但是,当我们看到了某种形式的相关关系后,常常会误以为这就是我们追求的因果关系了。

比如说,在中世纪的欧洲,很多人相信,虱子对人的健康是有帮助的。这是因为当时人们发现,得病的人身上很少有虱子,而健康人的身上反而是有虱子的。这是长期的观察累积下来,形成的经验。在中世纪的欧洲,很长一段时间里人们都根据这个经验,得出这样一个因果推论:这个人身上有虱子,所以他身体健康,那个人身上没虱子,说明他身体不健康。

当时,人们确实观察到虱子的存在与否跟人是否健康构成了相关关系,但是,这是因果关系吗?有了温度计以后,人们就发现了,这不是真正意义上的因果关系:因为虱子对人的体温非常敏感,它只能在一个很小的温度区间范围生存下来。而人体一旦生病的话,很多时候会出现发烧症状。人体一发烧,温度变化,虱子就无法适应发烧时候的热度,于是跑掉了。如果我们只停留在观察到健康与否和虱子多寡之间存在关系,那实际只是相关关系,而不是因果关系。与之类似的例子还有很多,比如说,我们看到每年冰淇淋销量增加的同时,各地不幸溺亡的人数也在增加。那么这两件事情是不是构成因果关系呢?常识告诉我们,肯定不是。其实是因为每年气温升高之后,游泳的人可能就多了起来了,随之溺亡人数也就相应增加了。而同样是因为气温升高,冰淇淋的销量也会增加。

也就是说,如果我们观察到一个因素出现了一点点变化,另外一个因素也会随着跟它变化,它们之间可能就有相关关系,但是这种相关关系,并不意味着这两个因素构成因果关系。

如何判断因果关系呢,这就需要我们非常小心,而且要非常艺术地做数据分析了,我们最终还是要回到统计学上来。

这里,我们举一个历史上的疾病案例,这就是小儿麻痹症,也就是脊髓灰质炎。现在大家看到的小儿麻痹症病例比较少,因为现在有相应的疫苗。历史上,脊髓灰质炎曾经是一个让人非常害怕的疾病。

在20世纪50年代,当时美国一所大学的实验室,做出了一种针对这个疾病的疫苗,已经证明它在实验室条件下能够产生有效的抗体。但是他们不知道,如果应用到实际生活中的大规模实验,这个疫苗还会不会有效。所以当时美国政府部门就决定要做实验,这个时间大致在1954年。因为当时脊髓灰质炎的患者主要是孩子,所以当时的实验人群定为小学一二三年级的学生。怎么做实验才能够真正说明疫苗是否有效呢?为了确保统计结果最终反映真实的因果关系,当时提出了五套实验方案。

第一套方案是,因为1953年之前是没有这个疫苗的,所以就从1954年开始,给所有的一二三年级小学生接种疫苗,最后再来看一下,1954年的发病率,跟1953年相比,会不会有差别。这个方案是个办法,但是它有问题,因为之前每一年的脊髓灰质炎发病率的差别比较大。比如说1951年全美可能有3万名脊髓灰质炎患者,1952年则有6万名,而1953年又可能缩减到不足4万名。这个脊髓灰质炎每年发病率的波动都比较大,万一到时候实验结果是3万名到4万名之间,如何判断这个结果是随机变化的,还是疫苗发生了作用?

第二个方案则提出要按照地区来做。比如,在纽约地区,就给一二三年级小学生们全部接种疫苗,而在芝加哥地区的就全部不接种疫苗,然后来统计,纽约和芝加哥这两个地区的脊髓灰质炎发病情况。这个方案后来发现也不行。因为脊髓灰质炎本身就是传染病,一个地区可能流行这个疾病了,而另外一个地区就可能没流行,那么这两个地区的数据看起来就会有差异,但是这不是疫苗的效果,不具有可比性。

于是就有人提出了第三个方案。因为当时这个疫苗接种,谁也不知道有没有副作用,因此是有一定风险的。所以这个方案就提出,让接种疫苗的孩子们的父母来自行选择。有的家长选择给孩子接种疫苗,有的就不选择接种,这样同一批孩子就会出现不同的对照。但是这么做,也有问题。因为当时人们已经发现,脊髓灰质炎的患者一般来自于家境比较好的家庭。这是因为,那些家庭经济状况比较差的家庭,因为生活条件差,卫生条件不好,可能一个人很早就接触过脊髓灰质炎的病毒了,甚至很可能在刚刚出生的时候就接触了脊髓灰质炎的病毒,但是刚出生的婴儿是有母体的免疫力的,婴儿凭借母体的免疫力,接触这个病毒之后能够产生抗体,反而不会得病。当时的这类数据情况已经展现了这种现象。如果采用自愿接种的方式,那些经济状况比较好的家庭,往往愿意让自己的小孩去接种,而经济状况不好的家庭由于经费原因,同时也知道自己这个阶层染病率稍微低一些,他可能就不愿意接种了。这样就造成了对实验结果的干扰,你无法判断到底是疫苗有效还是经济原因导致的不同结果。

然后是第四个方案。有人提出,只让二年级的学生接种,而一年级和三年级学生不接种。之后再比较接种的跟不接种的学生之间的区别,看他们的发病率会不会有差别。这个方案是当时的一个脊髓灰质炎防治委员会提出的方案。这个方案同样行不通,第一,它同样无法避开接种孩子家庭贫富差距导致的患病概率差异。第二,脊髓灰质炎是一种传染疾病,人群的年龄是对这种传染有影响的,一、二、三年级的学生年龄层次有差别,可能就会导致各个年级学生得病概率的差异。此外这个方案还有第三个重大缺陷,那就是可能会对医生形成心理上的诱导。如果按照这个方案执行下去,医生们就是知道的,一、三年学生没有接种疫苗,而二年级同学中有部分同学接种了疫苗。当时脊髓灰质炎的诊断还不太容易,如果医生已经知道了这个疫苗接种方案,而且也提前知道这个疫苗在实验室阶段是管用的,那么医生在面对一年级学生时,一旦这个疾病还无法确诊,那么这个医生就很可能根据“一年级学生没有接种疫苗”“疫苗是有效的”这两个提前的认知,就直接诊断这名一年级学生得了脊髓灰质炎。而且这种区别对待的方案,接种的学生本身心理也会受到影响的。

当时还有第五个方案,也就是最终执行并被采纳了调查结果的方案。这个方案具体来说,就是在征得学生家长同意之后,仍旧会告诉家长:你即使同意接种疫苗,我给你家孩子接种的,也不一定是疫苗,而是一种看起来跟疫苗一模一样的安慰剂,没什么副作用也没有什么效果。因为这个安慰剂跟疫苗长得一样,所以医生和学生都不知道到底接种的是疫苗还是普通的安慰剂,但是疫苗提供方是知道的,它对每一个药品都加了编号,因此疫苗提供方知道哪些是安慰剂,哪些是疫苗。通过这样的方式,实验室实现了随机的方式接种疫苗,而且无论家境好坏,这个接种疫苗都是随机的。同时医生们也不知道,到底是哪一些小孩接种了疫苗。这就规避了年龄、经济条件等各种扰动,有助于确定脊髓灰质炎与疫苗之间真正的因果关系。
1954年,这个实验大约有74万名小学生参与。最终的实验结果是,如果接种疫苗,孩子罹患脊髓灰质炎的概率大约是十万分之28,如果不接种疫苗,患病概率大约是十万分之77,二者相差一倍多。之后又经过各种努力,脊髓灰质炎疫苗在美国获得了通过。

许多科学结论、政策评价都依赖于因果分析而不是相关分析。统计学能够帮助我们证明那些我们所需要的因果关系。很多时候,真正的因果关系,不能简单地建立在相关关系的基础之上。还有很多科学问题,仍需要我们去发现真正的因果关系,这正是统计学可以提供数据收集以及分析方案的地方,也是统计学的魅力所在。

来源:光明网-《光明日报》《光明日报》( 2019年03月30日 10版)

作者:朱利平 教授,作者系中国人民大学统计与大数据研究院副院长、博士生导师,中国人民大学“杰出学者”特聘教授

]]>
解密淘宝推荐实战,打造 “比你还懂你” 的个性化APP Mon, 16 Dec 2019 05:35:02 +0800 以下内容根据演讲视频以及PPT整理而成。

手淘推荐简介

手淘推荐的快速发展源于2014年阿里“All in 无线”战略的提出。在无线时代,手机屏幕变小,用户无法同时浏览多个视窗,交互变得困难,在这样的情况下,手淘借助个性化推荐来提升用户在无线端的浏览效率。经过近几年的发展,推荐已经成为手淘上面最大的流量入口,每天服务数亿用户,成交量仅次于搜索,成为了手淘成交量第二大入口。
image.png

今天的推荐不仅仅包含商品,还包含了直播、店铺、品牌、UGC,PGC等,手淘整体的推荐物种十分丰富,目前手淘的整体推荐场景有上百个。推荐与搜索不同,搜索中用户可以主动表达需求,推荐很少和用户主动互动,或者和用户互动的是后台的算法模型,所以推荐从诞生开始就是大数据+AI的产品。

手淘推荐特点

相比于其他推荐产品,手淘推荐也有自身的如下特点:
1.购物决策周期:手淘推荐的主要价值是挖掘用户潜在需求和帮助用户购买决策,用户的购物决策周期比较长,需要经历需求发现,信息获取,商品对比和下单决策的过程,电商推荐系统需要根据用户购物状态来做出推荐决策。
2.时效性:我们一生会在淘宝购买很多东西,但是这些需求通常是低频和只在很短的时间窗口有效,比如手机1~2才买一次但决策周期只有几小时到几天,因此需要非常强的时效性,需要快速地感知和捕获用户的实时兴趣和探索未知需求,因此,推荐诞生之初就与Flink、Blink实时计算关系非常紧密。
3.人群结构复杂:手淘中会存在未登录用户、新用户、低活用户以及流式用户等,因此需要制定差异化的推荐策略,并且针对性地优推荐模型。
4.多场景:手淘推荐覆盖了几百个场景,每个场景都独立进行优化显然是不可能的,而且每个场景的条件不同,因此超参也必然不同,无法依靠人工逐个优化场景模型的参数,因此需要在模型之间进行迁移学习以及自动的超参学习等,通过头部场景的迁移学习来服务好尾部场景。
5.多目标和多物种
image.png

推荐技术框架

如下图所示的是手淘推荐的技术框架。2019年双11,整个阿里巴巴的业务全部实现上云,因此手淘推荐的技术架构也是生长在云上的。推荐的A-B-C包括了推荐算法和模型、原始日志和基于日志加工出来的特征和离在线计算及服务能力,比如向量检索、机器学习平台、在线排序服务等。除了云,今年我们通过把深度学习模型部署到了端上,实现了云和端的协同计算。
image.png

接下来将主要围绕数据、基础设施以及算法模型进行介绍。

数据-基础数据

手淘的推荐数据主要包括几种,即描述型数据比如用户画像,关系数据比如二部图或稀疏矩阵,行为序列和图数据等。基于用户行为序列推荐模型在手淘商品推荐应用最为广泛,图模型则是近两年发展较快的模型,因为序列通常只适合于同构的数据,而在手淘里面,用户的行为有很多种,比如看视频、搜索关键词等,通过graph embedding 等技术可以将异构图数据对齐或做特征融合。
image.png

数据-样本

数据样本主要包含两部分元素,label和特征。label一般在手淘推荐中有几类,比如曝光、点击、成交以及加购等。特征则比较多了,比如用户自己的特征、用户上下文特征、商品本身特征以及两两组合特征等。根据用户的特征和行为日志做Join就形成样本表,这些表格存储的时候就是按照稀疏矩阵方式进行存储,一般而言是按天或者按照时间片段形成表格,样本生成需要占用很大一部分离线计算资源。
image.png

离线计算-计算模式

离线计算主要有三种模式,即批处理、流处理和交互式查询。批处理中比较典型的就是MapReduce,其特点是延迟高但并行能力强,适合数据离线处理,比如小时/天级别特征计算,样本处理和离线报表等。流计算的特点是数据延迟低,因此非常适合进行事件处理,比如用户实时点击,实时偏好预测,在线学习的实时样本处理和实时报表等。交互式查询则主要用于进行数据可视化和报表分析。
image.png

离线计算-模型训练
模型训练也有三种主要的模式,即全量学习、增量学习和在线学习。全量学习这里是指模型初始化从0开始学习,如果日志规模比较小,模型简单并不需要频繁更新时,可以基于全量日志定期训练和更新模型,但当日志和模型参数规模较大时,全量学习要消耗大量计算资源和数天时间,性价比很低,这时通常会在历史模型参数基础上做增量学习,用小时/天日志增量训练模型和部署到线上,降低资源消耗和较高的模型更新频率。如果模型时效性非常强需要用秒/分钟级别样本实时更新模型,这是就需要用到在线学习,在学习和增量学习主要差别是依赖的数据流不一样,在线学习通常需要通过流式计算框架实时产出样本。
image.png

离线计算-训练效率

因为机器资源总是不够的,训练优化是如何用更快的速度,更少的计算和更少的数据训练出更好的模型,这里为大家提供一些加速训练的方式:

1.热启动:模型需要不断升级和优化,比如新加特征或修改网络结构,由于被修复部分模型参数是初始值,模型需要重新训练,热启动就是在模型参数只有部分修改时如何用少量的样本让模型收敛。
2.迁移学习:前面提到手淘推荐的场景非常多,而某些场景的日志非常少,因此无法实现大规模模型的训练,这是可以基于样本较多的大场景做迁移学习。
3.蒸馏学习:手淘用来做级联模型学习,比如精排模型特征更多模型更加精准,通过精排和粗排特征蒸馏,提升粗排模型精度,除此之外也可以用来做模型性能优化;
4.低精度、量化和剪枝:随着模型越来越复杂,在线存储和预测成本也在成倍增加,通过这些方式降低模型存储空间和预测速度,另外是端上模型通常对大小有强要求;
image.png

离线计算-端到端闭环

因为手淘推荐日志很大,特征来源很复杂,离线和在线的细微变动都可能导致样本出错或离线在线特征/模型不一致,影响迭代效率甚至造成生产故障,我们的解决办法是做一个端到端的开发框架,开发框架对日志,特征和样本做抽象,减低人工开发成本和出错的可能,并在框架嵌套debug 和数据可视化工具,提高问题排查效率。目前手淘搜索推荐已经基本上做到了从最原始日志的收集、到特征抽取以及训练模型的验证、模型的发布,再到线上部署以及实时日志的收集形成整体的闭环,提升了整体模型的迭代效率。
image.png

云和端

随着5G和IOT的发展数据会出现爆炸式的膨胀,将数据放在云上集中存储和计算,这样做是否是一个最合理的方式呢?一些数据和计算能否放在端上来做?端上相对于云上而言,还有几个较大的优势,首先延时低,其次是隐式性,各个国家对于隐私的保护要求越来越严厉,因此需要考虑当数据不能发送到云端的时候如何做个性化推荐。
image.png

云和端协同计算

在云和端协同计算方面,阿里巴巴已经做了大量的尝试,比如云和端如何实现协同推理,这里包括几个部分,比如手机端上拥有更加丰富的用户行为如用户滑屏速度、曝光窗口时长以及交互时长等,因此第一步是端上的用户行为模式感知的模型。第二步就是在端上决策,比如预测用户何时会离开APP,并在用户离开之前改变一些策略提高用户的浏览深度。此外,手淘还在端上做了一个小型推荐系统,因为目前云上推荐都是一次性给多个结果比如20多个,而手机一次仅能够浏览4到6个推荐结果,当浏览完这20个结果之前,无论用户在手机端做出什么样的操作,都不会向云端发起一次新的请求,因此推荐结果是不变化的,这样就使得个性化推荐的时效性比较差。现在的做法就是一次性将100个结果放在手机端上去,手机端不断地进行推理并且更新推荐结果,这样使得推荐能够具有非常强的时效性,如果这些任务全部放在云端来做,那么就需要增加成千上万台机器。
image.png

除了推理之外,还有云和端的协同训练。如果想要实现个人的隐私保护,云和端协同训练是非常重要的,只有这样才能够不将用户的所有原始数据全部加载到云上,大部分训练都在手机端完成,在云端只是处理一些不可解释的用户向量,从而更好地保护用户的隐私数据。
image.png

召回技术-动态实时多兴趣表达(MIND)

早些年大家在做推荐协同过滤可能使用Item2Vec召回、标签召回等,比如像Item2Vec召回而言,确实比较简单,而且时效性非常好,在很长一段时间内主导了推荐技术发展的进程,后续才诞生了矩阵分解等。但是Item2Vec召回存在很大的问题,如果商品的曝光点不多其实是很难被推荐出来的,因此推荐的基本上都是热门的Item。其次Item2Vec召回认为每个点击都是独立的,缺少对于用户的全局认知,此时需要做的是就是将用户的行为和标签进行全局感知并做召回。基于这样的出发点,我们提出了基于行为序列的召回模型,但这种方式存在的问题就是用户的兴趣不会聚焦在同一个点,单个向量召回通常只能召回一个类目或者兴趣点,因此如何通过深度学习做用户的多需求表达等都是挑战。这样的问题,阿里巴巴已经解决了,并且将论文发表在CIKM 2019上面。现在,淘宝所使用的是在线多向量化并行召回。
image.png

CTR模型

手淘推荐的CTR模型也经历了几个重要的变革,第一个模型是FTRL+LR,其优点是模型简单,能够支持千亿级别特征。第二个模型是XNN,对LR离散特征做embedding,并引入多层神经网络,由于引入新的参数,模型学习能力更强。第三个模型是Self-attention CTR,也就是基于图和用户行为序列实现的。
image.png

推荐序列优化-生成式推荐

推荐一般都是基于打分的,打完分之后在做一个贪心排序和打散,这样的做法得到的结果其实并不是最优的,因为这样做并没有考虑结果与结果之间的依赖性,使用贪心算法得到的结果并不是最优的。推荐本质上应该是对于集合而不是序列的优化,因此手淘推荐是用的是生成式排序模型。更多可以参考我们在KDD 2019发表的论文。
image.png
多目标均衡优化

在推荐时,大家往往会遇到多目标均衡问题,比如商品推荐的浏览深度,点击和成交,由于目标量纲不一致,不存在全局唯一最优解,需要同时优化多个目标或在多个目标之间做合理取舍,对此我们提出了基于帕累托的多目标优化排序模型。更多可参考我们发表在RecSys 2019的文章。
image.png



]]>
梅花创投吴世春:未来十年,依然是中国创业者的黄金时期 Mon, 16 Dec 2019 05:35:02 +0800

image.png

12月11日,2019年度CEO峰会暨猎云网创投颁奖盛典在北京望京凯悦酒店隆重举行,近百位知名资本大咖,独角兽创始人、创业风云人物及近千位投资人与创业者共聚“新势力·2019年度CEO峰会暨猎云网创投颁奖盛典”。

峰会上,梅花创投创始合伙人吴世春以《寒冬是机遇的起点》为主题分享了自己的观点。

吴世春认为,每十年是中国经济周期的一个循环,对比发达经济体,未来最好的投资机会就在中国。未来十年,依然是中国创业者的黄金时期。

总结过去的两个大周期,1999-2008年,互联网把中国所有产业重做了一遍,诞生了BAT;2009-2018年,所有产业被移动互联网重做一遍;现在,在市场陷入谷底时,吴世春认为,这恰恰是机遇诞生的机会点,人工智能、5G、智能制造,可以把很多行业再重做一遍。

因此在他看来,每一个周期都给了有梦想、有野心的年轻人来改变运气的机会。“在中国,阶层固化与阶级板结是一个伪命题,中国可以不断出现年轻人向上的通道。”

梅花创投成立于2014年5月,专注在新经济领域的投资,目前管理约30亿人民币基金,投资项目超300个。在创立梅花创投之前,吴世春作为天使投资人,曾投资大掌门,创造了1500倍回报的奇迹,投资趣店也获得了超过1000倍回报。作为资深连续创业者,吴世春被称为“最懂创业者”的天使投资人。

阅人无数,吴世春总结道,优秀的创业者要有比较强的战略能力,不要用战术上的勤奋掩盖战略上的懒惰。具体来看,创业者应当拥有四种战略能力。

第一,战略思维能力。要使用第一性原理去看待事物的本质,使用终局性思维去看待事物的发展。同时,要站在未来看现在,战略不解决当前问题,但能解决未来的问题。“如果一个企业家没有长期的战略,很难走得远,很难支持一家企业做到5-10年。为什么阿里巴巴自己要成为102年的公司,因为生存永远是企业第一要务,不管企业大还是小,最大的命题是生存。”

第二,战略机会把握能力。吴世春认为,战略机会有几种,一种是趋势性的机会,比如消费升级、5G带来的趋势性机会;第二种机会是搭便车能力;第三种机会是价值洼地,创始人应该抓住价值洼地,并投入100%的精力。

第三,战略布局能力。吴世春建议,创始人要动态地看待各种积极因素的内在关联,在人脉和链接上多下功夫。“链接本身就是价值,在对的人身上吃亏,本身就是价值。”

第四,战略耐心能力。“战略大部分都是做取舍,最高的境界是舍九取一。”吴世春认为,创始人应分清楚长期收益和短期收益,在下风期时不要盲动,不要浪费弹药,一旦遇到人生的重大机会,要等待又长又湿的雪坡滚下去,获得最大收益。

此次盛典上,猎云网将通过六个版块分享创业者和投资人在智能制造、文娱、零售、医疗、教育、汽车等领域的启发性的观点和行业前瞻,围绕多个维度,分享科技和产业前沿观点,探讨创新潮流趋势、把握未来新方向。

以下为吴世春分享实录,猎云网整理删改:

吴世春:很高兴来到猎云网新势力的盛典,跟大家做一个分享。

梅花创投成立于2014年5月,宗旨是帮助聪明的年轻人成为伟大的企业家。5年来,梅花创投投资项目超300个,很多的项目已经走到独角兽的级别,明年有8-10家可以上市。

很多人说现在是寒冬,我认为未来最好的机会还是在中国。因为按照过去40年来看,每个十年就是一个周期,每一个周期都会有寒冬,都会有爆发期。在每一个周期,都会诞生很多优秀的企业,像BAT诞生在1998-2001年,后来TMD是诞生在2008-2011年之间。每一个周期,我觉得都是厚积薄发的机遇。对比现在的美日欧,中国还是有很大的发展空间,所以最好的投资机会还是在中国。

从上一个十年来看,从互联网切入到移动互联网,这里面有很多移动互联网的原生性创业者能够做的很好,像头条、美团。但是新的周期,我们又看到可以从原来的ToC市场枯竭,我们逐渐转向2B产业互联网,甚至像5G、人工智能基础性设施完善的话,会带来大规模应用性的创新。

我上一个周期抓住了机会,从一名创业者转变为一个投资人,这个周期我们希望准备好弹药,投入更多在5G、智能制造、人工智能方面。

总结过去两个大周期的每十年一个周期的变化,1999-2008年,互联网把中国所有产业重做了一遍,诞生了BAT这样的公司;2009-2018年,又把所有产业重做一遍;现在又是谷底的时候,恰恰是很多机遇孕育诞生的机会点,像人工智能、5G、智能制造,我觉得又会把很多行业重做一遍。每一个周期都给了有梦想、有野心的年轻人来改变运气的机会。一个公平的社会应该不断地被年轻人创造与再分配,在中国,阶层固化与阶级板结是一个伪命题,中国还是可以不断出现给年轻人向上的通道。

中国的模式,其实除了中国是一个比较垂直化的经济体系,有很多下沉的机会,中国的模式也可以向海外复制。我们其实在海外也投了很多,比如说中国在印度的趣店,还有抖音的模式,我们都投了。

中国可能不是一个原创性创新最多的地方,但是中国是一个全世界最好的应用性创新最好的地方,所以像类似于5G、人工智能、智能制造应用性创新,最大规模的应用性创新会在中国诞生。像大数据、SaaS,企业云化与SaaS化,我认为也是未来非常大的趋势。这个趋势,中国也是可以带来很多的投资机会。

对于这个好的创业时代,我们需要投到优秀的创业者。我们希望优秀的创业者,能够有比较强的战略能力,不要用战术上的勤奋掩盖战略上的懒惰。对我们来讲,企业如果竞争获胜,最重要的是在战略上获胜。

我们把战略能力分成四种能力:

第一,战略思维能力。创业就是一场未知世界里面的冒险,很多新问题都没有答案。所以,我们希望创业者可以用第一性原理看待事物本质,用终局性思维来看待事物的发展。

今年看到很多的赛道,比如说项目做到可能三四年,甚至融到B轮、C轮之后,还倒下了。因为很多企业一开始模式就不成立,比如说负毛利的公司,需要靠大量的烧钱,来拉新的公司,一旦来资本的资金有缺口,他们很快难以为继。所以需要站在未来看现在,战略不解决当前的问题,解决的是未来的问题。

如果一个企业家没有长期的战略,是很难走得远,只看到未来三个月、半年的时间,是很难支持一家企业做到5-10年。为什么阿里巴巴自己要成为102年的公司,因为生存永远是企业第一要务,不管企业大还是小,最大的命题是生存。

第二,战略机会把握能力。战略机会有几种,一种是趋势性的机会,比如说像消费升级,类似于像5G带来趋势性的机会。第二种机会是搭便车能力,比如说趣店跟蚂蚁金服的合作,滴滴抓住微信支付推广的便车。还有一种机会是价值洼地,每一种媒体早期都是一种流量红利到价值洼地。所以,对于很多的创始人来讲,应该把握类似这样的价值洼地。对于一个创业者来讲,一生会有4-5次战略性机会,碰到大的机会,100%的精力来投入,以最高的方式把控住。

第三,战略布局能力。创业者动态看待各种积极因素的内在关联,在人脉和连接上多下功夫。你按天衡量自己的收益,你相信的是上天的命运安排,你按照按年衡量收益的话,你相信的是你的天赋与才华,你按照10年来衡量自己的才华,相信的是人脉。链接本身就是价值,很多创始人应该在对的人吃亏,这本身就是价值。战略布局的成本最低,收获最大。很多创始人要理解这一点,要很早开始进行战略性的布局。

第四,战略耐心。因为战略大部分都是做取舍,我觉得最高的境界就是抉择与取舍。对于创始人来讲有短期影响,也有媒体的干预,可能今天来一个区块链,明天来发币,这会给很多人带来诱惑,但是知道自己价值在什么地方,知道自己能够做到什么,边界在哪儿,很重要。所以,要能够分清楚长期收益、短期收益,下行期的时候不要盲目,不要浪费弹药。一旦遇到人生重大的机会,要等待又长又湿的雪坡滚下去,你才有大的收益,就像巴菲特说的这句话。

创业难是一个常规的现实,我觉得接受这个现实并且接着干的很少,我们不能总是强调宏观上的困难。对每个人来讲,困难都是一样的,困难是每个创业者的磨刀石。所以,认识困难,接受困难,并且感恩困难。只有这样的创业者,才可以从不断的困难当中得到学习,我们强调事上练,难上得,你愿意接受多大的困难,愿意接受多大的挑战,这是很多成功之前的前提。

所以我们认为困难的另外一面是机会,包括现在的资本寒冬,背面也是机会,当别人也不好融资的时候,也许是自己冒头的机会。机会的反面是陷阱。看到过去几年千团大战,还是单车颜色不够用了,都是毁灭大财富,很多投资人钱浪费掉了,很多创业者的精力也浪费掉了。

所以,一个创业者应该深度思考,做时间的朋友。我觉得对未来想的越深刻,对未来越有信心,对当下越有耐心,追求长期利益,拒绝短期诱惑。只要你在创业这条赛道上不站错队、不错过队、不掉队,就有机会。我们很多创业者经历过很多的失败,没有人可以顺风顺水成功。比如说趣店、小牛电动,前面经历了很多轮的失败,最后迎来了自己成功的那一刻。

如果你看过去的寒冬期,每一次寒冬期都是诞生大公司的机会,我们觉得这两三年也是诞生接下来十年里面的引领风云企业的机会。所以梅花坚定地扶持与服务年轻的聪明人,帮助他们成为伟大的企业家。

丘吉尔说,永远不要浪费一场好危机,现在的危机正是年轻人机遇的起点,希望大家可以利用好这场危机。谢谢大家!

转自创头条,原文链接为:http://www.ctoutiao.com/2563012.html

声明:以上内容来自于网络,如有侵权,请联系删除

]]>
蚂蚁金服联合IDC发布《中国金融级移动应用开发平台白皮书》 金融机构加速执行移动优先战略 Mon, 16 Dec 2019 05:35:02 +0800 ad5d75088d8f43739ab98bd0ebc34a47

移动端成金融机构零售转型的重要载体,战略地位日益凸显
《白皮书》认为,随着IT领域的新兴技术⾰命,企业数字化转型浪潮正在不断重塑各⾏各业的运⾏格局和发展风貌。以金融业为例,利率市场化、金融脱媒以及互联⽹跨界竞争等多重因素动摇了传统金融机构的盈利基础,使中国金融市场正在自内而外地发生巨大变革。

在此背景下,金融机构纷纷开启零售转型战略,以金融科技创新为抓手,为企业发展赋能。移动端作为金融机构重要的对外渠道之一,已成为零售转型的重要载体。利用优质的移动端设计提供精细化服务,吸引更多的个人客户长期驻留,是金融机构应对市场挑战、实现长期发展的必然选择,移动优先战略成为金融机构面向未来的发展共识。

《白皮书》显示,在⾦融科技的推动下,⼀⼤批传统线下业务通过技术创新转移⾄线上运营,⽤⼾不再受到银⾏服务时间和空间的限制,随时随地的享受移动端带来的便捷性,⽤⼾体验获得了⾰命性提升;保险公司⼤⼒拓展移动渠道,通过保险移动展业,以更加便捷⾼效地⽅式实现全业务触点的销售及管理,降低获客成本;证券企业则重点利⽤新技术提升信息和数据处理的时效性,满⾜客⼾对移动端⾏情资讯的传递和承载需求。

一站式移动开发平台mPaaS,助力金融机构移动优先战略落地
《白皮书》指出,金融业务的移动化、场景化、智能化趋势,推动金融移动应用需求的爆发性增长,对金融机构围绕移动端的业务开发和保障能力提出极大挑战。金融机构迫切需要引入新一代移动设计开发思想,利用先进的移动应用开发平台实现在开发、运维、管理以及快速迭代方面的一系列变革。

蚂蚁金服移动金融技术总监祁晓龙认为,金融级移动应用开发平台应具备统一的开发框架,拥有强大的技术整合和集成能力,有助于打造基于移动中台的能力输出,满足金融行业对移动开发平台技术先进性、安全合规性和高稳定性、高可用性等一系列特殊要求。

基于对金融市场的洞察和全新用户行为的理解,蚂蚁金服移动开发平台mPaaS借助统一的客户端开发框架和蚂蚁特有的金融级移动中台能力,有效地加快研发效率,增加对APP动态管控及千人千面的数字化运营能力。同时基于“后台连接服务”构建与服务端的数据、多媒体传输通道,确保全链路的稳定、安全和高效。
f85afc744df04471a9bfdadb8bdc3a8e

移动端创新技术方面,mPaaS提供智能推荐、语音识别、图像识别、生物识别、小程序等能力,改善产品体验,助力业务创新。

安全合规方面,mPaaS提供IPv6、国密、容灾等特色行业能力,满足监管合规要求。同时辅以应用加固、安全键盘、IFAA生物认证及数据加密能力,充分保障数据在客户端本地、传输过程中的安全性。

目前mPaaS已服务中国农业银行、广发银行,华夏银行,西安银行、国寿保险等众多B端客户,为国内国际用户都带来优质的移动端体验。

蚂蚁金服全栈式金融科技体系,助力金融业全域数字化转型
科技是面向未来的核心驱动力。基于对未来的洞察和蚂蚁金融科技开放的实践深耕,蚂蚁金服在金融领域构建了一个自底向上的全栈式金融科技体系,从具有金融级别支撑能力的分布式计算平台等底层技术,到以人工智能、区块链等为代表的应用技术,再到智能风控、生物核身等金融级专有技术,以及一站式的移动开发平台mPaaS,形成完整的技术堆栈,助力金融机构快速打造新一代超级移动金融平台与大数据智能运营体系,推动金融机构转型升级。

据悉,包括蚂蚁金服移动开发平台mPaaS、分布式中间件SOFAStack、分布式关系数据库OceanBase等在内的产品和解决方案正通过阿里云新金融统一对外输出,服务各种类型的金融机构。而在未来,还会有越来越多的蚂蚁金服技术产品通过阿里云新金融对外输出。在第二十七届中国国际金融展上,这些世界级的解决方案进行了亮相,并吸引了诸多关注。

]]>
全球5G倡议 | 《5G移动无线通信技术》之三 Mon, 16 Dec 2019 05:35:02 +0800 第二章:如何实现海量数据的处理?

全球5G倡议

全球范围内有很多 5G 的论坛和研究项目组。2011 年欧洲第一个开展了 5G 研究 [23], 不久之后中国、韩国、日本开始了各自的研究活动。这些活动和时间表归纳在图 1.6 中。
image.png

3.1 METIS 和 5G-PPP

METIS [24] 是欧盟第一个完整的 5G 项目,并对全球的 5G 发展产生了深远的影响。 METIS 属于欧洲框架 7 项目(FP7),项目准备始于 2011 年 4 月,正式启动于 2012 年 11 月 1 日,中止于 2015 年 4 月 30 日。
METIS 项目的原始诉求是为全球的 5G 研究建立参照体系,包括确定 5G 的应用 场景、测试用例和重要性能指标。目前这些成果被商界和学术界广泛引用。其主要成 果是筛选了 5G 的主要技术元素。欧洲通过该项目在 5G 的研发方面获得了明显的领先 地位。
5G 公私合作伙伴(5G-PPP) [25] 是欧盟框架 73 项目中 5G 后续项目。欧洲的 ICT 行业和欧洲委员会(EC)于 2013 年 12 月签署了商业协议,组建 5G 基础设施公私合作项 目(5G-PPP)。该项目主要是技术研究,其 2014–2020 年预算为 14 亿欧元。欧洲委员会 和 ICT 产业各出资一半(7 亿欧元)。5G-PPP 在设备制造企业、电信运营商、服务提供商和中小企业以及研究人员之间架起了桥梁。
根据与 METIS 签署的谅解备忘录,5G-PPP 项目内 METIS-II 于 2015 年 7 月启 动。METIS-II 致力于开发设计 5G 无线接入网络,其目标是进行足够的细节研究,支撑 3GPP R14 版本的标准化工作。METIS-II 将提出技术建议,并有效地集成当前开发的 5G 技术元素以及与原有 LTE-A 技术演进的集成。为了实现这一目标,METIS-II 非常重视 和 5G-PPP 的其他项目,以及全球其他 5G 项目的合作和讨论。讨论的范围包括 5G 应用 场景和需求、重要 5G 技术元素、频谱规划和无线网络性能等。
5G-PPP 项目的目标是确保欧洲在特定领域的领先,并在这些领域开发潜在的 新的市场,例如智慧城市、电子医疗、智能交通、教育或者娱乐和媒体 [25]。5G-PPP 的终极目标是设计第五代通信网络和服务。5G-PPP 的第一个子项目开始于 2015 年 7 月。

3.2 中国:5G 推进组

IMT-2020(5G)推进组于 2013 年 2 月由中国工业和信息化部、国家发展和改革委 员会、科学技术部联合推动成立,组织国内的企业和高校等成员开展 5G 的研发和产业 推进,是聚合移动通信领域产学研用力量、推动第五代移动通信技术研究、开展国际交 流与合作的基础工作平台。

3.3 韩国:5G 论坛

韩国的 5G 论坛 [28] 也是公私合作项目,成立于 2013 年 5 月。该项目的主要目 标是发展和提出国家的 5G 战略,并对技术创新作出战略规划。成员包括 ETRI,SK Telecom,KT,LG- 爱立信和三星公司。这个论坛也对中小企业开放。其目标之一是确 保 2018 年平昌冬奥会部分 5G 实验网预商用。

3.4 日本:ARIB 2020 和未来专项

ARIB 2020 和未来专项成立于 2013 年 9 月,目的是研究面向 2020 和未来的陆地移 动通信技术,也是成立于 2006 年的先进无线通信研究委员会(ADWICS)的一个子委 员会。这个组织的目标是研究系统概念、基本功能和移动通信的分布式架构。预期输出 包括白皮书,向 ITU 及其他 5G 组织提交的文件。2014 年,该项目发布了第一个白皮书 描述了 5G 的愿景,“面向 2020 和未来的移动通信系统”[29]。

3.5 其他 5G 倡议

其他的 5G 倡议相对于上述项目在规模和影响力方面较小。其中几个是北美 4G(4G Americas)项目、Surrey 大学创新中心、纽约大学无线研究中心。

3.6 物联网的活动

全球范围内开展了大量的物联网倡议,覆盖了物联网的诸多方面。其中工业物联网 共同体(IIC) [30] 和工业 4.0[31] 是和 5G 最紧密相关的项目。IIC 成立于 2014 年,把组织 机构和必要的技术结合在一起,加速工业互联网的成长。主要目标是 [30]:

  • 为现实应用创建新的工业用例和测试床;
  • 影响全球工业互联网系统的标准化进程。

工业 4.0 是德国 2013 年发起的倡议,目的在于保持德国工业制造的竞争力和保持全 球市场领导力,致力于在产品中集成物联网和服务,特别是整个生产流程中创建网络管 理,实现智能工厂环境 [31]。

3.7标准化活动

下面简要介绍 5G 在 ITU、3GPP 和 IEEE 的标准化工作。

3.8 ITU-R

2012 年 ITU 无线通信部分(ITU-R)在 5D 工作组(WP5D)的领导下启动了“面 向 2020 和未来 IMT”的项目,提出了 5G 移动通信空中接口的要求。WP5D 制定了工作 计划、时间表、流程和交付内容。需要强调的是 WP5D 暂时使用“IMT-2020”这一术语 代表5G。根据时间表的要求,需要在2020年完成“IMT-2020技术规范”。至2015年9月, 已经完成下列三个报告。

  • 未来陆地 IMT 系统的技术趋势 [32]:这个报告介绍了 2015—2020 年陆地 IMT 系统的技术趋势,包括一系列可能被用于未来系统设计的技术。
  • 超越 2020 的 IMT 建议和愿景 [19]:该报告描述了 2020 年和未来的长期愿景,并 对未来 IMT 的开发提出了框架建议和总体目标。
  • 高于 6 GHz 的 IMT 可行性分析 [33]:这份报告提供了 IMT 在高于 6 GHz 频段部 署的可行性。该报告被 WRC 2015 参照,将新增的 400 MHz 频谱分配给IMT使用,详见第 12 章。

3.9 3GPP

3GPP 已经确认了 5G 标准化时间表,现阶段计划延续到 2020 年 [34]。5G 无线网络 的主要需求的研究项目和范围于 2015 年 12 月开始,2016 年 3 月开始相应的 5G 新的无 线接入标准。此外, 3GPP在LTE 9[35] 和GSM 36 引入了海量机器类通信的有关需求, 即增强覆盖、低功耗和低成本终端。在 LTE 系统中,机器类通信被称作 LTE-M 和 NBIoT,在 GSM 系统中被称为增强覆盖的 GSM 物联网(EC-GSM-IoT)。

3.10 IEEE

在国际电气和电子工程师协会(IEEE)中,主要负责局域网和城域网的是 IEEE 802 标准委员会。特别是负责无线个人区域网络的 IEEE 802.15 项目(WPAN) [33] 和无 线局域网(WLAN)的 IEEE 802.11 项目 [39]。IEEE 802.11 技术在最初设计时使用频段 在 2.4 GHz。后来 IEEE 802.11 开发了吉比特标准,IEEE 802.11ac 可以部署在更高的频 段,例如 5 GHz 频段,以及 IEEE 802.11ad 可以部署在 60 GHz 毫米波频段。这些系统的 商用部署始于 2013 年,可以预见,到 2019 年的今后几年采用 6 GHz 以下(例如 IEEE 802.11ax)和毫米波频段(例如 IEEE 802.11ay)的系统将会实现高达若干 Gbit/s 的速率。 IEEE 很有可能会基于其高速率技术提交 IMT-2020 的技术方案。IEEE 802.11p 是针对车 辆应用的技术,预计 2017 年之后会获得在车联网 V2V 通信领域的广泛应用。在物联网领域IEEE也表现活跃。IEEE 802.11ah 支持在 1GHz 以下频段部署覆盖增强的 Wi-Fi。 IEEE 802.15.4 标准在低速个人通信网络(LR-WPAN)较为领先。这一标准被 Zigbee 联盟进一步拓展为专用网格连接技术,并被国际自动化协会(ISA)采纳,用于协同和同 步操作,即 ISA100.11a 规范。预计 5G 系统会联合使用由 IEEE 制定的空中接口。这些 接口和 5G 之间的接口的设计需要十分仔细,包括身份管理、移动性、安全性和业务。

3.11 本书的内容介绍

5G 构成的主要目模块如图 1.7所示:无线接入、固定和原有无线接入技术(例如 LTE)、核心网、云计算、数据分析和安全性。本书涵盖的内容在图 1.7中标记为灰色, 5G 无线接入和用例在第 2 章介绍。包括 LTE 的原有系统的作用在不同的章节有简要介 绍。核心网和云计算(包括网络功能虚拟化)的简介在第 3 章介绍。数据分析和安全性超出了本书的范围。
本书内容组织如下。

  • 第 2 章总结了目前定义的 5G 用例和需求,以及 5G 的系统概念。
  • 第 3 章给出了 5G 架构需要考虑的主要问题。
  • 第 4 章讲述 5G 的重要用例之一,即机器类通信。
  • 第 5 章介绍设备和设备通信。
  • 第 6 章介绍有可能分配的从 10 GHz 到 100 GHz 大量频谱的毫米波技术,这些频 谱可以用于无线回传和接入。
  • 第 7 章简要介绍 5G 最可能采用的无线接入技术。
  • 第 8 章重点介绍 5G 的重点技术之一,即大规模 MIMO。
  • 第 9 章讨论多点协同发送,特别是 5G 如何更好地实现联合发射。
  • 第 10 章聚焦中继器和无线网络编码技术。
  • 第 11 章介绍 5G 干扰和移动管理相关的技术。
  • 第11章讨论5G频谱,特别是预期的5G频谱组成和需求,以及预期的频谱接入模式。
  • 第 13 章介绍 5G 信道模型的主要挑战和新的信道模型。
  • 第 14 章提供了 5G 仿真的指导建议,以此来统一假设条件、方法和参考用例。

image.png

]]>
揭秘:你的支付宝由谁来守护? Mon, 16 Dec 2019 05:35:02 +0800 随着移动支付的普及,现在的人带着一个手机就可以走遍天下,但如果手机丢了怎么办,他放在支付宝里的钱又会怎样呢?

在知乎上,也有人问了类似的问题:

1.jpg

对于这个很多人关心的问题,支付宝官方也做了回复,总结就是:

首先支付宝承诺“你敢付我敢赔”,一旦发生盗刷会有保险公司赔付;其次,支付宝的风控系统,可以将盗刷控制在很小范围内。

事实上,支付宝曾经演示过比单纯的丢手机更严重的情景,在今年年初的一场节目上做过这样的演示:黑客获得了一个用户的完整信息,包括手机、身份证、银行卡等,然后试图用支付宝将银行卡里的钱取出。

使用这些信息,黑客成功进入了支付宝并且修改了登录密码,但在最后交易的关头,还是被支付宝成功识别为恶意交易并中断交易。

近几年,网络安全事件层出不穷,黑产行业愈发猖獗,对人们的信息安全和财产造成严重挑战。支付宝作为受人信赖的钱包和支付工具,是黑产们的重点目标,但与此同时,支付宝给人的印象很安全,就是因为支付宝背后有一个风控系统在守护着你的每一笔交易。

2005年,支付宝开始自主研发智能实时风控系统,经过不断的优化,从2017年开始升级到第五代(AlphaRisk)系统。这套系统集风险分析、预警、控制为一体,能通过数据分析、数据挖掘进行机器学习,自动更新完善风险监控策略,日均拦截黑产攻击近十万次,资金损失率小于千万分之一。

那么,这个风控系统为什么这么厉害呢?这就不得不提它背后的团队了。

这个团队就是支付宝安全团队,风险决策就是该团队中负责风险防控的模型团队,团队涉及的风险类型包括,盗用、欺诈、作弊、违规违禁等等。在日常的工作中,团队成员需要从每天百亿级别的交易数据中,抽丝剥茧,发现不法分子的蛛丝马迹,并为支付宝账户和商户提供极致的安全和体验,使他们免受盗用、欺诈、资金风险的侵害。

团队的成员来自五湖四海,人员的组成也是五花八门。由于研究的是利用最前沿的大数据和机器学习技术,不少人来自国内外的知名高校和研究机构,有学习统计、计算机的科班出身,也有学习数学、物理学半道出家的人;团队里既包含工业界的资深专家、学术界的助理教授,也有刚出校门的的新手小白。他们希望,每个人都能在这里找到自己的位置,找到能够为之奉献的终身事业和研究方向。

丰富多样的人员构成使决策科学有足够的能力在不同的领域进行深度拓展。

在人工智能的研究和利用方面,他们涉及的算法包含了知识图谱、时序分析、无监学习、图推理、模型可解释性、NLP、CV、AutoML、运筹优化、强化学习、联邦学习、在线学习等等。

利用这些算法和训练出的模型,他们可以做到对每条交易的风险程度进行评估,并给出对应的解释,然后还可以推荐合适的解决方案;利用图像检测和NLP算法,他们可以对黑产进行主动攻击、挖掘黑产团伙的信息,将犯罪行为暴露并联合执法部分进行打击。

今年还不到30岁的易灿就是团队中的一员,前不久,他刚和团队的几个小伙伴一起,利用业余时间在KDD Cup 2019 Regular ML Track全球竞赛中获得冠军,这项比赛被誉为数据挖掘界的奥林匹克。

2.jpg

KDD CUP大赛是大数据顶级峰会KDD大会设立的线上比赛,每年的5月到8月期间开启,以组队形式,只要成功报名,任何人都可以参加,来自全球的高校、研究机构以及公司的数千只队伍在三个月时间内反复厮杀,只有最后总分最高者才能获胜。

事实上,团队内部在算法竞赛方面称得上是高手如云,他们在过去两年的蚂蚁金服数据挖掘内部赛中连续获得冠军。也更是在专业赛道比如CCL2019中国法研杯比赛,获得了总分第一。

这样的一群人,能打造出这么厉害的风控系统也就不足为奇了。

支付宝每一个做安全的同学的目标就是守护人们的支付安全,他们就像李白笔下的侠客一样,在黑暗中与黑产厮杀,事了拂衣去,深藏身与名。对他们来说,安全风控不仅仅是一项工作,更是一份社会责任。

最后,不得不提到的是团队的培养和学习机制,也真正体现了在做风控安全这件有情有义的事情的是怎样的一群有情有义的人。

除了资深Kaggle GM不吝赐教、行业专家经常分享经验之外,新人从入职开始,每个人都有一个师兄或师姐一对一地传帮带;业务熟悉方面,他们准备了一系列课程,包括业务、产品、模型、案例分析等内容,可以帮助新人快速全面融入新的环境;在学习成长方面,团队内部有NLP/CV、联邦学习、无监督弱监督、图算法、强化学习、知识图谱等虚拟小组,每个人都可以根据自己的爱好报名参加,小组内定期分享学习讨论,这对于团队技术能力的广度和深度的提升都是有力的保障。

目前,支付宝安全团队仍在招募新成员,感兴趣的同学可以查看下方的招聘信息,欢迎投递简历~

支付宝安全团队招人啦!

招聘岗位:
算法专家/数据挖掘专家
简历投递邮箱:
weiqiang.wwq@antfin.com
岗位描述:
1.通过分析/挖掘数据,探索业务机会点并能通过多种AI机器学习算法,建立并持续优化各种风险行为预测模型;
2.平衡体验的便捷和安全,通过优化理论和方法,设计并实施风险-收益最优化的决策。
3.学习、总结、沉淀风控核心算法和能力,与团队一起打造风控算法架构。
职位描述(算法专家P7-P9):
1.计算机、数学、统计、金融等相关专业的硕士或以上学历;
2.三年以上数据挖掘或者机器学习相关工作经验;
3.熟练掌握机器学习算法(或者对于最优化理论和方法有所研究和实践),熟练运用SQL、R、Python等工具;
4.突出的分析问题和解决问题能力,自我驱动,并且具备较强的学习能力、创新应用能力及沟通协调能力;
5.拥有分布式图计算,实时流计算(Spark/Storm)、海量数据处理(Hadoop/Hbase/Hive)经验者优先;有盗用欺诈作弊套现等风险识别工作经验者优先。

更多支付宝安全团队的算法/产品/数据/安全/工程等职位,请浏览阿里巴巴招聘官网,搜索“蚂蚁金服 安全”

]]>
阿里云Link Security为企业级区块链提供易用性安全解决方案 Mon, 16 Dec 2019 05:35:02 +0800

_1


*上图为Forrester在最新报告“A Pragmatic Road Map For Blockchain”中评估内容

在Forrester的定义中,企业区块链平台有五个层次,基础架构,平台,应用,运营和安全性,每个层面都提供特定的业务价值。其中,安全作为企业至关重要的生命线,解决物联网数据上链前的可信问题成为了企业级区块链关注的核心问题之一。

以易用性为中心:区块链IoT安全解决方案

在IoT与分布式账本网络结合的应用场景中,IoT安全技术着力解决数据可信的问题,通过在IoT设备、应用、账号、网络与通信等多维度安全的基础上, 融合分析多源传感数据,为分布式网络中的数据消费方提供“物”的真实数字化描述。
_2

*上图为阿里云边端安全方案架构

阿里云Link Security为IoT设备提供基于多种安全可信根的企业级区块链客户端可信服务,为区块链云下节点应用提供多维度的安全保障。Link Security提供三大核心安全能力:

  • 账号安全能力:密钥全生命周期管理和安全计算
    支持企业级区块链账号和密钥在IoT设备本地安全模块(Link TEE等)中的全生命周期管理以及安全计算(国密和其他区块链相关默认算法)。
  • 客户端设备安全能力:可信设备标识和认证,远程取证,漏洞检测与修复
    提供基于阿里云Link ID²的可信设备身份标识和认证服务,保障接入企业级区块链网络的IoT设备可信可识别。

提供基于阿里云Link SOC的IoT设备全生命周期安全运营管理,实现威胁可感知,设备漏洞可检测与修复。

  • 客户端应用安全能力:可信应用环境
    针对区块链端上关键的数据采集/处理应用程序,提供安全运行环境以及远程可信应用管理的安全服务。

阿里云Link Security安全方案与阿里云区块链服务(Baas)深度对接,帮助企业级区块链实现环境一键式部署,并基于“云-边-端”一体的多安全机制,提供多层级安全防护,致力于解决数据上区块链之前的可信问题,使能可信数据流动与价值最大化。

了解更多阿里云Link Security安全方案,欢迎访问:https://iot.aliyun.com/products/bcw

]]>
有了 serverless,前端也可以快速开发一个 Puppeteer 网页截图服务 Mon, 16 Dec 2019 05:35:02 +0800 更多云原生技术资讯可关注阿里巴巴云原生技术圈

Puppeteer 是什么?

puppeteer 官网的介绍如下:
Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.

通俗描述就是:Puppeteer 可以将 Chrome 或者 Chromium 以无界面的方式运行(当然也可以运行在有界面的服务器上),然后可以通过代码控制浏览器的行为,即使是非界面的模式运行,Chrome 或 Chromium 也可以在内存中正确渲染网页的内容。
那么 Puppeteer 能做什么呢?

  • 生成网页截图或者 PDF
  • 抓取 SPA(Single-Page Application) 进行服务器渲染(SSR)
  • 高级爬虫,可以爬取大量异步渲染内容的网页
  • 模拟键盘输入、表单自动提交、登录网页等,实现 UI 自动化测试
  • 捕获站点的时间线,以便追踪你的网站,帮助分析网站性能问题

本文选择截图场景作为演示。

废话不多说了,我们直接给大家介绍下如何用函数计算产品来快速部署一个 Puppeteer Web 应用。

如何快速部署一个分布式 Puppeteer Web 应用?

为了快速部署分布式 Puppeteer Web 应用,本文以函数计算服务为例来做展示。

函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考

有了函数计算服务,我们这里目标是搭建一个分布式应用,但做的事情其实很简单,那就是写好业务代码,部署到函数计算,仅此而已。

使用函数计算后,我们的系统架构图如下:

1.png

效果演示

可以直接通过以下链接查看效果:
https://1911504709953557.cn-hangzhou.fc.aliyuncs.com/2016-08-15/proxy/puppeteer-test/html2png/?url=https://www.aliyun.com/product/fc
PS:第一次请求可能会有几秒的冷启动时间,通过使用预留模式可以完全去除冷启动,这题超纲,下次再讲。

搭建步骤步骤:

整体流程如下图所示:

2.png

其中,需要我们操作的只有 Fun Init、Fun Install 以及 Fun Deploy 命令,每个的步骤内容都会由这三个命令自动完成。

1. 工具安装

安装 Fun 工具

建议直接从这里下载二进制可执行程序,解压后即可直接使用。下载地址

安装 Docker
可以按照这里介绍的方法进行安装。

2. 初始化项目:

通过 Fun 工具,使用下面的命令可以快速初始化一个 Puppeteer Web 应用的脚手架:

fun init -n puppeteer-test http-trigger-node-puppeteer

其中 -n puppeteer-test  表示初始化项目的目录名称, http-trigger-node-puppeteer  表示要使用的模板名称,可以省略该名称,省略后,可以从终端提示的列表中自行选择需要的模板。
执行完毕后,可以看到如下的目录结构:

.
├── index.js
├── package.json
└── template.yml

相比较于传统的 puppeteer 应用,这里仅仅多了一个 template.yml 文件,用于描述函数计算的资源。
而 index.js 就是我们的业务代码了,可以按照 Puppeteer 官方帮助文档的要求书写自己的业务代码,这里不再重复阐述,核心代码如下:

const browser = await puppeteer.launch({
  headless: true,
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
  ]
});
const page = await browser.newPage();
await page.emulateTimezone('Asia/Shanghai');
await page.goto('https://www.baidu.com', {
  'waitUntil': 'networkidle2'
});
await page.screenshot({ path: '/tmp/example', fullPage: true, type: 'png' });
await browser.close();

package.json 内容如下:

{
  ... ...
  "dependencies": {
    "puppeteer": "^2.0.0"
  },
  ... ...
}

可以看到,在 package.json 中声明了 puppeteer 的依赖。这个也是我们使用 node 开发时的标准做法,并无特别之处。

3. 一键安装依赖

puppeteer 的安装,即使是在传统的 linux 机器上,也不是那么的轻松。因为 puppeteer 本身依赖了非常多的系统库,要安装哪些系统库、如何安装这些系统库成了一个比较头痛的问题。

好在函数计算命令行工具 Fun 已经集成了 Puppeteer 的解决方案,只要 package.json 中包含了 puppeteer 依赖,然后使用 fun install -d 即可一键安装所有系统依赖。

fun install -d

4. 本地运行、调试函数

Puppeteer 的本地运行、调试方法与这里介绍的完全一致,我们就不再重复介绍。我们这里只演示下运行效果:

4.gif

5. 一键部署应用

基本上所有的 FaaS 平台为了减小应用的冷启动,都会设置代码包的限制,函数计算也不例外。而 puppeteer 自身已经达到了 350M 左右,连同其系统依赖已经达到了 450M。如何将 450M 体积的函数部署到 FaaS 平台是一个比较头痛而且繁琐的问题。

函数计算的命令行工具 Fun 现在原生支持了这种大依赖部署(3.1.1 版本仅支持 node runtime)。不需要任何额外操作,仅仅执行 fun deploy:

$ fun deploy

fun 会自动完成依赖的部署。而当检测到打包的依赖超过了平台的限制时,会进入到配置向导,帮助用户自动化地配置。

我们这里推荐的路径是当提示是否由 Fun 自动帮助 NAS 管理是,输入 yes,然后提示提示是否使用 NasConfig: Auto 自动处理 NAS 时,也选择是,之后就不需要做其他的事情,等待函数部署成功即可。

5.png

如果有其他的需求,比如想使用自己已经存在的 NAS 服务,可以在提示使用 NasConfig: Auto 时,输入 no,这样就会进入到相应的流程。更详细的说明,请参考下面的 FAQ。

FAQ

在安装 puppeteer 时,Fun 都做了哪些事情?

puppeteer 本身是一个 npm 包,它的安装是非常简单的,通过 npm install 即可。这里的问题在于,puppeteer 依赖了 chromium,而 chromium 又依赖一些系统库。所以 npm install 后,还会触发下载 chromium 的操作。这里用户经常遇到的问题,主要是:

  1. 由于 chromium 的体积比较大,所以经常遇到网络问题导致下载失败。
  2. npm 仅仅只下载 chromium,chromium 依赖的系统库并不会自动安装。用户还需要自行查找缺失的依赖进行安装。

Fun 做的优化主要是:

  1. 通过检测网络环境,对于国内用户,会帮助配置淘宝 NPM 镜像实现加速下载的效果。
  2. 自动为用户安装 chromium 所缺失的依赖库。

Fun 是如何把大依赖部署到函数计算的?不是有代码包大小的限制吗?

基本上所有的 FaaS 为了优化函数冷启动,都会加入函数代码包大小的限制。函数计算也不例外。但是,Fun 通过内置 NAS(阿里云文件存储) 解决方案,可以一键帮用户创建、配置 NAS,并上传依赖到 NAS 上。而函数计算在运行时,可以自动从 NAS 读取到函数依赖。

为了帮助用户自动化地完成这些操作,Fun 内置了一个向导(3.1.1 版本仅支持 node,后续会支持更多,欢迎 github issue 提需求),在检测到代码体积大小超过平台限制时,会提示是否由 Fun 将其改造成 NAS 的方案,整个向导的逻辑如下:

  1. 询问是否使用 Fun 来自动化的配置 NAS 管理依赖?(如果回答是,则进入向导,回答否,则继续发布流程)
  2. 检测用户的 yml 中是否已经配置了 NAS
  3. 如果已经配置,则提示用户选择已经配置的 NAS 存储函数依赖
  4. 如果没有配置,则提示用户是否使用NasConfig: Auto自动创建 NAS 配置
  5. 如果选择了是,则帮助用户自动配置 nas、vpc 资源。
  6. 如果选择了否,则列出用户当前 NAS 控制台上已经有的 NAS 资源,让用户选择
  7. 无论上面使用哪种方式,最终都会在 template.yml 生成 NAS 以及 VPC 相关的配置
  8. 根据语言检测,比如 node runtime,会将 node_modules 以及 .fun/root 目录映射到 nas 目录(通过 .nas.yml 实现)
  9. 自动执行 fun nas sync 帮用户把本地的依赖上传到 NAS 服务
  10. 自动执行 fun deploy,帮用户把代码上传到函数计算
  11. 提示帮助信息,对于 HTTP Trigger 的,提示函数的 Endpoint,直接打开浏览器访问即可看到效果

是否可以指定 puppeteer 的版本?

可以的,只需要修改 package.json 中的 puppeteer 的版本,重新安装即可。

函数计算实例中的时区采用的 UTC,是否有办法改为北京时间?

某些网页的显示效果是和时区挂钩的,时区不同,可能会导致显示的内容有差异。使用本文介绍的方法,可以非常容易的使用 puppeteer 的最新版本,而在 puppeteer 的最新版本 2.0 提供了一个新的 API page.emulateTimezone(timezoneId) , 可以非常容易的修改时区。

如果 Puppeteer 后续版本更新后,依赖更多的系统依赖,本文介绍的方法还适用吗?

Fun 内置了 .so 缺失检测机制,当在本地调试运行时,会智能地根据报错识别出缺失的依赖库,然后精准地给出安装命令,可以做到一键安装。

如果添加了新的依赖,如何更新?

如果添加了新的依赖,比如 node_modules 目录添加了新的依赖库,只需要重新执行 fun nas sync 进行同步即可。

如果修改了代码,只需要使用 fun deploy 重新部署即可。由于大依赖和代码通过 NAS 进行了分离,依赖通常不需要频繁变化,所以调用的频率比较低,而 fun deploy 的由于没有了大依赖

除了本文介绍的方法还有哪些方法可以一键安装 puppeteer?

Fun 提供了非常多的依赖安装方式,除了本文介绍的将依赖直接声明在 package.json 中,然后通过 fun install -d 的方式安装外,还有很多其他方法,他们均有各自适用的场景:

  1. 命令式安装。比如 fun install -f functionName -p npm puppeteer。这种安装方式的好处是即使对 fun 不了解的用户也可以傻瓜式的使用。
  2. 声明式安装。这种安装方式的好处是提供了类 Dockerfile 的体验,Dockerfile 的大部分指令在这里都是可以直接使用的。通过这种方式声明的依赖,可以通过直接提交到版本仓库。他人拉取代码后,也可以一键安装所有依赖。
  3. 交互环境安装。这种安装方式的好处是提供了类似传统物理机的安装体验。在交互环境中,大部分 linux 命令都是可以使用的,而且可以不断试错。

总结

本文介绍了一种比较简单易行地从零开始搭建分布式 Puppeteer Web 服务的方法。利用该方法,可以做到不需要关心如何安装依赖、也不需要关系如何上传依赖,顺滑地完成部署。

部署完成后,即可享受函数计算带来的优势,即:

  • 无需采购和管理服务器等基础设施,只需专注业务逻辑的开发,可以大幅缩短项目交付时间和人力成本
  • 提供日志查询、性能监控、报警等功能快速排查故障
  • 免运维,毫秒级别弹性伸缩,快速实现底层扩容以应对峰值压力,性能优异
  • 成本极具竞争力

阿里巴巴云原生技术圈关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

]]>
权威发布 | 阿里云分析型数据库AnalyticDB 荣膺中国信通院大数据产品评测双料认证 Mon, 16 Dec 2019 05:35:02 +0800 大会汇集了国内外知名机构的数据资产管理领军专家,对政务、工业、金融等领域的数据资产管理问题展开深入探讨,并对中国信通院第九批大数据产品能力评测结果进行了公布和证书颁发。

其中阿里云分析型数据库产品 AnalyticDB 获得了分析型数据库基础能力和性能双料认证。尤其在大规模性能认证方面,本次评测采用了全球最大规模的 TPC-DS 100TB 测试标准,阿里云 AnalyticDB 完成了 640 节点的分布式分析型数据库性能测试,是迄今为止通过信通院评测认证的最大规模分布式分析型数据库集群,综合评测结果同领域领先。
1576067725915-db0eb348-d8bd-487b-961c-c7e48a220a1a.png
1576067725814-5fa96c83-9b95-4c51-9501-a5802f67d2e8.jpeg

随着业务和技术的变化演进,传统数据仓库方案在支撑企业业务上遇到一系列问题。
1576133794736-d945d01e-1102-4ba2-be8e-7d26c8ad82dc.png

相比较传统大数据产品 阿里云 AnalyticDB 具有更多优点。

1,扩展能力强,AnalyticDB 是 MPP架构的分布式集群数据库,摆脱单机处理瓶颈。

2,使用简单, AnalyticDB 支持SQL 2003,兼容MySQL,Oracle语法和支持PL/SQL存储过程,触发器,支持标准数据库事务。

3,支持场景丰富,AnalyticDB 通过行存储、列存储、多种分区表和索引等机制,可以支持海量数据的在线交付分析,也支持ETL批处理任务。

4,实时性更强,相比离线数仓方案,报表数据延时从天级别缩短至秒级,数据实时性高。

5,高可用,服务秒级恢复,AZ内/跨AZ部署,自动故障检测、摘除和副本重搭。

6,更安全,具有更完善和细化的权限体系模型,白名单和集群级别RAM控制

当前AnalyticDB For PostgreSQL正在进行 6.0 新版本的公测,6.0 版本大幅提升并发事务处理能力,更好的满足实时数仓场景,同时通过事务锁等优化,完备支持HTAP业务,在既有JSON类型上,支持JSONB存储格式,实现高性能的JSON数据处理及更丰富的JSON函数等特性。
1576133854036-b8aaa587-fcd1-4515-b1be-21081ab5d10d.png

阿里云 AnalyticDB 广泛应用于企业实时数仓构建,如电商&新零售大数据运营支撑平台,用户将平台业务线上、线下各渠道的行为数据清洗沉淀到实时数仓,通过数仓提供在线客户标签和用户群体分析能力,圈选目标客户,进行针对性的广告投放和营销活动。

1576067725798-a59bc30b-0437-42d1-87f2-8c9f894eb6f9.png

AnalyticDB 6.0 (事务增强版)火热公测中!限时免费,立即查看]]> Spring Boot 最简单整合Shiro+JWT方式 Mon, 16 Dec 2019 05:35:02 +0800 简介

目前RESTful大多都采用JWT来做授权校验,在Spring Boot 中可以采用ShiroJWT来做简单的权限以及认证验证,在和Spring Boot集成的过程中碰到了不少坑。便结合自身以及大家的常用的运用场景开发出了这个最简单的整合方式fastdep-shiro-jwt

源码地址

希望大家可以star支持一下,后续还会加入其它依赖的简易整合。
https://github.com/louislivi/fastdep

引入依赖

  • Maven
<dependency>
    <groupId>com.louislivi.fastdep</groupId>
    <artifactId>fastdep-shiro-jwt</artifactId>
    <version>1.0.2</version>
</dependency>
  • Gradle

    compile group: 'com.louislivi.fastdep', name: 'fastdep-redis', version: '1.0.2'

配置文件

  • application.yml

    fastdep:
    shiro-jwt:
      filter: #shiro过滤规则
        admin:
          path: /admin/**
          role: jwt # jwt为需要进行token校验
        front:
          path: /front/**/**
          role: anon # anon为无需校验
      secret: "6Dx8SIuaHXJYnpsG18SSpjPs50lZcT52" # jwt秘钥
    #    expireTime: 7200000 # token有效期
    #    prefix: "Bearer "  # token校验时的前缀
    #    signPrefix: "Bearer " # token生成签名的前缀
    #    header: "Authorization" # token校验时的header头
    #    以下对应为shiro配置参数,无特殊需求无需配置
    #    loginUrl: 
    #    successUrl: 
    #    unauthorizedUrl: 
    #    filterChainDefinitions: 
  • 用户权限配置类

    @Component
    public class FastDepShiroJwtConfig extends FastDepShiroJwtAuthorization {
      
      @Autowired
      private UserRequestDataMapper userRequestDataMapper;
    
      @Override
      public SimpleAuthorizationInfo getAuthorizationInfo(String userId) {
          // 查询该用户下的所有权限(当前为示例仅查询用户ID真实环境替换为用户的权限值)
          Set<String> collect = userRequestDataMapper.selectOptions().stream().map(u -> u.getUserId().toString()).collect(Collectors.toSet());
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            System.out.println(collect);
            // 当前值为 [1]
            // 添加用户权限到SimpleAuthorizationInfo中
            simpleAuthorizationInfo.addStringPermissions(collect);
            return simpleAuthorizationInfo;
        }
    }

运用

@RestController
public class TestController {
    @Autowired
    private JwtUtil jwtUtil;

    /**
     * 当前为示例所以直接返回了token,真实环境为校验登录信息后再返回token即可
     * @author : louislivi
     */
    @GetMapping("front/login")
    public String login() {
        // ...校验登录信息是否正确
        // 传入用户唯一标示
        return jwtUtil.sign("1"); 
    }

    /**
     * 当前为示例所以权限写的是用户ID 真实环境替换为权限key
     * @author : louislivi
     */
    @GetMapping("admin")
    @RequiresPermissions("1")
    public String jwt() {
        return "ok!";
    }
}

测试

1.获取token
front-login.png

2.测试权限校验

  • 带token
    hasToken.png
  • 不带token

    {
        "msg": "Access denied !",
        "code": 401
    }
    • 带上token但是,SimpleAuthorizationInfo中无指定权限
{
    "msg": "Subject does not have permission [1]",
    "code": 403
}

扩展

有时候需要自定义权限校验以及错误返回信息结构等,这时候就需要重写FastDepShiroJwtAuthorization类中的方法。更多详情请看这里

原理

使用ImportBeanDefinitionRegistrar BeanDefinitionBuilder.genericBeanDefinition动态注入Bean其实很简单有兴趣可以去看看源码,这样的依赖集成是不是简单了很多呢?

希望大家能够支持开源,给个小星星,后续还会继续开发其他依赖的整合,甚至兼容其他框架使用。fastdepjava整合依赖更简单。在此也招募有志同道合的coder共同完善这个项目。

]]>
旧手机回收不放心?阿里小程序为回收加码! Mon, 16 Dec 2019 05:35:02 +0800 小云家里有几台旧手机,不敢随意丢弃,担心手机里的隐私泄漏。又不愿卖给小商贩,价格不透明。犹犹豫豫,一直不知道怎么处理。

针对用户担心手机隐私泄漏、回收价不透明的痛点,闪回收牵手阿里云共同打造“闪回收手机回收”小程序,通过简单操作即可知晓手机回收价格,在回收完成后,闪回收会在全程监控下恢复手机出场设置,并做信息填压式覆盖,更好的保障用户的隐私不受侵害。阿里云为闪回收提供了稳定、扩展性极强的服务能力,可以放心的在对外推广。同时也帮助闪回收解决了用户信息、监控信息云端存储的难题。

闪回收是全国领先的手机数码回收平台,除了直接服务于线上用户,还为全国15万家手机门店赋能手机回收、以旧换新、手机碎屏险等业务能力。闪回收充分利用阿里云上提供的服务,如自动获取用户当前手机型号、获取用户基本信息、模版消息触达等,不断优化回收流程,给用户更好的回收体验。

然而在回收业务运营过程中,最困扰闪回收的一点是业务扩展。闪回收在阿里小程序上可以提供很好的回收服务,但还未能在钉钉、高德等其他阿里系产品中落地。而阿里云小程序的“一云多端”恰恰解决了这一困扰。

小程序对业务有哪些帮助?

1.提升业务可信度
手机回收业务最大的痛点在于用户对平台的信任度。支付宝天然给予用户信赖、安全的服务感受,更加适合回收类(信用背书要求比较高)的行业入驻。闪回收在各端的运营中,阿里小程序是转化最好的渠道之一。

2.为运营赋能
阿里小程序不断开放新的功能组件。从收藏有礼到关注有礼,从模版消息触达到付款后推荐。阿里小程序从商家运营角度出发,提升商家运营效率,真真切切的帮助商家做业务提升。

3.帮助商家提升服务能力
阿里小程序免费开放的云客服能力,简单的接入机制,帮助商家和用户之间形成高效的沟通通道。另外,阿里小程序还免费开放订单中心接入,让交易用户通过支付宝账单即可查看订单详情,既方便用户又减少闪回收的服务压力。

4.对接蚂蚁森林能量
闪回收小程序与蚂蚁森林合作,回收送森林能量。用户在闪回收回收手机、平板、电脑不仅能拿到回收款,还能拿到631g森林能量。自2019年10月接入蚂蚁森林至今,订单转化提高22.81%,回收订单量增长36.3%。大大提升闪回收用户的回收心智。

5.多端统一后台
闪回收应用在支付宝、钉钉、高德等不同端提供的服务大致相同,如:手机报价、一键上门等。因此统一后台,对减少技术开发、提升人效非常重要。“一云多端”下,统一后台成为可能。

带大家了解一下“闪回收”小程序的特别及界面。

1.png

2.png

1.良好的用户体验:用户来访闪回收小程序时,即可自动识别用户的手机型号,自动展示其最高回收价,减少用户操作。

2.便捷的回收方式:闪回收小程序提供回收包邮服务,用户可将要回收的机器以邮费到付形式邮寄到闪回收。并且闪回收自动呼叫快递上门,用户只要填写预约时间和地址,等待快递上门取件即可。

3.专业的回收服务:用户回收的机器自进入闪回收开始,即进入360度无死角监控。从收货拆包、质量检测到数据清理,每一步都有据可循。保障用户的财产安全、隐私安全。

“闪回收”小程序使用了阿里云哪些产品来打造自己的小程序呢?

  • 负载均衡SLB:贷款值5120Mbps
  • 应用层:云服务器3台
  • 数据层:云数据库主库1,从库3,备1台,redis主从2台
  • 任务层:云服务器1,主要用于执行定时任务、队列任务
  • 静态文件oss,cdn加速
  • 阿里短信服务
  • elasticsearch集群,3台服务器
  • rocketMQ服务

image.png

扫码体验小程序

3_meitu_1

了解更多最近的小程序能力和资讯,请访问开发者中心

_2019_11_28_2_04_45

]]>
服务网格在“路口”的产品思考与实践 Mon, 16 Dec 2019 05:35:02 +0800 点击下载《不一样的 双11 技术:阿里巴巴经济体云原生实践》

ban.jpg

本文节选自《不一样的 双11 技术:阿里巴巴经济体云原生实践》一书,点击上方图片即可下载!

作者 | 宋顺,花名齐天,蚂蚁金服高级技术专家

一、引言

Service Mesh 是蚂蚁金服下一代架构的核心,经过了 2 年的沉淀,我们探索出了一套切实可行的方案并最终通过了 双11 的考验。本文主要分享在当下“路口”,我们在产品设计上的思考和实践,希望能给大家带来一些启发。

二、为什么需要 Service Mesh?

1.1 微服务治理与业务逻辑解耦

在 Service Mesh 之前,微服务体系的玩法都是由中间件团队提供一个 SDK 给业务应用使用,在 SDK 中会集成各种服务治理的能力,如:服务发现、负载均衡、熔断限流、服务路由等。

在运行时,SDK 和业务应用的代码其实是混合在一个进程中运行的,耦合度非常高,这就带来了一系列的问题:

  1. 升级成本高

    1. 每次升级都需要业务应用修改 SDK 版本号,重新发布。
    2. 在业务飞速往前跑的时候,是不太愿意停下来做这些和自身业务目标不太相关的事情的。
  2. 版本碎片化严重

    1. 由于升级成本高,但中间件还是会向前发展,久而久之,就会导致线上 SDK 版本各不统一、能力参差不齐,造成很难统一治理
  3. 中间件演进困难

    1. 由于版本碎片化严重,导致中间件向前演进过程中就需要在代码中兼容各种各样的老版本逻辑,戴着“枷锁”前行,无法实现快速迭代

有了 Service Mesh 之后,我们就可以把 SDK 中的大部分能力从应用中剥离出来,拆解为独立进程,以 Sidecar 的模式部署。通过将服务治理能力下沉到基础设施,可以让业务更加专注于业务逻辑,中间件团队则更加专注于各种通用能力,真正实现独立演进,透明升级,提升整体效率。

1.png

1.2 异构语言统一治理

随着新技术的发展和人员更替,在同一家公司中往往会出现使用各种不同语言的应用和服务,为了能够统一管控这些服务,以往的做法是为每种语言都重新开发一套完整的 SDK,维护成本非常高,而且对中间件团队的人员结构也带来了很大的挑战。

有了 Service Mesh 之后,通过将主体的服务治理能力下沉到基础设施,多语言的支持就轻松很多了,只需要提供一个非常轻量的 SDK、甚至很多情况都不需要一个单独的 SDK,就可以方便地实现多语言、多协议的统一流量管控、监控等治理需求。
2.png
图片来源

1.3 金融级网络安全

当前很多公司的微服务体系建设都建立在“内网可信”的假设之上,然而这个原则在当前大规模上云的背景下可能显得有点不合时宜,尤其是涉及到一些金融场景的时候。

通过 Service Mesh,我们可以更方便地实现应用的身份标识和访问控制,辅之以数据加密,就能实现全链路可信,从而使得服务可以运行于零信任网络中,提升整体安全水位。

3.png

三、在当下“路口”的思考

3.1 云原生方案?

正因为 Service Mesh 带来了上述种种的好处,所以这两年社区中对 Service Mesh 的关注度越来越高,也涌现出了很多优秀的 Service Mesh 产品,Istio 就是其中一款非常典型的标杆产品。

Istio 以其前瞻的设计结合云原生的概念,一出现就让人眼前一亮,心之向往。不过深入进去看了之后发现,在目前阶段要落地的话,还是存在一些 gap 的。

4.png

图片来源https://istio.io/docs/concepts/what-is-istio/

3.2 Greenfield vs Brownfield

在正式展开讨论之前,我们先来看一副漫画。

5.png

图片来源https://faasandfurious.com/90

上面这幅漫画描绘了这样一个场景:

  • 有两个工人在工作,其中一个在绿色的草地(Greenfield)上,另一个在棕色的土地(Brownfield)上
  • 在绿色草地上的工人对在棕色土地上的工人说:“如果你没有给自己挖这么深的坑,那么你也可以像我一样做一些很棒的新东西”
  • 然后在棕色土地上的工人回答道:“你倒是下来试试!”

这是一幅很有意思的漫画,我们可以认为在绿色草地上的工人是站着说话不腰疼,不过其实本质的原因还是两者所处的环境不同。

在一片未开发过的土地上施工确实是很舒服的,因为空间很大,也没有周遭各种限制,可以使用各种新技术、新理念,我们国家近几十年来的一些新区新城的建设就属于这类。而在一片已经开发过的土地上施工就大不一样了,周围环境会有各种限制,比如地下可能有各种管线,一不小心就挖断了,附近还有各种大楼,稍有不慎就可能把楼给挖塌了,所以做起事来就要非常小心,设计方案时也会受到各种约束,无法自由发挥。

对于软件工程,其实也是一样的,Greenfield 对应着全新的项目或新的系统,Brownfield 对应着成熟的项目或遗留系统。

我相信大部分程序员都是喜欢做全新的项目的,包括我自己也是一样。因为可以使用新的技术、新的框架,可以按照事物本来的样子去做系统设计,自由度很高。而在开发/维护一个成熟的项目时就不太一样了,一方面项目已经稳定运行,逻辑也非常复杂,所以无法很方便地换成新的技术、新的框架,在设计新功能时也会碍于已有的架构和代码实现做很多妥协,另一方面前人可能不知不觉挖了很多坑,稍有不慎就会掉进坑里,所以行事必须要非常小心,尤其是在做大的架构改变的时候。

3.3 现实场景

3.3.1 Brownfield 应用当道

在现实中,我们发现目前大部分的公司还没有走向云原生,或者还刚刚在开始探索,所以大量的应用其实还跑在非 K8s 的体系中,比如跑在虚拟机上或者是基于独立的服务注册中心构建微服务体系。

虽然确实有少量 Greenfield 应用已经在基于云原生来构建了,但现实是那些大量的 Brownfield 应用是公司业务的顶梁柱,承载着更大的业务价值,所以如何把它们纳入 Service Mesh 统一管控,从而带来更大的价值,也就成了更需要优先考虑的话题。

6.png
图片来源
7.png
独立的服务注册中心

3.3.2 云原生方案离生产级尚有一定距离

另一方面,目前 Istio 在整体性能上还存在一些有待解决的点,以下引述熬小剑老师在蚂蚁金服 Service Mesh 深度实践中的观点):

Mixer

  1. Mixer 的性能问题,一直都是 Istio 中最被人诟病的地方。
  2. 尤其在 Istio 1.1/1.2 版本之后引入了 Out-Of-Process Adapter,更是雪上加霜。
  3. 从落地的角度看,Mixer V1 糟糕至极的性能,已经是“生命无法承受之重”。对于一般规模的生产级落地而言,Mixer 性能已经是难于接受,更不要提大规模落地……
  4. Mixer V2 方案则给了社区希望:将 Mixer 合并进 Sidecar,引入 web assembly 进行 Adapter 扩展,这是我们期待的 Mixer 落地的正确姿势,是 Mixer 的未来,是 Mixer 的“诗和远方”。然而社区望穿秋水,但Mixer V2 迟迟未能启动,长期处于 In Review 状态,远水解不了近渴。

Pilot

  1. Pilot 是一个被 Mixer 掩盖的重灾区:长期以来大家的性能关注点都在 Mixer,表现糟糕而且问题明显的Mixer 一直在吸引火力。但是当选择放弃 Mixer(典型如官方在 Istio 新版本中提供的关闭 Mixer 的配置开关)之后,Pilot 的性能问题也就很快浮出水面。
  2. 我们实践下来发现 Pilot 目前主要有两大问题:1)无法支撑海量数据 2)每次变化都会触发全量推送,性能较差

8.png

图片来源

3.3.3 当下“路口”我们该怎么走?

我们都非常笃信云原生就是未来,是我们的“诗和远方”,但是眼下的现实情况是一方面 Brownfield 应用当道,另一方面云原生的 Service Mesh 方案自身离生产级还有一定的距离,所以在当下这个“路口”我们该怎么走?

我们给出的答案是:

9.png

其实如前面所述,我们采用 Service Mesh 方案的初心是因为它的架构改变可以带来很多好处,如:服务治理与业务逻辑解耦、异构语言统一治理、金融级网络安全等,而且我们相信这些好处不管对 Greenfield 应用还是 Brownfield 应用都是非常需要的,甚至在现阶段对 Brownfield 应用产生的业务价值会远远大于 Greenfield 应用。

所以从“务实”的角度来看,我们首先还是要探索出一套现阶段切实可行的方案,不仅要支持 Greenfield 应用,更要能支持 Brownfield 应用,从而可以真正把 Service Mesh 落到实处,产生业务价值。

四、蚂蚁金服的产品实践

4.1 发展历程和落地规模

10.png

Service Mesh 在蚂蚁金服的发展历程,先后经历过如下几个阶段:

  • 技术预研 阶段:2017 年底开始调研并探索 Service Mesh 技术,并确定为未来发展方向。
  • 技术探索 阶段:2018 年初开始用 Golang 开发 Sidecar SOFAMosn ,年中开源基于 Istio 的 SOFAMesh 。
  • 小规模落地 阶段:2018 年开始内部落地,第一批场景是替代 Java 语言之外的其他语言的客户端 SDK,之后开始内部小范围试点。
  • 规模落地 阶段:2019 年上半年,作为蚂蚁金融级云原生架构升级的主要内容之一,逐渐铺开到蚂蚁金服内部的业务应用,并平稳支撑了 618 大促。
  • 对外输出 阶段:2019 年 9 月,SOFAStack 双模微服务平台入驻阿里云开始公测,支持 SOFA, Dubbo 和 Spring Cloud 应用
  • 全面大规模落地 阶段:2019 年下半年,在蚂蚁主站的大促核心应用中全面铺开,落地规模非常庞大,而且最终如“丝般顺滑”地支撑了 双11 大促。

在今年 双11,Service Mesh 覆盖了数百个交易核心链路应用,SOFAMosn 注入的容器数量达到了数十万(据信是目前全球最大的 Service Mesh 集群),双11 当天处理的 QPS 达到了几千万,平均处理响应时间<0.2 ms.
SOFAMosn 本身在大促中间完成了数十次的业务无感升级,达到了我们的预期,初步完成了基础设施和业务的第一步的分离,见证了 Mesh 化之后基础设施的迭代速度。

4.2 SOFAStack 双模微服务平台

我们的服务网格产品名是 SOFAStack 双模微服务平台,这里的“双模微服务”是指传统微服务和 Service Mesh 双剑合璧,即“基于 SDK 的传统微服务”可以和“基于 Sidecar 的 Service Mesh 微服务”实现下列目标:

 •  互联互通:两个体系中的应用可以相互访问;
 •  平滑迁移:应用可以在两个体系中迁移,对于调用该应用的其他应用,做到透明无感知;
 •  异构演进:在互联互通和平滑迁移实现之后,我们就可以根据实际情况进行灵活的应用改造和架构演进;

在控制面上,我们引入了 Pilot 实现配置的下发(如服务路由规则),在服务发现上保留了独立的 SOFA 服务注册中心。

在数据面上,我们使用了自研的 SOFAMosn,不仅支持 SOFA 应用,同时也支持 Dubbo 和 Spring Cloud 应用。

在部署模式上,我们不仅支持容器/K8s,同时也支持虚拟机场景。

11.png

4.3 大规模场景下的服务发现

要在蚂蚁金服落地,首先一个需要考虑的就是如何支撑 双11 这样的大规模场景。前面已经提到,目前 Pilot 本身在集群容量上比较有限,无法支撑海量数据,同时每次变化都会触发全量推送,无法应对大规模场景下的服务发现。

所以,我们的方案是保留独立的 SOFA 服务注册中心来支持千万级的服务实例信息和秒级推送,业务应用通过直连 Sidecar 来实现服务注册和发现。

12.png

4.4 流量劫持

Service Mesh 中另一个重要的话题就是如何实现流量劫持:使得业务应用的 Inbound 和 Outbound 服务请求都能够经过 Sidecar 处理。

区别于社区的 iptables 等流量劫持方案,我们的方案就显得比较简单直白了,以下图为例:

  1. 假设服务端运行在 1.2.3.4 这台机器上,监听 20880 端口,首先服务端会向自己的 Sidecar 发起服务注册请求,告知 Sidecar 需要注册的服务以及 IP + 端口(1.2.3.4:20880);
  2. 服务端的 Sidecar 会向 SOFA 服务注册中心发起服务注册请求,告知需要注册的服务以及 IP + 端口,不过这里需要注意的是注册上去的并不是业务应用的端口(20880),而是 Sidecar 自己监听的一个端口(例如:20881);
  3. 调用端向自己的 Sidecar 发起服务订阅请求,告知需要订阅的服务信息;
  4. 调用端的 Sidecar 向调用端推送服务地址,这里需要注意的是推送的 IP 是本机,端口是调用端的 Sidecar 监听的端口(例如:20882);
  5. 调用端的 Sidecar 会向 SOFA 服务注册中心发起服务订阅请求,告知需要订阅的服务信息;
  6. SOFA 服务注册中心向调用端的 Sidecar 推送服务地址(1.2.3.4:20881);

13.png


经过上述的服务发现过程,流量劫持就显得非常自然了:

  1. 调用端拿到的“服务端”地址是127.0.0.1:20882,所以就会向这个地址发起服务调用;
  2. 调用端的 Sidecar 接收到请求后,通过解析请求头,可以得知具体要调用的服务信息,然后获取之前从服务注册中心返回的地址后就可以发起真实的调用(1.2.3.4:20881);
  3. 服务端的 Sidecar 接收到请求后,经过一系列处理,最终会把请求发送给服务端(127.0.0.1:20880);

14.png

可能会有人问,为啥不采用 iptables 的方案呢?主要的原因是一方面 iptables 在规则配置较多时,性能下滑严重,另一个更为重要的方面是它的管控性和可观测性不好,出了问题比较难排查。

4.5 平滑迁移

平滑迁移可能是整个方案中最为重要的一个环节了,前面也提到,在目前任何一家公司都存在着大量的 Brownfield 应用,它们有些可能承载着公司最有价值的业务,稍有闪失就会给公司带来损失,有些可能是非常核心的应用,稍有抖动就会造成故障,所以对于 Service Mesh 这样一个大的架构改造,平滑迁移是一个必选项,同时还需要支持可灰度和可回滚。

得益于独立的服务注册中心,我们的平滑迁移方案也非常简单直白:

1.初始状态

以一个服务为例,初始有一个服务提供者,有一个服务调用者。

15.png

2.透明迁移调用方

在我们的方案中,对于先迁移调用方还是先迁移服务方没有任何要求,这里假设调用方希望先迁移到 Service Mesh 上,那么只要在调用方开启 Sidecar 的注入即可,服务方完全不感知调用方是否迁移了。所以调用方可以采用灰度的方式一台一台开启 Sidecar,如果有问题直接回滚即可。

16.png

3.透明迁移服务方

假设服务方希望先迁移到 Service Mesh 上,那么只要在服务方开启 Sidecar 的注入即可,调用方完全不感知服务方是否迁移了。所以服务方可以采用灰度的方式一台一台开启 Sidecar,如果有问题直接回滚即可。

17.png

4.终态

18.png

4.6 多协议支持

考虑到目前大部分用户的使用场景,除了 SOFA 应用,我们同时也支持 Dubbo 和 Spring Cloud 应用接入SOFAStack 双模微服务平台,提供统一的服务治理。多协议支持采用通用的 x-protocol,未来也可以方便地支持更多协议。

19.png

4.7 虚拟机支持

在云原生架构下,Sidecar 借助于 K8s 的 webhook/operator 机制可以方便地实现注入、升级等运维操作。然而大量系统还没有跑在 K8s 上,所以我们通过 agent 的模式来管理 Sidecar 进程,从而可以使 Service Mesh 能够帮助老架构下的应用完成服务化改造,并支持新架构和老架构下服务的统一管理。

20.png

4.8 产品易用性

在产品易用性上我们也做了不少工作,比如可以直接在界面上方便地设置服务路由规则、服务限流等,再也不用手工写 yaml 了:

21.png

22.png

也可以在界面上方便地查看服务拓扑和实时监控:

23.jpeg
24.png

五、展望未来

5.1 拥抱云原生

目前已经能非常清楚地看到整个行业在经历从云托管(Cloud Hosted)到云就绪(Cloud Ready)直至云原生(Cloud Native)的过程,所以前面也提到我们都非常笃信云原生就是未来,是我们的“诗和远方”,虽然眼下在落地过程中还存在一定的 gap,不过相信随着我们的持续投入,gap 会越来越小。

另外值得一提的是我们拥抱云原生其根本还在于降低资源成本,提升开发效率,享受生态红利,所以云原生本身不是目的,而是手段,切不可本末倒置了。

25.png

5.2 持续加强 Pilot 的能力

为了更好地拥抱云原生,后续我们也会和 Istio 社区共建,持续加强 Pilot 的能力。

而就在最近,在综合了过去一年多的思考和探索之后,蚂蚁金服和阿里巴巴集团的同事们共同提出了一套完整的解决方案,来融合控制平面和传统注册中心/配置中心,从而可以在保持协议标准化的同时,加强 Pilot 的能力,使其逐步具备生产级的能力。

26.png

5.3 支持透明劫持

前面提到在蚂蚁金服的实践中是基于服务注册中心来实现流量劫持的,该方案不管是在性能、管控能力还是可观测性方面都是不错的选择,不过对应用存在一定的侵入性(需要引入一个轻量的注册中心 SDK)。

考虑到很多用户对性能要求没那么敏感,同时有大量遗留系统希望通过 Service Mesh 实现统一管控,所以后续我们也会支持透明劫持,同时在管控性和可观测性方面会做增强。

27.png

六、结语

基于“务实”的理念,Service Mesh 在蚂蚁金服经过了 2 年的沉淀,我们探索出了一套现阶段切实可行的方案并最终通过了 双11 的考验。在这个过程中,我们也愈发体验到了 Service Mesh 带来的好处,例如 SOFAMosn 在大促中间完成了数十次的业务无感升级,见证了 Mesh 化之后基础设施的迭代速度。

我们判断,未来 Service Mesh 会成为云原生下微服务的标准解决方案,所以我们也会持续加大对 Service Mesh 的投入,包括接下来蚂蚁金服将和阿里巴巴集团一起深度参与到 Istio 社区中去,和社区一起把 Istio 打造成 Service Mesh 的事实标准。

ban.jpg

本书亮点

  • 双11 超大规模 K8s 集群实践中,遇到的问题及解决方法详述
  • 云原生化最佳组合:Kubernetes+容器+神龙,实现核心系统 100% 上云的技术细节
  • 双 11 Service Mesh 超大规模落地解决方案

“阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
在 Serverless Kubernetes(ASK) 集群中使用 Nginx Ingress Mon, 16 Dec 2019 05:35:02 +0800 原文作者:贤维
原文链接:https://developer.aliyun.com/article/727019

ASK: Alibaba Cloud Serverless Kubernetes

导读

不同于阿里云 ACK 集群默认通过 nginx-ingress-controller 提供 ingress 能力,在 ASK(Serverless Kubernetes) 集群中默认基于 SLB 七层转发提供ingress能力(请参考文档https://help.aliyun.com/document_detail/86398.html)。
这样的优势是Serverless集群开箱即用,用户无需部署任何controller即可创建自己的Ingress资源,更符合Serverless环境的用法。

然而基于SLB七层转发的ingress与nginx-ingress-controller相比,缺少了一些高级Ingress功能,无法满足某些客户场景的需求,比如支持域名path的正则匹配等。

所以ASK集群也提供了与ACK集群同样的 nginx-ingress-controller,供用户使用 nginx 提供的 ingress 转发能力。用户可以根据自己的需求决定选择两者之一。下面我们一起来尝试在 ASK 集群中使用 nginx-ingress。

部署 nginx-ingress-controller

在 ASK 集群中部署 yaml 文件:
https://github.com/AliyunContainerService/serverless-k8s-examples/blob/master/ingress-nginx/nginx-ingress-controller.yaml

#kubectl apply -f https://raw.githubusercontent.com/AliyunContainerService/serverless-k8s-examples/master/ingress-nginx/nginx-ingress-controller.yaml
service/nginx-ingress-lb created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-controller created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-controller created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-controller created
deployment.apps/nginx-ingress-controller created

# kubectl -n kube-system get pod
NAME                                       READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-c9d8697f6-n4bzs   0/1     Running   0          52s
nginx-ingress-controller-c9d8697f6-p8p6j   0/1     Running   0          52s

# kubectl -n kube-system get svc
NAME               TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                      AGE
metrics-server     ClusterIP      172.19.4.171   <none>         443/TCP                      72d
nginx-ingress-lb   LoadBalancer   172.19.6.118   47.93.131.72   80:32676/TCP,443:30256/TCP   116s

可以看到一个公网slb已经被创建出来(后端是两个nginx-ingress-controller pod),这是集群中所有ingress的入口IP地址。

部署Ingress示例

我们同样提供了简单的Coffee和Tea Ingress示例:https://github.com/AliyunContainerService/serverless-k8s-examples/blob/master/ingress-nginx/ingress-cafe-demo.yaml

需要注意的是Ingress中需要指定如下Annotation,才能保证ingress被nginx-ingress-controller正确处理。
kubernetes.io/ingress.class:nginx

# kubectl apply -f https://raw.githubusercontent.com/AliyunContainerService/serverless-k8s-examples/master/ingress-nginx/ingress-cafe-demo.yamldeployment.extensions/coffee created
service/coffee-svc created
deployment.extensions/tea created
service/tea-svc created
ingress.extensions/cafe-ingress created

# kubectl get pod
NAME                             READY   STATUS             RESTARTS   AGE
coffee-56668d6f78-g7g6p          1/1     Running            0          88s
coffee-56668d6f78-x9ktc          1/1     Running            0          88s
tea-85f8bf86fd-477d2             1/1     Running            0          88s
tea-85f8bf86fd-jlq6b             1/1     Running            0          88s
tea-85f8bf86fd-p4ng4             1/1     Running            0          88s

# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
coffee-svc   ClusterIP   None            <none>        80/TCP     102s
kubernetes   ClusterIP   172.19.0.1      <none>        443/TCP    72d
tea-svc      ClusterIP   None            <none>        80/TCP     102s

# kubectl get ing
NAME           HOSTS              ADDRESS        PORTS   AGE
cafe-ingress   cafe.example.com   47.93.131.72   80      2m1s

pod 和 ingress 都已创建成功,下面我们尝试访问 Ingress:

# curl -H "Host:cafe.example.com" 47.93.131.72/tea
Server address: 192.168.55.159:80
Server name: default-tea-85f8bf86fd-p4ng4
Date: 14/Nov/2019:09:01:46 +0000
URI: /tea
Request ID: 2c3a87eb89130d62664b640fcbabc74b

# curl -H "Host:cafe.example.com" 47.93.131.72/coffee
Server address: 192.168.55.156:80
Server name: default-coffee-56668d6f78-x9ktc
Date: 14/Nov/2019:09:01:49 +0000
URI: /coffee
Request ID: a4f1d84bb5288a260ecfc5d21ecccff6

Ingress 链路访问成功,可以看到上述域名转发由 nginx ingress controller 完成。

当运行上述示例成功后,记得清理集群中的 ingress:
kubectl delete -f https://raw.githubusercontent.com/AliyunContainerService/serverless-k8s-examples/master/ingress-nginx/ingress-cafe-demo.yaml

更多 ASK 集群示例请参考:https://github.com/AliyunContainerService/serverless-k8s-examples

“阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
阿里巴巴 Service Mesh 落地的架构与挑战 Mon, 16 Dec 2019 05:35:02 +0800 点击下载《不一样的 双11 技术:阿里巴巴经济体云原生实践》
ban.jpg
本文节选自《不一样的 双11 技术:阿里巴巴经济体云原生实践》一书,点击上方图片即可下载!

作者 | 方克明(溪翁)阿里云中间件技术部技术专家

导读:云原生已成为整个阿里巴巴经济体构建面向未来的技术基础设施,Service Mesh 作为云原生的关键技术之一,顺利完成在 双11 核心应用严苛而复杂场景下的落地验证。本文作者将与大家分享在完成这一目标过程中我们所面临和克服的挑战。

部署架构

切入主题前,需要交代一下在 双11 核心应用上落地的部署架构,如下图所示。在这篇文章中,我们主要聚焦于 Service A 和 Service B 之间 RPC 协议的 Mesh 化。

1.png

图中示例说明了 Service Mesh 所包含的三大平面:即数据平面(Data Plane)、控制平面(Control Plane)和运维平面(Operation Plane)。数据平面我们采用的是开源的 Envoy(上图中的 Sidecar,请读者注意这两个词在本文中可以互换使用),控制平面采用的是开源的 Istio(目前只使用了其中的 Pilot 组件),运维平面则完全自研。

与半年前落地时不同,这次 双11 核心应用上落地我们采用了 Pilot 集群化部署的模式,即 Pilot 不再与 Envoy 一起部署到业务容器中,而是搭建了一个独立的集群。这一变化使得控制平面的部署方式演进到了 Service Mesh 应有的终态。

挑战

落地所选择的 双11 核心应用都是采用 Java 编程语言实现的,在落地的过程中我们面临了以下挑战。

1. 在 SDK 无法升级的情形下如何实现应用的 Mesh 化

在决定要在 双11 的核心应用上落地 Mesh 时,Java 应用依赖的 RPC SDK 版本已经定稿,为了 Mesh 化完全没有时间去开发一个适用于 Mesh 的 RPC SDK 并做升级。那时,摆在团队面前的技术问题是:如何在不升级 SDK 的情形下,实现 RPC 协议的 Mesh 化?

熟悉 Istio 的读者想必清楚,Istio 是通过 iptables 的 NAT 表去做流量透明拦截的,通过流量透明拦截可在应用无感的情形下将流量劫持到 Envoy 中从而实现 Mesh 化。但很不幸,NAT 表所使用到的 nf_contrack 内核模块因为效率很低,在阿里巴巴的线上生产机器中被去除了,因此无法直接使用社区的方案。好在年初开始不久我们与阿里巴巴 OS 团队达成了合作共建,由他们负责承担 Service Mesh 所需的流量透明拦截和网络加速这两块基础能力的建设。经过两个团队的紧密合作,OS 团队探索了通过基于 userid 和 mark 标识流量的透明拦截方案,基于 iptables 的 mangle 表实现了一个全新的透明拦截组件。

下图示例说明了存在透明拦截组件的情形下,RPC 服务调用的流量走向。其中,Inbound 流量是指调进来的流量(流量的接受者是 Provider 角色),而 Outbound 是指调出去的流量(流量的发出者是 Consumer 角色)。通常一个应用会同时承担两个角色,所以有 Inbound 和 Outbound 两股流量并存。

2.png

有了透明拦截组件之后,应用的 Mesh 化完全能做到无感,这将极大地改善 Mesh 落地的便利性。当然,由于 RPC 的 SDK 仍存在以前的服务发现和路由逻辑,而该流量被劫持到 Envoy 之后又会再做一次,这将导致 Outbound 的流量会因为存在两次服务发现和路由而增加 RT,这在后面的数据部分也将有所体现。显然,以终态落地 Service Mesh 时,需要去除 RPC SDK 中的服务发现与路由逻辑,将相应的 CPU 和内存开销给节约下来。

2.短时间内支持电商业务复杂的服务治理功能

路由

在阿里巴巴电商业务场景下的路由特性丰富多样,除了要支持单元化、环境隔离等路由策略,还得根据 RPC 请求的方法名、调用参数、应用名等完成服务路由。阿里巴巴内部的 Java RPC 框架是通过嵌入 Groovy 脚本来支持这些路由策略的,业务方在运维控制台上配置 Groovy 路由模板,SDK 发起调用时会执行该脚本完成路由策略的运用。

未来的 Service Mesh 并不打算提供 Groovy 脚本那么灵活的路由策略定制方案,避免因为过于灵活而给 Service Mesh 自身的演进带去掣肘。因此,我们决定借 Mesh 化的机会去除 Groovy 脚本。通过落地应用所使用 Groovy 脚本的场景分析,我们抽象出了一套符合云原生的解决方案:扩展 Istio 原生的 CRD 中的 VirtualService 和 DestinationRule,增加 RPC 协议所需的路由配置段去表达路由策略。

3.png

目前阿里巴巴环境下的单元化、环境隔离等策略都是在 Istio/Envoy 的标准路由模块内做了定制开发,不可避免地存在一些 hack 逻辑。未来计划在 Istio/Envoy 的标准路由策略之外,设计一套基于 Wasm 的路由插件方案,让那些简单的路由策略以插件的形式存在。如此一来,既减少了对标准路由模块的侵入,也在一定程度上满足了业务方对服务路由定制的需要。设想的架构如下图所示:

4.png

限流

出于性能考虑,阿里巴巴内部落地的 Service Mesh 方案并没有采用 Istio 中的 Mixer 组件,限流这块功能借助阿里巴巴内部广泛使用的 Sentinel 组件来实现,不仅可以与已经开源的 Sentinel 形成合力,还可以减少阿里巴巴内部用户的迁移成本(直接兼容业务的现有配置来限流)。为了方便 Mesh 集成,内部多个团队合作开发了 Sentinel 的 C++版本,整个限流的功能是通过 Envoy 的 Filter 机制来实现的,我们在 Dubbo 协议之上构建了相应的 Filter(Envoy 中的术语,代表处理请求的一个独立功能模块),每个请求都会经过 Sentinel Filter 做处理。限流所需的配置信息则是通过 Pilot 从 Nacos 中获取,并通过 xDS 协议下发到 Envoy 中。

5.png

3. Envoy 的资源开销过大

Envoy 诞生之初要解决的一个核心问题就是服务的可观测性,因此 Envoy 一开始就内置了大量的 stats(即统计信息),以便更好地对服务进行观测。

Envoy 的 stats 粒度很细,甚至细到整个集群的 IP 级别,在阿里巴巴环境下,某些电商应用的 Consumer 和 Provider 服务加起来达到了几十万之多的 IP(每个 IP 在不同的服务下携带的元信息不同,所以不同的服务下的相同 IP 是各自独立的)。如此一来,Envoy 在这块的内存开销甚是巨大。为此,我们给 Envoy 增加了 stats 开关,用于关闭或打开 IP 级别的 stats,关闭 IP 级别的 stats 直接带来了内存节约 30% 成果。下一步我们将跟进社区的 stats symbol table 的方案来解决 stats 指标字符串重复的问题,那时的内存开销将进一步减少。

4. 解耦业务与基础设施,实现基础设施升级对业务无感

Service Mesh 落地的一项核心价值就是让基础设施与业务逻辑完全解耦,两者可以独立演进。为了实现这个核心价值,Sidecar 需要具备热升级能力,以便升级时不会造成业务流量中断,这对方案设计和技术实现的挑战还是蛮大的。

我们的热升级采用双进程方案,先拉起新的 Sidecar 容器,由它与旧的 Sidecar 进行运行时数据交接,在新的 Sidecar 准备发接管流量后,让旧的 Sidecar 等待一定时间后退出,最终实现业务流量无损。核心技术主要是运用了 Unix Domain Socket 和 RPC 的节点优雅下线功能。下图大致示例了关键过程。

6.png

数据表现

公布性能数据一不小心就会引发争议和误解,因为性能数据的场景存在很多变量。比如,并发度、QPS、payload 大小等对最终的数据表现将产生关键影响。也正因如此,Envoy 官方从来没有提供过本文所列出的这些数据,背后的原因正是其作者 Matt Klein 担心引发误解。值得强调的是,在时间非常紧迫的情形下,我们所落地的 Service Mesh 并非处于最优状态,甚至不是最终方案(比如 Consumer 侧存在两次路由的问题)。我们之所以选择分享出来,是希望让更多的同行了解我们的进展和状态。

本文只列出了 双11 所上线核心应用中某一个的数据。从单机 RT 抽样的角度,部署了 Service Mesh 的某台机器,其 Provider 侧的 RT 均值是 5.6ms,Consumer 侧的是 10.36ms。该机器在 双11 零点附近的 RT 表现如下图所示:

7.jpeg

没有部署 Service Mesh 的某台机器,Provider 侧的均值为 5.34ms,Consumer 侧的则是 9.31ms。下图示例了该机器在 双11 零点附件的 RT 表现。

8.jpeg

相比之下,Provider 侧的 RT 在 Mesh 化前后增加了 0.26ms,Consumer 侧则增加了 1.05ms。注意,这个 RT 差是包含了业务应用到 Sidecar,以及 Sidecar 处理的所有时间在内的,下图示例说明了带来时延增加的链路。

9.png

整体上,该核心应用所有上线了 Service Mesh 的机器和没有上线 Service Mesh 的机器在某个时间段的整体均值数据做了对比。Provider 侧 Mesh 化后的 RT 增加了 0.52ms,而 Consumer 侧增加了 1.63ms。

在 CPU 和内存开销方面,Mesh 化之后,Envoy 所消耗的 CPU 在所有核心应用上都维持在 0.1 核左右,会随着 Pilot 推送数据而产生毛刺。未来需要借助 Pilot 和 Envoy 之间的增量推送去对毛刺做优化。内存的开销随着应用的服务和集群规模不同而存在巨大差异,目前看来 Envoy 在内存的使用上仍存在很大的优化空间。

从所有双11 上线的核心应用的数据表现来看,Service Mesh 的引入对于 RT 的影响和带来的 CPU 开销是基本一样的,而内存开销则因为依赖服务和集群规模的不同而有相当大的差异。

展望

在云原生的浪潮下,阿里巴巴借这波技术浪潮致力于打造面向未来的技术基础设施。在发展的道路上将贯彻“借力开源,反哺开源”的发展思路,通过开源实现技术普惠,为未来的云原生技术在更大范围的普及做出自己的贡献。

接下来,我们的整体技术着力点在于:

  • 与 Istio 开源社区共同增强 Pilot 的数据推送能力。在阿里巴巴具备 双11 这种超大规模的应用场景下,我们对于Pilot 的数据推送能力有着极致的要求,相信在追求极致的过程中,能与开源社区一道加速全球事实标准的共建。从阿里巴巴内部来看,我们目前拉通了与 Nacos 团队的共建,将通过社区的 MCP 协议与 Nacos 对接,让阿里巴巴所开源的各种技术组件能体系化地协同工作;
  • 以 Istio 和 Envoy 为一体,进一步优化两者的协议以及各自的管理数据结构,通过更加精炼、更加合理的数据结构去减少各自的内存开销;
  • 着力解决大规模 Sidecar 的运维能力建设。让 Sidecar 的升级做到可灰度、可监控和可回滚;
  • 兑现 Service Mesh 的价值,让业务与技术设施能以更高的效率彼此独立演进。

ban.jpg

本书亮点

  • 双11 超大规模 K8s 集群实践中,遇到的问题及解决方法详述
  • 云原生化最佳组合:Kubernetes+容器+神龙,实现核心系统 100% 上云的技术细节
  • 双 11 Service Mesh 超大规模落地解决方案

阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
每秒7亿次请求,阿里新一代数据库如何支撑? Mon, 16 Dec 2019 05:35:02 +0800 作者 | 正研

2019年以来,Lindorm已经服务了包括淘宝、天猫、蚂蚁、菜鸟、妈妈、优酷、高德、大文娱等数十个BU,在今年的双十一中,Lindorm峰值请求达到了7.5亿次每秒,天吞吐22.9万亿次,平均响应时间低于3ms,整体存储的数据量达到了数百PB。

这些数字的背后,凝聚了HBase&Lindorm团队多年以来的汗水和心血。Lindorm脱胎于HBase,是团队多年以来承载数百PB数据,亿级请求量,上千个业务后,在面对规模成本压力,以及HBase自身缺陷下,全面重构和引擎升级的全新产品。相比HBase,Lindorm无论是性能,功能还是可用性上,都有了巨大飞跃。本文将从功能、可用性、性能成本、服务生态等维度介绍Lindorm的核心能力与业务表现,最后分享部分我们正在进行中的一些项目。

极致优化,超强性能

Lindorm比HBase在RPC、内存管理,缓存、日志写入等方面做了深度的优化,引入了众多新技术,大幅提升了读写性能,在相同硬件的情况下,吞吐可达到HBase的5倍以上,毛刺更是可以达到HBase的1/10。这些性能数据,并不是在实验室条件下产生的,而是在不改动任何参数的前提下,使用开源测试工具YCSB跑出来的成绩。我们把测试的工具和场景都公布在阿里云的帮助文件中,任何人都可以依照指南自己跑出一样的结果。

1202.jpg

取得这么优异的性能的背后,是Lindorm中积攒多年的“黑科技”,下面,我们简单介绍下Lindorm内核中使用到的部分“黑科技”。

Trie Index

Lindorm 的文件LDFile(类似HBase中的HFile)是只读 B+ 树结构,其中文件索引是至关重要的数据结构。在 block cache 中有高优先级,需要尽量常驻内存。如果能降低文件索引所占空间大小,我们可以节省 block cache 中索引所需要的宝贵内存空间。或者在索引空间不变的情况下,增加索引密度,降低 data block 的大小,从而提高性能。而HBase中的索引block中存的是全量的Rowkey,而在一个已经排序好的文件中,很多Rowkey都是有共同前缀的。

数据结构中的Trie (前缀树) 结构能够让共同前缀只存一份,避免重复存储带来的浪费。但是传统前缀树结构中,从一个节点到下一个节点的指针占用空间太多,整体而言得不偿失。这一情况有望用 Succinct Prefix Tree 来解决。SIGMOD2018年的最佳论文 Surf 中提出了一种用 Succinct Prefix Tree 来取代 bloom filter,并同时提供 range filtering 的功能。我们从这篇文章得到启发,用 Succinct Trie 来做 file block index。

1203.jpg

我们在线上的多个业务中使用了Trie index实现的索引结构。结果发现,各个场景中,Trie index可以大大缩小索引的体积,最多可以压缩12倍的索引空间!节省的这些宝贵空间让内存Cache中能够存放更多的索引和数据文件,大大提高了请求的性能。

1204.jpg

ZGC加持,百GB堆平均5ms暂停

ZGC(Powerd by Dragonwell JDK)是下一代Pauseless GC算法的代表之一,其核心思想是Mutator利用内存读屏障(Read Barrier)识别指针变化,使得大部分的标记(Mark)与合并(Relocate)工作可以放在并发阶段执行。

这样一项实验性技术,在Lindorm团队与AJDK团队的紧密合作下,进行了大量的改进与改造工作。使得ZGC在Lindorm这个场景上实现了生产级可用,主要工作包括:

Lindorm内存自管理技术,数量级减少对象数与内存分配速率。(比如说阿里HBase团队贡献给社区的CCSMap)。
AJDK ZGC Page缓存机制优化(锁、Page缓存策略)。
AJDK ZGC 触发时机优化,ZGC无并发失败。AJDK ZGC在Lindorm上稳定运行两个月,并顺利通过双十一大考。其JVM暂停时间稳定在5ms左右,最大暂停时间不超过8ms。ZGC大大改善了线上运行集群的RT与毛刺指标,平均RT优化15%~20%,P999 RT减少一倍。在今年双十一蚂蚁风控集群中,在ZGC的加持下,P999时间从12ms降低到了5ms。

1205.jpg

注:图中的单位应该为us,平均GC在5ms

LindormBlockingQueue

1206.jpg

上图是HBase中的RegionServer从网络上读取RPC请求并分发到各个Handler上执行的流程。HBase中的RPC Reader从Socket上读取RPC请求放入BlockingQueue,Handler订阅这个Queue并执行请求。而这个BlockingQueue,HBase使用的是Java原生的JDK自带的LinkedBlockingQueue。

LinkedBlockingQueue利用Lock与Condition保证线程安全与线程之间的同步,虽然经典易懂,但当吞吐增大时,这个queue会造成严重的性能瓶颈。因此在Lindorm中全新设计了LindormBlockingQueue,将元素维护在Slot数组中。维护head与tail指针,通过CAS操作对进队列进行读写操作,消除了临界区。并使用Cache Line Padding与脏读缓存加速,同时可定制多种等待策略(Spin/Yield/Block),避免队列为空或为满时,频繁进入Park状态。LindormBlockingQueue的性能非常突出,相比于原先的LinkedBlockingQueue性能提升4倍以上。

1207.jpg

VersionBasedSynchronizer

1208.jpg

LDLog是Lindorm中用于系统failover时进行数据恢复时的日志,以保障数据的原子性和可靠性。在每次数据写入时,都必须先写入LDLog。LDLog写入成功之后,才可以进行后续的写入memstore等操作。因此Lindorm中的Handler都必须等待WAL写入完成后再被唤醒以进行下一步操作,在高压条件下,无用唤醒会造成大量的CPU Context Switch造成性能下降。针对这个问题,Lindorm研发了基于版本的高并发多路线程同步机制(VersionBasedSynchronizer)来大幅优化上下文切换。

VersionBasedSynchronizer的主要思路是让Handler的等待条件被Notifier感知,减少Notifier的唤醒压力。经过模块测试VersionBasedSynchronizer的效率是JDK自带的ObjectMonitor和J.U.C(java util concurrent包)的两倍以上。

1209.jpg

全面无锁化

HBase内核在关键路径上有大量的锁,在高并发场景下,这些锁都会造成线程争抢和性能下降。Lindorm内核对关键链路上的锁都做了无锁化处理,如MVCC,WAL模块中的锁。另外,HBase在运行过程中会产生的各种指标,如qps,rt,cache命中率等等。而在记录这些Metrics的“不起眼”操作中,也会有大量的锁。面对这样的问题,Lindorm借鉴了tcmalloc的思想,开发了LindormThreadCacheCounter,来解决Metrics的性能问题。

1210.jpg

Handler协程化

在高并发应用中,一个RPC请求的实现往往包含多个子模块,涉及到若干次IO。这些子模块的相互协作,系统的ContextSwitch相当频繁。ContextSwitch的优化是高并发系统绕不开的话题,各位高手都各显神通,业界有非常多的思想与实践。其中coroutine(协程)和SEDA(分阶段事件驱动)方案是我们着重考察的方案。基于工程代价,可维护性,代码可读性三个角度考虑,Lindorm选择了协程的方式进行异步化优化。我们利用了阿里JVM团队提供的Dragonwell JDK内置的Wisp2.0功能实现了HBase Handler的协程化,Wisp2.0开箱即用,有效地减少了系统的资源消耗,优化效果比较客观。

全新Encoding算法

从性能角度考虑,HBase通常需要将Meta信息装载进block cache。如果将block大小较小,Meta信息较多,会出现Meta无法完全装入Cache的情况, 性能下降。如果block大小较大,经过Encoding的block的顺序查询的性能会成为随机读的性能瓶颈。针对这一情况,Lindorm全新开发了Indexable Delta Encoding,在block内部也可以通过索引进行快速查询,seek性能有了较大提高。Indexable Delta Encoding原理如图所示:

1211.jpg

通过Indexable Delta Encoding, HFile的随机seek性能相对于使用之前翻了一倍,以64K block为例,随机seek性能基本与不做encoding相近(其他encoding算法会有一定性能损失)。在全cache命中的随机Get场景下,相对于Diff encoding RT下降50%

其他

相比社区版HBase,Lindorm还有多达几十项的性能优化和重构,引入了众多新技术,由于篇幅有限,这里只能列举一部分,其他的核心技术,比如:

CCSMap
自动规避故障节点的并发三副本日志协议 (Quorum-based write)
高效的批量组提交(Group Commit)
无碎片的高性能缓存—Shared BucketCache
Memstore Bloomfilter
面向读写的高效数据结构
GC-Invisible内存管理
在线计算与离线作业架构分离
JDK/操作系统深度优化
FPGA offloading Compaction
用户态TCP加速
……

丰富的查询模型,降低开发门槛

原生的HBase只支持KV结构的查询,虽然简单,但是在面对各项业务的复杂需求时,显的有点力不从心。因此,在Lindorm中,我们针对不同业务的特点,研发了多种查询模型,通过更靠近场景的API和索引设计,降低开发门槛。

WideColumn 模型(原生HBase API)

WideColumn是一种与HBase完全一致的访问模型和数据结构,从而使得Lindrom能100%兼容HBase的API。用户可以通过Lindorm提供的高性能原生客户端中的WideColumn API访问Lindorm,也可以通过alihbase-connector这个插件,使用HBase客户端及API(无需任何代码改造)直接访问Lindorm。同时,Lindorm使用了轻客户端的设计,将大量数据路由、批量分发、超时、重试等逻辑下沉到服务端,并在网络传输层做了大量的优化,使得应用端的CPU消耗可以大大节省。像下表中,相比于HBase,使用Lindorm后的应用侧CPU使用效率提升60%,网络带宽效率提升25%。

1212.jpg

注:表中的客户端CPU代表HBase/Lindorm客户端消耗的CPU资源,越小越好。

在HBase原生API上,我们还独家支持了高性能二级索引,用户可以使用HBase原生API写入数据过程中,索引数据透明地写入索引表。在查询过程中,把可能全表扫的Scan + Filter大查询,变成可以先去查询索引表,大大提高了查询性能。关于高性能原生二级索引,大家可以参考:
https://help.aliyun.com/document_detail/144577.html

TableService模型(SQL、二级索引)

HBase中只支持Rowkey这一种索引方式,对于多字段查询时,通常效率低下。为此,用户需要维护多个表来满足不同场景的查询需求,这在一定程度上既增加了应用的开发复杂性,也不能很完美地保证数据一致性和写入效率。并且HBase中只提供了KV API,只能做Put、Get、Scan等简单API操作,也没有数据类型,所有的数据都必须用户自己转换和储存。对于习惯了SQL语言的开发者来说,入门的门槛非常高,而且容易出错。

为了解决这一痛点,降低用户使用门槛,提高开发效率,在Lindorm中我们增加了TableService模型,其提供丰富的数据类型、结构化查询表达API,并原生支持SQL访问和全局二级索引,解决了众多的技术挑战,大幅降低普通用户的开发门槛。通过SQL和SQL like的API,用户可以方便地像使用关系数据库那样使用Lindorm。下面是一个Lindorm SQL的简单示例。

-- 主表和索引DDL
create table shop_item_relation (
    shop_id varchar,
    item_id varchar,
    status varchar
constraint primary key(shop_id, item_id)) ;
create index idx1 on shop_item_relation (item_id) include (ALL);   -- 对第二列主键建索引,冗余所有列
create index idx2 on shop_item_relation (shop_id, status) include (ALL);  -- 多列索引,冗余所有列
-- 写入数据,会同步更新2个索引
upsert into shop_item_relation values('shop1', 'item1',  'active');
upsert into shop_item_relation values('shop1', 'item2',  'invalid');
-- 根据WHERE子句自动选择合适的索引执行查询
select * from shop_item_relation where item_id = 'item2';  -- 命中idx1
select * from shop_item_relation where shop_id = 'shop1' and status = 'invalid'; -- 命中idx2

相比于关系数据库的SQL,Lindorm不具备多行事务和复杂分析(如Join、Groupby)的能力,这也是两者之间的定位差异。

相比于HBase上Phoenix组件提供的二级索引,Lindorm的二级索引在功能、性能、稳定性上远远超过Phoenix,下图是一个简单的性能对比。

1214.jpg

1215.jpg

注:该模型已经在阿里云HBase增强版上内测,感兴趣的用户可以联系云HBase答疑钉钉号或者在阿里云上发起工单咨询。

FeedStream模型

现代互联网架构中,消息队列承担了非常重要的职责,可以极大的提升核心系统的性能和稳定性。其典型的应用场景有包括系统解耦,削峰限流,日志采集,最终一致保证,分发推送等等。

常见的消息队列包括RabbitMq,Kafka以及RocketMq等等。这些数据库尽管从架构和使用方式和性能上略有不同,但其基本使用场景都相对接近。然而,传统的消息队列并非完美,其在消息推送,feed流等场景存在以下问题:

存储:不适合长期保存数据,通常过期时间都在天级
删除能力:不支持删除指定数据entry
查询能力:不支持较为复杂的查询和过滤条件
一致性和性能难以同时保证:类似于Kafka之类的数据库更重吞吐,为了提高性能存在了某些状况下丢数据的可能,而事务处理能力较好的消息队列吞吐又较为受限。
Partition快速拓展能力:通常一个Topc下的partition数目都是固定,不支持快速扩展。
物理队列/逻辑队列:通常只支持少量物理队列(如每个partition可以看成一个队列),而业务需要的在物理队列的基础上模拟出逻辑队列,如IM系统中为每个用户维护一个逻辑上的消息队列,用户往往需要很多额外的开发工作。
针对上述需求,Lindorm推出了队列模型FeedStreamService,能够解决海量用户下的消息同步,设备通知,自增ID分配等问题。

1216.jpg

FeedStream模型在今年手机淘宝消息系统中扮演了重要角色,解决了手机淘宝消息推送保序,幂等等难题。在今年双十一中,手淘的盖楼和回血大红包推送都有Lindorm的身影。手淘消息的推送中,峰值超过了100w/s,做到了分钟级推送全网用户。

1217.jpg

注:该模型已经在阿里云HBase增强版上内测,感兴趣的用户可以联系云HBase答疑钉钉号或者在阿里云上发起工单咨询。

全文索引模型

虽然Lindorm中的TableService模型提供了数据类型和二级索引。但是,在面对各种复杂条件查询和全文索引的需求下,还是显得力不从心,而Solr和ES是优秀的全文搜索引擎。使用Lindorm+Solr/ES,可以最大限度发挥Lindorm和Solr/ES各自的优点,从而使得我们可以构建复杂的大数据存储和检索服务。Lindorm内置了外部索引同步组件,能够自动地将写入Lindorm的数据同步到外部索引组件如Solr或者ES中。这种模型非常适合需要保存大量数据,而查询条件的字段数据仅占原数据的一小部分,并且需要各种条件组合查询的业务,例如:

常见物流业务场景,需要存储大量轨迹物流信息,并需根据多个字段任意组合查询条件
交通监控业务场景,保存大量过车记录,同时会根据车辆信息任意条件组合检索出感兴趣的记录
各种网站会员、商品信息检索场景,一般保存大量的商品/会员信息,并需要根据少量条件进行复杂且任意的查询,以满足网站用户任意搜索需求等。

1218.jpg

全文索引模型已经在阿里云上线,支持Solr/ES外部索引。目前,索引的查询用户还需要直接查询Solr/ES再来反查Lindorm,后续我们会用TableService的语法把查询外部索引的过程包装起来,用户全程只需要和Lindorm交互,即可获得全文索引的能力。

更多模型在路上

除了上述这些模型,我们还会根据业务的需求和痛点,开发更多简单易用的模型,方便用户使用,降低使用门槛。像时序模型,图模型等,都已经在路上,敬请期待。

零干预、秒恢复的高可用能力

从一个婴儿成长为青年,阿里HBase摔过很多次,甚至头破血流,我们在客户的信任之下幸运的成长。在9年的阿里应用过程中,我们积累了大量的高可用技术,而这些技术,都应用到了HBase增强版中。

MTTR优化

HBase是参照Gooogle著名论文BigTable的开源实现,其中最核心特点是数据持久化存储于底层的分布式文件系统HDFS,通过HDFS对数据的多副本维护来保障整个系统的高可靠性,而HBase自身不需要去关心数据的多副本及其一致性,这有助于整体工程的简化,但也引入了"服务单点"的缺陷,即对于确定的数据的读写服务只有发生固定的某个节点服务器,这意味着当一个节点宕机后,数据需要通过重放Log恢复内存状态,并且重新派发给新的节点加载后,才能恢复服务。

当集群规模较大时,HBase单点故障后恢复时间可能会达到10-20分钟,大规模集群宕机的恢复时间可能需要好几个小时!而在Lindorm内核中,我们对MTTR(平均故障恢复时间)做了一系列的优化,包括故障恢复时先上线region、并行replay、减少小文件产生等众多技术。将故障恢复速度提升10倍以上!基本上接近了HBase设计的理论值。

可调的多一致性

在原来的HBase架构中,每个region只能在一个RegionServer中上线,如果这个region server宕机,region需要经历Re-assgin,WAL按region切分,WAL数据回放等步骤后,才能恢复读写。这个恢复时间可能需要数分钟,对于某些高要求的业务来说,这是一个无法解决的痛点。另外,虽然HBase中有主备同步,但故障下只能集群粒度的手动切换,并且主和备的数据只能做到最终一致性,而有一些业务只能接受强一致,HBase在这点上望尘莫及。

Lindorm内部实现了一种基于Shared Log的一致性协议,通过分区多副本机制达到故障下的服务自动快速恢复的能力,完美适配了存储分离的架构, 利用同一套体系即可支持强一致语义,又可以选择在牺牲一致性的前提换取更佳的性能和可用性,实现多活,高可用等多种能力。

在这套架构下,Lindorm拥有了以下几个一致性级别,用户可以根据自己的业务自由选择一致性级别:

1219.jpg

注:该功能暂时未在阿里云HBase增强版上对外开放

客户端高可用切换

虽然说目前HBase可以组成主备,但是目前市面上没有一个高效地客户端切换访问方案。HBase的客户端只能访问固定地址的HBase集群。如果主集群发生故障,用户需要停止HBase客户端,修改HBase的配置后重启,才能连接备集群访问。或者用户在业务侧必须设计一套复杂地访问逻辑来实现主备集群的访问。阿里HBase改造了HBase客户端,流量的切换发生在客户端内部,通过高可用的通道将切换命令发送给客户端,客户端会关闭旧的链接,打开与备集群的链接,然后重试请求。

1220.jpg

如果需要使用此项功能,请参考高可用帮助文档:
https://help.aliyun.com/document_detail/140940.html

云原生,更低使用成本

Lindorm从立项之初就考虑到上云,各种设计也能尽量复用云上基础设施,为云的环境专门优化。比如在云上,我们除了支持云盘之外,我们还支持将数据存储在OSS这种低成本的对象存储中减少成本。我们还针对ECS部署做了不少优化,适配小内存规格机型,加强部署弹性,一切为了云原生,为了节省客户成本。

ECS+云盘的极致弹性

目前Lindorm在云上的版本HBase增强版均采用ECS+云盘部署(部分大客户可能采用本地盘),ECS+云盘部署的形态给Lindorm带来了极致的弹性。

1221.jpg

最开始的时候,HBase在集团的部署均采用物理机的形式。每个业务上线前,都必须先规划好机器数量和磁盘大小。在物理机部署下,往往会遇到几个难以解决的问题:

业务弹性难以满足:当遇到业务突发流量高峰或者异常请求时,很难在短时间内找到新的物理机扩容。
存储和计算绑定,灵活性差:物理机上CPU和磁盘的比例都是一定的,但是每个业务的特点都不一样,采用一样的物理机,有一些业务计算资源不够,但存储过剩,而有些业务计算资源过剩,而存储瓶颈。特别是在HBase引入混合存储后,HDD和SSD的比例非常难确定,有些高要求的业务常常会把SSD用满而HDD有剩余,而一些海量的离线型业务SSD盘又无法利用上。
运维压力大:使用物理机时,运维需要时刻注意物理机是否过保,是否有磁盘坏,网卡坏等硬件故障需要处理,物理机的报修是一个漫长的过程,同时需要停机,运维压力巨大。对于HBase这种海量存储业务来说,每天坏几块磁盘是非常正常的事情。而当Lindorm采用了ECS+云盘部署后,这些问题都迎刃而解。

ECS提供了一个近似无限的资源池。当面对业务的紧急扩容时,我们只需在资源池中申请新的ECS拉起后,即可加入集群,时间在分钟级别之内,无惧业务流量高峰。配合云盘这样的存储计算分离架构。我们可以灵活地为各种业务分配不同的磁盘空间。当空间不够时,可以直接在线扩缩容磁盘。同时,运维再也不用考虑硬件故障,当ECS有故障时,ECS可以在另外一台宿主机上拉起,而云盘完全对上层屏蔽了坏盘的处理。极致的弹性同样带来了成本的优化。我们不需要为业务预留太多的资源,同时当业务的大促结束后,能够快速地缩容降低成本。

1222.jpg

一体化冷热分离

在海量大数据场景下,一张表中的部分业务数据随着时间的推移仅作为归档数据或者访问频率很低,同时这部分历史数据体量非常大,比如订单数据或者监控数据,降低这部分数据的存储成本将会极大的节省企业的成本。如何以极简的运维配置成本就能为企业极大降低存储成本,Lindorm冷热分离功能应运而生。Lindorm为冷数据提供新的存储介质,新的存储介质存储成本仅为高效云盘的1/3。

Lindorm在同一张表里实现了数据的冷热分离,系统会自动根据用户设置的冷热分界线自动将表中的冷数据归档到冷存储中。在用户的访问方式上和普通表几乎没有任何差异,在查询的过程中,用户只需配置查询Hint或者TimeRange,系统根据条件自动地判断查询应该落在热数据区还是冷数据区。对用户而言始终是一张表,对用户几乎做到完全的透明。详细介绍请参考:
https://yq.aliyun.com/articles/718395

1223.jpg

ZSTD-V2,压缩比再提升100%

早在两年前,我们就把集团内的存储压缩算法替换成了ZSTD,相比原来的SNAPPY算法,获得了额外25%的压缩收益。今年我们对此进一步优化,开发实现了新的ZSTD-v2算法,其对于小块数据的压缩,提出了使用预先采样数据进行训练字典,然后用字典进行加速的方法。我们利用了这一新的功能,在Lindorm构建LDFile的时候,先对数据进行采样训练,构建字典,然后在进行压缩。在不同业务的数据测试中,我们最高获得了超过原生ZSTD算法100%的压缩比,这意味着我们可以为客户再节省50%的存储费用。

1224.jpg

HBase Serverless版,入门首选

阿里云HBase Serverless 版是基于Lindorm内核,使用Serverless架构构建的一套新型的HBase 服务。阿里云HBase Serverless版真正把HBase变成了一个服务,用户无需提前规划资源,选择CPU,内存资源数量,购买集群。在应对业务高峰,业务空间增长时,也无需进行扩容等复杂运维操作,在业务低谷时,也无需浪费闲置资源。

在使用过程中,用户可以完全根据当前业务量,按需购买请求量和空间资源即可。使用阿里云HBase Serverless版本,用户就好像在使用一个无限资源的HBase集群,随时满足业务流量突然的变化,而同时只需要支付自己真正使用的那一部分资源的钱。

1225.jpg

关于HBase Serverless的介绍和使用,可以参考:
https://developer.aliyun.com/article/719206

面向大客户的安全和多租户能力

Lindorm引擎内置了完整的用户名密码体系,提供多种级别的权限控制,并对每一次请求鉴权,防止未授权的数据访问,确保用户数据的访问安全。同时,针对企业级大客户的诉求,Lindorm内置了Group,Quota限制等多租户隔离功能,保证企业中各个业务在使用同一个HBase集群时不会被相互影响,安全高效地共享同一个大数据平台。

用户和ACL体系

Lindorm内核提供一套简单易用的用户认证和ACL体系。用户的认证只需要在配置中简单的填写用户名密码即可。用户的密码在服务器端非明文存储,并且在认证过程中不会明文传输密码,即使验证过程的密文被拦截,用以认证的通信内容不可重复使用,无法被伪造。

Lindorm中有三个权限层级。Global,Namespace和Table。这三者是相互覆盖的关系。比如给user1赋予了Global的读写权限,则他就拥有了所有namespace下所有Table的读写权限。如果给user2赋予了Namespace1的读写权限,那么他会自动拥有Namespace1中所有表的读写权限。

Group隔离

当多个用户或者业务在使用同一个HBase集群时,往往会存在资源争抢的问题。一些重要的在线业务的读写,可能会被离线业务批量读写所影响。而Group功能,则是HBase增强版(Lindorm)提供的用来解决多租户隔离问题的功能。

通过把RegionServer划分到不同的Group分组,每个分组上host不同的表,从而达到资源隔离的目的。

1226.jpg

例如,在上图中,我们创建了一个Group1,把RegionServer1和RegionServer2划分到Group1中,创建了一个Group2,把RegionServer3和RegionServer4划分到Group2。同时,我们把Table1和Table2也移动到Group1分组。这样的话,Table1和Table2的所有region,都只会分配到Group1中的RegionServer1和RegionServer2这两台机器上。

同样,属于Group2的Table3和Table4的Region在分配和balance过程中,也只会落在RegionServer3和RegionServer4上。因此,用户在请求这些表时,发往Table1、Table2的请求,只会由RegionServer1和RegionServer2服务,而发往Table3和Table4的请求,只会由RegionServer3和RegionServer4服务,从而达到资源隔离的目的。

Quota限流

Lindorm内核中内置了一套完整的Quota体系,来对各个用户的资源使用做限制。对于每一个请求,Lindorm内核都有精确的计算所消耗的CU(Capacity Unit),CU会以实际消耗的资源来计算。比如用户一个Scan请求,由于filter的存在,虽然返回的数据很少,但可能已经在RegionServer已经消耗大量的CPU和IO资源来过滤数据,这些真实资源的消耗,都会计算在CU里。在把Lindorm当做一个大数据平台使用时,企业管理员可以先给不同业务分配不同的用户,然后通过Quota系统限制某个用户每秒的读CU不能超过多少,或者总的CU不能超过多少,从而限制用户占用过多的资源,影响其他用户。同时,Quota限流也支持Namesapce级别和表级别限制。

最后

全新一代NoSQL数据库Lindorm是阿里巴巴HBase&Lindorm团队9年以来技术积累的结晶,Lindorm在面向海量数据场景提供世界领先的高性能、可跨域、多一致、多模型的混合存储处理能力。对焦于同时解决大数据(无限扩展、高吞吐)、在线服务(低延时、高可用)、多功能查询的诉求,为用户提供无缝扩展、高吞吐、持续可用、毫秒级稳定响应、强弱一致可调、低存储成本、丰富索引的数据实时混合存取能力。

Lindorm已经成为了阿里巴巴大数据体系中的核心产品之一,成功支持了集团各个BU上千个业务,也多次在天猫双十一“技术大团建”中经受住了考验。阿里CTO行癫说过,阿里的技术都应该通过阿里云输出,去普惠各行各业数百万客户。因此Lindorm从今年开始,已经在阿里云上以“HBase增强版”的形式,以及在专有云中对外输出(详情点击文末“阅读原文”或长按下方二维码了解)让云上的客户能够享受到阿里巴巴的技术红利,助力业务腾飞!

]]>
干货 | 如何成为大数据Spark高手 Mon, 16 Dec 2019 05:35:02 +0800

原创: 浪尖
原文链接:https://mp.weixin.qq.com/s/jHp-LcqdHSg2DbLhWIbSfg

Spark是发源于美国加州大学伯克利分校AMPLab的集群计算平台,它立足于内存计算,性能超过Hadoop百倍,从多迭代批量处理出发,兼收并蓄数据仓库、流处理和图计算等多种计算范式,是罕见的全能选手。Spark采用一个统一的技术堆栈解决了云计算大数据的如流处理、图技术、机器学习、NoSQL查询等方面的所有核心问题,具有完善的生态系统,这直接奠定了其一统云计算大数据领域的霸主地位。

伴随Spark技术的普及推广,对专业人才的需求日益增加。Spark专业人才在未来也是炙手可热,轻而易举可以拿到百万的薪酬。而要想成为Spark高手,也需要一招一式,从内功练起:通常来讲需要经历以下阶段:

第一阶段:熟练的掌握Scala及java语言

  1. Spark框架是采用Scala语言编写的,精致而优雅。要想成为Spark高手,你就必须阅读Spark的源代码,就必须掌握Scala,;
  2. 虽然说现在的Spark可以采用多语言Java、Python等进行应用程序开发,但是最快速的和支持最好的开发API依然并将永远是Scala方式的API,所以你必须掌握Scala来编写复杂的和高性能的Spark分布式程序;
  3. 尤其要熟练掌握Scala的trait、apply、函数式编程、泛型、逆变与协变等;
  4. 掌握JAVA语言多线程,netty,rpc,ClassLoader,运行环境等(源码需要)。

第二阶段:精通Spark平台本身提供给开发者API

  1. 掌握Spark中面向RDD的开发模式部署模式:本地(调试),Standalone,yarn等 ,掌握各种transformation和action函数的使用;
  2. 掌握Spark中的宽依赖和窄依赖以及lineage机制;
  3. 掌握RDD的计算流程,例如Stage的划分、Spark应用程序提交给集群的基本过程和Worker节点基础的工作原理等
  4. 熟练掌握spark on yarn的机制原理及调优

第三阶段:深入Spark内核

此阶段主要是通过Spark框架的源码研读来深入Spark内核部分:

  1. 通过源码掌握Spark的任务提交过程;
  2. 通过源码掌握Spark集群的任务调度;
  3. 尤其要精通DAGScheduler、TaskScheduler,Driver和Executor节点内部的工作的每一步的细节;
  4. Driver和Executor的运行环境及RPC过程
  5. 缓存RDD,Checkpoint,Shuffle等缓存或者暂存垃圾清除机制
  6. 熟练掌握BlockManager,Broadcast,Accumulator,缓存等机制原理
  7. 熟练掌握Shuffle原理源码及调优

第四阶级:掌握基于Spark Streaming

Spark作为云计算大数据时代的集大成者,其中其组件spark Streaming在企业准实时处理也是基本是必备,所以作为大数据从业者熟练掌握也是必须且必要的:

  1. Spark Streaming是非常出色的实时流处理框架,要掌握其DStream、transformation和checkpoint等;
  2. 熟练掌握kafka 与spark Streaming结合的两种方式及调优方式
  3. 熟练掌握Structured Streaming原理及作用并且要掌握其余kafka结合
  4. 熟练掌握SparkStreaming的源码尤其是和kafka结合的两种方式的源码原理。
  5. 熟练掌握spark Streaming的web ui及各个指标,如:批次执行事件处理时间,调度延迟,待处理队列并且会根据这些指标调优。
  6. 会自定义监控系统

第五阶级:掌握基于Spark SQL

企业环境中也还是以数据仓库居多,鉴于大家对实时性要求比较高,那么spark sql就是我们作为仓库分析引擎的最爱(浪尖负责的两个集群都是计算分析一spark sql为主):

  1. spark sql要理解Dataset的概念及与RDD的区别,各种算子
  2. 要理解基于hive生成的永久表和没有hive的临时表的区别
  3. **spark sql+hive metastore基本是标配,无论是sql的支持,还是永久表特性
    **
  4. 要掌握存储格式及性能对比
  5. Spark sql也要熟悉它的优化器catalyst的工作原理。
  6. Spark Sql的dataset的链式计算原理,逻辑计划翻译成物理计划的源码(非必须,面试及企业中牵涉到sql源码调优的比较少)

第六阶级:掌握基于spark机器学习及图计算

企业环境使用spark作为机器学习及深度学习分析引擎的情况也是日渐增多,结合方式就很多了:

java系:

  1. spark ml/mllib spark自带的机器学习库,目前也逐步有开源的深度学习及nlp等框架( spaCy, CoreNLP, OpenNLP, Mallet, GATE, Weka, UIMA, nltk, gensim, Negex, word2vec, GloVe)
  2. 与DeepLearning4j目前用的也比较多的一种形式

python系:

  1. pyspark
  2. spark与TensorFlow结合

第七阶级:掌握spark相关生态边缘

企业中使用spark肯定也会涉及到spark的边缘生态,这里我们举几个常用的软件框架:

  1. hadoop系列:kafka,hdfs,yarn
  2. 输入源及结果输出,主要是:mysql/redis/hbase/mongod
  3. 内存加速的框架redis,Alluxio
  4. es、solr

第八阶级:做商业级别的Spark项目

通过一个完整的具有代表性的Spark项目来贯穿Spark的方方面面,包括项目的架构设计、用到的技术的剖析、开发实现、运维等,完整掌握其中的每一个阶段和细节,这样就可以让您以后可以从容面对绝大多数Spark项目。

第九阶级:提供Spark解决方案

  1. 彻底掌握Spark框架源码的每一个细节;
  2. 根据不同的业务场景的需要提供Spark在不同场景的下的解决方案;
  3. 根据实际需要,在Spark框架基础上进行二次开发,打造自己的Spark框架;

这就是浪尖总结的我们学好spark的主要步骤;想学好,着重留意深色字体的。坚持总是空难,但是坚持下来就会有质的飞跃。

]]>
探讨基于阿里云容器技术架构(一) Mon, 16 Dec 2019 05:35:02 +0800 为什么有这个主题?

记得2018年参加上海KubCon大会时,演讲人现场对国内生产使用Kubernetes情况的调查,现场举手的寥寥无几。时至今日,参加2019“MVP闭门大会”和“云栖大会”,感受到“云原生”无处不在。那么当容器、容器编排遇到传统微服务架构,会擦出怎样的火花,这其中有哪些坑?人类对科学的追求总是义无反顾的,进化到云原生时代,我们的机遇和挑战是什么?

希望在这个场合一起探讨下,没有对错,只有适合与否。关键是当开始有沟通,才可能继续往前走。

这个系列文章采用总分总的方式写,第一篇主要探讨整体架构,后面文章探讨各部分更具体的技术方案,最后总结。

探讨整体架构

让我们从一张图开始第一篇正式内容,这是一个可能的最小化服务化架构:
阿里云微服务技术架构.png
这是一个传统架构和容器技术混合的架构,在全面介绍之前,我们先分别看下各自的发展史,“知道从哪儿来,方知道我们往哪儿去”。

从传统部署时代到容器部署时代

下面这张图从运维角度描述了,应用从传统部署时代如何发展到容器部署时代。也折射出企业上云的发展过程。
image.png

在国内,阿里云吹响了企业上云的号角。第一阶段,是IT基础设施云化,包括虚拟机、网络等上云,降低企业运维成本、提升弹性伸缩能力。第二阶段,是核心架构云化,包括阿里云数据库、阿里云微服务引擎 ( Microservice Engine, 简称:MSE )、全局事务服务GTS等,Kubernetes或许也算。第二阶段的升级版可能是全面拥抱Cloud Native,随着有状态应用和无状态应用全面拥抱Kubernetes,我们可以猜测走向了面向Kubernetes编程时代,开发人员不必关心微服务治理的各种技术栈和开发语言(诸如:Golang、Java等),写好业务代码,定义好云原生开放应用模型(OAM),发布上线即可,应用将变得更轻量、接入成本更低、迭代更敏捷。

IT行业发展是如此迅速,却又是如此必然。类比下,编程语言从汇编、C++、Java到新型语言Golang,无不是从复杂到易用的过程。易用、轻量贯穿整个行业的发展脉络,所以我们有理由相信这一天的到来,尽管过程比较曲折,Istio如今还不尽如人意。

那些年,我们折腾过的微服务架构

下图来源于蚂蚁金服@卓与( 一个帅又专业的小伙:) )的一次SOFAMesh分享。基本代表了,传统微服务架构Dubbo、SOFABoot、Spring Cloud等微服务架构核心能力和应用之间的关系。这类微服务架构提供“胖客户端”集成到应用,这个小胖每次升级都会影响到应用,也增加了中间件开发团队和业务团队沟通、协调成本,因为耦合太紧了。让我们寄希望于Cloud Native来解吧!
image.png

混合架构

熟悉Kubernetes的同学知道,他有几个对于微服务架构来讲重要能力:
容器编排能力
架起了容器镜像和硬件资源的桥梁,通过yarml声明轻松发布“可执行”程序,配合Liveness 和 Readiness可以做到不停机滚动发布,这都减轻了微服务运营成本。
服务发现能力
Kubernetes可以使用DNS(这是一个较早的基于服务端的服务发现模式)名称暴露一个应用集群的服务地址。Kubernetes还可以用负载均衡,把流量分配到Pod,从而使服务更稳定。这部分看着是否和“胖客户端”的服务发现有点儿像。

在Service Mesh没有完全落地之前,我们是否可以结合Kubernetes上述能力和传统微服务架构能力,各自发挥所长,组成一个混合架构呢,于是有了开篇第一张大图。

本篇总结

我们探讨了容器技术和传统微服务架构特点,并且尝试结合各自优势,组成一个混合架构。
后面我们就具体的技术领域做探讨和可能的坑。

]]>
在 Cloudera Data Flow 上运行你的第一个 Flink 例子 Mon, 16 Dec 2019 05:35:02 +0800 文档编写目的

Cloudera Data Flow(CDF) 作为 Cloudera 一个独立的产品单元,围绕着实时数据采集,实时数据处理和实时数据分析有多个不同的功能模块,如下图所示:

1.jpg

图中 4 个功能模块从左到右分别解释如下:

  1. Cloudera Edge Management(CEM),主要是指在边缘设备如传感器上部署 MiNiFi 的 agent 后用于采集数据。
  2. Cloudera Flow Management(CFM),主要是使用 Apache NiFi 通过界面化拖拽的方式实现数据采集,处理和转换。
  3. Cloudera Streaming Processing(CSP),主要包括 Apache Kafka,Kafka Streams,Kafka 的监控 Streams Messaging Manager(SMM),以及跨集群 Kafka topic 的数据复制 Streams Replication Manager(SRM)。
  4. Cloudera Streaming Analytics(CSA),以前这块是使用 Storm 来作为 Native Streaming 来补充 Spark Streaming 的 Micro-batch 的时延问题,目前这块改为 Flink 来实现,未来的 CDF 中将不再包含 Storm。

本文 Fayson 主要是介绍如何在 CDH6.3 中安装 Flink 1.9 以及运行你的第一个 Flink 例子,以下是测试环境信息:

  1. CM 和 CDH 版本为 6.3
  2. Redhat 7.4
  3. JDK 1.8.0_181
  4. 集群未启用 Kerberos
  5. Root 用户安装

安装 Flink 1.9

1.准备 Flink 1.9 的 csd 文件,并放置到 Cloudera Manager Server 的 /opt/cloudera/csd 目录。然后重启 Cloudera Manager Server 服务。

[root@ip-172-31-13-38 ~]# cd /opt/cloudera/csd
[root@ip-172-31-13-38 csd]# ll
total 44
-rw-r--r-- 1 root root 12407 Nov  8 01:26 FLINK-1.9.0-csa1.0.0.0-cdh6.3.0.jar
-rw-r--r-- 1 root root 24630 Sep  4 20:02 STREAMS_MESSAGING_MANAGER-2.1.0.jar
[root@ip-172-31-13-38 csd]# systemctl restart cloudera-scm-server

2.CM 重启完成以后,添加服务页面可以看到有 Flink 服务。

22.jpg

3.下载 Flink 1.9 的 Parcel,并放置 /var/www/html 目录。

[root@ip-172-31-13-38 ~]# cd /var/www/html/flink1.9/
[root@ip-172-31-13-38 flink1.9]# ll
total 127908
-rw-r--r-- 1 root root 130962403 Nov  8 01:36 FLINK-1.9.0-csa1.0.0.0-cdh6.3.0-el7.parcel
-rw-r--r-- 1 root root        41 Nov  8 01:28 FLINK-1.9.0-csa1.0.0.0-cdh6.3.0-el7.parcel.sha1
-rw-r--r-- 1 root root      4421 Nov  8 01:28 manifest.json
[root@ip-172-31-13-38 flink1.9]#

4.通过 Hosts > Parcels 进入 Cloudera Manager 的 Parcel 页面,输入 SMM Parcel 的 http 地址,下载->分配->激活。

2.jpg
3.jpg

5.进入 CM 主页点击“添加服务”。

4.jpg

6.选择添加 Flink 服务,点击继续。

5.jpg

7.选择 Flink History Server 以及 Gateway 节点,点击继续。

6.jpg

8.点击继续。

7.jpg

9.等待 Flink History Server 启动成功,完成后点击继续。

8.jpg
9.jpg

10.安装完成,点击完成回到 CM 主页。

10.jpg
11.jpg

发现 Flink 的状态为灰色,CMS 有重启提示,按照提示重启 CMS 服务,重启过程略。重启完成后显示 Flink 服务正常。

12.jpg

第一个 Flink 例子

1.执行 Flink 自带的 example 的 wordcount 例子。

[root@ip-172-31-13-38 ~]# flink run -m yarn-cluster -yn 4 -yjm 1024 -ytm 1024 /opt/cloudera/parcels/FLINK/lib/flink/examples/streaming/WordCount.jar --input hdfs://ip-172-31-13-38.ap-southeast-1.compute.internal:8020/fayson/ods_user_600.txt --output hdfs://ip-172-31-13-38.ap-southeast-1.compute.internal:8020/fayson/wordcount_output

13.jpg
14.jpg

2.查看输出结果。

15.jpg

3.在 YARN 和 Flink 的界面上分别都能看到这个任务。

16.jpg
17.jpg

至此,Flink 1.9 安装到 CDH 6.3 以及第一个例子介绍完毕。

备注:这是 Cloudera Streaming Analytics 中所包含 Apache Flink 的抢先测试版。Cloudera 不提供对此版本的支持。该 Beta 版本的目的是让用户可以尽可能早的开始使用 Flink 进行应用程序的开发。
更多技术文章可了解以下 Apache Flink 系列入门教程。

]]>
容器日志管理:从 docker logs 到 ELK/EFK Mon, 16 Dec 2019 05:35:02 +0800 原文作者:EdisonZhou
原文链接:https://developer.aliyun.com/article/727997

监控和日志历来都是系统稳定运行和问题排查的关键,在微服务架构中,数量众多的容器以及快速变化的特性使得一套集中式的日志管理系统变成了生产环境中一个不可获取的部分。此次话题我们会集中在日志管理方面,本篇会介绍 Docker 自带的 logs 子命令以及其 Logging driver,然后介绍一个流行的开源日志管理方案 ELK/EFK。

一、Docker logs 子命令

  默认情况下,Docker 的日志会发送到容器的标准输出设备(STDOUT)和标准错误设备(STDERR),其中 STDOUT 和 STDERR 实际上就是容器的控制台终端。

  我们可以通过 logs 子命令来查看具体某个容器的日志输出:

docker logs edc-k8s-demo

image.png

  这时看到的日志是静态的,截止到目前为止的日志。如果想要持续看到新打印出的日志信息,那么可以加上 -f 参数,如:

docker logs -f edc-k8s-demo

二、Docker logging driver

  刚刚我们学习了默认配置下,Docker 日志会发送到 STDOUT 和 STDERR。但实际上,Docker 还提供了其他的一些机制允许我们从运行的容器中提取日志,这些机制统称为 logging driver。

  对 Docker 而言,其默认的 logging driver 是 json-file,如果在启动时没有特别指定,都会使用这个默认的 logging driver。

image.png

  json-file 会将我们在控制台通过 docker logs 命名看到的日志都保存在一个json文件中,我们可以在服务器Host上的容器目录中找到这个 json 文件。

容器日志路径:/var/lib/docker/containers/<container-id>/<container-id>-json.log
  例如我们可以查看一个 exceptionless-api 容器的 json 日志:

image.png

  一个快速查看某个容器的日志文件路径的方法:

docker inspect exceptionless_api_1
  通过 inspect 命令,可以查到该容器的 ID 及一系列配置信息,我们重点关注 LogPath 即可:

image.png

  查到 LogPath 后,即可复制其后面的日志路径了,打开这个 json 文件你就可以看到输出的容器日志了。

  除了 json-file,Docker 还支持以下多种 logging dirver,来源:Configure logging drivers

image.png

  其中,none 代表禁用容器日志,不会输出任何容器日志。

  其他几个logging driver解释如下:

  • syslog 与 journald 是Linux上的两种日志管理服务
  • awslog、splunk 与 gcplogs是第三方日志托管服务
  • gelf 与 fluentd 是两种开源的日志管理方案
      我们可以在容器启动时通过加上 --log-driver 来指定使用哪个具体的 logging driver,例如:

docker run -d --log-driver=syslog ......
  如果想要设置默认的logging driver,那么则需要修改Docker daemon的启动脚本,例如:

{
  "log-driver": "json-file",
  "log-opts": {
    "labels": "production_status",
    "env": "os,customer"
  }
}

  每个logging driver都有一些自己特定的log-opt,使用时可以参考具体官方文档。

三、关于ELK

3.1 ELK简介

  ELK 是Elastic公司提供的一套完整的日志收集以及展示的解决方案,是三个产品的首字母缩写,分别是ElasticSearch、Logstash 和 Kibana。

image.png

Elasticsearch 是实时全文搜索和分析引擎,提供搜集、分析、存储数据三大功能
Logstash 是一个用来搜集、分析、过滤日志的工具
Kibana 是一个基于 Web 的图形界面,用于搜索、分析和可视化存储在 Elasticsearch 指标中的日志数据

3.2 ELK 日志处理流程

image.png

  上图展示了在 Docker 环境下,一个典型的 ELK 方案下的日志收集处理流程:

  • Logstash 从各个 Docker 容器中提取日志信息
  • Logstash 将日志转发到 ElasticSearch 进行索引和保存
  • Kibana 负责分析和可视化日志信息
      由于 Logstash 在数据收集上并不出色,而且作为 Agent,其性能并不达标。基于此,Elastic 发布了 beats 系列轻量级采集组件。

image.png

  这里我们要实践的 Beat 组件是 Filebeat,Filebeat 是构建于 beats 之上的,应用于日志收集场景的实现,用来替代 Logstash Forwarder 的下一代 Logstash 收集器,是为了更快速稳定轻量低耗地进行收集工作,它可以很方便地与 Logstash 还有直接与 Elasticsearch 进行对接。

  本次实验直接使用Filebeat作为Agent,它会收集我们在第一篇《Docker logs & logging driver》中介绍的json-file的log文件中的记录变动,并直接将日志发给ElasticSearch进行索引和保存,其处理流程变为下图,你也可以认为它可以称作 EFK。

image.png

四、ELK套件的安装

  本次实验我们采用 Docker 方式部署一个最小规模的 ELK 运行环境,当然,实际环境中我们或许需要考虑高可用和负载均衡。

  首先拉取一下 sebp/elk 这个集成镜像,这里选择的 tag 版本是 640(最新版本已经是 7XX 了):

docker pull sebp/elk:640
  注:由于其包含了整个 ELK 方案,所以需要耐心等待一会。

  通过以下命令使用 sebp/elk 这个集成镜像启动运行 ELK:

docker run -it -d --name elk 
    -p 5601:5601 
    -p 9200:9200 
    -p 5044:5044 
    sebp/elk:640

  运行完成之后就可以先访问一下 http://[Your-HostIP]:5601 看看Kibana的效果:  

image.png

  Kibana管理界面

image.png

Kibana Index Patterns界面

  当然,目前没有任何可以显示的ES的索引和数据,再访问一下http://[Your-HostIP]:9200 看看ElasticSearch的API接口是否可用:

image.png

ElasticSearch API

  _Note:_如果启动过程中发现一些错误,导致ELK容器无法启动,可以参考《Docker启动ElasticSearch报错》及《ElasticSearch启动常见错误》一文。如果你的主机内存低于4G,建议增加配置设置ES内存使用大小,以免启动不了。例如下面增加的配置,限制ES内存使用最大为1G:

docker run -it -d --name elk 
    -p 5601:5601 
    -p 9200:9200 
    -p 5044:5044 
   -e ES_MIN_MEM=512m 
    -e ES_MAX_MEM=1024m 
    sebp/elk:640

五、Filebeat配置

5.1 安装Filebeat

  这里我们通过rpm的方式下载Filebeat,注意这里下载和我们ELK对应的版本(ELK是6.4.0,这里也是下载6.4.0,避免出现错误):

wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.4.0-x86_64.rpm
rpm -ivh filebeat-6.4.0-x86_64.rpm

5.2 配置Filebeat  

  这里我们需要告诉Filebeat要监控哪些日志文件 及 将日志发送到哪里去,因此我们需要修改一下Filebeat的配置:

cd /etc/filebeat
vim filebeat.yml

  要修改的内容为:

  (1)监控哪些日志?

filebeat.inputs:

# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.

- type: log

  # Change to true to enable this input configuration.
  enabled: true

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /var/lib/docker/containers/*/*.log
    - /var/log/syslog

  这里指定paths:/var/lib/docker/containers/_/_.log,另外需要注意的是将 enabled 设为 true。

  (2)将日志发到哪里?

#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
  # Array of hosts to connect to.
  hosts: ["192.168.16.190:9200"]

  # Optional protocol and basic auth credentials.
  #protocol: "https"
  #username: "elastic"
  #password: "changeme"

  这里指定直接发送到ElasticSearch,配置一下ES的接口地址即可。

  _Note:_如果要发到Logstash,请使用后面这段配置,将其取消注释进行相关配置即可:

#----------------------------- Logstash output --------------------------------
#output.logstash:
  # The Logstash hosts
  #hosts: ["localhost:5044"]

  # Optional SSL. By default is off.
  # List of root certificates for HTTPS server verifications
  #ssl.certificate_authorities: ["/etc/pki/root/ca.pem"]

  # Certificate for SSL client authentication
  #ssl.certificate: "/etc/pki/client/cert.pem"

  # Client Certificate Key
  #ssl.key: "/etc/pki/client/cert.key"

5.3 启动 Filebeat

  由于 Filebeat 在安装时已经注册为 systemd 的服务,所以只需要直接启动即可:

systemctl start filebeat.service

  检查 Filebeat 启动状态:

systemctl status filebeat.service

5.4 验证 Filebeat

  通过访问ElasticSearch API可以发现以下变化:ES建立了以filebeat-开头的索引,我们还能够看到其来源及具体的message。

image.png

六、Kibana 配置
  接下来我们就要告诉 Kibana,要查询和分析 ElasticSearch 中的哪些日志,因此需要配置一个 Index Pattern。从 Filebeat 中我们知道 Index 是 filebeat-timestamp 这种格式,因此这里我们定义 Index Pattern 为 filebeat-*

image.png

  点击 Next Step,这里我们选择 Time Filter field name 为 @timestamp:

image.png

  单击 Create index pattern 按钮,即可完成配置。

  这时我们单击 Kibana 左侧的 Discover 菜单,即可看到容器的日志信息啦:

image.png

  仔细看看细节,我们关注一下 message 字段:

image.png

  可以看到,我们重点要关注的是 message,因此我们也可以筛选一下只看这个字段的信息:

image.png

  此外,Kibana 还提供了搜索关键词的日志功能,例如这里我关注一下日志中包含 unhandled exception(未处理异常)的日志信息:

image.png

  这里只是朴素的展示了导入 ELK 的日志信息,实际上 ELK 还有很多很丰富的玩法,例如分析聚合、炫酷 Dashboard 等等。笔者在这里也是初步使用,就介绍到这里啦。

七、Fluentd 引入

7.1 关于 Fluentd

  前面我们采用的是 Filebeat 收集 Docker 的日志信息,基于 Docker 默认的 json-file 这个 logging driver,这里我们改用 Fluentd 这个开源项目来替换 json-file 收集容器的日志。

  Fluentd 是一个开源的数据收集器,专为处理数据流设计,使用 JSON 作为数据格式。它采用了插件式的架构,具有高可扩展性高可用性,同时还实现了高可靠的信息转发。Fluentd 也是云原生基金会 (CNCF) 的成员项目之一,遵循 Apache 2 License 协议,其 github 地址为:https://github.com/fluent/fluentd/
Fluentd 与 Logstash 相比,比占用内存更少、社区更活跃,两者的对比可以参考这篇文章《Fluentd vs Logstash》。

  因此,整个日志收集与处理流程变为下图,我们用 Filebeat 将 Fluentd 收集到的日志转发给 Elasticsearch。

image.png

  当然,我们也可以使用 Fluentd 的插件(fluent-plugin-elasticsearch)直接将日志发送给 Elasticsearch,可以根据自己的需要替换掉 Filebeat,从而形成 Fluentd => ElasticSearch => Kibana 的架构,也称作 EFK。

7.2 运行 Fluentd

  这里我们通过容器来运行一个 Fluentd 采集器:

docker run -d -p 24224:24224 -p 24224:24224/udp -v /edc/fluentd/log:/fluentd/log fluent/fluentd

  默认 Fluentd 会使用 24224 端口,其日志会收集在我们映射的路径下。

  此外,我们还需要修改 Filebeat 的配置文件,将 /edc/fluentd/log 加入监控目录下:

#=========================== Filebeat inputs =============================

filebeat.inputs:

# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.

- type: log

  # Change to true to enable this input configuration.
  enabled: true

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /edc/fluentd/log/*.log

  添加监控配置之后,需要重新 restart 一下 filebeat:

systemctl restart filebeat

7.3 运行测试容器

  为了验证效果,这里我们 Run 两个容器,并分别制定其 log-dirver 为 fluentd:

docker run -d 
           --log-driver=fluentd 
           --log-opt fluentd-address=localhost:24224 
           --log-opt tag="test-docker-A" 
           busybox sh -c 'while true; do echo "This is a log message from container A"; sleep 10; done;'

docker run -d 
           --log-driver=fluentd 
           --log-opt fluentd-address=localhost:24224 
           --log-opt tag="test-docker-B" 
           busybox sh -c 'while true; do echo "This is a log message from container B"; sleep 10; done;'

  这里通过指定容器的 log-driver,以及为每个容器设立了 tag,方便我们后面验证查看日志。

7.4 验证 EFK 效果

  这时再次进入 Kibana 中查看日志信息,便可以通过刚刚设置的 tag 信息筛选到刚刚添加的容器的日志信息了:

image.png

八、小结
本文从 Docker 自带的 logs 子命令入手,介绍了 Docker 具有多种 logging dirver,然后过度到 ELK 的基本组成,并介绍了 ELK 的基本处理流程,以及从 0 开始搭建了一个 ELK 环境,演示了基于 Filebeat 收集容器日志信息的案例。然后,通过引入 Fluentd 这个开源数据收集器,演示了如何基于 EFK 的日志收集案例。当然,ELK/EFK 有很多的知识点,希望未来能够分享更多的实践总结。

“阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
云原生时代的 Identity Mon, 16 Dec 2019 05:35:02 +0800 作者:
艾竞,花名庭坚,蚂蚁金服系统部研究员
李婷婷,花名鸿杉,蚂蚁金服平台安全资深安全专家

背景

随着轻量级容器(container)的兴起,应用(applications)逐渐由单体(monolithic)向微服务(micro-service)演进。相应的,应用的微服务化也带来了如下的变化:

  • 软件研发、运维人员组织围绕着微服务下的软件模块重新架构:研发、运维人员分化成更小的组织以专注于一个或多个软件模块(以容器的形式交付);在微服务 API 稳定的情况下,各个模块独立开发,测试和部署可以进行更高速的迭代
  • 应用中软件模块之间由函数调用的“强”耦合变成网络远程调用的“松”耦合;维持原先各个模块之间的信任需要有额外的安全机制

另一方面,除了台式机(desktop),其它可以接入应用的物理设备(device),例如笔记本电脑(laptop),手机(mobile phone),也已经大规模普及。因此,企业员工通常拥有多个设备来访问企业应用以完成日常工作。个人多设备以及设备的移动性对于企业传统的安全边界模型(perimeter model)提出了挑战。

可以观察到,在应用由单体向微服务,设备由单一、静态向多种、移动的演化下,系统中各个 Entity(实体,例如,人,设备,服务等)的 Identity(身份),由单一的网络标识,即 IP 或者 IP:Port,向多种形态(X.509 certificate, token, service account 等)分化。Identity 的分化会对研发、运维效能和资源效能也会产生深刻的影响。

在这些背景下,传统基于 IP、域名的管控方式临着巨大的挑战,静态的规则让安全策略变得无法维护;同时,在微服务架构下,安全人员很难快速找到一条边界,将不同的风险域隔离开来。因此,急需一种新 Access Control 模式来应对。

Forrester 的首席分析师约翰·金德维格在 2010 年提出了零信任(Zero Trust)的理念针对传统边界安全架构思想进行了重新评估和审视,并对安全架构思路给出了新的建议,其核心思想是 "Never Trust,Always Verify" - All network traffic is untrusted. There is no "trusted traffic"。阿里巴巴已经在内部开始推进零信任架构的落地,包括企业内部接入层的零信任、生产网内部机器、应用间的零信任,并已经开始在 双11 中发挥了重要的作用。

零信任第一个核心问题就是 Identity,赋予不同的 Entity 不同的 Identity,解决是谁在什么环境下访问某个具体的资源的问题。因此,本文将从 Identity 与微服务和 Identity 与企业应用访问两个方面来阐述 Identity 在生产应用和企业应用中的思考,同时也会介绍在不同的场景下如何利用 Identity 解决谁在什么环境可以访问某个资源的具体实践。

Identity 与微服务

随着用户需求在信息化时代的日益增长,软件也变得越来越复杂。为了应对软件复杂度的提升,软件的架构也由简单的单体应用逐渐演变成为复杂的微服务应用。2017 年,Kubernetes 开始成为事实上的标准容器编排平台。同一年,谷歌联合 IBM,Lyft 推出的 Istio 主打 SideCar 模式下的微服务治理。至此,在云原生时代,应用得以在 Kubernetes 和 Istio 构成的底座之上以容器的形式微服务化。

在云原生的转型中,软件研发、运维组织架构需要围绕微服务来重新构建:如果把一组在逻辑、功能上耦合紧密的软件模块看作一门“功夫”的话,它们背后的研发、运维人员就是一个“武林门派”;各个“武林门派”相对独立的“修炼”自己的“功夫”;配合起来,又能满足软件系统整体的演进。然而,这套适配微服务的组织架构对于研发、运维模式提出了很大的挑战。归结到一点:就是从每个研发、运维者的角度,如何在关注本门“功夫”的同时保证软件系统整体的可用性。

Identity 由单一网络地址变得更多元化以标识不同的对象(例如,用户,用户组,服务等)为应对上述挑战提供了可能性。接下来,我们会看到 Identity 是如何覆盖整个软件开发周期各个场景为每个研发、运维者创造相对隔离的“环境”的。

Identity 与 Kubernetes 集群

首先,我们来看 Identity 是如何依据用户/用户组提供所需 Kubernetes 集群资源的。Kubernetes 集群是用于容器生命周期管理的。细分一下,其用户大致可以分为如下两类:

  • Kubernetes 集群的管理者:关注集群本身,主要的职责包括并不限于:

    • Kuberentes 组件的维护及升级
    • Kuberentes 集群中 Node 的治理
    • Kuberentes 集群中 Namespace 的治理
    • Kuberentes 集群中各类 policy(例如,Role-Based Access Control(RBAC) for AuthZ)的治理
    • Kuberentes 集群中 Pod 调度管理
    • Kuberentes 集群中 C[X]I(例如,CRI,CNI,CSI 等)的治理
    • Kuberentes 集群资源容量管理
    • 。。。
  • Kubernetes 集群的使用者:关注如何在集群之上运行容器,依据角色(例如,开发/测试/运维)的不同,主要的使用方式有:

    • Kuberentes 集群中 Service Account 的治理
    • 将 Kubernetes 集群作为开发环境
    • 将 Kubernetes 集群作为线下测试环境,运行 CI/CD
    • 将 Kubernetes 集群作为线上发布环境,进行灰度,回滚等操作

对于第一类 Kubernetes 集群用户,可以通过 Kubernetes RBAC 机制下 ClusterRoleBinding 赋予集群级别权限;并且需要“垄断”集群和 Namespace 级别策略的制定;为了防止敏感信息泄露,还需要将集群和 Namespace 级别的信息以及敏感信息(例如 Secret)设置为仅为 Kubernetes 集群管理者可见。

对于第二类 Kubernetes 集群用户,可以进一步按照对应的微服务中软件模块来进行细分成不同的组(Group)。另一方面,Kubernetes Namespace 提供了虚拟集群的抽象。因此,当 Kubernetes API Server 认证用户身份之后,可以按照组的粒度将用户映射到 Kubernetes 集群某个 Namespace 的角色(Role)而这个角色在此 Namespace 中拥有相应权限。具体来说,用户到 Namespace 的映射可以通过 Kubernetes RBAC 机制下 RoleBinding 完成。考虑到系统策略的可维护性,以组 Identity 的粒度制定策略而以用户 Identity 用于审计(Audit)是合理的。

Kubernetes 中并没有代表用户的资源,并且企业一般都会拥有多个 Kubernetes 集群。因此,提供组织架构信息(例如,用户(User),组(Group))的 Identity Provider(IdP)应该独立于 Kubernetes 集群之外并可以服务多个 Kubernetes 集群。如果对多个 Kubernetes 集群采用相同的配置,用户可以收获跨集群的一致性用户体验。

1.png

图 1:Identity Provider 与 Kubernetes 集群

在 IdP 中的组织架构,一个组可以包含用户,也可以包含其他组;与此同时,一个用户也可以直接棣属于多个组。因此可以根据用户操作(用户执行的 yaml 文件中指定了具体的 Namespace)来更加灵活映射到不同的角色来操作相应的 Kubernetes Namespace:

  • 例子一:一个用户按架构域划分属于 A 组,按角色划分属于 dev 组。当要运行容器时,Kubernetes 集群的 RBAC 策略会允许他在 Namespace A-dev 中操作。
  • 例子二:一个用户按架构域划分既属于 A 组也属于 B 组,按角色划分属于 test 组。当要运行容器时,Kubernetes 集群的 RBAC 策略会允许他在 Namespace A-test 和 Namespace B-test 中操作。

2.png

图 2:企业组织架构与 Kubernetes 集群


值得注意的是,IdP 中的组织架构代表 Kubernetes 管理者和使用者的组还是要严格分开以防止权限泄露。此外,当有任何组织架构变动时(例如,用户从 Kubernetes 管理者变成使用者),Kubernetes 集群需要能够及时捕捉。

Identity 与 Service Mesh

其次,我们来看 Identity 是如何依据用户/用户组和相应的配置创造出不同的软件运行环境的。当用户通过 Kubernetes 开始运行容器后,容器所代表的微服务就交由 Service Mesh 来治理。如图 3 所示,在 Istio 1.1+,在启动 Pod 的时候,Pod Identity 会通过 SDS(Secret Discovery Service)获取。
3.png



图 3:Pod Identity 获取流程

Pod 的 Identity 的格式会采取源自谷歌 LOAS(Low-Overhead Authentication Service)的 SPIFFE(Secure Production Identity Framework for Everyone)标准,spiffe:///ns//sa/以全局唯一标识相应的 Workload;并且 Identity 相应的证书也会由 CA(Certificate Authority)来签发。有了证书背书,当 Pod 可以与其它 Pod 通信时,就可以通过 mTLS 完成对通信链路加密。

更为重要的是,Service Mesh 可以通过 Istio RBAC 实现基于 Identity 的 RPC(Remote Procedure Call)ACL(Access Control List)。因此,当由有不同角色(例如,开发/测试/运维)的用户来运行/部署同一个微服务时,因为所在组不同而获取不同的 SPIFFE ID,即使在同一个 Kubernetes 集群中,只要设置合适的 Istio RBAC Policy,他们能运行的微服务也处于彼此隔离的环境中。

4.png

图 4:Istio 下基于 Identity 隔离的环境


此外,一个组通常会拥有微服务的多组软件模块。当映射到 Kubernetes Namespace 时,对不同组的软件模块最好采用不同的 Service Account。这是因为,Pod 的 SPIFFE ID 的信任来自于 Kubernetes Service Account;一旦Service Account 被 compromise,它所造成的损失有限。

5.png

图 5:Service Account 的隔离

Workload Identity 的实践

阿里巴巴正在全面推行 Service Mesh 的架构演进,这为我们在此场景下快速落地 Workload 的 Identity 及访问控制提供了很好的基础。

6.png


图 6:Service Mesh 架构下应用间访问控制


应用的身份以及认证统一由安全 Sidecar 统一提供,授权模型我们采用了 RBAC 模型,在 Sidecar 中集成了 RBAC Filter。RBAC 模型在大部分场景下都能满足需求,但在项目推进过程中我们发现一种比较特殊的场景,比如 A 应用需要被所有的应用访问,会导致策略无法描述。因此在这种场景下,我们考虑升级为 ABAC(Attribute-Based Access Control)模型,采用 DSL(Domain Specific Language)语言来描述,并集成在安全 Sidecar 中。

Identity 与软件交付

此外,Identity 不仅仅体现在软件研发、测试及运维,它还覆盖其他的方面。

镜像管理

在云原生范式下,代码终将以镜像的形式来使用。在关注构成镜像本身代码的安全性同时,我们还关心镜像的来源(即相应代码库 URL),制作者(组)和标签。在线上生产环境(其它环境可以放松这个限制)以容器运行镜像时,我们需要确保镜像是来自已知代码库,由合法的用户(来自拥有代码所有权的组)制作并有合适的标签(例如,release)。因此,我们需要在镜像的 metadata 中植入相关的 Identity 信息以便应用相关的策略。

微服务部署

在云原生时代,微服务部署所需的 yaml 配置往往是庞大繁琐的。如前所述,Identity 结合 Kubernetes/Istio RBAC Policies 可以创建出不同的隔离环境以便于开发,测试和运维,但是也需要有相应的 yaml 配置来适配。然而,yaml仅仅只是对一组可嵌套的描述,自身没有任何复用,重载的计算机编程语言的特性。因此,我们需要使用云原生场景下的 DSL 来方便的刻画同一个微服务不同(例如,研发/测试/生产)环境下的配置。举例来说,针对不同的环境,主要区别在于:1)Kubernetes Namespace 不同;2)所需的计算资源不同。所以,DSL 可以将各个环境相同的配置沉淀下来形成模版,在此基础之上,对与环境相关的配置进行定制或重载以适配不同环境。

7.png


图 7:DSL 下的微服务配置

通常来讲,相对于微服务代码变更,微服务配置变更属于低频操作。DSL 将微服务配置接管过来使得配置也像代码一样可重用、可验证,大大降低因为配置及其变更带来的错误。因此,所有的开发者可以对代码进行更高速的迭代从而把代码缺陷暴露在更早的阶段。

Identity 与企业应用访问

阿里巴巴已经内部已部分地落地了基于零信任的企业应用访问的架构,从以前简单以员工的身份作为唯一且静态的授权依据,扩展为员工身份、设备、以持续的安全评估达到动态安全访问控制的新架构。

8.png


图 8:企业应用的访问控制

在这种新的架构下,首先,我们选择安全网关作为控制点,与阿里巴巴 IAM(Identity Access Management)结合,对员工的身份以及接入的设备进行认证,知道是否从对应的人和其对应的设备请求接入;协议方面,员工设备与安全网关之前,采用 HTTPS 对各种协议进行封装,统一由安全网关进行代理访问后端的应用;其次,安全网关内置的 Access Control Engine 结合流量中的上下文(Context)对访问的请求做持续的建模,对来自非可信、非认证设备、或者异常的访问行为做实时的阻断。

结语

随着互联网应用由单体向微服务架构转型,加之访问互联网应用的移动设备的繁荣,网络标识(例如,IP,Port等)已经不能作为稳定的 Identity 来标识分布式系统中的实体,建立在此之上的边界安全模型应对各种场景已经显得力不从心。因此,对于不同实体(例如,人,设备,服务等),Identity 需要由更能凸显其本质的、有密码学背书的稳定凭证(credential)来担当。相应的,建立在此类 Identity 基础之上安全策略有着丰富的语义来适配不同的场景:在研发、测试和运维微服务场景下,Identity 及其相关策略不仅是安全的基础,更是众多(资源,服务,环境)隔离机制的基础;在员工访问企业内部应用的场景下,Identity 及其相关策略提供了灵活的机制来提供随时随地的接入服务。无论那种场景下,Identity 对分布式系统中不同实体划分了有效的安全边界,并提供隔离机制来提高资源效能和用户体验。

ban.jpg

本书亮点

  • 双11 超大规模 K8s 集群实践中,遇到的问题及解决方法详述
  • 云原生化最佳组合:Kubernetes+容器+神龙,实现核心系统 100% 上云的技术细节
  • 双 11 Service Mesh 超大规模落地解决方案

阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
Kubernetes 下零信任安全架构分析 Mon, 16 Dec 2019 05:35:02 +0800 作者:
杨宁,花名麟童,阿里云基础产品事业部高级安全专家
刘梓溪,花名寞白,蚂蚁金服大安全基础安全安全专家
李婷婷,花名鸿杉,蚂蚁金服大安全基础安全资深安全专家

简介

零信任安全最早由著名研究机构 Forrester 的首席分析师约翰.金德维格在 2010 年提出。零信任安全针对传统边界安全架构思想进行了重新评估和审视,并对安全架构思路给出了新的建议。
其核心思想是,默认情况下不应该信任网络内部和外部的任何人/设备/系统,需要基于认证和授权重构访问控制的信任基础。诸如 IP 地址、主机、地理位置、所处网络等均不能作为可信的凭证。零信任对访问控制进行了范式上的颠覆,引导安全体系架构从“网络中心化”走向“身份中心化”,其本质诉求是以身份为中心进行访问控制。
目前落地零信任概念包括 Google BeyondCorp、Google ALTS、Azure Zero Trust Framework 等,云上零信任体系,目前还是一个新兴的技术趋势方向,同样的零信任模型也同样适用于 Kubernetes,本文重点讲解一下 Kubernetes 下零信任安全架构的技术分析。

传统零信任概念和目前落地情况

Microsoft Azure

Azure 的零信任相对来说还是比较完善的,从体系角度来看涵盖了端、云、On-Permises、SaaS 等应用,下面我们分析一下相关的组件:

  • 用户 Identity:然后通过 Identity Provider(创建、维护和管理用户身份的组件)的认证,再认证的过程中可以使用账号密码,也可以使用 MFA(Multi Factor Auth)多因素认证的方式,多因素认证包括软、硬 Token、SMS、人体特征等;
  • 设备 Identity:设备包含了公司的设备以及没有统一管理的设备,这些设备的信息,包含 IP 地址、MAC 地址、安装的软件、操作系统版本、补丁状态等存储到 Device Inventory;另外设备也会有相应的 Identity 来证明设备的身份;设备会有对应的设备状态、设备的风险进行判定;
  • Security Policy Enforcement:通过收集的用户 Identity 以及状态、设备的信息,状态以及 Identity 后,SPE 策略进行综合的判定,同时可以结合 Threat Intelligence 来增强 SPE 的策略判定的范围和准备性;策略的例子包括可以访问后面的 Data、Apps、Infrastructure、Network;
  • Data:针对数据(Emails、Documents)进行分类、标签、加密的策略;
  • Apps:可以自适应访问对应的 SaaS 应用和 On-Permises 应用;
  • Infrastructure:包括 IaaS、PaaS、Container、Serverless 以及 JIT(按需开启访问)和 GIT 版本控制软件;
  • Network:针对网络交付过程以及内部的微隔离进行策略打通。

1.png

下面这张微软的图进行了更加细化的讲解,用户(员工、合作伙伴、用户等)包括 Azure AD、ADFS、MSA、Google ID 等,设备(可信的合规设备)包括 Android、iOS、MacOS、Windows、Windows Defender ATP,客户端(客户端 APP 以及认证方式)包括浏览器以及客户端应用,位置(物理和虚拟地址)包括地址位置信息、公司网络等,利用 Microsoft 的机器学习 ML、实时评估引擎、策略等进行针对用户、客户端、位置和设备进行综合判定,来持续自适应的访问 On-Permises、Cloud SaaS Apps、Microsoft Cloud,包含的策略包括 Allow、Deny,限制访问、开启 MFA、强制密码重置、阻止和锁定非法认证等;从下图可以看出 Azure 已经打通了 On-Permises、Cloud、SaaS 等各个层面,构建了一个大而全的零信任体系。

2.png

Google BeyondCorp

Google BeyondCorp 是为了应对新型网络威胁的一种网络安全解决方案,其实 Google BeyondCorp 本身并没有太多的技术上的更新换代,而是利用了持续验证的一种思路来做的,去掉了 VPN 和不再分内外网。Google 在 2014 年之前就预测到互联网和内网的安全性是一样危险的,因为一旦内网边界被突破的话,攻击者就很容易的访问企业的一些内部应用,由于安全意识的问题导致企业会认为我的内部很安全,就对内部的应用进行低优先级别的处理,导致大量内部的安全问题存在。现在的企业越来越多的应用移动和云技术,导致边界保护越来越难。所以 Google 干脆一视同仁,不分内外部,用一样的安全手段去防御。

从攻防角度来看一下 Google 的 BeyondCorp 模型,例如访问 Google 内部应用http://blackberry.corp.google.com ,它会跳转到https://login.corp.google.com/ 也就是 Google Moma 系统,首先需要输入账号密码才能登陆,这个登录的过程中会针对设备信息、用户信息进行综合判定,账号密码正确以及设备信息通过规则引擎验证之后,会继续跳转到需要 YubiKey 登录界面,每个 Google 的员工都会有 Yubikey,通过 Yubikey 来做二次验证。Yubikey 的价值,Google 认为是可以完全杜绝钓鱼攻击的。另外类似的就是 Amazon 的 Midway-Auth 方式 ( https://midway-auth.amazon.com/login?next=%2F )。
3.png

Kubernetes 下容器零信任模型

容器下网络零信任

首先介绍一下容器下的网络零信任组件 Calico,Calico 是针对容器,虚拟机和基于主机的本机 Workload 的开源网络和网络安全解决方案产品。Calico 支持广泛的平台,包括 Kubernetes、OpenShift、Docker EE、OpenStack 和裸金属服务。零信任最大的价值就是即使攻击者通过其他各种手法破坏应用程序或基础架构,零信任网络也具有弹性。零信任架构使得使攻击者难以横向移动,针对性的踩点活动也更容易发现。

在容器网络零信任体系下,Calico+Istio 目前是比较热的一套解决方案;先来看看两者的一些差别,从差别上可以看到 Istio 是针对 Pod 层 Workload 的访问控制,以及 Calico 针对 Node 层的访问控制:

Istio Calico
Layer L3-L7 L3-L4
实现方式 用户态 内核态
策略执行点 Pod Node

下面重点讲解一下 Calico 组件和 Istio 的一些技术细节,Calico 构建了一个 3 层可路由网络,通过 Calico 的 Felix(是运行在 Node 的守护程序,它在每个 Node 资源上运行。Felix 负责编制路由和 ACL 规则以及在该 Node 主机上所需的任何其他内容,以便为该主机上的资源正常运行提供所需的网络连接)运行在每个 Node 上,主要做路由和 ACL 的策略以及搭建网络;通过运行在 Node 上的 Iptables 进行细粒度的访问控制。可以通过 Calico 设置默认 Deny 的策略,然后通过自适应的访问控制来进行最小化的访问控制策略的执行,从而构建容器下的零信任体系;Dikastes/Envoy:可选的 Kubernetes sidecars,可以通过相互 TLS 身份验证保护 Workload 到 Workload 的通信,并增加相关的控制策略;

4.png

Istio

再讲解 Istio 之前先讲一下微服务的一些安全需求和风险分析:
1、微服务被突破之后通过 Sniffer 监控流量,进而进行中间人攻击,为了解决这种风险需要对流量进行加密;
2、为了针对微服务和微服务之间的访问控制,需要双向 TLS 和细粒度的访问策略;
3、要审核谁在什么时候做了什么,需要审计工具;

分析了对应的风险之后,下面来解释一下 Istio 如何实现的零信任架构。首先很明显的一个特点就是全链路都是双向 mTLS 进行加密的,第二个特点就是微服务和微服务之间的访问也可以进行鉴权,通过权限访问之后还需要进行审计。Istio 是数据面和控制面进行分离的,控制面是通过 Pilot 将授权策略和安全命名信息分发给 Envoy,然后数据面通过 Envoy 来进行微服务的通信。在每个微服务的 Workload 上都会部署 Envoy,每个 Envoy 代理都运行一个授权引擎,该引擎在运行时授权请求。当请求到达代理时,授权引擎根据当前授权策略评估请求上下文,并返回授权结果 ALLOW 或 DENY。
5.png

微服务下的 Zero Trust API 安全

42Crunch( https://42crunch.com/ )将 API 安全从企业边缘扩展到了每个单独的微服务,并通过可大规模部署的超低延迟微 API 防火墙来进行保护。 42Crunch API 防火墙的部署模式是以 Kubernetes Pod 中以 Sidecar 代理模式部署,毫秒级别的性能响应。 这省去了编写和维护单个 API 安全策略过程,并实施了零信任安全体系结构,提升了微服务下的 API 安全性。42Crunch 的 API 安全能力包括:审核:运行 200 多个 OpenAPI 规范定义的安全审核测试,并进行详细的安全评分,以帮助开发人员定义和加强 API 安全;扫描:扫描实时 API 端点,以发现潜在的漏洞;保护:保护 API 并在应用上部署轻量级,低延迟 Micro API Firewall。

蚂蚁零信任架构体系落地最佳实践

随着 Service Mesh 架构的演进,蚂蚁已经开始在内部落地 Workload 场景下的服务鉴权能力,如何建设一套符合蚂蚁架构的 Workload 间的服务鉴权能力,我们将问题分为一下三个子问题:
1、Workload 的身份如何定义,如何能够实现一套通用的身份标识的体系;
2、Workload 间访问的授权模型的实现;
3、访问控制执行点如何选择。

Workload 身份定义 & 认证方式

蚂蚁内部使用 SPIFFE 项目中给出的 Identity 格式来描述 Workload 的身份,即:

spiffe://<domain>/cluster/<cluster>/ns/<namespace>

不过在工程落地过程中发现,这种维度的身份格式粒度不够细,并且与 K8s 对于 namespace 的划分规则有较强的耦合。蚂蚁的体量较大,场景较多,不同场景下 namespace 的划分规则都不完全一致。因此我们对格式进行了调整,在每一场景下梳理出能够标识一个 Workload 示例所须要的一组必备属性(例如应用名,环境信息等),并将这些属性携带在 Pod 的 Labels 中。调整后的格式如下:

spiffe://<domain>/cluster/<cluster>/<required_attr_1_name>/<required_attr_1_value>/<required_attr_2_name>/<required_attr_2_value>

配合这个身份格式标准,我们在 K8s API Server 中添加了 Validating Webhook 组件,对上述 Labels 中必须携带的属性信息进行校验。如果缺少其中一项属性信息,则实例 Pod 将无法创建。如下图所示:
6.png

在解决了 Workload 身份定义的问题后,剩下的就是如何将身份转换成某种可校验的格式,在 Workload 之间的服务调用链路中透传。为了支持不同的使用场景,我们选择了 X.509 证书与 JWT 这两种格式。
对于 Service Mesh 架构的场景,我们将身份信息存放在 X.509 证书的 Subject 字段中,以此来携带 Workload 的身份信息。如下图所示:
7.png

对于其他场景,我们将身份信息存放在 JWT 的 Claims 中,而 JWT 的颁发与校验,采用了 Secure Sidecar 提供服务。如下图所示:
8.png

授权模型

在项目落地的初期,使用 RBAC 模型来描述 Workload 间服务调用的授权策略。举例描述,应用 A 的某一个服务,只能被应用 B 调用。这种授权策略在大多数场景下都没有问题,不过在项目推进过程中,我们发现这种授权策略不适用于部分特殊场景。
我们考虑这样一个场景,生产网内部有一个应用 A,职责是对生产网内部的所有应用在运行时所需要使用的一些动态配置提供中心化的服务。这个服务的定义如下:
A 应用 - 获取动态配置的 RPC 服务:
message FetchResourceRequest {<br />// The appname of invoker<br />string appname = 1;<br />// The ID of resource<br />string resource_id = 2;<br />}<br />message FetchResourceResponse {<br />string data = 1;<br />}<br />service DynamicResourceService {<br />rpc FetchResource (FetchResourceRequest) returns (FetchResourceResponse) {}<br />}<br />

在此场景下,如果依然使用 RBAC 模型,应用 A 的访问控制策略将无法描述,因为所有应用都需要访问 A 应用的服务。但是这样会导致显而易见的安全问题,调用方应用 B 可以通过该服务获取到其它应用的资源。因此我们将 RBAC 模型升级为 ABAC 模型来解决上述问题。 我们采用 DSL 语言来描述 ABAC 的逻辑,并且集成在 Secure Sidecar 中。

访问控制执行点的选择

在执行点选择方面,考虑到 Service Mesh 架构推进需要一定的时间,我们提供了两不同的方式,可以兼容 Service Mesh 的架构,也可以兼容当前场景。

在 Service Mesh 架构场景下,RBAC Filter 和 ABAC Filter(Access Control Filter)集成在 Mesh Sidecar 中。
9.png

在当前场景下,我们目前提供了 JAVA SDK,应用需要集成 SDK 来完成所有认证和授权相关的逻辑。与 Service Mesh 架构场景类似,所有 Identity 的颁发、校验,授权与 Secure Sidecar 交互,由 Secure Sidecar 完成。

10.png

结语

零信任的核心是“Never Trust, Always Verify”,未来会继续深化零信任在整个阿里巴巴的实践,赋予不同的角色不同的身份,例如企业员工、应用、机器,并将访问控制点下沉到云原生基础设施的各个点,实现全局细粒度的控制,打造安全防护的新边界。本文从业界的零信任体系的落地最佳实践,到基于 Kubernetes 的零信任落地方式进行了简单的描述,本文只是抛砖引玉,希望能引发更多关于 Cloud Native 下的零信任架构体系的更多讨论和能看到更多的业界优秀的方案和产品能出现。

“阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
人人都在谈论的云原生到底是什么?——3分钟,让你快速了解云原生! Mon, 16 Dec 2019 05:35:02 +0800 原文链接
  随着虚拟化技术的成熟和分布式架构的普及,用来部署、管理和运行应用的云平台被越来越多的提及。IaaS、PaaS和SaaS是云计算的3种基本服务类型,它们是关注硬件基础设施的基础设施即服务、关注软件和中间件平台的平台即服务以及关注业务应用的软件即服务。
  在容器技术、可持续交付、编排系统等开源社区的推动下,以及微服务等开发理念的带动下,应用上云已经是不可逆转的趋势。随着云化技术的不断进展,云原生的概念也应运而生。

image.png


云原生概念的诞生

  云原生(Cloud Native)的概念,由来自Pivotal的MattStine于2013年首次提出,被一直延续使用至今。这个概念是Matt Stine根据其多年的架构和咨询经验总结出来的一个思想集合,并得到了社区的不断完善,内容非常多,包括DevOps、持续交付(Continuous Delivery)、微服务(MicroServices)、敏捷基础设施(Agile Infrastructure)和12要素(The Twelve-Factor App)等几大主题,不但包括根据业务能力对公司进行文化、组织架构的重组与建设,也包括方法论与原则,还有具体的操作工具。采用基于云原生的技术和管理方法,可以更好地把业务生于“云”或迁移到云平台,从而享受“云”的高效和持续的服务能力。
image.png

The Twelve-Factor App

  顾名思义,云原生是面向“云”而设计的应用,因此技术部分依赖于传统云计算的3层概念,基础设施即服务(IaaS)、平台即服务(PaaS)和软件即服务(SaaS),例如,敏捷的不可变基础设施交付类似于IaaS,用来提供计算网络存储等基础资源,这些资源是可编程且不可变的,直接通过API可以对外提供服务;有些应用通过PaaS服务本来就能组合成不同的业务能力,不一定需要从头开始建设;还有一些软件只需要“云”的资源就能直接运行起来为云用户提供服务,即SaaS能力,用户直接面对的就是原生的应用。

云原生并不是一个产品

  最近讨论云原生应用越来越多。关于云原生应用,简单地说,就是大多数传统的应用,不做任何改动,都是可以在云平台运行起来,只要云平台支持这个传统应用所运行的计算机架构和操作系统。只不过这种运行模式,仅仅是把虚拟机当物理机一样使用,不能够真正利用起来云平台的能力。
  云并非把原先在物理服务器上跑的东西放到虚拟机里跑,真正的云化不仅是基础设施和平台的事情,应用也要做出改变,改变传统的做法,实现云化的应用——应用的架构、应用的开发方式、应用部署和维护技术都要做出改变,真正的发挥云的弹性、动态调度、自动伸缩……一些传统IT所不具备的能力。这里说的“云化的应用”也就是“云原生应用”。云原生架构和云原生应用所涉及的技术很多,如容器技术、微服务、可持续交付、DevOps等。
image.png
  而云原生应用最大的特点就是可以迅速部署新业务。在企业里,提供新的应用程序环境及部署软件新版本通常所需时间以日、周甚至以月计算。这种速度严重限制了软件发布所能承受的风险,因为犯错及改错也需要花费同样的时间成本,竞争优势就会由此产生。
  所以云原生不是一个产品,而是一套技术体系和一套方法论,而数字化转型是思想先行,从内到外的整体变革。更确切地说,它是一种文化,更是一种潮流,是云计算的一个必然导向。意义在于让云成为云化战略成功的基石,而不是障碍。它可以根据商业能力对公司进行重组的能力,既包含技术、也包含管理,可以说是一系列云技术和企业管理方法的集合,通过实践及与其他工具相结合更好地帮助用户实现数字化转型。

云原生计算基金会(CNCF)

  CNCF,即云原生计算基金会,2015年由谷歌牵头成立,基金会成员目前已有一百多企业与机构,包括亚马逊、微软、思科等巨头。
  目前CNCF所托管的应用已达14个,下图为其公布的Cloud Native Landscape,给出了云原生生态的参考体系。
image.png

Cloud Native Landscape新版


CNCF(云原生计算基金会)认为云原生系统需包含的属性:

容器化封装: 以容器为基础,提高整体开发水平,形成代码和组件重用,简化云原生应用程序的维护。在容器中运行应用程序和进程,并作为应用程序部署的独立单元,实现高水平资源隔离。
自动化管理:统一调度和管理中心,从根本上提高系统和资源利用率,同时降低运维成本。
面向微服务:通过松耦合方式,提升应用程序的整体敏捷性和可维护性。
  正因为如此,你可以专注于创新,解决业务问题,而不是把时间花在“静态、不灵活的传统架构”存在的许多技术问题。

云原生的四要素:持续交付、DevOps、微服务、容器

  从云原生的概念中,我们总是能看到持续交付、DevOps、微服务、容器等技术的出现,那么它们到底是什么,这里引用Pivotal台湾云计算资深架构师的部分观点,为大家逐一揭开他们的神秘面纱!

image.png

持续交付——缩小开发者认知,灵活开发方向

  首先是持续交付,什么样的时候客户要求持续交付?敏捷开发要求持续交付,因为敏捷开发要求随时有一个版本可以上到大群环境,所以要持续交付
  而换句话说,持续交付就是不误时开发。举一个例子,有些公司非常喜欢谈需求,谈很久,可是开发只剩1/3时间就开发完成,然后交付,再上线运营。这就会碰到一个问题,就是你开始谈需求到最后交付产品的时间,短则三月,长则半年,这中间市场已经变化了,需求也随之变化了。因此市场上出现了新的想法,即是不是能够小步快跑,把交付的周期缩短一点,我可以实现快速交付,每次交付都可以重新确认方向,这样尽量避免与未来期待的落差。
image.png

用小步快跑的方式,打破瀑布式开发流程

  那么问题来了,持续交付对于开发的人谈的需求、开发的方式有改变,那它对于开发有影响吗?如果说公司的开发团队一天可以交付五次,那研发团队要帮忙部署一次吗?现在公司大部分部署都是研发团队帮忙部署应用的,研发团队部署五次,要改版五次就需要部署一次,这是无法实现的。而且每次部署的时候都要面对停机,而实际公司的应用经不起一天停机五次部署,在互联网的思维之下,零宕机时间已经是现在企业的基本要求。于是“蓝绿部署”的概念营运而生。即在一个环境里面,第一版还在线上服务,第二版先做封测,封测完成后,让外面的流量进来一些,看log是不是开发人员要的,确认后再把全部的流量导到新的版本上。
image.png

图:蓝绿(Blue-Green) 部署

  但“蓝绿部署”在系统过多过复杂的情况下,在传统架构上实现非常困难,所以企业要做到zero down time的持续交付就需要有良好的平台與工具协助。因此,持续交付的优势在于,它可以缩小开发者认知,重新确认开发方向。

微服务——内聚更强,更加敏捷

  第二部分是微服务。微服务是什么?有客户表示,提供商出产品,客户把应用全部放上去,结果就是一个微服务。这种认知是错误的,因为微服务是一个架构的改变。那么微服务是怎么做的呢?它所面临的最大挑战是什么?
  是切割。那么如何切割呢?其实这件事情早在1968年康威就提出了——康威定律,系统的服务划分应该是根据组织架构的功能来划分。1968年康威就提出了这个想法,我认为拿来做微服务的切割非常适用。
image.png

Going Agile - Breaking the monolith
Conway's Law and Microservices

  这样按照组织架构划分的优势在于:

  1.内聚更强,所有遵循同一种业务准则的人内聚在一起,就容易解决问题。
  2.服务解耦,变更容易,更加敏捷。当做到解耦合的时候,要变更就容易。所以微服务应该是切分成这个样子,由上而下来切,根据Function来切。
  另外一个划分微服务的技巧,可以运用领域驱动设计(Domain Driven Design)的理论,而领域驱动设计亦可算是面向物件的一种设计思维;聚合可以让微服务划分更有依据,也让未來的系統变更具有弹性。值得一提的是领域驱动设计,也提供微服务中的事物问题。因为过去巨石应用进行两个报数的阶段,相当容易也常见,但在微服务架构中,如何在分散的服务中进行事物就显得相当困难。利用领域驱动设计的Event Souring进行设计,是目前最好的解決办法。

  那么在什么情况下需要微服务?我认为有三个标准:

  1.有HA(High Available)的需求需要微服务。
  2.有性能调校的需求(例如:图片的呈现或者搜寻)需要微服务。
  3.经常变更的需要微服务。
  实际上,微服务需要关注的源代码范围比较小,使得各个服务解耦、变更容易,内聚更强,因为都会集中在服务里。另外,它更容易单独改版,因为微服务之间是用RESTful间接起来的,用RESTful只要API的界面不改,原则上则不会错,也更敏捷。
  但微服务也会留下一些问题,例如App团队如何分工?环境怎么配合?如何实现自动化部署?

容器技术——使资源调度、微服务更容易

  再来看看容器。在机器上运行的容器只是主机操作系统上的一个进程,与任何其他进程无异。那么,为什么容器如此受欢迎呢?原因在于这个进程被隔离和限制的方式。这种方式很特殊,可简化开发和运维。
  其实1979年就有容器技术,很多人会以为说Docker是不是等于容器,其实Docker不等于容器。容器的历史可追溯到Linux操作系统。容器利用了Linux的内核功能。Linux中容器的核心概念(cgroup、namespaces和filesystems)在独立的区域运行。容器的神奇之处在于将这些技术融为一体,以实现最大的便利性。
  VMware之前的技术专家在2011年发展出一个技术,把这个技术贡献出来成立了一个Cloud Foundry基金会。Docker在2013年才开始有,而且它第一版是用SLC的技术去做的。后来陆续一路成长,使得为服务的实现更容易了。
image.png

从 Infra 角度来看技术演进

  从上面这个表中可以看出,从左边开始,IaaS,虚拟化技术有了之后,刚刚提到的所谓第三代平台,这四个区块开发人员交付的内容不一样。所有的IaaS、CaaS、PaaS、FaaS一路的变化演进,对于客户的负担越到后面越小,而对于开发人员的想象力则愈发抽象。
  大家一定会遇到下列这些计算,一个是所谓的单体应用,或者翻译成巨石应用。此外,你们一定会有一些批次的管理,另外就是所谓的数据库的部分,开始可能会有容器技术,像K8S、Dock。
  Docker是软件行业最受欢迎的软件容器项目之一。思科、谷歌和IBM等公司在其基础设施和产品中使用Docker容器。
  Kubernetes是软件容器领域的另一个值得关注的项目。Kubernetes是一个允许自动化部署、管理和伸缩容器的工具。为了便于管理其容器,谷歌建立了Kubernetes。它提供了一些强大的功能,例如容器之间的负载均衡,重启失败的容器以及编排容器使用的存储。
image.png

容器生态图 /作者:Jimmy Song

  容器为云原生应用程序增加了更多优势。使用容器,你可以将微服务及其所需的所有配置、依赖关系和环境变量移动到全新的服务器节点上,而无需重新配置环境,这样就实现了强大的可移植性。

DevOps——以终为始,运维合一

  最后让我们走向DevOps,它不是一种工具,DevOps其实要谈的是运维合一。
  DevOps如果从字面上来理解只是Dev(开发人员)+Ops(运维人员),实际上,它是一组过程、方法与系统的统称,其概念从2009年首次提出发展到现在,内容也非常丰富,有理论也有实践,包括组织文化、自动化、精益、反馈和分享等不同方面。
  首先,组织架构、企业文化与理念等,需要自上而下设计,用于促进开发部门、运维部门和质量保障部门之间的沟通、协作与整合,简单而言组织形式类似于系统分层设计。
  其次,自动化是指所有的操作都不需要人工参与,全部依赖系统自动完成,比如上述的持续交付过程必须自动化才有可能完成快速迭代。再次,DevOps的出现是由于软件行业日益清晰地认识到,为了按时交付软件产品和服务,开发部门和运维部门必须紧密合作。
  总之,DevOps强调的是高效组织团队之间如何通过自动化的工具协作和沟通来完成软件的生命周期管理,从而更快、更频繁地交付更稳定的软件。在内部沟通上,你可以想象DevOps是一个敏捷思維,是一个沟通的文化。当运营和研发有良好的沟通效率,才可以有更大的生产力。如果你的自动化程度够高,可以自主可控,工作负担降低,DevOps能够带来更好的工作文化、更高的工作效率。

总结

  综上所述,云原生的DevOps、平台、持续交付、微服务都是云原生不可或缺的一部分,需要以全局地眼光看待问题,脱离任何一个元素,对于企业来说都是“管中窥豹”、“一叶障目”,只有加以整合才能见到云原生的全局风貌。
  面对业态各异的业务上云以及碎片化的物联网解决方案部署,利用云原生思维和模式,构建基于云原生的物联网平台以及解决方案,势必将加速企业,甚至整个社会的数字化转型。

]]>
阿里云Serverless应用引擎(SAE)3大核心优势全解析 Mon, 16 Dec 2019 05:35:02 +0800 软件发展到今,企业业务系统日趋复杂,开发一个业务系统需要掌握和关注的知识点越来越多。除实现业务逻辑本身,还需考虑很多非业务的基础技术系统:如分布式cache和队列、基础服务能力集成、容量规划、弹性伸缩等。这种情况下,研发门槛逐渐上升,效率逐渐下降。企业很难做到低成本创新、试错和快速扩展业务。

阿里云Serverless应用引擎(简称SAE)产品的出现,很好地解决了这类问题。帮助 PaaS 层用户免运维IaaS,按需使用,按量计费,提供了一系列通用能力,实现低门槛微服务/Web/多语言应用上云,有效解决成本及效率问题。

免运维、省成本是所有Serverless产品的核心优势之一,SAE除了免运维底层IaaS外,还能让用户免部署和运维微服务注册中心等组件,提供生产级别稳定可靠的微服务托管能力;免部署和运维K8s集群,零容器基础的用户也能拥抱K8s带来的技术红利。

10


很多企业在云上都会部署多套环境,存在很大的闲置浪费。使用SAE的“一键启停开发测试环境”,按需释放闲置资源,节省成本,需要使用时一键秒级拉起。后续SAE考虑基于K8s强大的编排能力,编排应用所需的DB、应用和应用的依赖,一键初始化拉起一套全新环境,以及多环境的克隆复制等。

11


云时代下弹性已成为新常态,很多业务场景无法提前预知,如天猫双11、突发事件导致社交网站瞬时过载。和传统弹性方案相比,SAE在成本和效率上都能做到极致。基于监控触发按需弹,不会出现资源浪费/不足,在效率上免去ECS扩容和ECS启动的时间,能做到秒级弹性。

12


SAE三个主要指标数据:端到端启动时长20s,满足突发场景快速扩容的需要。支持0.5core的最小规格,进一步降低用户使用成本。部署一套日常环境成本节省47%~57%。

13


据Serverless应用引擎(SAE)产品经理黛忻介绍,SAE继续探索弹性效率和用户成本的优化方案,继续将一些基础技术归纳抽象下沉到平台,让创新业务成为企业的唯一关注点。
据悉,阿里云是国内率先提供了面向应用的Serverless产品的云计算公司。截止目前,已有上百家企业通过 SAE 构建应用,实现业务的快速交付和IT成本优化。]]>
蚂蚁金服 双11 Service Mesh 超大规模落地揭秘 Mon, 16 Dec 2019 05:35:02 +0800 点击下载《不一样的 双11 技术:阿里巴巴经济体云原生实践》

ban.jpg

本文节选自《不一样的 双11 技术:阿里巴巴经济体云原生实践》一书,点击上方图片即可下载!

作者:
黄挺,花名鲁直,蚂蚁金服微服务以及云原生方向负责人,主导蚂蚁金服的云原生落地。
雷志远,花名碧远,蚂蚁金服 RPC 框架负责人

更多云原生技术资讯可关注阿里巴巴云原生技术圈

引言

Service Mesh 是蚂蚁金服下一代架构的核心,本主题主要分享在蚂蚁金服当前的体量下,我们如何做到在奔跑的火车上换轮子,将现有的 SOA 体系快速演进至 Service Mesh 架构。聚焦 RPC 层面的设计和改造方案,分享蚂蚁金服 双11 核心应用如何将现有的微服务体系平滑过渡到 Service Mesh 架构下并降低大促成本。

蚂蚁金服每年 双11 大促会面临非常大的流量挑战,在已有 LDC 微服务架构下已支撑起弹性扩容能力。本次分享主要分为 4 部分:

  1. Service Mesh 简介;
  2. 为什么要 Service Mesh;
  3. 我们的方案是什么;
  4. 分时调度案例;

Service Mesh 简介

在讲具体的蚂蚁金服落地之前,想先和大家对齐一下 Service Mesh 的概念,和蚂蚁金服对应的产品。
这张图大家可能不陌生,这是业界普遍认可的 Service Mesh 架构,那么对应到蚂蚁金服,蚂蚁金服的 Service Mesh 也分为控制面和数据面,分别叫做 SOFAMesh 和 SOFAMosn,其中 SOFAMesh 后面会以更加开放的姿态参与到 Istio 里面去。

1.png

今天我们讲的实践主要集中在 SOFAMosn 上,以下我的分享中提到的主要就是集中在数据面上的落地,这里面大家可以看到,我们有支持 HTTP/SOFARPC/Dubbo/WebService。

为什么我们要 Service Mesh

有了一个初步的了解之后,可能大家都会有这样一个疑问,你们为什么要 Service Mesh,我先给出结论:

因为我们要解决在 SOA 下面,没有解决但亟待解决的:基础架构和业务研发的耦合,以及未来无限的对业务透明的稳定性与高可用相关诉求。

那么接下来,我们一起先看看在没有 Service Mesh 之前的状况。

在没有 Service Mesh 之前,整个 SOFAStack 技术演进的过程中,框架和业务的结合相当紧密,对于一些 RPC 层面的需求,比如流量调度,流量镜像,灰度引流等,是需要在 RPC 层面进行升级开发支持,同时,需要业务方来升级对应的中间件版本,这给我们带来了一些困扰和挑战。如图所示:

2.png

  1. 线上客户端框架版本不统一;
  2. 业务和框架耦合,升级成本高,很多需求由于在客户端无法推动,需要在服务端做相应的功能,方案不够优雅;
  3. 机器逐年增加,如果不增加机器,如何度过 双11;
  4. 在基础框架准备完成后,对于新功能,不再升级给用户的 API 层是否可行; 
  5. 流量调拨,灰度引流,蓝绿发布,AB Test 等新的诉求;

这些困扰着我们,我们知道在 SOA 的架构下,负责每个服务的团队都可以独立地去负责一个或者多个服务,这些服务的升级维护也不需要其他的团队的接入,SOA 其实做到了团队之间可以按照接口的契约来接耦。但是长期以来,基础设施团队需要推动很多事情,都需要业务团队进行紧密的配合,帮忙升级 JAR 包,基础设施团队和业务团队在工作上的耦合非常严重,上面提到的各种问题,包括线上客户端版本的不一致,升级成本高等等,都是这个问题带来的后果。

而 Service Mesh 提供了一种可能性,能够将基础设施下沉,让基础设施团队和业务团队能够解耦,让基础设施和业务都可以更加快步地往前跑。

3.png

我们的方案

说了这么多,那我们怎么解决呢?

方案一:全部迁移到 Envoy?不现实,自有协议+历史负担。
方案二:透明劫持?性能问题,且表达能力有限,运维和可监控性,风险不太可控。
方案三:自研数据面,最终我们给出的答案是 SOFAMosn。

总体

4.png

我们的 SOFAMosn 支持了 Pilot ,自有服务发现 SOFARegistry,和自有的消息组件,还有一些 DB 的组件。在产品层,提供给开发者,不同的能力,包括运维,监控,安全等能力,这个是目前我们的一个线上的状态。

SOFARegistry 是蚂蚁金服开源的具有承载海量服务注册和订阅能力的、高可用的服务注册中心,在支付宝/蚂蚁金服的业务发展驱动下,近十年间已经演进至第五代。

看上去很美好,要走到这个状态,我们要回答三个问题。

5.png

这三个问题后面,分别对应着业务的几大诉求,大家做过基础框架的应该比较有感触。

框架升级方案

准备开始升级之后,我们要分析目前我们的线上情况,而我们现在线上的情况,应用代码和框架有一定程度的解耦,用户面向的是一个 API,最终代码会被打包,在 SOFABoot 中运行起来。

SOFABoot 是蚂蚁金服开源的基于 SpringBoot 的研发框架,它在 SpringBoot 的基础上,提供了诸如 Readiness Check,类隔离,日志空间隔离等能力。在增强了 SpringBoot 的同时,SOFABoot 提供了让用户可以在 SpringBoot 中非常方便地使用 SOFA 中间件的能力。

6.png

那么,我们就可以在风险评估可控的情况下,直接升级底层的 SOFABoot,在这里,我们的 RPC 会检测一些信息,来确定当前 Pod 是否需要开启 SOFAMosn 的能力。然后我们完成如下的步骤。

7.png

这里,我们通过检测 PaaS 传递的容器标识,知道自己是否开启了 SOFAMosn,则将发布和订阅给 SOFAMosn,然后调用不再寻址,直接完成调用。

可以看到,我们通过批量的运维操作,直接修改了线上的 SOFABoot 版本,以此,来直接使得现有的应用具备了 SOFAMosn 的能力,有些同学可能会问,那你一直这么做不行吗?不行,因为这个操作时要配合流量关闭等操作来运行的,也不具备平滑升级的能力。而且直接和业务代码强相关。不适合长期操作。

这里我们来详细回答一下,为什么不采用社区的流量劫持方案?

主要的原因是一方面 iptables 在规则配置较多时,性能下滑严重。另一个更为重要的方面是它的管控性和可观测性不好,出了问题比较难排查。而 Service Mesh 从初期就把蚂蚁金服现在线上的系统全量切换 Mesh 作为目标,并不是只是跑跑 demo,所以我们对性能和运维的要求是非常高的,毕竟,技术架构升级,如果是以业务有损或者资源利用率大幅度上升,这是无论如何都不能接受的。

容器替换方案

解决了刚刚提到的第一个难题,也只是解决了可以做,而并不能做得好,更没有做得快,面对线上数十万,带着流量的业务容器, 我们如何立刻开始实现这些容器的快速稳定接入?

这么大的量,按照传统的替换接入显然是很耗接入成本的事情,于是我们选择了原地接入,我们可以来看下两者的区别
8.png

在之前,我们做一些升级操作之类的,都是需要有一定的资源 Buffer,然后批量的进行操作,替换 Buffer 的不断移动,来完成升级的操作。这就要求 PaaS 层留有非常多的 Buffer,但是在 双11 的情况下,我们要求不增加机器,并且为了一个接入 SOFAMosn 的操作,反而需要更多的钱来买资源,这岂不是背离了我们的初衷。有人可能会问,不是还是增加了内存和 CPU 吗,这是提高了 CPU 利用率。以前业务的 CPU 利用率很低。并且这个是一个类似超卖的方案。看上去分配了。实际上基本没增加。

可以看到, 通过 Paas 层,我们的 Operator 操作,直接在现有容器中注入,并原地重启,在容器级别完成升级。升级完成后,这个 Pod 就具备了 SOFAMosn 的能力。

SOFAMosn 升级方案

在快速接入的问题完成后,我们要面临第二个问题,由于是大规模的容器,所以 SOFAMosn 在开发过程中,势必会存在一些问题,出现问题,如何升级,要知道,线上几十万容器要升级一个组件的难度是很大的,因此,在版本初期,我们就考虑到 SOFAMosn 升级的方案。

9.png

能想到的最简单的方法,就是销毁容器,然后用新的来重建,但是在容器数量很多的时候,这种运维成本是不可接受的。如果销毁容器重建的速度不够快,就可能会影响业务的容量,造成业务故障。因此,我们在 SOFAMosn 层面,和 PaaS 一起,开发了无损流量升级的方案。

10.png

在这个方案中。SOFAMosn 会感知自己的状态,新的 SOFAMosn 启动会通过共享卷的 Domain Socket 来检测是否已有老的 SOFAMosn 在运行,如果有,则通知原有 SOFAMosn 进行平滑升级操作。

11.png

具体来说,SOFAMosn 启动的时候查看同 Pod 是否有运行的 SOFAMosn (通过共享卷的domain socket),如果存在,需要进入如下流程:
1.New Mosn 通知 Old Mosn,进入平滑升级流程
2.Old Mosn 把服务的 Listen Fd 传递给 New Mosn,New Mosn 接收 Fd 之后启动, 此时 Old 和 New Mosn 都正常提供服务。
3.然后 New Mosn 通知 Old Mosn,关闭 Listen Fd,然后开始迁移存量的长链接。
4.Old Mosn 迁移完成, 销毁容器。

这样,我们就能做到,线上做任意的 SOFAMosn 版本升级,而不影响老的业务,这个过程中的技术细节,不做过多介绍,之后,SOFAStack 会有更详细的分享文章。

分时调度案例

技术的变革通常一定不是技术本身的诉求,一定是业务的诉求,是场景的诉求。没有人会为了升级而升级,为了革新而革新,通常,技术受业务驱动,也反过来驱动业务。

在阿里经济体下,在不断的淘宝直播,实时红包,蚂蚁森林,各种活动的不断扩张中,给技术带了复杂了场景考验。

这个时候,业务同学往往想的是什么?我的量快撑不住了,我的代码已经最优化了,我要扩容加机器,而更多的机器付出更多的成本,面对这样的情况,我们觉得应用 Service Mesh,是一个很好的解法。通过和 JVM, 系统部的配合,利用进阶的分时调度实现灵活的资源调度,不加机器。这个可以在资源调度下有更好的效果。

12.png

首先,我们假设有两个大的资源池的资源需求情况,可以看到在 X 点的时候,资源域 A 需要更多的资源,Y 点的时候,资源域 B 需要更多的资源,总量不得增加。那当然,我们就希望能借调机器。就像下面这样。

请大家看左图。

13.png

在这个方案中, 我们需要先释放资源,然后销毁进程,然后开始重建资源,然后启动资源域 B 的资源。这个过程对于大量的机器,是很重的,而且变更就是风险,关键时候,做这种变更,很有可能带来衍生影响。

而在 SOFAMosn 中,我们有了新的解法。如右图所示,有一部分资源,一直通过超卖,运行着两种应用,但是 X 点的时候,对于资源域 A,我们通过 SOFAMosn 来将流量全部转走,这样,应用的 CPU 和内存就被限制到非常低的情况,大概保留 1% 的能力。这样,机器依然可以预热,进程也不停。

在这里。我们可以看这张图。

14.png

当需要比较大的资源调度的时候,我们推送一把开关,则资源限制打开,包活状态取消。资源域 B 瞬间可以满血复活。而资源域 A 此时进入上一个状态,CPU 和内存被限制。在这里,SOFAMosn 以一个极低的资源占用。完成流量保活的能力。使得资源的快速借调成为可能。

我们对 Service Mesh 的思考与未来

Service Mesh 在蚂蚁金服经过 2 年的沉淀,最终经过 双11 的检验,在 双11 ,我们覆盖了 200+ 的 双11 交易核心链路,Mosn 注入的容器数量达到了数十万,双11 当天处理的 QPS 达到了几千万,平均处理 RT<0.2 ms,SOFAMosn 本身在大促中间完成了数十次的在线升级,基本上达到了我们的预期,初步完成了基础设施和业务的第一步的分离,见证了 Mesh 化之后基础设施的迭代速度。

不论何种架构,软件工程没有银弹。架构设计与方案落地总是一种平衡与取舍,目前还有一些 Gap 需要我们继续努力,但是我们相信,云原生是远方也是未来,经过我们两年的探索和实践,我们也积累了丰富的经验。

我们相信,Service Mesh 可能会是云原生下最接近“银弹”的那一颗,未来 Service Mesh 会成为云原生下微服务的标准解决方案,接下来蚂蚁金服将和阿里集团一起深度参与到 Istio 社区中去,与社区一起把 Istio 打造成 Service Mesh 的事实标准。

ban.jpg

本书亮点

  • 双11 超大规模 K8s 集群实践中,遇到的问题及解决方法详述
  • 云原生化最佳组合:Kubernetes+容器+神龙,实现核心系统 100% 上云的技术细节
  • 双 11 Service Mesh 超大规模落地解决方案

阿里巴巴云原生技术圈关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

]]>
快速搭建 Serverless 在线图片处理应用 Mon, 16 Dec 2019 05:35:02 +0800 作者:倚贤

首先介绍下在本文出现的几个比较重要的概念:

函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考

ImageMagick:ImageMagick 是一个用于查看、编辑位图文件以及进行图像格式转换的开放源代码软件套装。它可以读取、编辑超过100种图象格式。。参见维基百科词条

ImageMagick 是图片处理的利器,借助 ImageMagick 可以轻松实现图片的裁剪和缩放。虽然很多语言都封装了 ImageMagick 的调用库,但是把图片处理功能和核心业务功能放在同一个服务内,在软件架构上往往不适合。有如下两方面的原因:

一方面,图片处理依赖外部的 bin,已经编译好的二级制不具备可移植性,给打包发布带来了麻烦。另一方面,图片处理往往是比较耗费计算资源的,对于大多数业务系统来说图片处理属于边缘业务,而非核心业务,所以为整个服务预留较多的计算资源是不划算的。更好的选择是把图片处理类业务以微服务的形式切分出来,部署在具备弹性的底层服务之上。对于此类技术需求, Serverless 是非常切合的。

本文重点介绍如何快速地在函数计算平台上部署一个弹性高可用的图片处理服务,然后在此基础上轻松的定制化。

快速开始

下面我们借助于函数计算的应用中心,快速地将图片转换服务给部署出来。

  1. 打开函数计算 Image Resizer 应用详情页。如果您尚未开通函数计算服务可能需要先,开通服务是免费的,另外函数计算有每月免费额度,试用服务不会产生费用。


1.png

  1. 滚动到Image Resizer 应用详情页的最底部,点击“立即部署”按钮。


2.png

  1. 填写应用名称:my-image-resizer,然后点击“部署”按钮。


3.png

  1. 拷贝 HttpTriggerEndpoint 里的网址。


4.png

  1. 在浏览器里打开上面的网址,或者通过 curl 进行调用。注意:由于没有绑定域名,所以应用中心会默认下载而不是直接在浏览器里打开图片。
curl 'https://xxxxx.cn-shanghai.fc.aliyuncs.com/2016-08-15/proxy/my-image-resizer-ResizeService-5A40B5A8B981/my-image-resizer-ResizeFunction-3E71C57C0094/' --output resized.jpg

工作原理

这是一个单函数结合 Http Trigger 的应用。Http Trigger 以 HTTP GET 方法对外暴露服务,客户端传递三个请求参数:url、width 和 height。其中

  • url 表示需要进行处理的源图片地址
  • width 表示裁剪或缩放后的图片宽度
  • height 表示裁剪的图片宽度。该参数缺失时,表示采用缩放的方式调整图片。

该应用的架构图如下:

6.jpg

FC 函数接受到 HTTP 请求之后,执行如下三个步骤:

  1. 把 url 指向的图片下载下来
  2. 使用 imagemagick 进行图片转换
  3. 将图片通过 http 协议返回给客户端

上面我们通过了函数计算的应用中心快速上线了一个图片转换的服务。函数计算是按照调用次数收费的,所以上述服务即使保持在线也不会产生费用。而又因为函数计算每月有免费的额度,所以日常开发的调用也不会产生费用。

定制化开发

依赖工具

本项目是在 MacOS 下开发的,涉及到的工具是平台无关的,对于 Linux 和 Windows 桌面系统应该也同样适用。在开始本例之前请确保如下工具已经正确的安装,更新到最新版本,并进行正确的配置。

Fun 工具依赖于 docker 来模拟本地环境。

对于 MacOS 用户可以使用 homebrew 进行安装:

brew cask install docker
brew tap vangie/formula
brew install fun

Windows 和 Linux 用户安装请参考:

  1. https://github.com/aliyun/fun/blob/master/docs/usage/installation.md

安装好后,记得先执行 fun config 初始化一下配置。

注意, 如果你已经安装过了 funcraft,确保 funcraft 的版本在 3.1.3 以上。

$ fun --version
3.1.3

初始化

git clone https://github.com/vangie/fc-image-resizer
cd fc-image-resizer

安装依赖

npm install

本地运行

$ fun local start
using template: .fun/build/artifacts/template.yml
HttpTrigger httpTrigger of ResizeService/ResizeFunction was registered
        url: http://localhost:8000/2016-08-15/proxy/ResizeService/ResizeFunction
        methods: [ 'GET' ]
        authType: ANONYMOUS


function compute app listening on port 8000!

然后使用浏览器或者 curl 调试网址 http://localhost:8000/2016-08-15/proxy/ResizeService/ResizeFunction

部署

fun deploy

为了获得更好的开发体验,建议安装 Aliyun Serverless VSCode Extension

参考链接

  1. Funcraft
  2. Aliyun Serverless VSCode Extension

阿里巴巴云原生技术圈关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

]]>
Flexvolume插件分批升级方案 Mon, 16 Dec 2019 05:35:02 +0800 Flexvolume支持在线自动升级,您可以登陆控制台实现一键升级,参考:https://help.aliyun.com/document_detail/100605.html

Flexvolume升级不会影响您的应用,但是建议您可以选择在业务低峰的时候进行升级。您也可以参考本文给出的给flexvolume执行分配升级方案:

Flexvolume分批升级原理:

Daemonset更新策略支持:OnDelete、RollingUpdate两中模式,其中:

  • OnDelete:表示对DaemonSet更新模板后,pod不会马上升级,而是等待Pod删除重建的时候升级;
  • RollingUpdate:表示更新了模板Pod就会马上执行升级操作;

默认情况下升级策略是RollingUpdate,为了实现分批升级功能,我们修改升级策略为OnDelete,然后手动升级一批节点,查看数据卷挂载状态,然后再一批一批的升级;

Flexvolume分批升级步骤:

记录升级前的Flexvolume版本:
# kubectl describe ds flexvolume -nkube-system | grep Image

给Flexvolume配置升级策略为OnDelete;
# kubectl patch ds flexvolume -p '{"spec":{"updateStrategy":{"type":"OnDelete"}}}' -nkube-system

检查Flexvolume升级策略更新是否成功;下面命令有输出即认为成功;
# kubectl get ds flexvolume -nkube-system -oyaml | grep "type: OnDelete"

部署新版本Flexvolume
# kubectl apply -f flexvolume.yaml

检查Flexvolume DaemonSet镜像已经更新,到这一步pod还没有更新;
# kubectl describe ds flexvolume -nkube-system | grep Image
Image:      registry.cn-beijing.aliyuncs.com/acs/flexvolume:v1.14.6.15-8d3b7e7-aliyun

列出所有Flexvolume Pod;
# kubectl get pod -nkube-system -nkube-system -owide | grep flexvolume

分批升级:删除那个pod,pod重启后就会使用新镜像和配置;
# kubectl delete pod ** -nkube-system

检查所有pod是否已经是最新版本;
# for podname in `kubectl get pod -nkube-system | grep flexvolume | awk '{print $1}'`; do kubectl describe pod $podname -nkube-system | grep Image: ;done

将Flexvolume的更新策略修改为RollingUpdate;完成升级;
# kubectl patch ds flexvolume -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}' -nkube-system

Flexvolume部署模板:

把下面模板的{{.Region}}字段换成您的集群region名。

apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
  name: flexvolume
  namespace: kube-system
  labels:
    k8s-volume: flexvolume
spec:
  selector:
    matchLabels:
      name: acs-flexvolume
  template:
    metadata:
      labels:
        name: acs-flexvolume
    spec:
      hostPID: true
      hostNetwork: true
      tolerations:
      - operator: "Exists"
      priorityClassName: system-node-critical
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: type
                operator: NotIn
                values:
                - virtual-kubelet
      nodeSelector:
        beta.kubernetes.io/os: linux
      containers:
      - name: acs-flexvolume
        image: registry-vpc.{{.Region}}.aliyuncs.com/acs/flexvolume:v1.14.6.15-8d3b7e7-aliyun
        imagePullPolicy: Always
        securityContext:
          privileged: true
        env:
        - name: ACS_DISK
          value: "true"
        - name: ACS_NAS
          value: "true"
        - name: ACS_OSS
          value: "true"
        - name: ACS_CPFS
          value: "false"
        resources:
          limits:
            cpu: 1000m
            memory: 1000Mi
          requests:
            cpu: 100m
            memory: 100Mi
        livenessProbe:
          exec:
            command:
            - sh
            - -c
            - ps -ef |grep /acs/flexvolume | grep monitoring | grep -v grep
          failureThreshold: 8
          initialDelaySeconds: 15
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 15
        volumeMounts:
        - name: usrdir
          mountPath: /host/usr/
        - name: etcdir
          mountPath: /host/etc/
        - name: logdir
          mountPath: /var/log/alicloud/
      volumes:
      - name: usrdir
        hostPath:
          path: /usr/
      - name: etcdir
        hostPath:
          path: /etc/
      - name: logdir
        hostPath:
          path: /var/log/alicloud/
  updateStrategy:
    type: RollingUpdate
]]>
Alicloud-Nas-Controller插件升级 Mon, 16 Dec 2019 05:35:02 +0800 您在ACK集群中使用alicloud-nas-controller时,如果安装的版本较低,可以通过如下方式升级组件:

当前集群状态:

如果您使用的nas controller是早期版本,如下:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: alicloud-nas-controller
  name: alicloud-nas-controller
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: alicloud-nas-controller
  template:
    metadata:
      labels:
        app: alicloud-nas-controller
    spec:
      containers:
      - env:
        - name: PROVISIONER_NAME
          value: alicloud/nas
        - name: NFS_SERVER
          value: 2564f49129-**.cn-shenzhen.nas.aliyuncs.com
        - name: NFS_PATH
          value: /
        image: registry.cn-hangzhou.aliyuncs.com/acs/alicloud-nas-controller:v3.1.0-k8s1.11
        imagePullPolicy: IfNotPresent
        name: alicloud-nas-controller
        volumeMounts:
        - mountPath: /persistentvolumes
          name: nfs-client-root
      serviceAccount: admin
      serviceAccountName: admin
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
        operator: Exists
      - effect: NoSchedule
        key: node.cloudprovider.kubernetes.io/uninitialized
        operator: Exists
      volumes:
      - flexVolume:
          driver: alicloud/nas
          options:
            path: /
            server: 2564f49129-**.cn-shenzhen.nas.aliyuncs.com
            vers: "4.0"
        name: nfs-client-root

StorageClass配置如下:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: alicloud-nas
mountOptions:
- vers=4.0
provisioner: alicloud/nas
reclaimPolicy: Retain

集群中有应用使用上述controller配置创建了pvc/pv,并挂载到pod中使用:

# kubectl describe pod web-nas-1 | grep ClaimName
    ClaimName:  html-web-nas-1

# kubectl get pvc html-web-nas-1
NAME             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
html-web-nas-1   Bound    pvc-2612b272-14e7-11ea-a9b7-00163e084110   2Gi        RWO            alicloud-nas   85m

这时pv的配置为v4版本;
# kubectl get pv pvc-2612b272-14e7-11ea-a9b7-00163e084110 -oyaml | grep mountOptions -A 6
  mountOptions:
  - vers=4.0
  nfs:
    path: /default-html-web-nas-1-pvc-2612b272-14e7-11ea-a9b7-00163e084110
    server: 2564f49129-**.cn-shenzhen.nas.aliyuncs.com
  persistentVolumeReclaimPolicy: Retain
  storageClassName: alicloud-nas

PV新诉求

登陆Pod所在节点,查看挂载nas的参数为:

# mount | grep nfs
2564f49129-**.cn-shenzhen.nas.aliyuncs.com:/default-html-web-nas-1-pvc-2612b272-14e7-11ea-a9b7-00163e084110 on /var/lib/kubelet/pods/32222e36-14f2-11ea-a9b7-00163e084110/volumes/kubernetes.io~nfs/pvc-2612b272-14e7-11ea-a9b7-00163e084110 type nfs4 (rw,relatime,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.25,local_lock=none,addr=192.168.1.152)

如果你希望更新nas挂载参数,期望修改pv的mountOptions参数,例如配置为下面参数:

- nolock,tcp,noresvport
- vers=3

执行编辑命令:

# kubectl edit pv pvc-2612b272-14e7-11ea-a9b7-00163e084110

将mountOptions参数更新为:

  mountOptions:
  - nolock,tcp,noresvport
  - vers=3

重启Pod:

# kubectl delete pod web-nas-1

登陆Pod所在节点插件nas挂载参数:可见已经配置了noresvport等参数;
# mount | grep nfs
2564f49129-**.cn-shenzhen.nas.aliyuncs.com:/default-html-web-nas-1-pvc-2612b272-14e7-11ea-a9b7-00163e084110 on /var/lib/kubelet/pods/ba374a37-14f3-11ea-a9b7-00163e084110/volumes/kubernetes.io~nfs/pvc-2612b272-14e7-11ea-a9b7-00163e084110 type nfs (rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.152,mountvers=3,mountport=4002,mountproto=tcp,local_lock=all,addr=192.168.1.152)

通过上面方法,可以对当前已经生成的NAS PV进行更新,并通过重启Pod使其生效。(注意:noresvport参数生效有其特殊性,咨询nas技术支持。)

升级Nas Controller:

上面的文档只是把老版本生成的pv更新挂载参数,只有更新了nas controller版本后才能使后续生成的pv自动使用新挂载参数。

新Controller模板:

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: alicloud-nas-controller
  namespace: kube-system
spec:
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: alicloud-nas-controller
    spec:
      tolerations:
      - operator: Exists
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: node-role.kubernetes.io/master
                operator: Exists
      priorityClassName: system-node-critical
      serviceAccount: admin
      hostNetwork: true
      containers:
        - name: nfs-provisioner
          image: registry.cn-hangzhou.aliyuncs.com/acs/alicloud-nas-controller:v1.14.3.8-58bf821-aliyun
          env:
          - name: PROVISIONER_NAME
            value: alicloud/nas
          securityContext:
            privileged: true
          volumeMounts:
          - mountPath: /var/log
            name: log
      volumes:
      - hostPath:
          path: /var/log
        name: log

通过下面命令重建Nas Controller:

# kubectl delete deploy alicloud-nas-controller
# kubectl create -f controller.yaml

StorageClass更新:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: alicloud-nas
mountOptions:
- nolock,tcp,noresvport
- vers=3
parameters:
  server: "2564f49129-**.cn-shenzhen.nas.aliyuncs.com:/"
  driver: nfs
provisioner: alicloud/nas
reclaimPolicy: Retain

通过下面命令更新StorageClass:

# kubectl delete sc alicloud-nas
# kubectl create -f stroageclass.yaml

验证:

扩容应用Pod数量,生成新PVC、PV:

# kubectl get pv default-html-web-nas-5-pvc-91f37aa0-14f6-11ea-a9b7-00163e084110 -oyaml| grep mountOptions -A 6
  mountOptions:
  - nolock,tcp,noresvport
  - vers=3
  nfs:
    path: /default-html-web-nas-5-pvc-91f37aa0-14f6-11ea-a9b7-00163e084110
    server: 2564f49129-**.cn-shenzhen.nas.aliyuncs.com
  persistentVolumeReclaimPolicy: Retain

查看Pod挂载信息,noresvport等参数均已配置成功:

2564f49129-**.cn-shenzhen.nas.aliyuncs.com:/default-html-web-nas-5-pvc-91f37aa0-14f6-11ea-a9b7-00163e084110 on /var/lib/kubelet/pods/4bc4bb3e-14f7-11ea-a9b7-00163e084110/volumes/kubernetes.io~nfs/default-html-web-nas-5-pvc-91f37aa0-14f6-11ea-a9b7-00163e084110 type nfs (rw,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,nolock,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.152,mountvers=3,mountport=4002,mountproto=tcp,local_lock=all,addr=192.168.1.152)
]]>
数据卷挂载问题快速恢复 Mon, 16 Dec 2019 05:35:02 +0800 Pod挂载、卸载数据卷出现问题的原因很多,有存储卷设计的缺陷、有相关组件实现的bug、有使用方式不当的可能,面对复杂的应用、存储交互系统,我们需要从两个方面对待数据卷问题:

  • 尽量别出问题:减少存储组件的自身稳定性 && 规范的使用方式。
  • 如何面对问题:首要是快速恢复业务,然后分析问题。

本文阐述的是业务快速恢复方案:当Pod因为数据卷挂载重启失败时,暂不去解决节点挂载的问题,而是让pod先在其他节点启动成功,快速恢复业务,待业务恢复后再去分析出问题的节点。

更新一个Pod,卡在了 ContainerCreating 状态:

例如:你在Deployment类型应用中挂载NAS数据卷,Pod在启动的时候报错为挂载失败:

Warning  FailedMount  18s   kubelet, cn-shenzhen.192.168.1.24  Unable to mount volumes for pod "nas-static-796b49b5f8-svbvh_default(2d483078-1400-11ea-a9b7-00163e084110)": 
timeout expired waiting for volumes to attach or mount for pod "default"/"nas-static-796b49b5f8-svbvh". 
list of unmounted volumes=[pvc-nas]. list of unattached volumes=[pvc-nas default-token-9v9hl]

更新前数据卷使用是正常的,而更新后pod启动不了,并有上述信息显示数据卷挂载不上,有一个可能性为:当前pod所在节点对此pv/pvc出现状态异常。具体异常原因暂不深究。

通过把pod调度到其他节点快速启动pod,参考如下步骤:

1. 确定pod所在节点:

根据上述错误信息即可拿到节点为:cn-shenzhen.192.168.1.24

也可以通过下面步骤拿到:
# podname="nas-static-796b49b5f8-svbvh"
# namespace="default"
#  kubectl describe pod $podname -n $namespace | grep Node: | awk '{print $2}'
cn-shenzhen.192.168.1.24/192.168.1.24

2. 设置节点不可调度:

您可以使用控制台来配置节点调度状态,参考

也可以使用下面命令行执行给当前挂载有问题的节点打上污点标签,确保pod不会再往这个节点调度:

# kubectl taint nodes cn-shenzhen.192.168.1.24 key=value:NoSchedule
node/cn-shenzhen.192.168.1.24 tainted

3. 重启问题Pod:

这时重启问题Pod,新建的Pod就不会调度到刚才有问题的节点了:

删除问题Pod:
# kubectl delete pod nas-static-796b49b5f8-svbvh
pod "nas-static-796b49b5f8-svbvh" deleted

新的pod启动成功,且调度到新节点:
# kubectl get pod
NAME                          READY   STATUS        RESTARTS   AGE
nas-static-857b99fcc9-vvzkx   1/1     Running       0          14s
# kubectl describe pod nas-static-857b99fcc9-vvzkx | grep Node
Node:               cn-shenzhen.192.168.1.25/192.168.1.25

4. 后续处理:

上述步骤目的是保证您您的业务快速恢复,但问题节点的问题还存在,您可以通过[存储常见问题]()进行排查分析。

如果您无法解决节点问题,可以联系阿里云容器服务技术支持。节点问题解决后,您可以通过控制台或者命令行将问题节点配置为可调度状态;

# kubectl taint nodes cn-shenzhen.192.168.1.24 key:NoSchedule-
node/cn-shenzhen.192.168.1.24 untainted

更新一个pod,卡在 Terminating 状态:

例如:你使用statefulset创建应用,并挂载了云盘数据卷;当更新应用的时候,pod一直处于Terminating状态从而导致新的pod无法正常启动。

# kubectl delete pod web-0

# kubectl get pod
NAME    READY   STATUS        RESTARTS   AGE
web-0   0/1     Terminating   0          47m

到pod所在节点查看下面日志文件:

# tailf /var/log/alicloud/flexvolume_disk.log
# tailf /var/log/messages | grep kubelet

如果发现报错原因为数据卷Umount/Detach等失败,例如:

unmount command failed, status: Failure, reason:

device is busy 字样
或
target is busy 字样
或
Orphan Pod字样
等等

如果在没有找到如何解决问题时急于恢复业务,可以先将问题pod强制删除,优先恢复业务。

1. 使用强制删除命令结束当前pod:

# kubectl delete pod web-0 --force=true --grace-period=0
pod "web-0" force deleted

此命令会强制删除Etcd数据库中的pod信息,从而为创建新pod提供可能(StatefulSet中,老pod没有删除前新pod不会重建)。

2. 如果新建pod启动的时候失败,卡在 ContainerCreating:

可以参考 “更新一个Pod,卡在了 ContainerCreating 状态” 做法,为node配置不可调度,快速恢复pod运行。

3. 登陆问题节点,分析原因:

登陆问题所在节点,通过[存储常见问题]()进行排查分析。无法解决时可能联系阿里云容器服务技术支持。

]]>
妙到毫巅,在阿里云容器服务中体验RAPIDS加速数据科学 Mon, 16 Dec 2019 05:35:02 +0800 摘要
算法、数据和算力称为人工智能的三大要素,如果没有算力的支撑,人工智能难以落地。而Nvidia GPU的强劲算力是AI模型训练加速的首选,但是它的价格也确实不菲。如何能够简单,有效同时低成本的使用Nvidia GPU的算力,使用阿里云容器服务+ECI+Arena的方案是一个可以参考的选项。

而一谈起Nvidia GPU,大家首先会想到的就是深度学习,传统的机器学习和数据分析的方法对GPU的利用却很少,实际上Nvidia有一个非常优秀的项目RAPIDS,全称Real-time Acceleration Platform for Integrated Data Science,是NVIDIA针对数据科学和机器学习推出的GPU加速库。更多RAPIDS信息请参见官方网站。这是一个致力于将GPU加速带给传统算法的项目,并且提供了与Pandas和scikit-learn一致的用法和体验。实际上RAPIDS有三个模块:cuDF相当于Pandas,cuML相当于scikit-learn,cuGraph则是处理图数据的。由于它的兼容性很好,我们可以把RAPIDS与深度学习框架结合,用cuDF来利用GPU加速处理数据,然后使用TensorFlow和PyTorch的深度学习模型框架处理任务。

image.png

在本文中,我们将介绍如何利用TensorFlow和Rapids实现在阿里云容器服务上以图搜图的功能;同时通过ECI实现GPU资源的使用即申请,秒级的GPU资源准备速度,完成即释放,用户无需提前准备GPU实例;而站在使用者的角度,他并不需要和Kubernetes的基础设施打交道,通过arena的命令行,就可以实现包含GPU的RAPIDS环境的构建和运行,并且完成对GPU基础设施的管理。

执行步骤

步骤1:准备集群

准备托管k8s的集群,所谓托管k8s的集群就是这个k8s的管控节点由阿里云承担资源和运维成本,并且创建了虚拟的Kubelet节点

需要您已创建好容器服务 Kubernetes集群。 您可以选择管版的Kubernetes集群。
由于需要运行系统组件容器,节点中至少有一个Worker节点。

  • 安装虚拟节点,具体可以参考虚拟节点
  • 配置virtual-kubelet-autoscaler,当集群内的GPU资源不足的时候,通过virtual-kubelet-autoscaler将弹出使用GPU的ECI实例。具体参考文档

步骤2:从无到有运行arena创建RAPIDS服务

1.安装arena

$ wget http://kubeflow.oss-cn-beijing.aliyuncs.com/arena-installer-0.3.0-b556a36-linux-amd64.tar.gz
$ tar -xvf arena*.tar.gz
$ cd arena-installer
$ ./install.sh

2.先运行一下arena命令查看集群的GPU资源, 可以看到在该用户集群下,有一个真实节点并没有包含GPU资源,同时存在了一个虚拟节点,该节点并不真实存在,无需付费,同时它提供了无限的GPU资源可以扩展。

$ arena top node
arena top node
NAME                       IPADDRESS      ROLE    STATUS  GPU(Total)  GPU(Allocated)
cn-shanghai.192.168.1.248  192.168.1.248  <none>  ready   0           0
virtual-kubelet            172.20.2.18    agent   ready   1000        0
-----------------------------------------------------------------------------------------
Allocated/Total GPUs In Cluster:
0/1000 (0%)

3.再提交rapids任务前,我们需要做一些准备。准备的目的是加速创建过程和简化访问操作。

3.1.设置访问方式。将访问方式设置为LoadBalancer(该方法只是为了示例简单,并不推荐您在生产环境开放外网ip方访问)

$ find /charts/ -name "*.yaml" | xargs sed -i "s/NodePort/LoadBalancer/g"

3.2.加速启动速度

3.2.1.GPU的容器镜像通常很大,以本实验要使用的rapids容器镜像为例,它的容量为14.7GB.通常启动时间会在10分钟左右。而通过镜像缓存的能力可以将这个从无到有的过程缩短到20s左右。

docker images | grep rapids
registry.cn-shanghai.aliyuncs.com/tensorflow-samples/rapids-samples                0.8.2-cuda10.0-runtime-ubuntu16.04   4597a0334d41        12 days ago         14.7GB

3.2.2.而在serverless kubernetes中,你只需要创建一个ImageCache CRD,就可以直接使用镜像缓存的能力。

$ cat > imagecache.yaml << EOF
apiVersion: eci.alibabacloud.com/v1
kind: ImageCache
metadata:
  name: imagecache-rapids
spec:
  images:
  - registry.cn-shanghai.aliyuncs.com/tensorflow-samples/rapids-samples:0.8.2-cuda10.0-runtime-ubuntu16.04
  imageCacheSize:
   50
EOF

$ kubectl create -f imagecache.yaml

3.2.3.提交后稍等片刻。查看ImageCache状态,其中CACHID可以做后面提交任务时指定的snapshot-id

$ kubectl get imagecache
NAME                AGE    CACHEID                    PHASE   PROGRESS
imagecache-rapids   3d9h   imc-uf6dxdji7txxxxx        Ready   100%

具体操作可以参考文档

4.提交rapids的开发环境

$ arena serve custom 
     --name=rapids 
     --selector=type=virtual-kubelet 
     --toleration=all 
     --annotation=k8s.aliyun.com/eci-image-snapshot-id=imc-uf6dxdji7txxxxx 
     --annotation=k8s.aliyun.com/eci-instance-type=ecs.gn5i-c8g1.2xlarge 
     --gpus=1 
     -e=PASSWORD=mypassw0rd 
     --restful-port=80 
     --image=registry.cn-shanghai.aliyuncs.com/tensorflow-samples/rapids-samples:0.8.2-cuda10.0-runtime-ubuntu16.04
configmap/rapids-201912011815-custom-serving created
configmap/rapids-201912011815-custom-serving labeled
service/rapids-201912011815 created
deployment.extensions/rapids-201912011815-custom-serving created

--selector=type=virtual-kubelet表示通过Virtual Node启动Pod
--annotation=k8s.aliyun.com/eci-instance-type=ecs.gn5i-c8g1.2xlarge表示指定使用ECI的实例类型,ecs.gn5i-c8g1.2xlarge代表阿里云P4机型。具体规格可以查看文档
--annotation=k8s.aliyun.com/eci-image-snapshot-id=imc-uf6dxdji7txxxxx指定3.2.3步中的CACHEID
-e=PASSWORD=mypassw0rd就是通过环境变量PASSWORD设置访问RAPIDS notebook
--gpus=1表示申请的GPU数目

4.查看访问地址,这里是ENDPOINT_ADDRESS和PORTS的组合, 在本示例中它是106.15.173.2:80。同时发现该任务在32秒的时候就可以变成Running状态

$ arena serve list
NAME    TYPE    VERSION       DESIRED  AVAILABLE  ENDPOINT_ADDRESS  PORTS
rapids  CUSTOM  201911181827  1        1          105.13.58.3      restful:80

$ arena serve get rapids
 arena serve get rapids
NAME:             rapids
NAMESPACE:        default
VERSION:          201912011815
DESIRED:          1
AVAILABLE:        1
SERVING TYPE:     CUSTOM
ENDPOINT ADDRESS: 106.15.173.2
ENDPOINT PORTS:   restful:80
AGE:              32s

INSTANCE                                           STATUS   AGE  READY  RESTARTS  NODE
rapids-201912011815-custom-serving-6b54d5cd-swcwz  Running  32s  1/1    0         N/A

5.再次查看集群的GPU使用情况,发现已经有一个GPU资源被占用了

$ arena top node
NAME                       IPADDRESS      ROLE    STATUS  GPU(Total)  GPU(Allocated)
cn-shanghai.192.168.1.248  192.168.1.248  <none>  ready   0           0
virtual-kubelet            172.20.2.20    agent   ready   1000        1
-----------------------------------------------------------------------------------------
Allocated/Total GPUs In Cluster:
1/1000 (0%)

6.如果想查询是哪个Pod占用了这个GPU, 可以在原有命令中加一个-d就可以看到具体的Pod名称。

$ arena top node -d


NAME:       cn-shanghai.192.168.1.248
IPADDRESS:  192.168.1.248
ROLE:       <none>

Total GPUs In Node cn-shanghai.192.168.1.248:      0
Allocated GPUs In Node cn-shanghai.192.168.1.248:  0 (0%)
-----------------------------------------------------------------------------------------

NAME:       virtual-kubelet
IPADDRESS:  172.20.2.20
ROLE:       agent

NAMESPACE  NAME                                                GPU REQUESTS
default    rapids-201912011815-custom-serving-6b54d5cd-swcwz  1

Total GPUs In Node virtual-kubelet:      1000
Allocated GPUs In Node virtual-kubelet:  1 (0%)
-----------------------------------------------------------------------------------------


Allocated/Total GPUs In Cluster:  1/1000 (0%)

7.根据步骤4中的访问地址和端口,打开本地浏览器。输入http://{ENDPOINT ADDRESS}:{ENDPOINT PORT},在本例子中是http://105.13.58.3:80

说明: 推荐使用Chrome浏览器。

8.输入启动命令中设置的密码,然后单击Log in。 在本例子中,密码为mypassw0rd

image.png

步骤三:执行以图搜图的示例

1.进入示例所在目录cuml。
2.双击cuml_knn.ipynb文件。
3.单击image.png

说明: 单击一次执行一个cell,请单击至示例执行结束,详细说明请参见示例执行过程。

image.png

示例执行过程

图像搜索示例的执行过程分为三个步骤:处理数据集、提取图片特征和搜索相似图片。本文示例结果中对比了GPU加速的RAPIDS cuml KNN与CPU实现的scikit-learn KNN的性能。

1.处理数据集。
1.1 下载和解压数据集。 本文示例中使用了STL-10数据集,该数据集中包含10万张未打标的图片,图片的尺寸均为:96 x 96 x 3, 您可以使用其他数据集,为便于提取图片特征,请确保数据集中图片的尺寸相同。

本文示例提供了download_and_extract(data_dir)方法供您下载和解压STL-10数据集。RAPIDS镜像中已经将数据集下载到./data目录,您可以执行download_and_extract()方法直接解压数据集。

image.png

1.2. 读取图片。 从数据集解压出的数据为二进制格式,执行read_all_images(path_to_data)方法加载数据并转换为NHWC(batch, height, width, channels)格式,以便用Tensorflow提取图片特征。

image.png

1.3. 展示图片。 执行show_image(image)方法随机展示一张数据集中的图片。

image.png

1.4. 分割数据集。 按照9:1的比例把数据集分为两部分,分别用于创建图片索引库和搜索图片。

image.png

2.提取图片特征。 使用开源框架Tensorflow和Keras提取图片特征,其中模型为基于ImageNet数据集的ResNet50(notop)预训练模型。
2.1 设定Tensorflow参数。 Tensorflow默认使用所有GPU显存,我们需要留出部分GPU显存供cuML使用。您可以选择一种方法设置GPU显存参数:

  • 方法1:依据运行需求进行显存分配。
config.gpu_options.allow_growth = True
  • 方法2:设定可以使用的GPU显存比例。本示例中使用方法2,并且GPU显存比例默认设置为0.3,即Tensorflow可以使用整块GPU显存的30%,您可以依据应用场景修改比例。
config.gpu_options.per_process_gpu_memory_fraction = 0.3

image.png

2.2 下载ResNet50(notop)预训练模型。 连接公网下载模型(大小约91M),目前该模型已经被保存到/root/.keras/models/目录。

12-10.png

image.png

您可以执行model.summary()方法查看模型的网络结构。

image.png

2.2 提取图片特征。 对分割得到的两个图片数据集执行model.predict()方法提取图片特征。

image.png

搜索相似图片。
3.1 使用cuml KNN搜索相似图片。 通过k=3设置K值为3,即查找最相似的3张图片,您可以依据使用场景自定义K值。
其中,knn_cuml.fit()方法为创建索引阶段,knn_cuml.kneighbors()为搜索近邻阶段。

image.png
KNN向量检索耗时791 ms。

3.2 使用scikit-learn KNN搜索相似图片。 通过n_neighbors=3设置K值为3,通过n_jobs=-1设置使用所有CPU进行近邻搜索。

说明: ecs.gn5i-c8g1.2xlarge的配置为8 vCPU。

image.png

KNN向量检索耗时7分34秒。

3.3 对比cuml KNN和scikit-learn KNN的搜索结果。 对比两种方式的KNN向量检索速度,使用GPU加速的cuml KNN耗时791 ms,使用CPU的scikit-learn KNN耗时7min 34s。前者为后者的近600倍。

验证两种方式的输出结果是否相同,输出结果为两个数组:

  • distance:最小的K个距离值。本示例中搜索了10000张图片,K值为3,因此distance.shape=(10000,3)。
  • indices:对应的图片索引。indices.shape=(10000, 3)。
    由于本示例所用数据集中存在重复图片,容易出现图片相同但索引不同的情况,因此使用distances,不使用indices对比结果。考虑到计算误差,如果两种方法得出的10000张图片中的3个最小距离值误差都小于1,则认为结果相同。

image.png

图片搜索结果

本示例从1万张搜索图片中随机选择5张图片并搜索相似图片,最终展示出5行4列图片。

第一列为搜索图片,第二列至第四列为图片索引库中的相似图片,且相似性依次递减。每张相似图片的标题为计算的距离,数值越大相似性越低。

image.png

步骤4:清理工作

$ arena serve delete rapids
service "rapids-201912011815" deleted
deployment.extensions "rapids-201912011815-custom-serving" deleted
configmap "rapids-201912011815-custom-serving" deleted
INFO[0000] The Serving job rapids with version 201912011815 has been deleted successfully

总结

本文介绍通过Arena+阿里云Serverless Kubernetes快速,简单,低成本的使用RAPIDS加速数据科学。

]]>
阿里云上万个 Kubernetes 集群大规模管理实践 Mon, 16 Dec 2019 05:35:02 +0800 内容简介:
阿里云容器服务从2015年上线后,一路伴随并支撑双十一发展。在2019年的双十一中,容器服务ACK除了支撑集团内部核心系统容器化上云和阿里云的云产品本身,也将阿里多年的大规模容器技术以产品化的能力输出给众多围绕双十一的生态公司和ISV公司。通过支撑来自全球各行各业的容器云,容器服务已经沉淀了支持单元化架构、全球化架构、柔性架构的云原生应用托管中台能力,管理了超过1W个以上的容器集群。本文会介绍下容器服务ACK在海量k8s集群管理上的实践经验。

引言
什么是海量k8s集群管理。大家可能之前看过一些分享,介绍了阿里巴巴或蚂蚁金服内部如何管理单集群1W节点的最佳实践,管理大规模的节点是一个很有意思的挑战。不过这里讲的海量k8s集群管理,会侧重讲如何管理超过1W个以上不同规格的k8s集群。跟据我们和一些同行的沟通,往往一个企业内部只要管理几个到几十个k8s集群,那么我们为什么需要考虑管理如此庞大数量的k8s集群?首先,容器服务ACK是阿里云上的云产品,提供了Kubernetes as a Service的能力,面向全球客户,目前已经在全球20个地域支持。其次,得益于云原生时代的发展,越来越多的企业拥抱k8s,K8s已经逐渐成为云原生时代的基础设施,成为platform of platform。

image.png

image.png

首先我们一起来看下托管这些k8s集群的痛点:
1.集群种类不同:有标准的、无服务器的、AI的、裸金属的、边缘、Windows等k8s集群。不同种类的集群参数、组件和托管要求不一样,并且需要支撑更多面向垂直场景的k8s。
2.集群大小不一:每个集群规模大小不一,从几个节点到上万个节点,从几个service到几千个service等。需要能够支撑每年持续几倍集群数量的增长。
3.集群安全合规:分布在不同的地域和环境的k8s集群,需要遵循不同的合规性要求。比如欧洲的k8s集群需要遵循欧盟的GDPR法案,在中国的金融业和政务云需要有额外的等级保护等要求。
4.集群持续演进:需要能够持续的支持k8s的新版本新特性演进。。

设计目标:

1.支持单元化的分档管理、容量规划和水位管理
2.支持全球化的部署、发布、容灾和可观测性
3.支持柔性架构的可插拔、可定制、积木式的持续演进能力

1.支持单元化的分档管理、容量规划和水位管理

单元化:
一般讲到单元化,大家都会联想到单机房容量不够或二地三中心灾备等场景。那单元化和k8s管理有什么关系?对我们来说,一个地域(比如杭州)可能会管理几千个k8s,需要统一维护这些k8s的集群生命周期管理。作为一个k8s专业团队,一个朴素的想法就是通过多个k8s元集群来管理这些guest K8s master。而一个k8s元集群的边界就是一个单元。
曾经我们经常听说某某机房光纤被挖断,某某机房电力故障而导致服务中断,容器服务ACK在设计之初就支持了同城多活的架构形态,任何一个用户k8s集群的master组件都会自动地分散在多个机房,采用主主模式运行,不会因单机房问题而影响集群稳定性;另外一个层面,同时要保证master组件间的通信稳定性,容器服务ACK在打散master时调度策略上也会尽量保证master组件间通信延迟在毫秒级。

分档化:
大家都知道,k8s集群的master组件的负载主要与k8s集群的节点规模、worker侧的controller或workload等需要与kube-apiserver交互的组件数量和调用频率息息相关,对于上万个k8s集群,每个用户k8s集群的规模和业务形态都千差万别,我们无法用一套标准配置来去管理所有的用户k8s集群,同时从成本经济角度考虑,我们提供了一种更加灵活、更加智能的托管能力。考虑到不同资源类型会对master产生不同的负载压力,因此我们需要为每类资源设置不同的因子,最终可归纳出一个计算范式,通过此范式可计算出每个用户k8s集群master所适应的档位;同时我们也会基于已构建的k8s统一监控平台实时指标来不断地优化和调整这些因素值和范式,从而可实现智能平滑换挡的能力。

image.png

容量规划: 接下来我们看下k8s元集群的容量模型,单个元集群到底能托管多少个用户k8s集群的master? 首先要确认容器网络规划。这里我们选择了阿里云自研的高性能容器网络Terway, 一方面需要通过弹性网卡ENI打通用户VPC和托管master的网络,另一方面提供了高性能和丰富的安全策略。接下来我们需要结合VPC内的ip资源,做网段的规划,分别提供给node、pod和service。最后,我们会结合统计规律,结合成本、密度、性能、资源配额、档位配比等多种因素的综合考量,设计每个元集群单元中部署的不同档位的guest k8s的个数,并预留40%的水位。

image.png

image.png

容器服务已经在全球20个地域支持,我们提供了完全自动化的部署、发布、容灾和可观测性能力。这里重点介绍下全球化跨数据中心的可观测。

全球跨数据中心的可观测性

全球化布局的大型集群的可观测性,对于k8s集群的日常保障至关重要。如何在纷繁复杂的网络环境下高效、合理、安全、可扩展的采集各个数据中心中目标集群的实时状态指标,是可观测性设计的关键与核心。我们需要兼顾区域化数据中心、单元化集群范围内可观测性数据的收集,以及全局视图的可观测性和可视化。基于这种设计理念和客观需求,全球化可观测性必须使用多级联合方式,也就是边缘层的可观测性实现下沉到需要观测的集群内部,中间层的可观测性用于在若干区域内实现监控数据的汇聚,中心层可观测性进行汇聚、形成全局化视图以及告警。样设计的好处在于可以灵活的在每一级别层内进行扩展以及调整,适合于不断增长的集群规模,相应的其他级别只需调整参数,层次结构清晰;网络结构简单,可以实现内网数据穿透到公网并汇聚。

针对该全球化布局的大型集群的监控系统设计,对于保障集群的高效运转至关重要,我们的设计理念是在全球范围内将各个数据中心的数据实时收集并聚合,实现全局视图查看和数据可视化,以及故障定位、告警通知。进入云原生时代,Prometheus作为CNCF中第二个毕业的项目,天生适用于容器场景,Prometheus 与 Kubernetes 结合一起,实现服务发现和对动态调度服务的监控,在各种监控方案中具有很大的优势,实际上已经成为容器监控方案的标准,所以我们也选择了Prometheus作为方案的基础。
针对每个集群,需要采集的主要指标类别包括:

  • OS指标,例如节点资源(CPU, 内存,磁盘等)水位以及网络吞吐;
  • 元集群以及用户集群K8s master指标,例如kube-apiserver, kube-controller-manager, kube-scheduler等指标;
  • K8s组件(kubernetes-state-metrics,cadvisor)采集的关于K8s集群状态;
  • etcd指标,例如etcd写磁盘时间,DB size,Peer之间吞吐量等等。
    当全局数据聚合后,AlertManager对接中心Prometheus,驱动各种不同的告警通知行为,例如钉钉、邮件、短信等方式。

监控告警架构

为了合理的将监控压力负担分到到多个层次的Prometheus并实现全局聚合,我们使用了联邦Federation的功能。在联邦集群中,每个数据中心部署单独的Prometheus,用于采集当前数据中心监控数据,并由一个中心的Prometheus负责聚合多个数据中心的监控数据。基于Federation的功能,我们设计的全球监控架构图如下,包括监控体系、告警体系和展示体系三部分。

监控体系按照从元集群监控向中心监控汇聚的角度,呈现为树形结构,可以分为三层:

边缘Prometheus

为了有效监控元集群K8s和用户集群K8s的指标、避免网络配置的复杂性,将Prometheus下沉到每个元集群内,

级联Prometheus

级联Prometheus的作用在于汇聚多个区域的监控数据。级联Prometheus存在于每个大区域,例如中国区,欧洲美洲区,亚洲区。每个大区域内包含若干个具体的区域,例如北京,上海,东京等。随着每个大区域内集群规模的增长,大区域可以拆分成多个新的大区域,并始终维持每个大区域内有一个级联Prometheus,通过这种策略可以实现灵活的架构扩展和演进。

中心Prometheus

中心Prometheus用于连接所有的级联Prometheus,实现最终的数据聚合、全局视图和告警。为提高可靠性,中心Prometheus使用双活架构,也就是在不同可用区布置两个Prometheus中心节点,都连接相同的下一级Prometheus。

image.png
图2-1 基于Prometheus Federation的全球多级别监控架构

优化策略

监控数据流量与API server流量分离
API server的代理功能可以使得K8s集群外通过API server访问集群内的Pod、Node或者Service。

image.png

常用的透传K8s集群内Prometheus指标到集群外的方式是通过API server代理功能,优点是可以重用API server的6443端口对外开放数据,管理简便;缺点也明显,增加了API server的负载压力。如果使用API Server代理模式,考虑到客户集群以及节点都会随着售卖而不断扩大,对API server的压力也越来越大并增加了潜在的风险。对此,针对边缘Prometheus增加了LoadBalancer类型的service,监控流量完全走LoadBalancer,实现流量分离。即便监控的对象持续增加,也保证了API server不会因此增加Proxy功能的开销。

收集指定Metric
在中心Prometheus只收集需要使用的指标,一定不能全量抓取,否则会造成网络传输压力过大丢失数据。

Label管理
Label用于在级联Prometheus上标记region和元集群,所以在中心Prometheus汇聚是可以定位到元集群的颗粒度。
同时,尽量减少不必要的label,实现数据节省。

3.支持柔性架构的可插拔、可定制、积木式的持续演进能力

前面两部分简要描述了如何管理海量k8s集群的一些思考,然而光做到全球化、单元化的管理还远远不够。k8s能够成功,包含了声明式的定义、高度活跃的社区、良好的架构抽象等因素,k8s已经成为云原生时代的Linux。我们必须要考虑k8s版本的持续迭代和CVE漏洞的修复,必须要考虑k8s相关组件的持续更新,无论是CSI、CNI、Device Plugin还是Scheduler Plugin等等。为此我们提供了完整的集群和组件的持续升级、灰度、暂停等功能。

image.png

2019年6月,阿里巴巴将内部的云原生应用自动化引擎OpenKruise开源,这里我们重点介绍下其中的BroadcastJob功能,他非常适用于每台worker机器上的组件进行升级,或者对每台机器上的节点进行检测。(Broadcast Job 会在集群中每个node上面跑一个pod直至结束。类似于社区的DaemonSet, 区别在于DaemonSet始终保持一个pod长服务在每个node上跑,而BroadcastJob中最终这个pod会结束。)

image.png

此外,考虑不同k8s使用场景,我们提供了多种k8s的cluster profile,可以帮助用户提供更方便的集群选择。我们会结合大量集群的实践,持续提供更多更好的集群模板。

image.png

总结
随着云计算的发展,以Kubernetes为基础的云原生技术持续推动行业进行数字化转型。容器服务ACK提供了安全稳定、高性能的Kubernetes托管服务已经成为云上运行Kubernetes的最佳载体。在本次双11,容器服务 ACK 在各个场景为双十一作出贡献,支撑了阿里巴巴内部核心系统容器化上云,支撑了阿里云微服务引擎MSE、视频云、CDN等云产品,也支撑了双11 的生态公司和 ISV 公司,包括聚石塔电商云、菜鸟物流云、东南亚的支付系统等等。容器服务ACK会持续前行,持续提供更高更好的云原生容器网络、存储、调度和弹性能力,端到端的全链路安全能力,serverless 和 servicemesh 等能力。对于有兴趣的开发者,可以前往阿里云控制台 ,创建一个 Kubernetes 集群来体验。对于容器生态的合作伙伴,也欢迎加入阿里云的容器应用市场,和我们一起共创云原生时代。

]]>
Serverless Kubernetes入门:对kubernetes做减法 Mon, 16 Dec 2019 05:35:02 +0800 背景
Kubernetes作为通用的容器编排系统,承载了广泛的应用和场景,包括CI/CD,数据计算,在线应用,AI等,然而由于其通用性和复杂性,管理一个kubernetes集群对于很多用户而言还是充满挑战的,主要体现在:

  • 学习成本高;
  • 集群运维管理成本高,包括节点管理、容量规划,以及各种节点异常问题的定位;
  • 计算成本在很多场景中没有达到最优,比如对于一个定时运行Jobs的集群,长期持有资源池对于用户来说是浪费的行为,资源利用率不高。
    Serverless Kubernetes是阿里云容器服务团队对未来kubernetes演进方向的一种探索,通过对kubernetes做减法,降低运维管理负担,简化集群管理,让kubernetes从复杂到简单。

对Kubernetes集群做减法

无节点管理

我们相信未来用户会更加关注应用的开发,而不是基础设施的维护。体现在kubernetes集群中,我们希望用户能够关注在pod/service/ingress/job等应用编排语义上,对底层node则可以减少关注。

无需管理节点也可以显著降低集群的运维管理成本,经统计kubernetes常见的异常问题中大多数与节点相关,比如Node NotReady问题,也无需担忧Node的安全问题,以及基础系统软件的升级和维护。

在ASK集群中,我们使用虚拟节点virtual-kubelet代替ecs节点,虚拟节点的容量可以认为是“无限大”,用户不需要为集群的容量担忧,无需预先做容量规划。

image.png

无Master管理

和ACK托管版一样,ASK的Master(apiserver, ccm, kcm等)资源被容器服务平台托管,用户无需管理这些核心组件的升级和运维,也不用付出成本。

极简的k8s基础运行环境

除了无需管理节点和Master外,我们还对kubernetes集群管理做了大量简化,包括默认托管很多addon,用户无需再管理一些基础的addon,也不需要为这些addon付费。依赖阿里云原生的网络和存储等能力,以及独特的托管架构设计,我们提供了极度简化但功能完备的kubernetes基础运行环境。

12-10  图.png

综上可以看到,ACK集群至少需要2台ecs机器以运行这些基本的Addon,而ASK集群把这些基础Addon化为无形,可以达到0成本创建一个开箱可用的kubernetes集群。

简化弹性伸缩

因为无需管理节点和容量规划,因此当集群需要扩容时也就不需要考虑节点层面的扩容,只需要关注pod的扩容,
这对于扩容的速度和效率都是极大的提升,目前一些客户指定使用ASK/ECI的方式来快速应对业务流量高峰。

当前ASK/ECI支持30s完全启动500个pod(至Running状态),单个pod启动可以达到10s以内。

更低成本

除去ASK集群本身的低成本创建外,pod的按需使用也让很多场景下资源利用率达到最优。对于很多Jobs或者数据计算场景而言,用户并不需要长期维护一个固定的资源池,这时ASK/ECI可以很好的支持这些诉求。

经验证,当pod一天中运行时间少于16个小时,则ASK/ECI的方式相比保有ecs资源池更节省经济成本。

ECI:快速交付容器资源的弹性计算服务

谈起ASK,一定会谈到ASK的资源底座ECI。ECI是阿里云基于ECS IaaS资源池提供的稳定、高效、高弹性容器实例服务。ECI让容器成为了公有云的第一等公民,用户无需购买和管理ecs就可以直接部署容器应用,这种简化的容器实例产品形态和ASK形成了一个完美的组合。
用户可以直接使用ECI Open API创建容器实例资源,但在容器场景中用户普遍需要一个编排系统,来负责容器的调度、高可用编排等能力,而ASK正是这样的kubernetes编排层。

对于ASK而言,ECI让ASK容器服务免去了搭建后台计算资源池的必要,更不用为底层计算资源池的容量而担忧。基于ECI就意味着基于整个阿里云IaaS规模化资源池,天然拥有了库存和弹性优势(比如可以通过Annotation的方式指定底层eci对应的ecs规格,大部分ecs规格都可以在ASK中使用,满足多种计算场景的需求)。另外ECI和ECS复用资源池意味着我们可以最大化释放规模化红利,给用户提供更低成本的计算服务。

容器生态支持

ASK对kubernetes容器生态提供了完善的支持,目前已有大量客户使用ASK来支撑如下各种场景。

  • CI/CD:gitlab-runner,jenkins/jenkins-x
  • 数据计算:spark/spark-operator,flink,presto,argo
  • AI:tensorflow/arena
  • ServiceMesh: istio,knative
  • 测试:locust,selenium
    ASK集群不支持Helm v2,近期ACK/ASK会发布Helm v3的支持,之后用户可以非常方便的在ASK集群中部署Charts。

更多ASK参考文档

快速部署jenkins环境及执行流水线构建

创建Service

基于privatezone服务发现

创建Ingress

使用nginx ingress

sls日志收集

使用kaniko自动化构建镜像

使用虚拟节点

使用GPU容器实例

pod挂载eip

使用镜像快照加速启动

收集pod日志到sls

运行Argo workflow

使用vk-autoscaler

ASK Examples

]]>
容器镜像服务 联手 IDE 插件,实现一键部署、持续集成与交付 Mon, 16 Dec 2019 05:35:02 +0800 容器技术提供了一种标准化的交付方式,将应用的代码以及代码环境依赖都打包在一起,成为一个与环境无关的交付物,可以被用在软件生命周期的任何阶段,彻底改变了传统的软件交付方式。

甚至可以说,是在容器技术之后,DevOps、CI/CD 等运维关键问题才有了质的飞跃:实现资源的动态创建和销毁,更轻量的容器技术既能保证环境一致性也能进一步提高迭代频率,各种容器平台也能更好地保证应用高可用、自动伸缩、业务连续等等。

今天将跟大家分享支撑双十一的容器镜像服务 ACR,以及它是如何实现搭配 IDE 插件和 CICD/云原生应用交付链来实现一键部署与持续集成,以下是本文提纲:

  • 什么是 容器镜像服务 ACR
  • 如何搭配 免费 IDE 插件 实现一键部署
  • 如何运用 CICD/云原生应用交付链 实现持续集成与交付

想听软萌音在线讲解?阿里云小姐姐直播,手把手教你,12月5日晚上8点—9点,直播间等你(还有弹幕截屏送礼品!)

容器镜像服务 ACR

为了更好地支持双十一大规模分发需求,容器镜像服务(Alibaba Cloud Container Registery, ACR)团队提前进行规划及迭代更新,全面提升了大规模分发场景下的性能、可观测性和稳定性。在新的双十一来临前,容器镜像服务已达到了 PB 的镜像托管量,月均镜像拉取达数亿次,平滑度过 54.4 万笔交易峰值。

阿里云镜像仓库 ACR 分为默认实例版与企业版,虽然结合阿里云产品做了多维度优化,但是并不与阿里云强制绑定。ACR 默认实例版面向容器开发者,提供安全的镜像托管、便捷的镜像授权功能,方便用户进行镜像全生命周期管理,并且简化了 Registry 的搭建运维工作,支持全球 20 个地域的镜像托管。ACR 企业版面向安全需求高、业务多地域大规模部署的企业级客户,提供大规模镜像分发能力、企业级的安全独享特性,以及云原生应用交付链,全链路可观测、可跟踪以及可设置,可实现一次应用变更,多场景自动化交付。
1

如何搭配 免费 IDE 插件实现一键部署

2

Cloud Toolkit 是一款免费的本地 IDE 插件,很多技术博客都有相关的测评,是一款口碑较好的插件。它能够帮助开发者更高效地开发、测试、诊断并部署应用。设置好插件的初始配置之后,可以将本地应用一键部署到任意服务器 Host,甚至云端(ECS、ACR、Kubernetes 和 小程序云 等);并且还内置了 Arthas 诊断、Dubbo工具、Terminal 终端、文件上传、函数计算 和 MySQL 执行器等工具,减少了切换工作界面的时间,灵巧且实用,推荐安装试用一波。下面介绍,插件如何将应用一键部署到容器镜像服务 ACR 。

开发者的部署包从形成镜像到镜像仓库,手动操作的话,每一次都需要经历下图 4 个步骤:登录阿里云Docker Registr--> 从Registry中拉取镜像 --> 将镜像推送到Registry --> 选择合适的镜像仓库地址,但是,使用 Cloud Toolkit ,开发者可以实现在本地 IDE 就能一键部署到镜像仓库。

(一)配置插件首选项

安装完插件之后,点击:顶部菜单Tools --> Alibaba Cloud Toolkit --> Preferences-->左边列表的 Alibaba Cloud Toolkit--> Accounts ,出现如下界面,配置阿里云账号的 AK 和 SK,即可完成首选项配置。(如果是子账号,则填写子账号的 AK 和 SK)

3

(二)设置本地 Docker 镜像打包

点击:顶部菜单Tools --> Alibaba Cloud Toolkit --> Preferences --> 左边列表的 Alibaba Cloud Toolkit --> Docker,如下图,设置本地 Docker 镜像打包。

4

(三)部署应用

第一步:在 Intellij IDEA 中,如下图点击:顶部菜单Tools --> Alibaba Cloud -->Deploy to ACR/ACK --> Deploy to ACR

5

第二步:设置 Image

  • 在 Image 标签页中,选择本地应用程序的 Context Directory 和 Dockerfile (通常会根据您本地的应用工程自动识别并设置)。
  • 选择容器镜像服务的地域、命名空间和镜像仓库。

6

第三步:执行部署

点击 Run 按钮之后,即可完成将本地 Docker 镜像推送到 ACR 中去。

如何运用 CICD/云原生应用交付链 实现持续集成与交付

7

ACR企业版的云原生交付链在托管交付分发等方面进一步提升,历经双11大促,沉淀了云原生应用万节点协同的技术经验。

目前支持容器镜像、Helm Chart 两类云原生应用资产,并采用独立网络访问控制,可细粒度控制公网及VPC 网络的访问策略,仅允许符合策略的来源方访问资产,保障访问安全。

同时实现了整个应用交付周期的流程自动化,开发者只要一次变更应用,按照配置多场景交付,即可实现一次应用变更,全球化多场景自动交付。
8

在应用交付环节,ACR EE 支持自动发起静态安全扫描并自定义配置安全阻断策略。一旦识别到静态应用中存在高危漏洞后,可自动阻断后续部署链路。用户可基于漏洞报告中的修复建议,更新优化构建成新的镜像版本,再次发起交付。

建设 CICD 体系还需要考虑到整体稳定和尽可能不断提升整体交付能力,比如监控报警、容错容灾、依赖治理、限流降级、容量规划。这里可以和大家分享 ACR 团队的相关经验:

  • 在依赖治理方面,要对云原生应用交付链中相关重点环节及外部依赖进行统一管理,识别热点仓库及追踪交付链执行结果;
  • 在限流降级方面,最好分析识别云原生应用分发核心环节的主次业务功能,优先保障主要业务逻辑完成,次要业务逻辑可降级延后处理;
  • 在容量规划方面,平台根据上下游业务变化情况,对资源进行按需扩容,确保云原生应用正常交付完成。

容器镜像服务 ACR 与 插件 Cloud Toolkit 免费面向开发者,帮助技术人员提高开发、部署效率,在减少时间成本的同时提高了业务的质量,还有双十一的顶级洪峰流量场景作为实践案例,希望这篇文章能帮助到有需要的人,并通过相关文章快速上手,真正实现业务价值。

有疑问的同学可以 钉钉扫码 加群解决:

k8s 社区
93b3628c50ba4a6746f68be0f50ea87ef1a1327f.png



IDE 插件群
0a43e54e4738bffb3a1fd28cb221a0040b0b7ad7.jpeg

]]>
Seata GA Meetup 杭州站,报名啦! Mon, 16 Dec 2019 05:35:02 +0800 Seata GA Meetup 杭州站免费报名!

  • Seata AT 模式的精髓是什么?
  • Seata 的过去、现在和未来都是怎样的?

Seata 项目发起人清铭,煊檍为大家现场解读。

When & Where ?

活动时间:2019年12月21日13:30 ~18:00
活动地点:浙江省杭州市余杭区良睦路 1399 号梦想小镇互联网村 26 号浙江青年众创空间
参会收益:Seata 项目发起人清铭给大家全面介绍《Seata 的过去、现在和未来》以及 Seata 1.0 的新特性。更有 Seata 在互联网医疗,滴滴出行上的落地实践现场分享。
福利放送:来到现场的同学可打包下载讲师 PPT ,提供精美茶歇,还有阿里公仔,天猫精灵等好礼等你来拿。

点击“传送门”,免费报名啦~,这一次,你会来么?



seata 不带人头.png

]]>
【升级】12月18日DDoS高防(新BGP)系统升级通知 Mon, 16 Dec 2019 05:35:02 +0800

【阿里云】【DDos高防】【升级通知】

升级窗口:北京时间2019年12月18日 00:00 - 06:00
升级内容:云盾高防(新BGP)机房进行系统升级操作。
升级影响:升级期间,业务无影响,极端情况下部分强安全校验的IP需要重新认证,会导致TCP连接闪断4-6次。闪断对短连接和具备自动重连的长连接业务基本无影响,请确保您在业务上做好重连重试机制,以增强业务的容错能力。

给您带来的不便敬请谅解,有任何问题,可随时通过工单或服务电话95187联系反馈。

]]>
【升级】12月27日DDoS高防系统升级通知 Mon, 16 Dec 2019 05:35:02 +0800

【阿里云】【DDos高防】【升级通知】

升级窗口:北京时间2019年12月27日 00:00 - 06:00
升级内容:云盾高防华北联通机房进行系统升级操作。
升级影响:升级期间,业务无影响,极端情况下部分强安全校验的IP需要重新认证,会导致TCP连接闪断8次。闪断对短连接和具备自动重连的长连接业务基本无影响,请确保您在业务上做好重连重试机制,以增强业务的容错能力。

给您带来的不便敬请谅解,有任何问题,可随时通过工单或服务电话95187联系反馈。

]]>
【升级】12月20日图数据库GDB老实例关闭读写通道,12月31日商业化 Mon, 16 Dec 2019 05:35:02 +0800

【阿里云】【图数据库 GDB】【重要变更通知】
变更时间:北京时间 2019年12月20日 00:00
变更内容:图数据库GDB老实例(12.11日前申请的实例)关闭读写操作
变更影响:尊敬的公测用户,GDB预计于2019年12月31日商业化。计划将于2019.12.20日关闭12.11日前申请的老实例的读写通道,并于2019.12.30日释放老实例。建议您删除不再使用的老实例,免费申请新实例测试;对于在用的老实例,可在12.30日前免费创建新实例,将数据备份恢复到新实例后,再删除老实例。
给您带来的不便敬请谅解,有任何问题,可随时通过工单或服务电话95187反馈。

]]>
【升级】Datahub升级通知 Mon, 16 Dec 2019 05:35:02 +0800

【阿里云】【Datahub】【升级通知】

升级区域:华北,华南,新加坡,吉隆坡,孟买,法国

升级时间:北京时间2019年12月18日 10:00 - 18:00

升级影响:升级过程用户读写请求会有短暂失败重试

升级内容:本次新版本2.14后将有如下特性 :

1)支持同步ots非主键字段指定类型;
2)支持同步ots使用append方式;
3)支持同步es 6.0;
4)支持企业用户按照uid来设置project数量;
5)同步maxcompute逻辑改进;
6)增加schema的数量限制校验;
7)访问日志格式化改进;

]]>
【升级】12月15日新BGP高防系统升级通知 Mon, 16 Dec 2019 05:35:02 +0800

【阿里云】【DDos高防】【升级通知】

升级窗口:北京时间2019年12月15日 06:00 - 09:00
升级内容:云盾新BGP高防机房进行系统升级操作。
升级影响:升级后新BGP高防线路将新增回源网段,具体网段信息如下所示。

新BGP高防线路新增回源网段信息:

47.113.25.0/24

如果您当前正在使用新BGP高防线路并且在服务器侧有相关针对源IP的访问控制策略,请及时更新白名单放行上述回源网段,避免进行机房异地容灾时误拦截造成业务影响。升级期间,业务无影响,极端情况下部分强安全校验的IP需要重新认证,会导致TCP连接闪断2-4次。闪断对短连接和具备自动重连的长连接业务基本无影响,请确保您在业务上做好重连重试机制,以增强业务的容错能力。
给您带来的不便敬请谅解,有任何问题,可随时通过工单或服务电话95187联系反馈。

]]>
Knative Serverless 之道:如何 0 运维、低成本实现应用托管?-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 作者 | 牛秋霖(冬岛)  阿里云容器平台技术专家

关注“阿里巴巴云原生”公众号,回复关键词“1205”即可观看 Knative-Demo 演示视频。

导读:Serverless 无疑是当前最热的云原生话题,那么作为业务的开发人员或者运维人员咱们应该怎么看待这个事情?云原生和 Serverless 到底有什么关系?通过本次分享咱们将逐一揭开这些神秘的面纱。

通过本文您将了解到:

  1. Knative 是如何让普通的应用具备 Serverless 能力的?
  2. 为什么说 Knative 是云原生的应用 Serverless 编排引擎?
  3. Knative 为什么是由 Tekton 、Eventing 和 Serving 三个模块组成,以及这三个模块的协作方式。

本文共有四部分内容:首先咱们一起来看一下云的核心驱动力是什么,接着从这个核心驱动力出发看一下云原生应用是什么样子。然后咱们再一起来看看 Knative 到底给应用的云原生化带来了什么价值,最后咱们通过一个 Demo 亲身感受一下 Knative 带来的这些能力。

云的核心驱动力

在讨论云原生之前我们先来思考一下:为什么企业要上云、为什么技术人员要学习面向云的编程思维以及咱们应该怎么看待云这件事儿。

咱们先来剖析一下发生这些事情的核心驱动力,然后通过这个核心驱动力出发看看整个云原生技术栈是什么样子。

社会分工

1.png

我们先从一顿火锅谈起,一顿火锅虽然很简单,但会涉及到非常多的东西,比如各种蔬菜、牛羊肉等。细想一下,所有的这些东西我们都经常食用,但是其中有哪些东西是我们自己亲手种植或养殖的呢?事实上都没有,我们每天都是坐在办公室,下班的路上到市场或超市买到这些东西,不知道也并不关心这些东西的具体生产过程。

我小时候在内蒙的农村长大,大家都知道,内蒙很大。村里每户人家都有一个大园子,夏天的时候家家户户都会在园子里种植各种蔬菜,如西红柿、黄瓜、茄子、辣椒等;但到了冬天,由于天气很冷,根本见不到新鲜的蔬菜,大家吃的都是咸菜、酸菜,或者是秋天晾晒的一些干菜。我们可以发现:一个地域非常容易受到季节的影响,虽然夏天可以种植各种蔬菜,但是到了冬天就什么都没有了。但是现在就不同了,全国各地随处都能非常容易地买到新鲜蔬菜,这其实是社会分工的结果、是不同地域、不同角色之间通过市场相互协作的成果。

现在因为有专业的人在做这些事情,所以我们大多数人都无需劳心蔬菜是怎么种植的。而我们工程师所做的和计算机打交道的事情也能通过其他的渠道反过来帮助那些种菜的人。

分工提高效率,这是现代经济学之父亚当斯密 200 多年前在他的经典著作《国富论》中的开篇观点。其实现代社会的运行机制也印证了该理论;我认为它也是企业拥抱云计算的根本原因。因为大家需要把一些非业务核心的部分“承包”给专业的人士去完成,那些和自己的业务强相关的部分才是企业的核心竞争力。

应用上云

2.png

接着咱们再来看看一个应用都是由哪些部分构成的。

应用要提供服务首先要有计算、存储和网络资源才能把进程跑起来。当然这些也仅仅是把进程跑起来,如果要承接具体的业务还需要依赖数据库等服务;如果要做分布式架构还需要做微服务拆分,这时候就需要缓存、注册中心、消息各种中间件的服务。

以上的情况都是程序已经存在,如何把程序跑起来承接业务的部分。还有一部分是如何把代码变成可启动的程序,这就是 CICD 部分了。从代码到应用启动再到应用依赖的周边系统支撑都说完了,还有一部分就是日常运维相关的:

  • 比如日志收集、分析
  • 比如监控和告警

虽然我们本来只是想要写一个应用,来为业务提供服务。但是应用周边的这些支撑系统比这个应用自身的消耗还要高上很多。这其实不是我们期望的结果,让业务团队更多的聚焦在业务逻辑本身,而不是周边的这些系统上,这才是我们希望看到的。

3.png

实际上有一定规模的公司,内部的组织架构基本也都是由一个基础平台团队和多个业务团队构成的,基础平台团队负责提供这些应用需要的公共能力支撑,业务团队更聚焦在业务上,直接使用基础平台团队的能力即可。这其实就是社会分工在 IT 组织中的体现,专业的人做专业的事儿,分工提升效率。

现在我们再回顾一下刚才吃火锅的例子。

如果时间倒退 20 年,回到北方的冬天,我们想要吃一顿有肉、有蔬菜、还有金针菇的火锅,根本就不可能,但是现在,我们可以随时随地买到这些东西,而所有这些都是专业的人士生产的,我们无法自给自足这么丰富的资源。

那么对于一家企业而言,也是一样的。虽然每个企业都有自己的基础平台团队,但是由于规模或者资金投入等原因,不可能提供像云这么丰富的平台支撑。如果有,那一定也是一个云厂商。所以对于业务来说,把所有和应用相关的周边系统都使用云的初始设施搭建,把这些周边系统承包给云厂商才是高效率的做法。我理解为这就是云原生出现的背景。

分工提高效率这是大家使用云的根本动力。云原生理念是在各大企业上云的过程中逐渐形成和完善的。这套理念是协调所有参与方对服务上云逐渐形成的统一标准,这个统一的标准可以很好地帮助企业上云、帮助云厂商释放云的能力。从云的客户角度来讲,这个统一标准就是避免云厂商锁定。比如 Kubernetes 就是一个非常好的统一共识,因为所有云平台都支持 Kubernetes。

4.png

那么这个标准的价值是什么呢?为什么云厂商和上云的企业都积极参与这个标准的“制定”呢?这其实是一个互利互惠的结果。在具体谈论这个标准的作用之前,我们先来聊聊两种资源分配模式的差别。

排队(先到先得)

这部分咱们以就医为例进行说明。

去医院看病需要提前挂号,医生的号源这是一种先到先得的资源分配方式。特别是在北上广这些大城市,好医生的号源更是一号难求。如果想保证一定要拿到某个医生的就诊号,就要保证比别人都更早地到医院排队,提前排队可以优先拿到就诊号。我们现在来分析一下,提前排队的人所付出的努力都有什么价值。

  • 对于排队的当事人:当事人付出的努力对于自己是有意义的,自己拿到了就诊号,得到了回报;
  • 对于其他的排队者而言,是没有任何好处的。早来的人拿到了就诊号,这就给别的竞争号源的人发出了一个信号——来的越早就越有可能得到号源。这有可能引发更多人更早的前来排队,这是一个恶性循环;
  • 对于医生来说,没有任何意义,谁来看病都是一样,谁得到这个号对医生来说差别不大。很多时候甚至患者要求加号,但医生其实是不愿意的,因为每增加一个号源就意味着医生要付出一点儿休息的时间。对于医生而言,多付出的休息时间是不能换来更多报酬的,因为这是一个先到先得的排队秩序规则,每一个号源的价格都是一样的。

有没有发现在排队的过程中所做出的付出只对排队的当事人是有意义的,对于医生以及其他排队者都没有任何意义,甚至会带来恶性竞争,造成社会资源的巨大浪费。在排队的过程中,大量的资源都白白地流失,没有给社会带来任何价值。

市场经济

这部分我们以购买云服务器 ECS 为例进行说明。

假设目前阿里云的 ECS 是性价比最高的,大家上云都优先选择使用阿里云的 ECS,那么如果出现供不应求的情况就可能会导致 ECS 价格上涨,而价格上涨就会导致更多的云厂商供应 ECS ,最终导致价格又回落下来。我们分析一下在这个过程中购买 ECS 的人和提供 ECS 的云厂商之间的关系:

  • 我们发现大量客户选购 ECS 这件事情本身对于上云的客户是有益无害的,因为大量的需求会导致云厂商做更多的供应,价格不可能持续高攀。所以 ECS 需求的竞争者之间其实不是零和博弈,而是一个相互合作的关系。大家一起把饼做大,就让整个供应链更稳定、便宜。就好比我买苹果手机,你也买苹果手机,但是咱俩不是竞争关系,而且买的人越多,苹果手机的质量就会越来越好;
  • 大量的 ECS 需求会促使 ECS 技术的成熟。对于 ECS 的提供者云厂商而言,越多的人购买自己的服务就越好,所有的客户和云厂商之间都是相互促进的关系。

市场经济这种基于价格的自由交易能够非常高效地促进大家的合作,任何一方的努力对于其他的参与者而言都是有价值的。和医院排队中先到的人付出的努力只对自己产生价值相比较,市场经济的自由交易方式中,每一方的付出都让整个系统得到了优化,这是社会资源合理利用、合理分配的一种非常好的方式。

5.png

是不是感觉扯远了,这和云计算有什么关系?我们继续来剖析一下市场经济,就可以看到和云计算的密切关系了。

我们先来看一下这个场景:如果云厂商 A 提供的服务性价比很高,但是有一天云厂商 B 提供了性价比更高的服务,客户会不会立即把服务迁移到云厂商 B 上去?答案是客户想要迁移,但是比较难迁移。因为每一个云厂商提供的服务标准都不太一样,服务迁移的过程需要适配大量差异化的底层基础设施,这给迁移带来了巨大的成本,甚至抵消了云厂商 B 提供的高性价比,所以平常比较少见到这种迁移。

前面咱们分析了市场经济的资源分配方式是非常有利于社会各方面资源进行最优配置的,可是如果云客户不能在云厂商之间低成本的流动,其实就很难选择性价比高的云厂商。所以从有效配置社会资源这个角度来分析,现在迫切需要一个能够让客户在不同云厂商之间低成本“流动”的体系,而这就是云原生的意义所在。

如果把客户要在云上托管的应用比喻成水的话,那么云服务的价格就是海拔的高度。哪里海拔低,水就很自然的流到哪里去。无限降低迁移的成本,对于客户和云厂商来说都是非常有价值的一件事情。云原生旨在以标准化云服务的提供方式衔接云厂商和客户。这种方式对于客户而言降低了上云和跨云迁移的成本,让客户始终保有和云厂商议价的能力;对云厂商而言,因为客户跨云迁移的成本低,所以只要能提供性价比更高的云服务,就能很容易的聚集大量用户。

云原生是在不断促进整个系统的良性循环:既能让客户始终保有选择的能力,又能让优秀的云厂商快速服务更多的客户。如果客户的业务服务能像水一样低成本在不同云厂商之间流通,那么云厂商提供的服务就能像货币一样在客户之间流通。这是一个多赢的局面。

云原生应用

说完云原生这个理念,我们来看一下云原生应用,以及在云原生的这个大背景下,如何看待传统的应用架构?

云上基础设施

6.png

无论是云上的应用,还是云下的应用,其实依赖的核心要素都没有变,只是这些核心要素的提供形式发生了变化。

如上图所示,共有 7 个核心要素。这 7 个要素中日常运维这一块其实不是强依赖的,虽然它对业务的稳定性影响极大,但是这并不是业务跑起来的核心链路,没有这些业务也能跑,而其它的几块都是核心链路。那么我们就来看一下在云原生架构下,这些核心链路的要素都处于什么位置?然后剖析一下云原生应用的基本范式。

云原生技术栈

7.png

我们先来看看最右边的中间件这一块,里面有数据库、Redis 以及消息中间件组件。而这一块其实是应用代码里面直接调用的,并且这里包含的所有能力都有标准的协议,比如无论是使用 SQL Server 还是使用 MySQL,我们程序里都可以使用 SQL 规范进行操作。这部分其实早就被标准化了。 

如图所示,计算、存储和网络这三个核心要素已经被 Kubernetes 层统一了。很多云服务已经实现了计算、存储和网络资源的无服务器化,比如阿里云的 ECI 和 ASK(Aliyun Serverless Kubernetes)。那么还有两块 CICD 和应用托管没有标准化,这就是应用编排这一层需要标准化的事情。Serverless 其实不单单是无服务器,还包括应用本身的编排,这也是应用编排这一层的价值所在。

云原生应用 Serverless 编排

Serverless Kubernetes 已经提供了 Pod 的无服务器支持,而应用层想要用好这个能力其实还有很多事情需要处理。

  • 弹性:

    • 缩容到零
    • 突发流量
  • 灰度发布

    • 如何实现灰度发布
    • 灰度发布和弹性的关系
  • 流量管理

    • 灰度发布的时候如何在 v1 和 v2 之间动态调整流量比例
    • 流量管理和弹性是怎样一个关系
    • 当有突发流量的时候如何和弹性配合,做到突发请求不丢失

我们发现虽然基础资源可以动态申请,但是应用如果要做到实时弹性、按需分配和按量付费的能力还是需要有一层编排系统来完成应用和 Kubernetes 的适配。这个适配不单单要负责弹性,还要有能力同时管理流量和灰度发布。

Knative 应运而生

上文中的内容就是 Knative 要解决的问题,这也是 Knative 出现的背景。接下来咱们来看看 Knative 。

Knative 是什么

8.png

我们先看看官方给出的定义:“基于 Kubernetes 平台,用于构建、部署和管理现代 Serverless 工作负载”。Knative 就是基于 Kubernetes 的应用 Serverless 编排系统。实际上 Knative 包含的不单单是 Workload,它还有 Kubernetes 原生的流程编排引擎和完备的事件系统。

前面提到 Kubernetes 实现了计算、存储和网络的标准化,而 Knative 目标基于 Kubernetes 提供了应用 Serverless 工作负载编排的标准化。

Knative 核心模块

9.png

Knative 由三个核心模块构成:Tekton、Eventing 和 Serving。

  • Tekton 是 Kubernetes 原生的流程编排框架,主要用于构建 CICD 系统;
  • Eventing 主要负责事件处理功能,可以接入外部系统的事件,事件接入以后进行一系列的流程处理以及触发 Serving 消费事件;
  • Serving 是应用运行工作负载的核心管理模块,主要负责流量调度、弹性以及灰度发布等职责。

Tekton

10.png

Tekton 是一套 Kubernetes 原生的流程编排框架,主要用于构建 CICD 系统。比如从源码编译成镜像,以及对镜像里的服务进行测试、把镜像发布成应用等一系列的操作都可以基于 Tekton 完成。

Tekton 里面基本的执行单元是 Task。>

  • Task 里面可以包含多个顺序执行的 Step。一个 Task 最终就是一个 Pod,里面的每一个 Step 最终执行的时候就是一个 Container 。每提交一个 TaskRun CRD 到 Kubernetes 就会触发一次 Task 的执行;
  • Pipeline 可以编排多个 Task,Pipeline 中的 Task 是可以设置依赖关系。Pipeline 会根据依赖关系生成一个有向无环图,然后生成的根据有向无环图并发或者串行执行一系列的 Task。每提交一个 PipelineRun CRD 就会触发 Pipeline 的一次执行;
  • PipelineResource 代表 Pipeline 使用或者生成的资源,比如:github 代码仓库、依赖或者使用的镜像等等;
  • Tekton 是 Kubernetes 原生的实现,所以资源鉴权的秘钥等信息都可以通过 Kubernetes 的 Secret 进行管理。

Eventing

11.png

Eventing 模块基于 CloudEvent 标准实现了一系列的事件处理机制。Eventing 模块的核心能力分成四大块。

  • 外部事件接入

Eventing 有很强的扩展机制,可以接入任何外部事件源的事件,比如 github 里面的 commit、pull request 等事件;Kubernetes 里面的事件;消息系统里面的消息;以及 OSS、表格存储、Redis 等系统的事件。

  • CloudEvent 标准

Eventing 接入外部事件以后会转换成 CloudEvent 格式,事件在内部的流转都是通过 CloudEvent  事件标准完成的。

  • 事件在内部的处理

Eventing 模块引入的 Broker 、Trigger 模型,不仅将事件复杂的处理实现给用户屏蔽起来,更提供了丰富的事件订阅、过滤机制。

  • 事件处理事务管理

Eventing 基于可靠的消息系统,可以对事件进行事务管理。如果事件消费失败可以进行重试或者重新分发等操作。

Serving

12.png

Serving 核心的 CRD 就是 Service,Knative Controller 通过 Service 的配置自动操作 Kubernetes 的 Ingress、K8s Service 和 Deployment 从而实现简化应用管理的目标。

Knative Service 对应一个叫做 Configuration 的资源,每次 Service 变化如果需要创建新的 Workload 就更新 Configuration,然后每次 Configuration 更新都会创建一个唯一的 Revision,Revision 可以认为是 Configuration 的版本管理机制。理论上 Revision 创建完以后是不会修改的,不同的 Revision 一般用于灰度发布。

Route 是 Knative 管理流量的核心逻辑,Knative 是建立在 Istio 之后的,Knative  Route Controller 通过 Route 的配置自动生成 Istio 的 VirtualService 资源,从而实现了流量的管理。

Knative  Serving 对应用 Workload 的 Serverless 编排是从流量开始的。

流量首先达到 Knative 的 Gateway,Gateway 根据 Route 的配置自动把流量根据百分比拆分到不同的 Revision 上,然后每一个 Revision 都有一个自己独立的弹性策略。当过来的流量请求变多的时候当前 Revision 就开始自动扩容。每一个 Revision 的扩容策略都是独立的,相互不影响。

基于流量百分比对不同的 Revision 进行灰度,每一个 Revision 都有一个自己独立的弹性策略。Knative Serving 通过对流量的控制实现了流量管理、弹性和灰度三者的完美结合。

Knative 的云原生特性

14.png

Kubernetes 是业界公认的云原生操作系统,作为云原生的 Serverless 编排引擎 Knative 当然是兼容 Kubernetes API 的。

Knative 本身就是开源的,你可以在任何 Kubernetes 集群上面部署一套 Knative 。同样,你在任何 Knative 集群里面的服务都可以无缝迁移到另外一个 Knative 集群。如果你的服务是搭建在 Knative 之上,那么你的服务就可以像水一样在各个云厂商流通,任何一个云厂商的 Kubernetes 搭建好 Knative 就能轻松地把你的服务部署起来。咱们透过下面这个支持列表可以看到 Knative 已经被大量的厂商或平台支持:

云原生的力量就在于此,开放的标准得到了广泛的支持。作为使用云的客户,基于这种开放的标准其实就是始终保有和服务商议价的权利,哪里的服务好就到哪里去,否则就有可能会被一家锁定。对于云厂商而言,通过开放的标准可以接入更多的客户,而这个标准之下的具体实现,每家都会根据自身特点进行支持,这也是云厂商的核心竞争力。

Knative 的典型应用场景

15.png

介绍了这么多,接下来咱们就捋一捋 Knative 都适合在哪些场景中使用。

应用 Serverless 编排场景 

Knative Serving 从流量入手对应用进行 Serverless 编排。

首先 Knative 基于 Istio Gateway 来接管服务的流量,可以做到按百分比对流量进行切分。切分的流量可以直接用于灰度发布,比如把按百分比切分的流量直接转给一个 Revision,精准地控制每一个 Revision 承接的流量百分比,从而达到精准控制灰度版本对线上服务应用的范围。

Knative 的弹性策略是作用在每一个 Revision 之上的,不同的 Revision 根据“自己的节奏”独自伸缩,实现了从流量到灰度灰度再到弹性这三者的完美结合,所有应用弹性托管诉求都可以通过 Knative 来实现。下面这些场景非常适合使用 Knative 来解决:

  • 比如托管微服务应用
  • 比如托管 Web 服务
  • 比如托管 gRPC 服务

事件驱动

Knative 的 Eventing 提供了完整的事件模型,可以很容易地接入各个外部系统的事件。事件接入以后通过 CloudEvent 标准在内部流转,Broker/Trigger 机制给事件处理提供了非常好的方式。

这套完备的事件系统可以比较容易的实现事件驱动的服务,比如:

  • IOT 场景
  • 比如和各种云产品的事件对接,从而实现云产品状态更新自动触发一个服务等

基于 Tekton 的 Pipeline

基于 Tekton 构建 CICD 系统等,比如:

  • 当 gihub 有代码提交以后自动触发镜像构建、服务发布流程
  • 当 docker 镜像仓库有镜像提交的时候,自动对镜像进行测试以及发布成服务等

MicroPaaS

基于 Knative Servering 部署服务,你就无需手动操作 Kubernetes 资源,这样可以大大降低使用 Kubernetes 的门槛。所以如果不是维护 Kubernetes 系统、或者要基于 Kubernetes 做复杂的开发,就可以使用 Knative 来管理自己的服务,非常便捷。

客户案例

16.png

阿里云 Knative 现在都有哪些典型的客户案例?

Web 服务托管

Web 托管服务其实就是前面介绍的 MicroPaaS 类型的场景,客户使用 Knative 是为了简化使用 Kubernetes 的复杂度。即便不使用 Knative 的弹性也可以带来应用托管效率的提升。

应用 Serverless 编排

  • 微服务托管场景
  • web 应用托管和弹性
  • 小程序、公众号后台
  • 电商服务后台

AI 服务托管

  • 基于任务队列的弹性伸缩
  • 使用 ECI 做弹性,有效降低长期保有资源的成本

SaaS 服务托管

  • SaaS 用户提交代码之后自动给用户构建镜像
  • SaaS 用户自己推送了一个镜像之后自动帮助用户发布服务
  • CMS 系统 SaaS 提供商可以通过 Helm Chart 非常方便地给用户部署一套全新的服务

SpringCloud 微服务托管

把 Knative Service 的地址注册到注册中心,通过 Knative 的能力实现微服务的流量切分、灰度发布和弹性。这样 Knative 就给普通的微服务应用赋予了 Serverless 能力。

构建 CICD 系统

  • 基于 git 代码仓库的自动构建、服务发布的 CICD 系统
  • 当 docker 镜像仓库有新镜像的时候自动执行测试或者服务发布

OSS 事件

  • 当 OSS 中新增一个文件自动触发机器学习任务的执行,对图片进行分析、识别等
  • 当 OSS 中新增一个视频文件,自动触发一个任务处理视频,比如视频内容识别等

TableStore 事件

  • Feed 流系统设计
  • 社交信息发送通知等

Demo 演示

17.png

Demo 执行的命令如下:

https://help.aliyun.com/document_detail/126413.html 
https://github.com/knative-sample/cloud-native-go-weather
缩容到零的场景  http://weather-web.default.live.kuberun.com/#/   
https://tracing-analysis.console.aliyun.com/#/appList/cn-shenzhen 
registry.cn-hangzhou.aliyuncs.com/knative-sample/weather-detail:limit-v1 
hey -z 60s -c 30  http://weather-web.default.live.kuberun.com/api/city/detail/010/2019-12-05 
helm install ./chart --name live-weather --namespace live
helm delete live-weather --purge 

关注“阿里巴巴云原生”公众号,回复关键词“1205”即可观看演示视频。

欢迎加入钉钉交流群

18.jpeg

Q & A

Q1:开发怎么远程调试 K8s 中的应用?
A1:Kubernetes 底层首先是一个容器,那咱们就从容器谈起。容器相对于宿主机来说其实只是把业务进程限制在一个更合理的权限范围内,在调试容器里面的业务进程时可以直接 docker exec 到容器内。到了容器内部就和一个 vm 没有什么差别了。而 Kubernetes 的 Deployment 可以认为是编排很多容器,每一个容器都可以通过 宿主机 docker exec 进去。当然也可以通过 Kubernetes 的方式 kubectl exec 到容器内进行调试。如果实在初期调试阶段建议使用比较完整的 CentOS 或者 Ubuntu 镜像,基础镜像内要有一些基本的调试工具。摸索熟悉了之后可以使用精简的基础镜像,这样更经济。

Q2:Knative 的 build 和开发流程管理可以代替 jenkins 吗?
A2:Knative 的 Build 现在是 Tekton 。Tekton 本身的定位不是替换 Jenkins,它的核心理念是建立在 Kubernetes 生态之上。比如 Pod 的执行力度,每一个 Pod 内可以包含很多容器,每一个容器是一个 step,这样我们就可以使用不同的镜像驱动容器,每一个容器内部的环境都是可以完全自定义的。并且容器之间以及 Pod 之间共享资源都是通过 Kubernetes 的模式提供的。另外我们知道 CICD 系统一般都会被运维系统集成,在被集成的的场景中 Tekton 的优势是比较大的。Tekton 是可以通过 Kubernetes API 进行操作的,而 Jenkins 的 API 以及设计理念都是需要单独学习的,这些都是成本。核心还是在于 Kubernetes 这个生态比较强大,而未来的趋势 Kubernetes 将是一个必备技能。在这个大环境下掌握 Tekton 的成本就更低,向前看 Tekton 正在成为主流。

Q3:Knative 编排和 K8s 应用编排的区别及应用场景?
A3:Kubernetes 的最大价值是把对 IaaS 资源的操作标准化了,比如无论是在 AWS 还是在阿里云上面使用计算、存储、网络等资源,都可以直接通过 Kubernetes 语义完成,不需要关系不同厂商底层差异化的实现。而 Knative 才是面向应用的编排。Knative 对应用的 Serverless 编排主要体现在:对流量、灰度策略以及弹性的管理,并且流量、灰度和弹性这三者是完美契合在一起的。从另一个角度来说 Knative 是建立在 Kubernetes 之上的,Knative 需要使用 Kubernetes 提供的对 IaaS 的标准化服务。这二者是上下层的依赖和被依赖的关系,不是竞争关系。

Q4:Knative 有哪些成功的行业应用实践?A4:在阿里云上面已经有很多用户在使用了。另外 Google 的 CloudRun 产品完全是建立在 Knative 之上的。

Q5:Knative 的现状和预期达到的目的?
A5:Knative 现在已经被众多厂商开始支持了,Knative 的目标是标准化应用 Serverless 编排模型。比如:通过 Knative 对应用进行编排、通过 Knative 支撑上层 faas 系统实现。这里说的应用其实不限于在线服务,很多 AI 任务也是通过 Knative 驱动的,比如分享中提到的 KFServing。

Q6:缩容时,怎么才能当 pod 内的流量消耗完,再销毁?
A6:Kubernetes 中 Pod 是可以设置 Prestop 的,Prestop 可以保证先卸载流量,然后再摘除服务。

Q7:在企业私有云环境部署knative会有哪些挑战?
A7:只要是标准的 Kubernetes 集群之上就能部署 Knative,不过很多镜像需要翻墙。

Q8:Istio 层面的管控和维护成本比较高,如 envoy 性能问题、网络问题等,这部分工作是由云平台负责的吗?Knative 这边有没有相应措施?A8:目前阿里云容器服务 Kubernetes 集群控制台可以通过 UI 管理 Istio 和 Knative,可以快速上手。控制台也提供了很多便捷操作降低运维成本。Knative 主要依赖了 Istio 的 Gateway,Gateway 本身是可以横向扩展的,不会有太大影响。

Q9:容器的冷启动问题如何解决,第一个流量岂不是延时很高?
A9:如果缩容到零以后,到一个请求的延时是会很高。第一个请求冷启动的问题是一个公认的业界难题,这也是各大云厂商在竞相解决的问题。相比使用云的客户而言,云厂商自己其实更迫切解决这个问题,敬请关注。

Q10:Knative 的组件本身怎么部署?如何保证 HA?
A10:Knative 是建立在 Kubernetes 之上的,Knative 组件其实就是 CRD 的 Controller。在 Kubernetes 中 Controller 是可以部署多个实例,通过抢锁保证只有一个 Controller 可以执行写操作,HA 的问题容易解决。

阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
“阿里云创峰会·南昌站”即将举行,三大亮点抢先看-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 由江西万科牵手阿里云创新中心共同举办的“阿里云创峰会”,将于12月9日登陆江西南昌。

此次峰会聚焦人工智能、物联网等领域,不仅聚集了知名院士、科学家,知名财经作家,产业、创业孵化、投融资等领域一众国际国内知名人士,还将发布阿里云创新中心项目落地万科·万创科技城等重磅消息。

image.png

据了解,国际核能院院士、中国人工智能学会不确定性人工智能专委会主任张勤,中国工程院院士、中芯国际集成电路制造有限公司研发副总裁吴汉明,国家杰出青年基金获得者、中国科学院软件研究所研究员张健,著名财经评论人、财经作家叶檀、Inbo 国际亚洲董事Mark、以色列BaseCamp公司创始人、盖夫亚姆产业园联合创始人Uzy,以及阿里云高层、多个BU负责人、万科高层等,已确认出席本次活动。

1.jpg

小编以目前官方流出的会议资料,为大家梳理了本次创投峰会的三大亮点:

亮点一、“阿里云创峰会”首次来到江西

“阿里云创峰会”是阿里云创新中心在阿里巴巴集团“五新战略”背景下,为赋能全国科技创新创业群体,于2018年发起的线下活动。

峰会依托阿里云事业群及阿里巴巴大生态资源,聚合全球、全国权威智库、投资机构、产业资源、媒体资源,探索前沿商业模式、连接阿里巴巴及合作伙伴生态资源,为企业发展赋能加速,助力区域产业数字化升级。

此前,阿里云创峰会先后在北京、上海、深圳、杭州等一二线城市,围绕新经济、新金融、人工智能、智能制造、智慧城市等领域,举行过诸多场次。

此次万科·万创科技城项目发布仪式暨阿里云创峰会南昌站的举行,标志着江西万科与阿里云在创新创业领域展开的深入合作进入实际性落地阶段。

阿里云创新中心作为双方合作的首个落地项目,将入驻赣江新区唯一科创基地“万科·万创科技城”,助力打造创新创业赋能体系,以物联网、智能制造、信息科技等科技元素为企业赋能,带动南昌乃至江西整个区域传统行业的转型升级。

亮点二、国内外产学研大咖云集,南昌论道产业前沿

本次创投峰会聚集了国内外智库专家、经济学家、创业孵化、投融资以及互联网企业的知名大咖,小编简要介绍几位将在会议上作重头演讲的嘉宾。

首先是人工智能等领域的院士、科学家、财经大咖。

张勤,国际核能院院士,中国科协原副主席,中国人工智能学会不确定性人工智能专委会主任。张勤院士为清华大学教授,其创立了动态不确定因果图(Dynamic Uncertain Causality Graph)人工智能理论模型,并将其成功应用于核电站等在线状态监测、故障预报、故障诊断和发展预测中。2016年7月,当选国际核能院INEA院士,是国际核能院8位中国院士之一。

吴汉明,中国工程院院士、中芯国际集成电路制造有限公司研发副总裁。其在“十一五”国家重大专项中,主持了“65-45-32纳米成套产品工艺研发”项目,兼任课题“32纳米关键工艺”负责人,是我国在集成电路行业史上投入资金规模最大、难度跨越最高的成套工艺研发项目。

张健,国家杰出青年基金获得者、中国科学院软件研究所研究员,主要研究领域包括自动推理、约束求解、软件测试与分析。担任《计算机学报》,JCST,Frontiers of CS,IEEE Trans. On Reliability,《中国科学》,《计算机科学与探讨》编委,国家973计划“安全攸关软件系统的构造与质量保障方法研究”首席科学家。获得中创软件人才奖、国家杰出青年科学基金。

叶檀,著名财经评论人,财经作家,叶檀财经创始人、华鑫股份首席经济学家。曾著有《拿什么拯救中国经济》、《中国房地产战争》等作品,是《每日经济新闻》主笔、《解放日报》经济评论员,央视财经频道特约评论员。在《南方都市报》、《南方人物周刊》、《财经国家周刊》、FT中文网等多家媒体开辟财经评论专栏。曾获《南方人物周刊》2008年度青年领袖、中国证券市场20年回顾与展望论坛最具影响力财经传媒人奖等奖项。

来自国际上的知名创业孵化服务机构的嘉宾,同样值得关注。

Uzy,以色列BaseCamp公司创始人、盖夫亚姆产业园联合创始人。Basecamp公司是以色列唯一一家专注人工智能、网络安全、物联网、VR/AR产业领域,系统孵化多个高校学术创新的专业公司,在以色列高科技领域享有盛誉。目前正在运营管理的以色列本古里安大学先进技术园,是以色列最成功的高科技园区之一,并促成了英特尔公司斥资150亿美元收购Mobileye的经典案例,创造了“科技沙漠绿洲”的奇迹,是以色列高科技园区的一张名片。

此外,曾投出寒武纪、云从科技等人工智能独角兽的知名投资人、元禾原点合伙人乐金鑫,复星投资总经理钟实、LKK洛可可创新设计集团副总裁、洛克城市设计中心总经理蔚江等嘉宾,也将在大会进行主题演讲及进行圆桌对话。

亮点三、万创科技城牵手阿里云创新中心,赋能江西创新创业

今年5月,习近平总书记在江西主持了《推动中部地区崛起座谈会》,提出要不断增强中部地区综合实力和竞争力,奋力开创中部地区崛起新局面。

作为中部地区第2个、全国第18个国家级新区,赣江新区的发展权重也随之不断提升,被赋予承载江西高质量发展、助推中部崛起的历史使命。越来越多的互联网企业及产业龙头公司开始聚焦有着丰沃产业、人才、环境资源的赣江新区,江西省“产业高地”雏形正加速形成。

本次峰会是由江西万科与阿里云创新中心,携手多家机构共同举办。产业资源、创投资源、以及创新创业服务资源强强联合,力图打造江西南昌创新创业新高地。

今年8月,万科•万创科技城落子赣江新区,将着力打造三大中心——阿里云创新中心、国际创新中心和金融服务中心,聚焦发展人工智能、云计算、物联网等智慧产业集群,助推江西加大科技创新工作力度,不断提高开发利用技术水平,延伸产业链,提高附加值,实现绿色可持续发展。

据了解,本次峰会上,举行万科·万创科技城项目发布仪式的同时,也将举行科技城首个中心即阿里云创新中心的签约仪式,这标志着江西万科与阿里云在创新创业领域展开的深入合作进入实际性落地阶段。

此外,峰会还通过圆桌论坛、嘉宾智慧碰撞等方式,集众智、汇众力,为南昌乃至江西的创新创业赋能,推动区域产业升级。

了解活动详情,报名请点入:
https://www.huodongxing.com/event/9521342669100

image.png

]]>
以线及面--进入二维数组的世界 | 带你学《Java面向对象编程》之十六-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 上一篇:又见引用--数组元素的奇妙之旅 |带你学《Java面向对象编程》之十五
【本节目标】
通过阅读本节内容,你将拓展思维,以线及面,初步了解到数据的魅力,并学会二维数组的定义与初始化相关方法。

二维数组

在之前所定义的数组里面会发现只有一个“[]”,所以这个时候的数组就好像一行数据一样,可以利用下标进行行数据的访问。

  • 传统的数组就好比一行数据,如果要想找到一个数据只需要确定一个下标即可;

表一 传统数组
image.png

  • 如果说现在需要一个多行多列的结构(表),则就需要通过两个下标才可以描述出一个数据,行下标与列下标共同定义才可以找到,所以这样的数组形式就称为二维数组。

表二 二维数组
image.png

对于二维数组可以使用的定义语法如下:

  • 数组的动态初始化

    • 数据类型 数组名称 [][] = new 数据类型 行个数
  • 数组的静态初始化

    • 数据类型 数组名称 [][] =new 数据类型 [][] { {数据,数据,……},{数据,数据,……},{数据,数据,……},……}

范例:定义二维数组

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] []= new int [] []{{1,2,3,4,5},{1,2,3},{5,6,7,8}} ;
     }
}

表三 表示程序结果
image.png

既然二维数组的每一行都属于一个数组,那么这种情况下就可以通过每一行的数组求出数组长度。

public class ArrayDemo {
   public static void main (String args[ ]) {
      int data [] []= new int [] []{{1,2,3,4,5},{1,2,3},{5,6,7,8}} ;
      for (int x = 0 ; x < data.length ; x ++ ){
         for(int y = 0 ;y <data[x].length ; y ++){
        System.out.println(“data[“+x+”][“+y+”] = ”+ data[x][y]) ;
         }
         System.out.println() ;    //换行
      }
   }
}

image.png
图一 执行结果一

如果这时要求使用foreach来进行输出呢?
范例:使用foreach输出二维数组

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] []= new int [] []{{1,2,3,4,5},{1,2,3},{5,6,7,8}} ;
         for (int temp [] : data) {
            for(int num : temp) {
               Sysem.out.println(num + “、”)
             }
             System.out.println() ;    //换行
         }
    }
}

image.png
图二 执行结果二

通过foreach的输出格式可以清楚地观察到,二维数组就是数组的嵌套使用。随着尅发技术的发展,如果要进行一些应用层的程序开发,那么很少会涉及到二维数组,更不用说更高级的多维数组了。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:熟练运用数组,看这篇就够了 | 带你学《Java面向对象编程》之十七
更多Java面向对象编程文章查看此处

]]>
熟练运用数组,看这篇就够了 | 带你学《Java面向对象编程》之十七-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 上一篇:以线及面--进入二维数组的世界 | 带你学《Java面向对象编程》之十六
【本节目标】
通过阅读本节,你将了解到数组在方法调用中的内存变化,初步了解到程序“设计”的含义,并掌握使用方法完成对数组的操作以满足某些需求的能力。

数组与方法

对于引用数据类型而言,主要的特点是可以与方法进行引用传递,而数组本身也属于引用数据类型,所以自然也可以通过方法实现引用传递操作。
范例:实现一个数组的引用传递

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {1,2,3,4,5} ;
         printArray(data) ;     //传递数组
     }
//要求接收一个int型的数组
     public static void printArray(int temp []) {
         for (int x = 0 ; x < temp.lenght ; x ++) {
            System.out.println(temp[x]) ;
         }
     }
}

image.png
图一 执行结果一

对于此时的引用传递具体的内存关系如下。

image.png
图二 内存分析结果一

既然可以通过方法来接收一个数组,那么也就可以通过方法返回一个数组对象,那么此时只需要在方法的返回值类型上进行控制即可。
范例:定义方法返回数组

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = initArray() ;    //通过方法可以获得数组内容
         printArray(data) ;     //传递数组
     }
     public static int [] initArray () {
     int arr [] = new int [] {1,2,3,4,5} ;
     return arr ;         //返回一个数组
     }
//要求接收一个int型的数组
     public static void printArray(int temp []) {
         for (int x = 0 ; x < temp.lenght ; x ++) {
            System.out.println(temp[x]) ;
         }
     }
}

image.png
图三 执行结果二

接下来针对于此程序进行内存关系分析。

image.png
图四 内存分析结果二

范例:通过方法修改数组内容

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {1,2,3,4,5} 
         changeArray(data) ;    //修改数组内容
         printArray(data) ;     //传递数组
    }
    public static void changeArray(int arr[]) {
        for (int x = 0 ;x < arr.length ; x ++) {
            arr[x] *= 2 ;          //每个元素的内容乘2保存
        }
    }
//要求接收一个int型的数组
    public static void printArray(int temp []) {
        for (int x = 0 ; x < temp.lenght ; x ++) {
            System.out.println(temp[x]) ;
        }
    }
}

image.png
图五 修改数组内容执行结果

本程序的内存关系如下:

image.png
图六 内存分析结果图三

案例

随意定义一个int数组,要求可以计算出这个数组元素的总和、最大值、最小值、平均值。
对于此程序最基本的实现如下:

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {1,2,3,4,5} 
         int sum = 0 ;
         double avg = 0.0 ;
         int max = data[0] ;       //假设第一个是最大值
         int min = data[0] ;       //假设第一个是最小值
         for(int x = 0 ; x < data.length ; x ++){
            if(data[x] > max) {        //max地位改变
                max = data[x] ;
            }
            if(data[x] < min) {
                min = data[x] ;
            }
         sum += data[x] ;
         } 
         avg = sum / data.length ;
         System.out.println(“数组内容总和:” + sum) ;
         System.out.println(“数组内容平均值:” + avg) ;
         System.out.println(“数组内容最大值:” + max) ;
         System.out.println(“数组内容最小值:” + min) ;
     }
     public static void printArray(int temp []) {
         for (int x = 0 ; x < temp.lenght ; x ++) {
            System.out.println(temp[x]) ;
         }
     }
 }

image.png
图七 求值结果图

主方法所在的类往往被称为主类,那么既然是主类肯定不希望涉及到过于复杂的功能。在进行开发的过程当中,主方法本身就相当于是一个客户端,而对于客户端的代码应该尽量简单一些,所以这个时候最好的做法是将这一系列的计算过程交给单独的程序类去完成。
范例:改善操作设计

class ArrayUtil {          //是一个操作工具的类
   private int sum ;         //保存总和
   private double avg ;      //保存平均值
   private int max ;         //保存最大值
   private int min ;         //保存最小值
   public ArrayUtil(int data[]) {     //进行数组计算
        this.max = data[0] ;       //假设第一个是最大值
        this.min = data[0] ;       //假设第一个是最小值
        for(int x = 0 ; x < data.length ; x ++){
            if(data[x] > max) {        //max地位改变
               this.max = data[x] ;
            }
            if(data[x] < min) {
               this.min = data[x] ;
            }
          this.sum += data[x] ;
        } 
        this.avg = this.sum / data.length ;
    }
    public int getSum() {
       return this.sum ;
    }
    public double getAvg() {
       return this.avg ;
    }
    public int getMax() {
       return this.max ;
    }
    public int getMin() {
       return this.min ;
    }
}
public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {1,2,3,4,5} 
         ArrayUtil util = new ArrayUtil(data) ;   //数据计算
         System.out.println(“数组内容总和:” + util.getSum()) ;
         System.out.println(“数组内容平均值:” + util.getAvg()) ;
         System.out.println(“数组内容最大值:” + util.getMax()) ;
         System.out.println(“数组内容最小值:” + util.getMin()) ;

     }
}

image.png
图八 求值结果图二

此时的主类就好比我们使用的电脑一样,只关心如何操作,而具体的操作过程被类进行包装了。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:数组排序-触摸算法的门槛 | 带你学《Java面向对象编程》之十八
更多Java面向对象编程文章查看此处

]]>
标记您的MongoDB数据库实例-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 云数据库 MongoDB版标签基本概述
  1. 标签基本定义

    • 标签是资源Meta信息,标签是一些充当元数据的词和短语,支持用户自定义和系统预制。每个标签都包含一个键(Key)和一个值(Value)。标签是一种资源的属性描述。
    • 标签与资源是 多对多的关系。
  2. 标签基本限制

    • 最大键(key)长度:128 个 Unicode 字符
    • 最大值(value)长度:128 个 Unicode 字符
    • 同一个资源上的同一个键只能有一个标签。如果您尝试添加现有标签 (相同键),现有标签值会更新为新值。
    • 允许的字符包括 Unicode 字母、空格和数字,以及以下特殊字符为

      • 匹配这些中文标点符号 。?!,、;:“ ” ‘ ’( ) 《 》 〈 〉 【 】 『 』 「 」 ﹃ ﹄ 〔 〕 … — ~ ﹏ ¥
      • 匹配这些英文标点符号 -.!@#$%?/^&*)(+={}[]",'<>~·`?:;|_
    • 每个资源的最大 自定义 标签数:20
    • 键(key)不支持 aliyun、acs: 开头。 不允许包含http://https:// 。不允许为空字符串。
    • 值(value)不允许包含http://https:// 。允许为空字符串。
  3. 标签在MongoDB中的作用

    标签可以识别资源和用户组,允许企业或个人将相同作用的云数据库MongoDB资源归类,便于搜索和资源聚合。
    云数据库MongoDB支持对云数据库实例添加和绑定标签。

标签设计最佳实践

云数据库 MongoDB版标记标签的操作方式

  1. 控制台操作

通过控制台标记资源
操作步骤

  1. API操作

通过API标记资源
调用方式

  1. 多语言SDK操作

通过sdk方式调用标签操作接口,代码示例仿照:
Mongo云数据库SDK概述

通过标签搜索云数据库MongoDB实例的方式(以MongoDB为例)

  1. 控制台操作

控制台检索资源操作步骤

  1. API 操作

API检索资源
调用方式

  1. 多语言SDK操作

通过sdk方式调用标签操作接口,代码示例仿照:
MongoDB云数据库SDK概述

相关文档

标记您的 CDN 资源——域名(domain)
标记您的 OSS 资源
标记您的 RDS 资源
标记您的 SLB 资源
标记您的 ECS 资源
如何检查您的资源是否具有您指定的标签?
基于标签批量管理资源
支持标签产品及其文档
标签的最佳实践
通过OOS基于标签批量启动ECS实例实践
如何使用标签控制对ECS 资源的访问?
使用标签检索资源
创建资源标签分组设置
ECS全局标签实践
ECS控制台云资源分组管理---全局标签

]]>
HBase 2.0.0 META 数据修复工具-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 问题起因

必须先吐槽一下 Cloudera 6.x 和 Hbase 2.0 太坑了!

不久前生产上的一套Hbase集群出现著名的RIT(Regions in Transition)问题。

查看hbase web ui
1

于是通过hbck命令查看一下集群状态,果然好多inconsistency

 ...
 ERROR: Region { meta => XXX,XXX:,1573019231000.ff2aecaf28917792395c341d01e0b8cc., hdfs => hdfs://nameservice1/hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc, deployed => , replicaId => 0 } not deployed on any region server.
 ...
 ERROR: Found inconsistency in table XXX
 ...
 9 inconsistencies detected.
 Status: INCONSISTENT

看到错误提示问题明显了,这个Region在hdfs中有数据文件但没有依赖任何Region Server,原因可能region被原来的Region Server unassigned了,但是还没有被assigned到一个新的Region Server上。

那么尝试用hbase hbck -repairhbase hbck -fixMeta -fixAssignments来修复吧,于是就有了下面的提示,hbase2.0+以后hbck的所有修复功能全都不支持...

-----------------------------------------------------------------------
NOTE: As of HBase version 2.0, the hbck tool is significantly changed.
In general, all Read-Only options are supported and can be be used
safely. Most -fix/ -repair options are NOT supported. Please see usage
below for details on which options are not supported.
-----------------------------------------------------------------------

NOTE: Following options are NOT supported as of HBase version 2.0+.

  UNSUPPORTED Metadata Repair options: (expert features, use with caution!)
   -fix              Try to fix region assignments.  This is for backwards compatiblity
   -fixAssignments   Try to fix region assignments.  Replaces the old -fix
   -fixMeta          Try to fix meta problems.  This assumes HDFS region info is good.
   -fixHdfsHoles     Try to fix region holes in hdfs.
   ...
  UNSUPPORTED Metadata Repair shortcuts
   -repair           Shortcut for -fixAssignments -fixMeta -fixHdfsHoles -fixHdfsOrphans -fixHdfsOverlaps -fixVersionFile -sidelineBigOverlaps -fixReferenceFiles-fixHFileLinks
   -repairHoles      Shortcut for -fixAssignments -fixMeta -fixHdfsHoles

既然hbck不支持,觉得hbase总得有解决方案吧,科学上网后发现hbase2.0+提供了一个叫hbck2工具,不过得自己编译麻烦了点。
克隆下来准备动手编译发现不对,于是仔细看了一下hbck2的介绍,最低支持版本2.0.3和2.1.1
image

image

WTF......这就是个黑洞啊,还有你就不能把支持的版本号字体放大点吗!

修复方案

吐槽过后,还是得想解决办法啊:

  1. 升级Hbase版本

    • 目前这种情况是根本无法升级的,存量数据怎么办,就算数据可以重入,目前使用的hbase是CDH版,Cloudera 6.x版本集成的hbase只有2.0.0和2.1.0版本,还是黑洞。。。此方案行不通。
  2. 暴力删除hbase数据

    • 暴力删除数据,格式化hdfs,删除hbasemeta数据,删除zookeeper记录,这和重新部署一套hbase差不多了,但是前提是数据可以重入或者允许清除,那以后怎么办,总不能一遇到问题就删库吧,生产上面的数据一般都比较敏感根本不能删。。。此方案行不通。
  3. 写个工具修复hbase

    • 看来只能这样了。。。

修复步骤

回到最初的错误提示,思考一下,如果Region下数据文件在hdfs中存在,那是否可以通过.regioninfo文件(hdfs存储hbase region信息的文件)获取Region信息,同时读取'hbase:meta'表中的Region信息,进行对比取差集就是要修复的Region,然后将需要修复的Region信息再写入到'hbase:meta'中。

按照这个思路,先验证一下hdfs
检测一下hbase的block是否完整 hdfs fsck /hbase

Status: HEALTHY
 Number of data-nodes:  12
 Number of racks:               1
 Total dirs:                    4650
 Total symlinks:                0
...
The filesystem under path '/hbase' is HEALTHY

检查一下.regioninfo文件是否完整 hadoop fs -ls /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc

Found 4 items
-rw-r--r--   3 hbase hbase         65 2019-10-26 18:29 /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc/.regioninfo
drwxr-xr-x   - hbase hbase          0 2019-11-26 09:37 /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc/.tmp
drwxr-xr-x   - hbase hbase          0 2019-11-26 13:59 /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc/0
drwxr-xr-x   - hbase hbase          0 2019-10-26 18:29 /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc/recovered.edits

再看一下'hbase:meta'中的存储结构:

列名 说明
info:state Region状态
info:sn Region Server Node,由 server和serverstartcode组成,如slave1,16020,1557998852385
info:serverstartcode Region Server启动Code,实质上就是Region Server启动的时间戳
info:server Region Server 地址和端口,如slave1:16020
info:seqnumDuringOpen 表示Region在线时长的一个二进制串
info:regioninfo Region Info,和.regioninfo内容相同

OK,觉得这个方案可行,接下来就开始动手coding吧

获取'hbase:mata'中的Region信息

    public Set<String> getMetaRegions(Configuration conf, String tableName) throws Exception {

        Connection conn = ConnectionFactory.createConnection(conf);
        Table table = conn.getTable(TableName.valueOf(TABLE));

        PrefixFilter filter = new PrefixFilter(Bytes.toBytes(tableName + ","));

        Scan scan = new Scan();
        scan.setFilter(filter);

        Set<String> metaRegions = new HashSet<>();

        Iterator<Result> iterator = table.getScanner(scan).iterator();
        while (iterator.hasNext()) {
            Result result = iterator.next();
            metaRegions.add(Bytes.toString(result.getRow()));
        }

        conn.close();

        return metaRegions;
    }

读取.regioninfo中的Region信息

    public Map<String, RegionInfo> getHdfsRegions(Configuration conf, String tablePath) throws Exception {

        FileSystem fs = FileSystem.get(conf);
        Path path = new Path(hdfsRootDir + "/data/default/" + tablePath + "/");

        Map<String, RegionInfo> hdfsRegions = new HashMap<>();

        FileStatus[] list = fs.listStatus(path);
        for (FileStatus status : list) {
            if (!status.isDirectory()) {
                continue;
            }

            boolean isRegion = false;
            FileStatus[] regions = fs.listStatus(status.getPath());
            for (FileStatus regionStatus : regions) {
                if (regionStatus.toString().contains(REGION_INFO_FILE)) {
                    isRegion = true;
                    break;
                }
            }

            if (!isRegion) {
                continue;
            }

            RegionInfo hri = HRegionFileSystem.loadRegionInfoFileContent(fs, status.getPath());
            hdfsRegions.put(hri.getRegionNameAsString(), hri);

        }
        return hdfsRegions;
    }

两者进行对比取差集

        Set<String> metaRegions = getMetaRegions(configuration, repairTableName);

        Map<String, RegionInfo> hdfsRegions = getHdfsRegions(configuration, repairTableName);

        Set<String> hdfsRegionNames = hdfsRegions.keySet();

        metaRegions.removeAll(hdfsRegionNames);

构造META信息并写入HBase

        ServerName[] regionServers = admin.getRegionServers().toArray(new ServerName[0]);
        
        int rsLength = regionServers.length;
        int i = 0;
        for (String regionName : hdfsRegionNames) {

            String sn = regionServers[i % rsLength].getServerName();
            String[] snSig = sn.split(",");

            RegionInfo hri = hdfsRegions.get(regionName);
            Put info = MetaTableAccessor.makePutFromRegionInfo(hri, EnvironmentEdgeManager.currentTime());
            info.addColumn(Bytes.toBytes(FAMILY), Bytes.toBytes(SN), Bytes.toBytes(sn));
            info.addColumn(Bytes.toBytes(FAMILY), Bytes.toBytes(SERVER), Bytes.toBytes(snSig[0] + ":" + snSig[1]));
            info.addColumn(Bytes.toBytes(FAMILY), Bytes.toBytes(STATE), Bytes.toBytes("OPEN"));

            table.put(info);
            i++;
        }

重启Region Server 和 Hbase Master,重启之后会自动生成'info:seqnumDuringOpen'以及'info:serverstartcode'

工具开发完成后,找了个环境验证了一下,没出什么问题,接下来就部署到生产上试试了,反正hbase已经这个样子,死马当司马懿吧。

先用了个region不多的表试验,发现可以呀,然后陆续把所有错误的表都修复一遍,重启hbase,接下来就是见证BUG的时刻:

...
0 inconsistencies detected.
Status: OK

hbase修复完成 此处有掌声

修复工具

本着开源精神,工具已上传GitHub : hbase-meta-repair

image

]]>
数组排序-触摸算法的门槛 | 带你学《Java面向对象编程》之十八-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 上一篇:熟练运用数组,看这篇就够了 | 带你学《Java面向对象编程》之十七
【本节目标】
通过阅读本节内容,你将学会通过循环巧妙地实现数组排序问题,并通过控制台输出结果分析代码异常,解决异常,最终完成设计,初步步入算法的领域。

数组操作案例:数组排序

数组排序指的是可以将一个杂乱的数组按照顺序进行码放,但是对于数组排序总是通过一个基础的模型完成的,例如:本次先通过一个升序排序的方式来观察排序的处理。

image.png
图一 排序过程

范例:数组排序分析

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {8,9,0,2,3,5,10,7,6,1} ;
         for (int y = 0 ; y < data.length ; y ++) {
            if (data[y] > data[y + 1]){
                int temp = data[y] ;
                data[y] = data[y + 1] ;
                data[y + 1] = temp ;
            }
          }
          printArray(data) ;
     }
     public static void printArray(int temp []) {
         for (int x = 0 ; x < temp.lenght ; x ++) {
             System.out.print (temp[x] + “、”) ;
         }
     System.out.println() ;
     }
}

image.png
图二 运行结果一

发生数组越界,修改:

for (int y = 0 ; y < data.length-1 ; y ++)

image.png
图三 运行结果二

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {8,9,0,2,3,5,10,7,6,1} ;
         for (int x =0 ; x < data.length ; x ++) {
           for (int y = 0 ; y < data.length-1 ; y ++) {
              if (data[y] > data[y + 1]){
                 int temp = data[y] ;
                 data[y] = data[y + 1] ;
                 data[y + 1] = temp ;
               }
            }
         }
        printArray(data) ;
     }
     public static void printArray(int temp []) {
         for (int x = 0 ; x < temp.lenght ; x ++) {
             System.out.print (temp[x] + “、”) ;
         }
         System.out.println() ;
     }
}

image.png
图四 执行结果三

针对于已经排好序的,不需要再次进行比较,修改

for (int y = 0 ; y < data.length-x-1 ; y ++)

image.png
图五 执行结果四

以上的程序代码都是通过主方法完成的,不符合面向对象的设计结构,最好的做法是将这个排序处理的操作交给一个类进行处理完成。
优化:

class ArrayUtil {
   public static void sort(int data[]) {    //进行数组的排序处理
       for (int x =0 ; x < data.length ; x ++) {
           for (int y = 0 ; y < data.length-x-1 ; y ++) {
              if (data[y] > data[y + 1]){      //交换数据
                 int temp = data[y] ;
                 data[y] = data[y + 1] ;
                 data[y + 1] = temp ;
              }
            }
        }
   }
   public static void printArray(int temp []) {
       for (int x = 0 ; x < temp.lenght ; x ++) {
          System.out.print (temp[x] + “、”) ;
       }
       System.out.println() ;
    }
}
public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {8,9,0,2,3,5,10,7,6,1} ;
         ArrayUtil.sort(data) ;         //排序
         ArrayUtil.printArray(data) ;
     }    
}

image.png
图六 优化后执行结果

在以后进行类设计的时候,如果发现类中没有属性存在的意义,那么定义的方法就没有必要使用普通方法了,因为普通方法需要在有实例化对象产生的情况下才可以调用。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

更多Java面向对象编程文章查看此处

]]>
阿里巴巴NACOS(1)- 概述及简单使用-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 作者:阿里云 MVP郦强

记得2016年公司采用Java微服务架构开发项目,选型用的是Spring Boot + Spring Cloud + Eureka(服务发现框架),Spring Cloud将Eureka(如下图)集成在子项目spring-cloud-netflix中,用于实现SpringCloud的服务发现功能。
1.png

spring Eureka 管理控制台

后来由于Eureka2.X的断更,有接触到新的服务注册和发现框架Consul(如下图),于是一阵折腾,从2018年起公司开发的项目,都采用Consul服务发现框架。
2.png

Consul管理控制台

当今比较热门用于服务注册和发现的开源项目包括zookeeper、etcd、euerka和consul,当然也少不了,我今天要给大家介绍的阿里巴巴的开源项目NACOS,它也是一个服务注册和发现框架,正好公司有新的打车]]> 会升层思考有多吃香?有的人毕业10年才懂! | 开发者必读(116期)-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800

最炫的技术新知、最热门的大咖公开课、最有趣的开发者活动、最实用的工具干货,就在《开发者必读》!

每日集成开发者社区精品内容,你身边的技术资讯管家。


每日头条

毕业10年才懂,会升层思考,工作有多轻松?

从学生开始老师就教导我们什么是问题?如何找出标准答案。然而,经过十几年的学习,大多数人依然没有理解问题的本质。正确定义问题是成功的开始,更是成功架构师的必要条件。今天,阿里资深技术专家张荣华从问题的本质入手,用“升层思维”解决问题,告诉我们创新的核心,给出高效工作的途径。


最强干货

还不知道HBase冷热分离的技术原理?看这一篇就够了!

HBase是当下流行的一款海量数据存储的分布式数据库。往往海量数据存储会涉及到一个成本问题,如何降低成本。常见的方案就是通过冷热分离来治理数据。冷数据可以用更高的压缩比算法(ZSTD),更低副本数算法(Erasure Coding),更便宜存储设备(HDD,高密集型存储机型)。

ALive:淘宝双11直播,技术同学却可以“偷懒”?

2019年双11淘宝直播带来近 200亿 成交,以天猫双11交易总额2684亿计算,直播已经占总成交额的近 7.45%!ALive:助力阿里经济体,开启直播新纪元。

Knative Serverless 之道:如何 0 运维、低成本实现应用托管?

Serverless 无疑是当前最热的云原生话题,那么作为业务的开发人员或者运维人员咱们应该怎么看待这个事情?云原生和 Serverless 到底有什么关系?通过本次分享咱们将逐一揭开这些神秘的面纱。


每天读本书

《Unity游戏开发(原书第3版)》之一:Unity介绍

本书主要介绍Unity2018的使用和游戏开发流程中涉及的各种知识。每一章的结构特别清晰,先综述该章要介绍的内容,然后一步步深入讲解,中间穿插着很多动手做的实践操作,可以让读者加深对某个概念、方法的理解,每章的最后还有一个小测验和一个稍微大一点的实践练习,用于巩固该章的学习内容。


精品公开课

万科·万创科技城项目发布仪式暨阿里云创峰会·南昌站

【万创更新·云聚未来】江西万科与阿里云创新中心携手,将于12月9日举行“万科•万创科技城项目发布仪式暨阿里云创峰会•南昌站”,中国工程院院士、财经大咖、国际国内知名创投和产业大咖,重磅发布、趋势探讨、圆桌论坛,共同探讨云计算、人工智能、物联网发展趋势。

南昌科创年度盛会,不容错过!


每日集成开发者社区精品内容,请持续关注开发者必读

]]>
MVP一周精选 20191206: 直面未来技术风口-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 一周精选头图.jpg

又到了周五分享MVP精彩内容的时刻。针对医疗行业数据的强隐私性,从脱敏数据集着手进行分析是较为理想的手段。朱祺对医院的信息系统流程进行思考,结合公开数据集对于医疗健康数据特征进行分析,探讨了未来医疗健康产业数据架构模式的发展方向。吴仲毓的文章则为我们介绍了人工智能入门的三大门槛及基本要求。郭旭东则为大家介绍了一个实用Kubernetes 资源观测工具,可实时监测业务高峰到来。本周开始连载郦强的系列文章,分享阿里巴巴开源项目NACOS的使用心得。更有一篇关于HBase 2.0.0的有趣吐槽。

阿里云MVP(阿里云最有价值专家),是专注于帮助他人充分了解和使用阿里云的技术实践领袖。在这里,您可以跟随各行各业技术达人快速Get到行业热点和前沿技术的发展现状。点击了解更多

【MVP说】

朱祺:医疗数据典型特征及架构发展方向研究

目前医疗健康产业呈高速发展状态,被预估为下一个风口,互联网对医疗行业赋能正在关键阶段。本文立足于最近阿里云的天池比赛,对于医疗数据的特征进行分析,并提出未来医疗健康产业数据架构的发展方向思路。

吴仲毓:学习人工智能必须攻克三道门槛:数学基础、英语水平与编程技术

基于人工智能的发展优势,很多人都想要在这个领域大展宏图。本文则深入浅出地为大家介绍了人工智能行业对个人的要求标准以及解决方向。

郭旭东:Kubernetes 资源观测利器:KubeWatch

介绍了一个 Kubernetes 资源观测工具,实时监控 Kubernetes 集群中各种资源的新建、更新和删除,并实时通知到各种协作软件/聊天软件,可以实时观测到业务高峰的到来,是一个不错的小工具。

郦强:阿里巴巴NACOS(1)- 概述及简单使用

实用的系列文章,第一篇先向大家介绍了阿里巴巴的开源项目NACOS,并分享一些使用心得。

曾宪宇:HBase 2.0.0 META 数据修复工具

HBase 2.0.0 META 数据修复工具,分享给那些使用了hbase2.0.0 因其他原因无法升级 又被坑的小伙伴们。

【MVP时间】

刘洪峰:阿里云物联网平台属性、事件,服务详解

北京叶帆易通科技有限公司CEO刘洪峰,研发了物联网智能网关、YFIOs和YFHMI等物联网中间件软硬件平台。

本次公开课为刘老师系列直播的第三节,主要从阿里云IoT Studio如何进行设备管理以及阿里云IoT Studio如何进行服务开发、可视化开发和移动应用开发等方面介绍了自己在行业中实践的案例。

即刻关注“阿里云 MVP技术圈”,和MVP共同探索属于每个领域独一无二的道路,我们在阿里云开发者社区等您!

第11期阿里云 MVP 全球招募将在今日落下帷幕,一次顶尖技术人才的汇聚,期待您的加入,点击申请

往期精彩回顾:

MVP一周精选 20191129

MVP一周精选 20191122

MVP一周精选 20191115

MVP一周精选 20191108

MVP一周精选 20191101

MVP一周精选 20191025

您还希望阿里云 MVP分享哪些领域的技术思考?请在下方评论区留言。

]]>
重磅首发 |《Elasticsearch 中国开发者调查报告》探索开发者的现状和未来-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800

点击免费下载
《Elasticsearch开发者调查报告》

2012年,Elasticsearch 首个版本发布,经过7年多的发展,Elastic系列开源项目的热度持续升温,Elastic 技术社区的用户量和开发者群体逐步壮大,也在不断进化。那么,这个群体是谁?他们在怎样使用 Elastic Stack ?他们又将如何进阶成长?

为了洞察这个独特开发者群体的发展、技术应用现状,以及整个行业的发展趋势,Elastic 技术社区、阿里巴巴 Elasticsearch 技术团队和阿里云开发者社区联合首发《Elasticsearch 中国开发者调查报告》。

image.png

本次报告从开发者的职业路径、Elasticsearch 的技术演进、技术社区的发展等三个维度,描绘了开发者群体的轮廓和成长路径。

开发者们的典型画像

90后是 Elasticsearch 技术兴起的中坚力量,6成以上开源贡献者管理着TB或PB级的海量数据。

image.png

技术入门进阶之路

从入门到进阶,资深专家的第一手技术指南。

image.png

Elasticsearch 的实践应用TOP5

信息检索和日志分析占实际应用场景的大壁江山,业务数据分析、数据库加速、运维指标监控三者平分秋色。

image.png

大厂的最佳实践

18位资深专家分享在 Elasticsearch 技术领域的案例干货。

image.png

Elastic 技术社区的建设经验

30多场线下活动,触达5000多人次,技术社区如何培育发展?

image.png

Elasticsearch 因轻量级、稳定、可靠、快速等特性成为越来越多开发者的选择,本报告将为从业者们提供更多关于职业、行业以及技术应用的参照依据,一览开发者的现状和未来。

关于本次调查的详细数据分析、案例经验和行业前瞻,请下载《Elasticsearch 中国开发者调查报告》并详细阅读报告全文。

]]>
阿里巴巴NACOS(2)- 为Spring Cloud提供服务注册发现及配置-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 作者:阿里云 MVP郦强

1、使用Nacos提供服务发现功能

1)首先我们要做的是写一个微服务,公司打车]]> 阿里巴巴NACOS(3)- 部署Nacos的生产集群环境-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 作者:阿里云 MVP郦强

1、集群部署

相比较 Nacos 的单机部署方式(第一篇文章中有介绍),集群部署方式稍显麻烦一些,当然为了用于生产环境,必须确保 Nacos 的高可用性,所以还是有必要使用集群部署。

准备环境跟第一篇文章中说的相同,额外的要求就是 Nacos 需要 3个或3个以上Nacos节点才能构成集群,而且要使用 MySQL 作为数据源,主要用于服务配置的数据持久化。

下图是官方推荐的集群方案,通过域名 + VIP模式的方式来实现,我的理解VIP模式就用 Nginx 就行,用它来负载多个 Nacos 节点 IP,外部客户端直接通过域名访问就可,不仅可读性好,而且更换 IP 方便,最为推荐采用。
郦3-1.png

官方集群方案图

2、添加集群配置文件

nacos的conf目录下有配置文件cluster.conf,请每行配置成ip:port

如果您只有一台机器,可以创建3个或3个以上的Nacos文件夹,改一下端口号,也可以实现2.png

cluster.conf配置

3、配置MySQL数据库

Nacos 推荐生产环境中数据库使用建议至少主备模式,或者采用高可用数据库。

这里为了简化只采用了一个数据库,首先创建一个名为 nacos_config 的数据库,然后找到nacos/conf下的 nacos-mysql.sql 文件执行即可。

3.png

nacos_config数据库

在nacos的conf目录下的application.properties,添加以下配置4.png

application.properties配置

4、启动Nacos集群模式

在没有参数模式,是集群模式

sh startup.sh

输出信息看start.out,如果最后提示: INFO Nacos started successfully in cluster mode.这样就表示集群模式启动成功,然后打开任何一个Nacos控制台都能看到节点列表
列表.png

集群节点列表

可以从上面看到,集群下的 Nacos 节点状态分为LEADER 和 FOLLOWER 两种,跟我们熟悉的主从架构相似。如果您想简单的话,推荐使用阿里云的MSE,3分钟帮您搞定Nacos集群模式
MSE的Nacos集群模式.png

MSE的Nacos集群模式

5、Nginx配置

我是Mac电脑,所以使用brew的方式安装Nginx,然后在Nginx中进行配置
Nginx中的配置.png

Nginx中的配置

注意:server_name 就是 直接改成域名就行。

然后Nginx -s reload 重新加载配置后即可,我把nacos官方Spring Cloud Nacos Example的示例打开,Provider和Consumer两个项目中的application.properties文件的nacos server地址都改成了 Nginx中配置的server_name。

指定nacos的server地址.png

指定nacos的server地址

启动项目,就可以在nacos集群的任何一个节点的服务管理列表中看到里面已经有服务注册成功了
服务列表页.png

服务列表页

然后在浏览器中输入 http://localhost:8080/echo/强哥 ,看到返回 Hello Nacos Discovery 强哥,这样就表示成功了,其实这个Example就是微服务和微服务之间的调用,所有nacos示例代码下载
执行Consumer服务,成功请求到Provider服务.png

执行Consumer服务,成功请求到Provider服务

6、总结

如果是开发环境建议单节点就行了,测试和生产环境用集群模式,而且MySQL数据库也建议使用阿里云的RDS服务,主从架构。下一篇我们将介绍 几个主流微服务框架配置中心产品比较 Spring Cloud Config、阿里云ACM、Nacos等。

首发简书。

]]>
把阿里巴巴的核心系统搬到云上,架构上的挑战与演进是什么?-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 作者丨张瓅玶(谷朴)阿里巴巴研究员

阿里巴巴核心系统作为全球最大规模、峰值性能要求最高的电商交易系统,在 2018 年之前只通过混合云弹性上云方式,为 双11 节约大量成本。直到 2019 年,阿里巴巴实现了核心交易系统全面上云并经历了 双11 峰值的考验。

在今天由极客邦科技举办的 ArchSummit 全球架构师峰会 2019 北京站上,阿里巴巴研究员张瓅玶博士作了主题演讲《阿里巴巴核心系统上云:挑战和架构演进的思考》,以下内容为演讲整理。

核心系统上云之路

工程师时常把我们的系统用飞机来做比喻,乘客则是上面承载的业务。云也是一架这样的载客飞机,作为基础平台承载着千万家企业的业务。今年阿里巴巴实现了核心系统 100% 上云,这个过程实际上走了几年才达到今天的进展,而且这还不是结束,也只是阿里巴巴上云的一个开始。

阿里巴巴集团自身业务体量巨大,支撑其的互联网技术体系任务也非常繁重,再加上核心电商业务系统的复杂度,对技术带来的挑战可想而知。

用王坚博士的话说,核心系统上云让阿里巴巴和客户真正坐上了同一架飞机。从 in-house 的基础设施、定制化的平台能力,到通用的云平台,从 cloud hosting 到 cloud native,这个过程面临着巨大的挑战,同时也是阿里巴巴自身和阿里云的架构演进升级的历程。

1.png

阿里巴巴的核心交易系统涉及到包括天猫、淘宝、河马、菜鸟、聚划算、咸鱼、飞猪等一系列业务,其背后的核心电商系统的架构演进经历了单机房架构、同城双机房架构再到目前的中心同城容灾,三地多单元多活架构。软件也分为应用、微服务/中间件和数据库。

阿里巴巴的上云步骤一共分为三个阶段:

  • 第一阶段:在 2015 年之前未上云,全部采用内部的基础设施。

2.png

  • 第二阶段:2015 开始,双11 期间单元化的交易应用开始通过弹性使用云资源,实现成本节约的目标(注: 图中上云单元规模和实际上云规模不成比例)。

3.png

  • 第三阶段:2018 年的 12 月,CTO 行癫决定阿里巴巴启动全面上云,随后组建了以毕玄为上云总架构师的架构组,确定了上云的方案和步骤。

2019 年经过 1 年的努力,终于在 双11 前实现了核心系统的全面上云。这一年核心电商的中心和单元业务,包括数据库、中间件等组件,实现了全面上云和使用云的服务。通过弹性运化,以及离在线混部(图中未标识)等能力,使大促成本持续下降,到 2018 年,大促新增成本比前一年下降 17%,比早期方案下降 3/4。

这一年核心电商的中心和单元业务,包括数据库、中间件等组件,实现了全面上云和使用云的服务。全面上云也不只是将机器搬到云上,更重要的是 replatforming,集团的技术栈和云产品融合,应用通过神龙服务器+容器和 K8s 上云,数据库接入 PolarDB,中间件采用云中间件和消息产品,负载均衡采用云 SLB 产品等。

4.png

云已经成为了基础设施,无论是电商公司还是其他行业,都可以用云去做更多事情。

云化架构

以全面上云的 2019 年为例,2019 年 双11 的实测,集群的规模超过百万容器,单容器集群节点数量过万,数据库的峰值超过 54 万笔每秒,对应 8700 万查询每秒,而实时计算每秒峰值处理消息超过 25 亿条,消息系统 RocketMQ 峰值处理了超过每秒 1.5 亿条消息。

5.png

这些数据背后所代表的,就是上云过程中形成的巨大挑战。针对这些挑战,阿里巴巴集团从服务器、存储、网络、数据中心等基础设施方面做了针对性的应对。

1. 自研神龙服务器

核心系统全面上云决定采用了神龙服务器。神龙服务器自研了 HyperVisor 虚拟化卡来替代软件虚拟化,从而实现无性能损耗的虚拟化架构。其特点在于:

  • 高性能:去掉了虚拟化带来的 8% 的性能损耗;
  • 支持二次虚拟化:使多样虚拟化技术 (Kata, Firecracker 等) 的探索和创新成为可能。

6.png

在阿里巴巴上云过程中,双11 期间压力测试显示,高负载压力下的电商应用,实现 30% 的 QPS 上升,而 rt 也有明显下降,长尾 rt 下降尤其明显。同时,云化的神龙服务器,促进了运维管理的自动化和在线率水平的提升。阿里巴巴认为,神龙是容器的最佳载体,神龙+服务是无服务器化基础设施的最佳载体。

存储方面,走向了全面云化存储,也即全面存储计算分离。

7.png

上云也带来了大规模使用云存储产品:盘古(盘古 2.0),实现了集团业务的更大规模的存储计算分离。存储计算分离即业务逻辑执行在计算集群上面,存储部署在存储集群上面。计算和存储集群之间通过高速网络连接。

随着数据处理对存储需求和计算需求在规模、速度、容量和成本等维度的不断变化,计算与存储分离可以最大限度地解耦并使这两类不同的关键资源相对独立地扩展和演进,获得更好的弹性、资源效率,同时可以让应用更容易的获得分布式存储的可靠性。

上云过程中,盘古 2.0 的升级也带来更好的 io 长尾延迟的稳定性,通过慢盘黑名单、backup read、动态 timeout 等关键技术大幅度的改进了长尾延迟。

8.png

2. 网络:高速混合云

原有的集团安全域,由现有的集团自建网络为主体逐渐转变为以云上集团的虚拟网络为主体,以 VPC 的方式实现网络隔离混合云网络:为了实现集团网络与云上 VPC 内业务单元的互通,采用了云专线产品方案,组成了混合云网络。云专线方案中的虚拟网络网关(xGW 集群),采用硬件化 HGW 集群。

9.png

3. 数据中心:自建网络迁移上云

数据中心自建网络迁移到 VPC,在上云过程中,实现了云 VPC 最大规模提升 4 倍。安全组性能大幅度优化,企业级安全组最大容量提升 25 倍。

在公司内部,各业务自建的网络之间是相互独立的。随着全站云化,网络安全域的形态也随之发生变化,TB 级别的云上云下网络流量对穿,从软件实现的 XGW 升级到软硬结合的 HGW,单节点性能提升 20 倍。

10.png

另外,值得指出的是,资源、账号和权限体系对接互通是上云的重要环节。

上云架构未来演进:云原生

上云已成为趋势,但是核心系统上云只是下一个开始。

企业上云今天已经成为广泛接受的必然趋势,Rightscale state of the cloud report 2019 显示,94% 企业已经在使用云,其中公有云 91%,on prem 70%。

企业的数字化转型的过程中,利用云的能力的过程也分为不同的阶段,一般来说也会是走过和阿里上云类似的过程:首先是弹性使用云的资源,实现部分业务上云,Cloud-hosting。在此过程中,一般是非核心系统使用云资源。然后涉及到核心系统的云化,这里发生的变化不仅仅是上云的应用的数量,更是底层基础设施整体使用云平台的能力的过程。

在阿里巴巴看来,未来是云原生化的。

11.png

什么是云原生?从技术角度讲,云原生技术是一系列的应用构建和运维最佳实践的集合。云原生技术的生命力在于它聚焦于给用户带来价值,这些价值分为几个方面:

  • 容器和资源的编排,如 K8s、Container,带来的运维效率提升,和资源利用率的提升。中心化的编排可以很好的充分编排资源降低企业成本;
  • 分布式系统的可以弹性扩展的能力 Scalability 以及可靠性。尽管互联网技术发展了几十年,到今天,分布式、可扩展、可靠的系统,仍然是很难构建的。也得益于云原生领域开放技术和云的快速发展,一切正在变得越来越容易;
  • 开放治理和开放的技术,改变了云厂商和用户之间的信赖关系,越来越多的企业信赖开放标准的云服务。同时云原生也降低了迁云的成本;
  • 云原生技术所倡导的持续交付,聚焦于企业真正关注的价值,即迭代创新的速度,time to market。

12.png

从上云视角看,云原生(Cloud native)化是最大化使用云的能力,使企业聚焦于业务的实践。

为什么这么说?我们以阿里核心系统演进为例说明云原生化和使用云的能力的关系。

阿里巴巴的应用上云前仍然存在应用和基础设施耦合问题,由于采用自建软件基础设施,配置管理、发布升级、监控观测、流量治理等与业务应用耦合在一起,对于运维效率、研发演进效率和稳定性都带来了挑战。

我们在上云过程中看到,实现标准的云基础设施和业务应用的全面解耦,将会带来全面的研发运维效率提升。

13.png

那么,使用 in-house 自建基础设施就一定不行吗?

阿里巴巴集团的基础设施也是由专门的团队维护的,也在一定意义上实现了基础设施和应用的解耦。不是所有的 in-house 的基础设施就不云原生。事实上,云原生技术的很多发源地,比如 Google 内部的基础设施很好地实现了和应用的解耦并带来了业界领先的研发运维效率。

但是一般来说,由于内部开发容易忽视基础设施和应用的边界而实现了过多的非标功能或者倾向于采用更快速落地的方案,这些容易带来基础设施和应用的更多耦合,不利于长期的演进和效率。

例如阿里的容器化虽然带来了应用发布的标准化的优势,但是在容器化过程中我们采用了富容器方案加快容器化进程,使容器支持了很多虚拟机使用模式(启停、原地更新等),带来了容器的可迁移性比较差,容器运行生命周期可变带来运维成本等。因此运维效率、稳定性和业务的演进效率,在这种耦合中,都受到了不同程度损失。

所以云原生化的关键路径,是实现应用和基础设施的解耦,并且通过采用标准化的云产品方式来支持。

那么基础设施和业务的边界应该在哪里?

阿里巴巴认为边界是在不断的变化过程中,真正的判断标准是业务关注的边界而非架构边界,基础设施应无须业务持续关注和维护。例如,使用了容器服务,是否能让业务无须关注底层资源?也未必,取决于资源的弹性能力是否有充分的支持(否则业务仍需时刻关注流量和资源压力),也取决于可观测性(否则问题的排查仍需关注底层环境)的能力。因此,能够让业务无须持续关注的基础设施本身是一次重要技术演进。

无服务器化的基础设施,具有以下三个特点:

14.png

阿里核心系统的云原生化演进

阿里巴巴集团的核心系统的云原生架构演进,将继续朝着基础设施解耦,业务研发运维效率提升,成本下降的整体目标推进。具体来说,围绕几个重点的方向工作正在展开:

1. 节点托管的 K8s 服务

实现节点运行环境全托管的标准 K8s 基础设施,实现资源和节点运行环境解耦:通过全托管的节点计算资源,业务无须管理服务器降低运维成本。今年 双11 集团实现了上海单元的 ASI 升级,带来发布扩容效率提升、运行时更稳定容器自愈率提升的效果。未来一年将实现核心系统整体 ASI 化。

15.png

2. Service Mesh 化

实现网络、流量管理配置下沉基础设施,与应用充分解耦。Mesh 化带来的价值:

  • 软件基础设施和业务解耦,各自独立演进;
  • 全链路精准流量控制和资源动态隔离;
  • 提供对应用透明的云安全特性(安全特性解耦)。

16.png

3. 应用和基础设施全面解耦

阿里巴巴集团核心系统通过云原生化,实现应用基础设施全面解耦,将有效解决此前存在的运维、研发效率及可迁移性、稳定性风险,这也是云原生带来的技术赋能。像下图所表示的,应用的关注对象,从繁杂的基础设施耦合组件,到只需要关于业务逻辑本身。

17.png

4. 应用交付的标准化:OAM

今天应用的交付仍然面临挑战:目前云上进行应用管理,需要面对的是差异性的云基础设施能力和多样化的运行环境, 需要分别对接和管理,如 SLB、日志、网络环境、后端依赖等。

今年,阿里云和微软云 Azure 联合发布了一个全新的项目,叫做 Open Application Model OAM:开放应用模型。是业界第一个云原生应用标准定义与架构模型。在这个模型下,应用的开发人员、运维人员和支持 OAM 模型的平台层,就可以通过一个标准的 OAM 应用描述来进行协作。

18.png

通过上云,最大化的使阿里巴巴的业务使用云的技术,通过技术架构的演进使业务更好的聚焦于自身的发展而无须关于通用底层技术,使业务研发效率提升,迭代速度更快是技术人的真正目标。正如阿里巴巴集团上云项目的代号所说的,“云创未来”,通过技术创造新的价值和机会,通过技术创新带来更好的未来。

阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
在线教育场景下的点播试看功能实现-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 业务场景

在线教育场景下,提供视频课程给用户试看一段时间(如前5分钟),用户试看完后如果要继续观看,需要付费购买。

业务流程

|center|500x400

  1. 客户端到应用后台请求试看地址
  2. 应用后台请求阿里云点播服务,获取视频试看地址
  3. 阿里云点播服务返回试看地址
  4. 应用后台返回试看地址给客户端播放
  5. 客户端通过试看地址播放

使用步骤

  • 点播域名开启试看功能
    登陆点播控制台,配置管理-分发加速配置-域名管理-配置(对应域名处)-访问控制-URL鉴权中,开启A方式鉴权,同时,勾选”支持试看”选项。

|center|500x400

  • 试看地址获取
    调用 获取播放地址接口 ,通过参数 PlayConfig 结构中的 PreviewTime 来获取指定时长的播放试看地址。示例代码:
from aliyunsdkvod.request.v20170321 import GetPlayInfoRequest
from aliyunsdkcore import client

access_key_id = "your access_key_id"
access_key_secret = "your access_key_secret"
region = "cn-shanghai"
videoId = "your videoId"

def GetPreviewURL(clt):
    request = GetPlayInfoRequest.GetPlayInfoRequest()
    request.set_VideoId(videoId)
    #设置set_PlayConfig参数指定试看时长为15秒    
    request.set_PlayConfig('{"PreviewTime":"15"}')
    request.set_accept_format('JSON')
    response = clt.do_action(request)
    return response

clt = client.AcsClient(access_key_id, access_key_secret, region)
print GetPreviewURL(clt)

​​|center|500x400

注意事项

试看的基本原理是,播放的CDN加速地址带有试看的指定时长信息,云端会对该信息进行鉴权,鉴权通过会返回指定的文件内容,否则拒绝访问、返回403。

  1. 点播试看功能基于阿里云CDN加速实现,且必须在视频点播(VOD)控制台配置CDN加速域名。
  2. 此方案必须开启A鉴权,同时,为了防止试看参数被篡改,试看参数也作为auth_key计算的一部分。
  3. 域名必须开启 range回源 和 拖拽播放。具体可在域名管理-配置(对应域名处)-视频相关处开启。
]]>
钉钉文档协同编辑背后的核心技术原理-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 有人说,互联网给人类社会带来最深层次的变革是改变了人与人协作的方式,将信息传播的成本大幅降低。身在互联网行业之中,研究信息传播的方式方法,是我们的日常功课。
信息传播的方式,按照时序效果,可分为同步和异步两类。

信息的同步传播

信息被生产的同时被消费。

image.png

话出我之口,入你之耳,过了此时此刻,想还原此情此景,麻烦得很,大多时候也不需要。同步场景下,信息的生产往往不需要深思熟虑,而是通过你来我往的讨论,澄清,逐步勾勒出话题的全貌。表达的时效性较之方式的丰富性更为重要。典型的场景如即时通讯,语音通话,视频会议等。简单明了,没有太多的格式。

信息的异步传播

信息的生产和消费异步发生。
典型的场景如论坛,博客,文档库,邮件。我在写这篇文档的时候,你们看不到。你们看的时候,我早已写完。异步场景下,信息的生产者会谨慎的推敲措辞,以确保自己的意思被准确的传达。表达方式的丰富性很重要,除了文本以外,段落结构,列表,示意图,表格都有利于信息的准确表达。

image.png

文档的信息表达方式

传统文档的信息表达方式是典型的异步传播。上述的几类异步场景都可见文档的影子。
然而2016年3月,Google上线的Google Docs颠覆了这个结论,这个改变世界的功能就是“多人实时编辑”,或者称作“协同编辑”。引入了协同编辑的在线文档,就像一块儿在线的白板,使得身处世界两端的人可以在上面共同迭代一个内容,通过你来我往的信息反馈,实现信息的同步传播。而编辑的结果又将沉淀下来,成为信息异步传播的载体。

image.png

兼具信息同步与异步传播的能力,协同文档的诞生,无疑给基于互联网的沟通协作带来了一场革命。
这场革命爆发于2006年,而它的起源,早在17年前。

image.png

1989年,代表着“文档”的Microsoft Office第一次在Macintosh系统上与世人见面,而代表着“协同”的操作变换算法也第一次见诸论文。
Microsoft Office 中所周知,而操作变换算法又是什么呢?

数据一致性问题与操作变换算法

对协同编辑最简单的理解类似于群聊天,每个人在自己的电脑上修改文档,把操作群发给其他打开这篇文档的用户。当收到来自其他用户的操作时,重放这个操作。比如下面这个例子:

image.png

但美好的设想,难免遭遇现实的挑战。因为网络存在延迟,来自不同用户的操作有可能在各端有不同的执行顺序。相同的操作,不同的执行顺序,会产生不同的结果。比如:

image.png

数据一致性是协同编辑的最低要求。当然,我们可以强制操作按照到达服务器的时间来排序,但这种排序会破坏用户编辑当时的上下文,产生不符合用户预期的编辑效果。
操作变换算法就在这里被引入了。

操作变换算法不是一个算法,而是对一类算法的统称。它们针对不同的文档数据模型,解决一个相同的问题:
基于同一个状态的两个操作,如何调整一个操作的参数,使得它可以在另一个操作之后执行,表达同样的用户意图。
上面的例子加上了操作变换,就可以解决数据一致性的问题,如下图所示:

image.png

当然,协同文档和操作变换算法的水还是很深的。本文只是对基本原理做个简单的介绍。想要了解更多,可以参考以下文献:

Operational Transformation Frequently Asked Questions and Answers
南洋理工大学教授Chengzheng Sun的Survey,覆盖了OT领域绝大多数研究成果

Google Wave Operational Transformation
G-Suite协同引擎的协议白皮书

Achieving convergence,causality-preservation, and intention-preservation in real-time cooperative editing systems
GOT算法及一维数据操作变换算法论文

Context-based Operational Transformation in Distributed Collaborative Editing Systems
COT算法论文

结语

2006年3月,Google Docs上线,多人实时协同编辑的功能惊艳世界,让稳坐办公套件头把交椅的 Microsoft Office 也感到虎躯一震。Office奋起直追,但同等功能的 Office 365 上线已是五年之后。协同编辑究竟是怎样的一座坚城,让兵强马壮的微软止步了五年之久?做一款协同编辑器需要哪些核心技术?协同编辑技术对于普通的前端应用开发会有怎样的启发? 在 D2 ,与大家分享更多技术原理与实践。

image.png

]]>
DataV数据可视化-基础版下线公告!-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 温馨提醒:

亲爱的会员,DataV基础版将在12月12号0点后停止新购。
如果您现在使用基础版,请务必在服务到期前续费;如您没有按时续费,将导致后期无法购买和使用基础版。
如果您需要基础版但是现在没有购买,请务必在12月12号0点之前进行新购,否则后期无法购买。
给您造成不便,请您谅解!


DataV还有多个版本供您选择:

DataV企业版(原价6千/年-双12专享7折)
具有较多的数据展示组件,能够极大的丰富数据呈现的多样性,并且支持更多种类的数据来源,适合对数据呈现方式有较高要求、对数据安全性有要求的用户,特别适用于企业级业务分析、数据监控看板等场景。案例如下:

全球贸易案例-企业版.gif

DataV专业版(原价3W/年-双12专享7折)
增加了可交互的特性,可以不受任何限制的开发自定义组件,具有极高的自由度,能够完成复杂的数据可视化应用搭建,对地图数据具有更强的呈现能力,小部分功能需要用户具有一定的专业技术能力,适合对展示效果有较高要求、数据敏感度高、需要快速、自由搭建可交互的可视化数据看板的专业用户使用,特别适用于企业形象展示、对高层领导做业务汇报、企业级项目交付等场景。案例如下:

学区房案例-专业版.gif

购买链接:https://common-buy.aliyun.com/?spm=5176.2020520107.105.2.tqlPtv&commodityCode=datav#/buy

]]>
标记您的redis数据库实例-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 redis标签基本概述
  1. 标签基本定义

    • 标签是资源Meta信息,标签是一些充当元数据的词和短语,支持用户自定义和系统预制。每个标签都包含一个键(Key)和一个值(Value)。标签是一种资源的属性描述。
    • 标签与资源是 多对多的关系。
  2. 标签基本限制

    • 最大键(key)长度:128 个 Unicode 字符
    • 最大值(value)长度:128 个 Unicode 字符
    • 同一个资源上的同一个键只能有一个标签。如果您尝试添加现有标签 (相同键),现有标签值会更新为新值。
    • 允许的字符包括 Unicode 字母、空格和数字,以及以下特殊字符为

      • 匹配这些中文标点符号 。?!,、;:“ ” ‘ ’( ) 《 》 〈 〉 【 】 『 』 「 」 ﹃ ﹄ 〔 〕 … — ~ ﹏ ¥
      • 匹配这些英文标点符号 -.!@#$%?/^&*)(+={}[]",'<>~·`?:;|_
    • 每个资源的最大 自定义 标签数:20
    • 键(key)不支持 aliyun、acs: 开头。 不允许包含http://https:// 。不允许为空字符串。
    • 值(value)不允许包含http://https:// 。允许为空字符串。
  3. 标签在redis中的作用

    标签可以识别资源和用户组,允许企业或个人将相同作用的云数据库redis资源归类,便于搜索和资源聚合。
    云数据库redis支持对云数据库实例添加和绑定标签。

标签设计最佳实践

redis 标记标签的操作方式

  1. 控制台操作

通过控制台标记资源
操作步骤

  1. API操作

通过API标记资源
调用方式

  1. 多语言SDK操作

通过sdk方式调用标签操作接口,代码示例仿照:
redis 云数据库SDK概述

通过标签搜索redis实例的方式(以redis为例)

  1. 控制台操作

控制台检索资源
操作步骤

  1. API 操作

API检索资源
调用方式

  1. 多语言SDK操作

通过sdk方式调用标签操作接口,代码示例仿照:
redis 云数据库SDK概述

相关文档

如何检查您的资源是否具有您指定的标签?
基于标签批量管理资源
支持标签产品及其文档
标签的最佳实践
通过OOS基于标签批量启动ECS实例实践
如何使用标签控制对ECS 资源的访问?
使用标签检索资源
创建资源标签分组设置
ECS全局标签实践
ECS控制台云资源分组管理---全局标签
标记您的MongoDB数据库实例
标记您的 CDN 资源——域名(domain)
标记您的 OSS 资源
标记您的 RDS 资源
标记您的 SLB 资源
标记您的 ECS 资源

]]>
ECS支持跨地域跨资源类型的标签操作-阿里云开发者社区 Mon, 16 Dec 2019 05:35:02 +0800 问题

ECS(弹性云服务器)如何解决跨地域跨资源类型的分组管理,为后续分账、运维、分权等做准备。

标签编辑器使用说明

  1. 点击 ECS控制台 - 点击标签 - 点击标签编辑器
    image.png
  2. 选择你需要关心的地域及资源类型
    【可选】选择您需要过滤的标签

image.png

  1. 筛选后结果
    image.png

导出数据
image.png

点击image.png可以修改标签编辑器的显示列,以资源共同的标签键作为列,点击后面的滑动开关。

image.png
就可以显示在控制台的列表页。
image.png

点击image.png可以编辑你选择的资源

image.png

新增标签应用于所选择的资源,点击提交更新

image.png

相关文档

如何检查您的资源是否具有您指定的标签?
基于标签批量管理资源
支持标签产品及其文档
标签的最佳实践
通过OOS基于标签批量启动ECS实例实践
如何使用标签控制对ECS 资源的访问?
使用标签检索资源
创建资源标签分组设置
ECS全局标签实践
ECS控制台云资源分组管理---全局标签
标记您的MongoDB数据库实例
标记您的 CDN 资源——域名(domain)
标记您的 OSS 资源
标记您的 RDS 资源
标记您的 SLB 资源
标记您的 ECS 资源
标记您的redis数据库实例

]]>
Flink Forward Asia 2019 | 总结和展望(附PPT) Mon, 16 Dec 2019 05:35:02 +0800 作者 | 梅源(Yuan Mei)

1.jpg

11 月 28 - 30 日,北京迎来了入冬以来的第一场雪,2019 Flink Forward Asia(FFA)也在初雪的召唤下顺利拉开帷幕。尽管天气寒冷,FFA 实际到会人次超过 2000,同比去年增加近 100%。

Flink Forward 是由 Apache 官方授权举办的会议,每年在欧洲、北美洲、亚洲各举办一场。通过参会不仅可以了解到 Flink 社区的最新动态和发展计划,还可以了解到业界围绕 Flink 生态的生产实践经验,是 Flink 开发者和使用者的盛会。去年 12 月 Flink Forward 首次在中国举办,是规模最大、参与人数最多的 Flink Forward 大会。今年 Flink Forward China 正式升级为 Flink Forward Asia,吸引到更多的关注,并于 11 月 28 日在北京开幕。

除了参会人数的迅速增加,多元化也是今年 FFA 的一大闪光点。笔者根据大会纲要数了一下,大约有超过 25 家来自北美,欧洲和亚洲的公司,高校以及科研机构参与分享了超过 45 个议题。国内外一线大牌互联网公司齐聚一堂,其乐融融。这也说明越来越多的业界公司更加看好 Flink,并且深度参与 Flink 的规划与发展,这无论是对 Flink 的未来还是 Flink 社区的发展都有非常积极的意义。

经过几年的发展,Flink 已经成为 Apache 最活跃的社区和在 Github 上访问量前三的项目。Github 的星数(代表项目受欢迎程度)在 2019 一年之内翻了一番。Apache Flink 在中国本土也更加的普及,下图列出了一些使用 Flink 作为实时计算解决方案的中国公司 logo。

2.jpg

笔者总体的参会感受:引擎一体化和生态多元化是 Flink 一以贯之的发展策略。引擎一体化指的是离线(batch),实时(streaming)在线(application)应用在执行层面的一体化。生态多元化指的是对 AI 生态环境的搭建和对更多生态的支持,包括 Hive,Python,Kubernetes 等。

接下来,笔者将根据自己参加的议题聊一聊参会的体验和一些自己的思考,希望能对感兴趣的同学有所助益。

主会场议题

在主议题之前有两个环节值得提一提。一是作为主场的阿里云智能请出阿里集团 CTO 兼阿里云智能总裁张建锋作为开场嘉宾进一步强化阿里集团以数据智能为驱动,All in Cloud 的决心以及开源的 Flink 在此过程中起到的关键性作用。下图很好地提炼了他的演讲。

3.jpg

二是由阿里云天池平台和 Intel 联合举办的 Apache Flink 极客挑战赛颁奖仪式。本次比赛吸引了全球超过 4000 名参赛者,经过四个月的四轮角逐最终产生共 10 个优胜队伍。值得一提的是获奖选手中有两位女将,未来也期待能有更多的妹子参与进来,放一张照片瞻仰一下。

4.jpg

下面言归正传,聊一聊几个主议题。

Stateful Function

照例,第一个主议题由 Flink 一哥 Stephan Ewen 执棒。作为对 Flink Forward 柏林站的延续,Stephan 继续推广他对 Flink 作为应用服务场景(Applications and Services)通用引擎的展望和规划。简而言之,他认为 Flink 除了能够做到批流一体,Flink 框架对于事件驱动的在线应用也可以有效甚至更好的支持,如下图所示:

5.jpg

我的理解是他所指的应用服务场景(Applications and Services)和传统意义上的 OLTP 类似。云上对此类问题的主流解决方案是现在很火的 FaaS (Function as a Service),但通常会有以下四方面痛点:

Bottlenecked by state access & I/O
State Consistency Problem
Scalability of Database (storing the states)
Connections and Request rates

6.jpg

特别是在应用逻辑非常复杂的情况下,应用逻辑之间的组合调用会更加复杂,并且加剧上面四个痛点的复杂度。

同时你会发现上面的这些问题都和 State 的存储(storage),读写(access)以及一致性(consistency)相关,而 Flink 的 Stream Processing 框架可以很好的解决这些和状态相关的问题。所以 Stateful Function 在 Flink 现有的框架上拓展了对 Function Composition 和 Virtual Instance(轻量级的 Function 资源管理)的支持,以达到对应用服务场景(Application)的通用支持。

目前所有 Stateful Function 代码均已开源,在获得社区认可后也会 merge 回 Apache Flink,有兴趣的同学可以去官网自己实践一下:https://statefun.io/ 。在分议题 Apache Flink 核心技术中也有一场专门讲 Stateful Function 的实现,使用和 demo,小伙伴们也可以去感受一下,题目叫“Stateful Functions: Unlocking the next wave of applications with Stream Processing”。

看到这里可能还是会觉得不太直观,我结合自己的理解再多说两句,我们可以从两个维度理解 Stateful Function:

  • Stateful Function 到底要解决什么问题
  • 为什么 Stateful Function 比现有的解决方案更好

7.jpg

设想如图所示的场景,我们使用 Lyft 打共享车。在乘客发起打车请求以后,Lyft 首先会根据乘客的定位,空闲司机的状态,目的地,交通状况和个人喜好给乘客推荐不同类型车辆的定价。在乘客选择定价以后,Lyft 会根据乘客的喜好(比如有些司机被乘客拉了黑名单),司机的喜好(乘客也有可能被司机拉了黑名单),司机和乘客的相对位置以及交通状况进行匹配,匹配完成后订单开始。在这个例子中,我们会发现:

  • 有很多 Function Composition:乘客的喜好的计算,司机的喜好计算,司机和乘客相对位置计算,交通状况计算,以及最终匹配计算。
  • 状态的一致性的重要:在匹配的过程中如果发生错误,在保持状态一致性的情况下回滚非常重要。我们不希望一个乘客匹配给两个司机,也不希望一个司机匹配给两个乘客,更不希望乘客或者司机因为一致性问题无法得到匹配。

Stateful Function 在 Flink 开源 Runtime 的基础上很好的解决了 Function Composition 和 State Consistency 的问题。

下面讨论一下第二个维度:为什么 Stateful Function 比现有的解决方案更好。我的理解是 Stateful Function 提供了更清晰的 abstraction。Stateful Function 把消息传输、状态管理从 Function 中隔离出来,使得用户只需要关注 Function 计算逻辑本身,而不需要关注 Function 的调度,组合等问题,这也使得 Stateful Function 框架能有更多的自由度为 Function 调度组合等问题做优化。当然这只是我个人的理解,抛砖引玉。

Flink Heading Towards a Unified Engine

第二场由阿里巴巴实时计算负责人王峰(阿里花名:莫问)接棒,主要总结了 2019 年 Apache Flink 在一体化引擎发展方面的成果和未来的方向。他认为未来 Flink 的发展趋势是一体化:包括离线(batch),实时(streaming)在线(application)一体化。在此基础上,也需要把拥抱 AI云原生纳入到一体化中。后面的内容就是围绕这三方面来展开的。

对于批流融合,通过 1.9 和 1.10 两个版本的发布,Flink 在 SQL 和 Table API 的层面以及 Flink runtime 层面对批流模式已经做到统一。对于 Flink SQL,在 1.10 这个版本里面,已经可以实现完整的 DDL 功能,兼容 Hive 生态系统并且支持 Python UDF。

总体得到的讯息是:

Flink SQL 在批模式下经过多方验证已经达到生产可用的状态。
Flink SQL 可以在 Hive 生态上直接运行,没有迁移成本。
Flink SQL 可以做到批流在 SQL 优化,算子层以及分布式运行层的一体化。

另外这部分印象比较深刻的一点是:跑 TPC-DS benchmark,Flink 1.10 比 Hive-3.0 快 7 倍:

8.png

在 AI 部分,2019 Flink 重点主要在优化和铺垫 AI 的基础设施部分:

  • Flink 1.9 发布一套标准化的 Machine Learning Pipeline API (这个 pipeline 的概念最早在 Scikit-learn 中提出,在其他生态中也有广泛的采纳)。AI 的开发人员可以使用这套 API(Transformer,Estimator,Model)来实现机器学习算法。
  • 更好的支持 Python 生态。Flink 1.10 在 Table API 中可以支持 Python UDF,复用了 Beam 的 Python 框架来进行 Java 和 Python 进程之间的通讯。
  • Alink 开源发布。
    Alink 是基于 Flink 的机器学习算法库,最大的亮点是对流式和在线学习的支持。这是开源地址 https://github.com/alibaba/alink ,感兴趣的同学可以研究一下。

9.png

在 AI 部分还有一个很值得期待的项目是 Flink AI 明年的一个重点投入方向:AI Flow。AI Flow 为 AI 链路定制了一套完整的解决方案:包括从 data acquisition,preprocessing,到 model training & validation & serving 以及 inference 的一整套链路。这个方案是针对解决现在 AI 链路里面数据预处理复杂,离线训练和在线预测脱钩等问题定制的,让我们拭目以待。

此外还有一个重要的方向是 Flink 对云原生生态的支持,具体来说就是与 Kubernetes 生态的深度融合。Kubernetes 环境可以在 multi-user 的场景下提供更好的隔离,对 Flink 在生产的稳定性方面会有所提升。Kubernetes 广泛应用在各种在线业务上,Flink 与 Kubernetes 的深度融合可以在更大范围内统一管理运维资源。Kubernetes 生态本身发展很快,可以给 Flink 在生产中提供更好的运维能力。后面 Lyft 和其他企业在分享中也提到希望 Flink 对 Kubernetes 可以原生地支持,也有以上这些方面的考虑。Flink 在 1.10 版本发布后可以原生地运行在 Kubernetes 之上。

10.png

阿里巴巴通过 1.9 和 1.10 两个版本历经 1 年左右将 Blink 中比较通用的部分悉数回馈给 Apache Flink 社区,回馈总代码数超过一百万行。阿里内部的 Blink 内核也逐步会由 Flink 内核替换,并且推出基于 Flink 内核的企业版 Ververica Platform,明年 1 月会正式商用。

另外这部分演讲中的两个 demo 让我眼前一亮。一个是基于 Flink + Hive + Zeppelin 的 Flink SQL demo,看完以后可以深刻感受到“可以在 Hive 生态上直接运行,没有迁移成本“,以及“一套 SQL,批流一体运行”的真正含义。还有一个是 Alink ML 基于 Jupyter 的 demo,看完以后我发现现在机器学习模型训练和使用可以如此简单,感兴趣的同学可以找来看看。

Storage Reimagined for a Streaming World

第三个议题是由戴尔科技集团带来的流式存储议题: Pravega。

他们的主要观点是随着流式计算在大企业用户中越来越广泛的应用,流式计算对存储也产生了新的需求:流式存储。需求来自两个方面:一是大型企业用户希望计算框架流程化繁为简,从而提出对流式计算存储一体化的需求;二是批流的计算一体化本身也对存储提出批流一体化需求。

11.jpg

在后面的分会场议题开源大数据生态中,Pravega 还有一场更偏技术的分享,包括整体的设计架构,如何保证 exactly once 语义,Stream Segment 如何更方便的提供 scaling up/down 等等,感兴趣的同学也可以看看,题目叫“Delivering stream data reliably with Pravega”。

这个议题本身也很有趣。不可避免的,我们会想到流式存储和通常意义上的消息队列系统(例如 Kafka)之间有什么区别,毕竟 infinite retention 的消息队列系统也可以被看成是一个 stream storage。另一个比较有趣的问题是一体化的抽象应该在哪个层面上来做,以及如何做。换言之,读写是否应该和存储分离,只提供统一的API?因为笔者对 storage 这块儿细节不是特别了解,这里就不班门弄斧了,感兴趣的小伙伴我们可以私下讨论。分议题中还有一场关于 Pulsar 的,也相关,题目叫“基于 Pulsar 和 Flink 进行批流一体的弹性数据处理”。

基于 Apache Flink 的大规模准实时数据分析平台

主议题的最后一场是 Flink 实践,是由 Lyft 带来的大规模准实时数据分析平台的分享。这里所说的准实时,指端到端数据延迟不超过 5 分钟,在 Lyft 内部主要用于数据交互式查询,下图是 Lyft 准实时平台架构图。

12.jpg

Flink 在整个架构中是用来做流数据注入的,Flink 向 AWS S3 以 Parquet 的格式持久化数据,并以这些原始数据为基础,进行多级 non-blocking 的 ETL 加工(压缩去重),建立实时数仓,用于交互式数据查询。

在这个分享中印象深刻的几点:

  • Flink 的高效性。据 Lyft 的大佬们讲,这个新的平台相较于先前基于 Kinesis Client 的 ingestion 相比较,仅数据注入部分的集群就缩减了 10%,所以他们对 Flink 的高效性是非常认可的。
  • Lyft 也提到,他们花了蛮多精力基于 Flink 的 StreamingFileSink 来解决 Flink 和 ETL 之间 watermark 的同步问题。其实我很希望他们能分享一下为何压缩去重(ETL)部分不也用 Flink 来做。如果是技术上的问题可以帮助 Flink 更好的完善自己。
  • Lyft 提到 Flink 的重启和部署会对 SLO 造成延迟影响,subtask 停滞会造成整个 pipeline 的停滞以及期望 Flink 能够有一套在 Kubernetes 环境下运行的方案。其实这里提到的几点也在其他的几场企业实践分享中被提到,这些也是当前 Flink 亟待解决的几大痛点。社区对这几点都有规划,分议题中有一场“Pluggable Shuffle Service and Unaligned Checkpoints”有针对 Flink 重启和停滞的讨论;“Optimize Apache Flink on Kubernetes with YuniKorn Scheduler”讨论了一些和 Kubernetes 应用相关的问题。

除了 Lyft,在分会场中也有很多企业参与分享了自己使用和深度参与 Flink 开发的经验和教训。Flink 不仅在国内公司中深受欢迎,很多北美欧洲的公司比如 Netflix,Uber 和 Yelp 也越来越多的使用和开发 Flink,感兴趣的同学可以关注一下分会场议题中的“企业实践”和“实时数仓”专场。

分会场议题

分会场议题主要围绕着上面四个主议题展开,分为五个专场:

Apache Flink 核心技术:主要针对 Flink 1.9 和 1.10 中比较核心的技术更新。
人工智能:除了主议题已经包括的,Flink+TensorFlow 的实践分享也很有趣。
企业实践:字节跳动、快手、滴滴、网易、爱奇艺、Bilibili、360 等分享的实践经验。
实时数仓:Netflix,美团,小米等分享的基于 Flink 的数仓平台。
开源大数据生态:和 Flink 生态相关的内容,主要包括 Zeppelin,Kubernetes,Hive 等等。

由于篇幅关系,这里就不作展开了,分议题清单和所有PPT资料请点击:https://developer.aliyun.com/article/737925

总结和感想

三天的 FFA,感触颇深。Flink 创始人之一 Ververica CEO Kostas Tzoumas 感慨说,五年前当他们 5 个初创刚刚开始 Flink 这个项目的时候无法想象今天 Flink 能有如此大的生态和如此广的应用。虽然我无法深切体会到他的感受,但是当前 Flink 社区的繁荣和 Flink 的应用广度是有目共睹的,但更重要的问题是:未来我们如何延续这种繁荣。Flink 在经历了高性能流式引擎,批流一体两代发展后,我们确实需要思考一下未来的 Flink 是什么样的。

在这届 FFA 中一直强调一体化和多元化的概念,也就是开篇讲的引擎一体化和生态多元化,具象化来说有三点:Stateful Function,拥抱AI,云原生。再到下一个层面也给 Flink 引擎本身提出更多的要求,这是挑战当然也是机遇。古语云瑞雪兆丰年, FFA 在北京的初雪中圆满落下帷幕,也让我们共同努力,把握好机遇一起迎接挑战,共创美好的 Flink 2020。最后,分享一张一哥 Stephan 在 Flink Forward Asia 的 cool 照作为全篇的收尾,大家一起感受一下。

]]>
更强、更稳、更高效:解读 etcd 技术升级的三驾马车 Mon, 16 Dec 2019 05:35:02 +0800 点击下载《不一样的 双11 技术:阿里巴巴经济体云原生实践》

ban.jpg

本文节选自《不一样的 双11 技术:阿里巴巴经济体云原生实践》一书,点击上方图片即可下载!

作者 | 陈星宇(宇慕)阿里云基础技术中台技术专家

导读:etcd 是阿里巴巴内部容器云平台用于存储关键元信息的组件。阿里巴巴使用 etcd 已经有 3 年的历史, 在今年 双11 过程中它又一次承担了关键角色,接受了 双11 大压力的检验。为了让更多同学了解到 etcd 的最佳实践和阿里巴巴内部的使用经验,本文作者将和大家分享阿里巴巴是如何把 etcd 升级得更强、更稳、更高效的,希望通过这篇文章让更多人了解 etcd, 享受云原生技术带来的红利。

让 etcd 变得更强

本节主要介绍 etcd 在性能方面的升级工作。首先我们来理解一下 etcd 的性能背景。

性能背景

这里先庖丁解牛,将 etcd 分为如下几个部分,如下图所示:
1.png

每一部分都有各自的性能影响,让我们逐层分解:

  1. raft 层:raft 是 etcd 节点之间同步数据的基本机制,它的性能受限于网络 IO、节点之间的 rtt 等, WAL 受到磁盘 IO 写入延迟;
  2. 存储层:负责持久化存储底层 kv, 它的性能受限于磁盘 IO,例如:fdatasync 延迟、内存 treeIndex 索引层锁的 block、boltdb Tx 锁的 block 以及 boltdb 本身的性能;
  3. 其他还有诸如宿主机内核参数、grpc api 层等性能影响因子。

服务端优化

了解完背景后,这里介绍一下性能优化手段,主要由服务端和客户端两个方面组成,这里先介绍服务端优化的一些手段。

硬件部署

etcd 是一款对 cpu、内存、磁盘要求较高的软件。随着内部存储数据量的增加和对并发访问量的增大,我们需要使用不同规格的硬件设备。这里我们推荐 etcd 至少使用 4 核 cpu、8GB 内存、SSD 磁盘、高速低延迟网络、独立宿主机部署等(具体硬件的配置信息)。在阿里巴巴,由于有超大规模的容器集群,因此我们运行 etcd 的硬件也较强。

软件优化

etcd 是一款开源的软件,集合了全世界优秀软件开发者的智慧。最近一年在软件上有很多贡献者更新了很多性能优化,这里分别从几个方面来介绍这些优化,最后介绍一个由阿里巴巴贡献的 etcd 存储优化。

  1. 内存索引层。由于索引层大量使用锁机制同步对性能影响较大,通过优化锁使用,提升了读写性能,具体参考:github pr
  2. lease 规模化使用。lease 是 etcd 支持 key 使用 ttl 过期的机制。在之前的版本中 scalability 较差,当有大量 lease 时性能下降的较为严重,通过优化 lease revoke 和过期失效的算法,解决了 lease 规模性的问题,具体参考:github pr
  3. 后端 boltdb 使用优化。etcd 使用 boltdb 作为底层数据库存储 kv, 它的使用优化对整体性能影响很大。

通过调节不同的 batch size 和 interval, 使我们可以根据不同硬件和工作负载优化性能,具体参考:github pr

除此之外,新的完全并发读特性也优化了 boltdb tx 读写锁性能,大幅度地提升了读写性能,具体参考:github pr

最后介绍一个由阿里巴巴自主研发并贡献开源社区的优化:基于 segregated hashmap 的 etcd 内部存储 freelist 分配回收算法。

下图是一个 etcd 节点的架构,etcd 使用 boltdb 持久化存储所有 kv,它的性能好坏对 etcd 性能起着非常重要的作用。

2.png

在阿里巴巴内部大规模使用 etcd 用于存储元数据,在使用中我们发现了 boltdb 的性能问题。这里给大家分享一下:

3.png

上图是 etcd 内部存储分配回收的核心算法。etcd 内部默认以 4kB 为一个页面大小存储数据。图中的数字表示页面 id, 红色表示该页面正在使用, 白色表示没有。当用户删除数据时 etcd 不会把存储空间还给系统,而是内部先留存起来维护一个页面池,以提升再次使用的性能,这个页面池专业术语叫 freelist。当 etcd 需要存储新数据时,普通 etcd 会线性扫描内部 freelist,时间复杂度 o(n),当数据量超大或是内部碎片严重的情况下,性能会急剧下降。

因此我们重新设计并实现了基于 segregated hashmap 的 etcd 内部存储 freelist 分配回收新算法,该优化算法将内部存储分配算法时间复杂度从 o(n) 降为 o(1), 回收从 o(nlgn) 也降为 o(1), 使 etcd 性能有了质的飞跃,极大地提高了 etcd 存储数据的能力,使得 etcd 存储容量提升 50 倍,从推荐的 2GB 提升到 100GB;读写性能提升 24 倍。CNCF 官方博客收录了此次更新,感兴趣的读者可以读一下。

客户端优化

性能优化除了服务端要做的事情外,还需要客户端的帮助。保持客户端使用最佳实践将保证 etcd 集群稳定高效地运行,这里我们分享 3 个最佳实践:

  1. put 数据时避免大的 value, 大的 value 会严重影响 etcd 性能,例如:需要注意 Kubernetes 下 crd 的使用;
  2. 避免创建频繁变化的 key/value, 例如:Kubernetes 下 node 数据上传更新;
  3. 避免创建大量 lease 对象,尽量选择复用过期时间接近的 lease, 例如 Kubernetes 下 event 数据的管理。

让 etcd 管理更高效

作为基于 raft 协议的分布式键值数据库,etcd 是一个有状态的应用。管理 etcd 集群状态、运维 etcd 节点、冷热备份、故障恢复等过程均有一定复杂性,且需要具备 etcd 内核相关的专业知识,想高效地运维 etcd 有不小的挑战。

目前在业界里已经有一些 etcd 运维的工具,例如开源的 etcd-operator 等,但是这些工具往往比较零散,功能通用性不强,集成度比较差,学习这些工具的使用也需要一定的时间,关键是这些工具不是很稳定,存在稳定性风险等。

面对这些问题,我们根据阿里巴巴内部场景,基于开源 etcd-operator 进行了一系列修改和加强,开发了 etcd 运维管理平台 Alpha。利用它,运维人员可以高效地运维管理 etcd,之前要前后操作多个工具完成的任务,现在只要操作它就可以完成,一个人就可以管理成百上千的 etcd 集群。

下图展示了 Alpha 的基础功能:

4.png

如上图所示,Alpha 分为 etcd 生命周期管理和数据管理两大部分。

其中生命周期管理功能依托于 operator 中声明式的 CustomResource 定义,将 etcd 的集群创建、销毁的过程流程化、透明化,用户不再需要为每个 etcd 成员单独制定繁琐的配置,仅需要指定成员数量、成员版本、性能参数配置等几个简单字段。除此之外,我们还提供了 etcd 版本升级、故障节点替换、集群实例启停等功能,将 etcd 常用的运维操作自动化,同时也在一定程度上保证了 etcd 变更的稳定性。

其次,数据作为 etcd 的核心内容,我们也开发了一系列功能进行重点保障。在备份上,数据管理工具支持定期冷备及实时热备,且保持本地盘和云上 OSS 两类备份,同时也支持从备份上快速恢复出一个新的 etcd 集群。此外,数据管理工具支持对 etcd 进行扫描分析,发现当前集群的热点数据键值数和存储量,弥补了业界无法提供数据管理的空白,同时该拓展也是 etcd 支持多租户的基础。最后,数据管理工具还支持对 etcd 进行垃圾数据清理、跨集群数据腾挪传输等功能。

这些丰富的功能为上层 Kubernetes 集群的管理提供了很多灵活的帮助,例如用户 A 原来在某云厂商或自建 Kubernetes 集群,我们可以通过迁移 etcd 内部的账本数据的功能,将用户的核心数据搬移至另外一个集群,方便地实现用户的 K8s 集群跨云迁移。

利用 Alpha,我们可以做到透明化、自动化、白屏化,减少人肉黑屏操作,让 etcd 运维管理更高效。

让 etcd 变得更稳

本节主要介绍一些 etcd 稳定建设的技巧。大家知道 etcd 是容器云平台的底层依赖核心,它的服务质量、稳定程度决定了整个容器云的稳定程度,其重要性无需赘述。这里先介绍一下 etcd 常见的问题和风险分析,如下图所示,主要分三个方面:

  • etcd 自身:例如 OOM、代码 bug、panic 等;
  • 宿主机环境:例如宿主机故障、网络故障、同一台宿主机其他进程干扰;
  • 客户端:例如客户端 bug、运维误操作、客户端滥用 ddos 等。

5.png

针对这些风险点,我们从以下几方面入手:

  1. 建立完善的监控告警机制,覆盖客户端输入,etcd 自身以及宿主机环境状态;
  2. 客户操作审计,高危操作如删除数据做风控限流;
  3. 数据治理,分析客户端滥用,引导最佳实践;
  4. 定期数据冷备,通过热备实现异地多活,保证数据安全;
  5. 常态化故障演练,做好故障恢复预案。

总结展望:让 etcd 变得更智能

本文分别从性能、稳定性、生态工具三个部分享了 etcd 变得更强、更快、更高效的技巧。在未来我们还将为让 etcd 变得更智能而努力。如何让 etcd 变得更智能是一个比较高级的话题,这里简单做一下展望。更智能的意思是指可以使 etcd 的管理更加地聪明,更少的人为干预,例如遇到一些故障,系统可以自行修复等。

ban.jpg

本书亮点

  • 双11 超大规模 K8s 集群实践中,遇到的问题及解决方法详述
  • 云原生化最佳组合:Kubernetes+容器+神龙,实现核心系统 100% 上云的技术细节
  • 双 11 Service Mesh 超大规模落地解决方案

阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
三维空间重建(临云镜)重磅发布,30分钟体验AI构建的3D空间 Mon, 16 Dec 2019 05:35:02 +0800 2019年12月2日下午,阿里云峰会广东站飞天大数据与AI平台专场落幕,专场上阿里云智能高级产品专家王巍正式发布了三维空间重建(临云镜)产品,基于三维视觉AI技术实现空间展示及场景还原,致力于用人工智能技术实现三维重建能力。

图片 1_meitu_1.jpg

三维空间重建(临云镜),包含全景摄影测量设备及三维空间重构工具,指通过对空间的全景摄影及实景重构,实现空间的三维模型构建。产品可以帮助品牌商与平台以较低的成本完成空间的快速采集,并支持对室内/室外空间的三维全景展示及空间漫游,同时支持VR浏览、设备的接入,从而实现空间数据的采集、管理与营销应用。

e08ea0fa0f1a4f498e1c81410a26f0b6 (1).png


一、应用场景

房产租售:VR看房帮助用户在线查看3D实景房屋,全面体验空间格局,减少无效看房次数,提升租售平台业务效率,降低运营成本。装修样板间等3D全景模型,提升消费者对空间的真实感知,提升房产装修行业转化率。
酒店度假:使用三维重建产品对酒店/度假村等场所进行三维建模,帮助企业的用户实现在线看房订房,预期与实际入住体验一致,提升企业的用户满意度,提高企业在的口碑和品牌形象。
企业实景认证:实力商家认证深度绑定3D全景,提供更丰富的工厂展示形式,提升商家可信度。
电商零售:让用户在线上获得线下实体店的展示体验,促进新零售线上线下的融合。
警用领域:提供轻量级应用全景方案,完成犯罪现场重建,辅助警用领域搭建标准化证据采集体系,降低现场采集难度。

图片 2.png


二、产品核心能力

设备端:
提供阿里巴巴定制化全景设备,设备操作容易,具备一键启动功能,利用自带APP可以进行自动拍摄,一个房间仅需几分钟就能完成拍摄,同时硬件设备支持12K全景相片、4K全景视频,超过同类产品。
图片 3.png

云端:
三维空间重建(临云镜)在云端构建数据处理中台,基于深度学习的墙线/门线预测、门对应关系改造,用户通过简单地标注操作,后台系统基于特征点AI自动提取搭建三维模型,15分钟内,完成100平米建模。同时云端支持自定义全景照片上传,通过用户现有设备,也可进行三维模型搭建。

云端产品体验地址:https://www.aliyun.com/product/tdsr

图片 4.png

展示端:
通过全景展示链接,同时适配PC/无线端/VR端。用户可以深度体验通过三维空间重建(临云镜)构建的3D空间,并且支持自由嵌入音频。视频、商品、地点、链接等信息,实现场景内多样化展示,进行多方联动。
图片 5.png


三、最佳实践
同时,专场现场还邀请了合作伙伴,来自SGS中国消费品及零售检验服务业务拓展高级经理朱乔琪先生为大家展示三维空间重建(临云镜)产品在工厂实景建设方面的,作为产品的深度使用客户,目前SGS已经将原有产品进行更新换代,极大提高了SGS在进行各类全景拍摄认证时的质量与效率。!
图片 6.png

(SGS作为国际公认的检验、鉴定、测试和认证机构,在世界各地共有97,000多名员工,分布在2,600多个分支机构和实验室,构成了全球性的服务网络。)

作为首次重磅发布的产品,除了SGS,三维空间重建(临云镜)产品已经拥有了十几家使用客户,覆盖商家数超过40000家,累计图像处理数量100000张,拍摄服务人数1200人。希望通过与更多合作伙伴合作,为行业带来丰富、高质量的三维空间建设服务。

云端平台公测免费体验地址:https://www.aliyun.com/product/tdsr

产品案例:
工厂:
https://lyj.alibaba.com/preview/9205ca2d62d5454c87390fd1f4b99b1a?spm=0.13685700.1400076.1.49442b8aXK8vEm
酒店:
https://huodong.m.taobao.com/1111zhandui/SceneGoNV.html?spm=0.13685700.1400076.2.49442b8aXK8vEm&model=A.e.nspiIsFHmZfuawBq&srcType=idst_scenego
房产:
https://zao.alibaba.com/scenetour.html?spm=0.13685700.1400076.3.49442b8aXK8vEm&model=A.e.cXaJNQGPWYDTzKil&srcType=idst_scenego
零售:
https://zao.alibaba.com/scenetour.html?spm=0.13685700.1400076.4.49442b8aXK8vEm&model=A.e.TPnLlcSWVwMCdKqU&srcType=idst_scenego
旅游:
https://huodong.m.taobao.com/1111zhandui/SceneGoNV.html?spm=0.13685700.1400076.5.49442b8aXK8vEm&model=A.e.USAsNOrbSYLihdoW&srcType=idst_scenego

钉钉交流群:
image.png

]]>
初识“数据巨轮”:数组 | 带你学《Java面向对象编程》之十四 Mon, 16 Dec 2019 05:35:03 +0800 上一篇:六组案例一举拿下Java实体类 | 带你学《Java面向对象编程》之十三
【本节目标】
通过阅读本节内容,你将接触到Java中常用的一类数据:数组,并初步掌握其多种定义及初始化方法,通过for循环实现对简单数组的各种运用。
所有的项目开发之中都一定会存在有数组的使用,但是本次所讲解的只是数组的基本概念,而基本形式的数组出现的几率会有,但是不高,并且也不会涉及到过多复杂的操作,这只是针对于自己编写的程序代码而言。

数组的基本概念

如果说现在要定义100个整型变量,那么按照传统的做法,现在的实现如下:
int i1,i2,i3……i100;
这种方式的确是可以进行定义,但是如果说着100个变量属于关联的一组变量,则按照此种模式定义出来的变量就不适合于程序维护了(没有任何的参考规律),所以在程序开发之中考虑到一组变量的整体维护,专门提供有数组的概念。数组的本质在于:一组相关变量的集合,但是需要注意的一点是:在Java中将数组定义为引用数据类型,所以数组的使用一定要牵扯到内存分配,那么首先就一定可以想到使用关键字new来处理。数组的定义格式:

  • 数组的动态初始化,初始化之后数组每一个元素的保存内容为其对应数据类型的默认值;

    • 声明并初始化数组:

      • 数据类型 数组名称 [] = new 数据类型 [长度];
      • 数据类型 [] 数组名称= new 数据类型 [长度];
  • 数组的静态初始化:在数组定义的时候就为其设置好了里面的内容;

    • 简化格式:数据类型 数组名称 [] ={数据1,数据2,数据3,…};
    • 完整格式:数据类型 数组名称 [] = new 数据类型 [] {数据1,数据2,数据3,…};

当创建了一个数组之后就可以按照如下的方式进行使用:

  • 数组里面可以通过脚标进行每一个元素的访问,脚标从0开始定义,所以可以使用的脚标范围:“0~数组长度-1”,同时一定要注意,如果使用的时候超过了数组脚标范围则会出现
    “ArrayIndexOutOfBoundsException”(数组越界)异常。
  • 使用数组是为了其可以进行方便的变量管理,所以在进行数组操作的时候往往会利用for循环来完成;
  • 对于数组的长度也可以使用“数组名称.length”属性进行获得。

范例:定义数组

public class ArrayDemo {
   public static void main(String args[]) {
   //使用数组的动态初始化实现了数组的定义
       int data [] = new int [3] ;
       System.out.println(data[0]) ;
       System.out.println(data[1]) ;
       System.out.println(data[2]) ;
   }
}

image.png
图一 执行结果一

修改

System.out.println(data[2]) ;

变为

System.out.println(data[3]) ;

则会出现:数组越界

image.png
图二 执行结果二

利用for循环:

public class ArrayDemo {
    public static void main(String args[]) {
   //使用数组的动态初始化实现了数组的定义
       int data [] = new int [3] ;
       for(int x = 0 ; x < 3 ;x ++){
       System.out.println(data[x]) ;
       }
    }
}

image.png
图三 执行结果三

利用“数组名称.length”属性获得数组长度:

public class ArrayDemo {
    public static void main(String args[]) {
   //使用数组的动态初始化实现了数组的定义
        int data [] = new int [3] ;
        System.out.println(data.length) ;
        for(int x = 0 ; x < 3 ;x ++){
           System.out.println(data[x]) ;
        }
    }
}

image.png
图四 执行结果四

所以:

public class ArrayDemo {
   public static void main(String args[]) {
   //使用数组的动态初始化实现了数组的定义
       int data [] = new int [3] ;
       for(int x = 0 ; x < data.length ;x ++){
           System.out.println(data[x]) ;
       }
    }
}

image.png
图五 执行结果五

赋值:

public class ArrayDemo {
    public static void main(String args[]) {
   //使用数组的动态初始化实现了数组的定义
        int data [] = new int [3] ;
        data [0] = 11 ;    //为数组设置内容
        data [1] = 23 ;    //为数组设置内容
        data [2] = 56 ;    //为数组设置内容
        for(int x = 0 ; x < data.length ;x ++){
           System.out.println(data[x]) ;
        }
    }
}

image.png
图六 执行结果六

在以后进行项目的开发过程之中,见到最多的数组使用形式:进行数组的循环处理。
数组本身分为动态初始化与静态初始化,之前所讲的是动态初始化,动态初始化之后会发现数组之中的每一个元素的内容都是其对应数据类型的默认值,随后可以通过下标为数组进行内容的设置,如果现在不希望这么复杂,而是希望数组定义的时候就已经可以提供内容,则可以采用静态初始化的方式完成。
范例:使用静态初始化定义数组

public class ArrayDemo {
    public static void main(String args[]) {
   //使用数组的静态初始化实现了数组的定义
        int data [] = new int [] {11,23,56} ;
        for(int x = 0 ; x < data.length ;x ++){
            System.out.println(data[x]) ;
        }
    }
}

image.png
图七 执行结果七

对于数组的操作而言,基本上都是拿到数据后循环控制。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

又见引用--数组元素的奇妙之旅 | 带你学《Java面向对象编程》之十五
更多Java面向对象编程文章查看此处

]]>
又见引用--数组元素的奇妙之旅 | 带你学《Java面向对象编程》之十五 Mon, 16 Dec 2019 05:35:03 +0800 上一篇:初识“数据巨轮”:数组 | 带你学《Java面向对象编程》之十四
【本节目标】
通过阅读本节内容,你将了解到调用数组元素时内存层面的变化,对数组初始化有更深的理解,并学会通过foreach快速遍历数组元素。

数组的引用传递

通过数组的基本定义可以发现,在数组使用的过程之中依然需要关键字new进行内存空间的开辟,同理,那么这里面也一定存在有内存的关系匹配。
范例:定义一个简单代码

public class ArrayDemo {
    public static void main(String args[]) {
   //使用数组的静态初始化
        int data [] = new int [3] ;
        data [0] = 10 ;    //为数组设置内容
        data [1] = 20 ;    //为数组设置内容
        data [2] = 30 ;    //为数组设置内容
        for(int x = 0 ; x < data.length ;x ++){
           System.out.println(data[x]) ;
        }
    }
}

以上面的程序为例下面要进行一次内存的简单分析。

image.png
图一 数组内存分析结果一

但是数组本身毕竟是属于引用数据类型,那么既然是引用数据类型,就一定会发生引用传递。引用传递应该还是按照传统的方式那样:一个堆内存可以被多个栈内存所指向。
范例:观察数组引用

public class ArrayDemo {
    public static void main(String args[]) {
        int data [] = new int [] {10,20,30} ;   //静态初始化
        int temp [] = data ;             //引用传递
        temp [0] = 99 ;
        for(int x = 0 ; x < data.length ;x ++){
           System.out.println(data[x]) ;
        }
    }
}

image.png
图二 执行结果一

下面通过此程序进行内存的分析。

image.png
图三 内存分析结果二

由于数组属于引用类型,所以一定要为其开辟堆内存空间后才可以使用,如果现在使用了未开辟堆内存空间的数组,会出现“NullPointerException”异常。

public class ArrayDemo {
    public static void main(String args[]) {
        int data [] = null ; 
        System.out.println(data[0]) ;
   }
}

image.png
图四 执行结果二

必须提供有实例化对象才可以使用数组的操作形式进行数组的操作。

foreach迭代输出

对于数组而言,一般都会使用for循环进行输出,但是在使用传统for循环输出的时候往往都采用了下标的形式进行数组元素的访问。
范例:传统形式

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [ ] = new int [ ] {1,2,3,4,5} ;
         for(int x = 0 ;x < data.length ; x ++) {
            System.out.println(data[x]) ;
          }
     }
}

image.png
图五 执行结果三

而从JDK1.5之后为了减轻下标对程序的影响(如果下标处理不当则会出现数组越界异常),所以参考.NET中的设计引入了一个增强型的for循环(foreach),利用foreach的语法结构可以自动获取数组中的每一个元素,避免下标访问,语法结构:
for (数据类型 变量 : 数组 | 集合) { }
最大的特点在于可以将数组中的每一个元素的内容取出保存在变量里面,这样就可以直接通过变量获取数据内容,而避免下标的方式来获取了。
范例:使用foreach语法形式输出

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [ ] = new int [ ] {1,2,3,4,5} ;
         for(int temp : data) {  //自动循环,将data数组的每个内容交给temp
            System.out.println(temp) ;
          }
     }
}

image.png
图六 执行结果四

这种语法的好处是可以避免下标的操作。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:以线及面--进入二维数组的世界 | 带你学《Java面向对象编程》之十六
更多Java面向对象编程文章查看此处

]]>
福利来啦!7天速成零基础快速入门Java编程 | 开发者必读(115期) Mon, 16 Dec 2019 05:35:03 +0800

最炫的技术新知、最热门的大咖公开课、最有趣的开发者活动、最实用的工具干货,就在《开发者必读》!

每日集成开发者社区精品内容,你身边的技术资讯管家。


每日头条

7天零基础快速入门Java编程 | 开发者速成班

Java是现在最流行的编程语言之一,并且自身拥有庞大且完善的生态系统。在国内而言,之所以咱们的 Java 使用广泛,更多的主要原因在于有许多的大户都在使用 Java 实现其各自的核心业务。

如果你还是Java小白,那么福利来啦!开发者社区整理了 7篇Java入门教程,一日一课,一周开启你的编程之旅!


最强干货

Flink Forward Asia 2019 | 总结和展望(附PPT)

Flink Forward 是由 Apache 官方授权举办的会议,每年在欧洲、北美洲、亚洲各举办一场。通过参会不仅可以了解到 Flink 社区的最新动态和发展计划,还可以了解到业界围绕 Flink 生态的生产实践经验,是 Flink 开发者和使用者的盛会。去年 12 月 Flink Forward 首次在中国举办,是规模最大、参与人数最多的 Flink Forward 大会。今年 Flink Forward China 正式升级为 Flink Forward Asia,吸引到更多的关注,并于 11 月 28 日在北京开幕。

明年想跳槽?前端人现在就要开始准备了!

12月份来临,想跳槽涨薪的朋友们都已经开始考虑起了年后的“金三银四”!但是明年的“金三银四”可能不如想象般火热。前端在飞速发展,市场却在逐渐冷却。

公司招前端的面试考量点也悄然改变。但是不用慌,我来细细给大家梳理下,好在明年跳槽加薪前做好准备!

5G的7大用途,你知道几个?

5G时代悄悄来临,甚至成为街头巷尾都在讨论的话题。相信你一定有过一些疑问:什么是5G?仅仅只是网速更快吗?5G如何做到毫秒级的延迟?网络切片是什么?5G的标准之争是怎么回事,在争什么?看完本文,相信你对5G能有基本的了解。


每天读本书

电子书开放下载!这应该是最全的一份目标检测算法&模型盘点

从简单的图像分类到3D姿势识别,计算机视觉从来不缺乏有趣的问题和挑战。通过肉眼我们可以检测出一张宠物照中的猫和狗,可以识别出梵高作品《星夜》中的星星和月亮,那如何通过算法赋予机器“看”的智能,就是我们接下来要讲的。


精品公开课

手把手教你用「免费 IDE 插件」一键部署「容器镜像」

阿里云小姐姐软萌音直播,面向开发者,讲解容器镜像、CICD/云原生应用交付链 和免费 IDE插件,如何实现一键部署,工作效率提速 8 倍。

  • 容器镜像服务
  • 弹幕截屏送奖品
    (主持人说出“暗号”,大家在评论区打出“暗号”,主持人针对弹幕进行截屏,出现在截屏中的人即可获得奖品纪念版淘公仔、指尖陀螺。)
  • 使用 Cloud Toolkit 高效制作、部署镜像
  • Cloud Toolkit 一键部署

每日集成开发者社区精品内容,请持续关注开发者必读

]]>
毕业10年才懂,会升层思考,工作有多轻松? Mon, 16 Dec 2019 05:35:03 +0800 作者 | 张荣华

一、问题的本质

我也在很多场合问过一个问题:什么是问题?虽然我们天天挂在嘴边,但是没有人能够给出较为合理的答复。之前我也没有想过这个问题,很多人对问题的理解还不太一样。一部分人认为问题就是方案中的难点,一部分认为问题是现实和目标的差距,这些解读我觉得都还不够精确,我在尝试定义无果之后查询了大量的资料,终于找到了一个比较合理的定义,目前我认为毛主席的解释是比较合理的:“问题就是事物的矛盾。哪里有没有解决的矛盾,哪里就有问题。”

而主管们经常问到:

你要解决的问题是什么?
这里的问题定义是什么?

其实潜台词在问,这里事物间的矛盾是什么(已经发生的矛盾,将来会发生的矛盾,可能潜在会发生的矛盾),这个矛盾如果不早点解决,可能会激化,带来很严重的后果。
其他例子:

中国人日益增加的财富和国产商品的低劣品质就存在矛盾,这个矛盾就是个问题(已经发生的矛盾)。所以我们要提倡中国质造。
如何利用新技术,更快更准地帮助消费者找到其最需要的商品,提升幸福感(将来会发生的矛盾,在矛盾发生之前,我们应该将之解决)。

上面几个问题的定义都是社会级问题,而且都是公司层面在解决的问题,在我们技术同学的手头的工作中应该也存在各种问题,比如说QPS太低,RT太高,不稳定,研发效率低,等等,这些问题的定义稍微常见一点,基本上大家只要解决问题,而不用定义问题。

二、准确定义问题是成功的开始

这么多年来笔者review过很多技术方案,而且也经历混沌混乱的模块设计,大部分糟糕的设计基本上是摸不清楚自己到底要解决什么问题,总是觉得这个问题我要解决,那个问题我也要解决,甚至不是问题的问题我也要解决。然后设计出了一个能解决所有“问题”的方案。但是实际情况是有些问题根本不是问题,有些问题确实是问题但是却又不是核心问题,有些问题是核心问题,但是又不是当下最核心的问题。我相信类似的方案有很多在review的时候被挡下了,但是还有很多应该已经上线了。如何尽可能减少这方面的损失?那就是要开始阶段就要准确的定义问题,这也是这么多思想家推崇问题定义的原因。

著名思想家杜威如是说道:“A problem well-defined is a problem half solved.”

爱因斯坦如是说道:“提出一个问题往往比解决一个问题更重要,因为解决问题也许仅能是一个数学上或实验室上的技能而已。而提出新的问题、新的可能性,从新的角度去看旧的问题,都需要有创造性的想象力,而且标志着科学的真正进步。”

那么准确定义一个问题要考虑哪些维度呢?我粗粗地列了一个表格,只是代表我自己的理解,未必是正确或者全面的,大家批判的阅读:

1.png

这里应该是一个三维的图形,有时间维度,主次要维度,紧急不紧急维度。

对这个主要次要,紧急不紧急是不是眼熟,没错,在很多如何高效工作上都有类似的方法,把要做的事情分成重要紧急,重要不紧急,不重要紧急,不重要不紧急。

其实我不太认同将事情划分成重要或者不重要,紧急或者不紧急,我建议大家将自己手头要解决的问题划分为重要或者不重要,紧急或者不紧急,因为事情只是一种方案或者手段,区分问题本身的重要度和紧急度才是思考的源头(包含问题的升层思考)。

要填满这张表格必须结合对业务的理解,和对产品的理解,尤其是业务理解,如果没有业务理解,很难准确地刻画问题。

可是什么叫问题的重要度呢?我也思考了很久,终于得出了一些较为自洽的解释。

三、问题的严重程度

3.1 问题严重程度的定义

当我们明确地定义问题之后,我们就要设定目标来解决这个问题,但是现状是残酷的,我们目标和现状之间可能存在巨大的落差,这个落差的程度就是问题的严重程度,所以说:问题的严重程度是希望(目标)与现实的落差!

2.jpg

有些书或者文章里这样定义问题:问题 = 目标 - 现状,这个定义是模糊的,因为目标-现状和这张图一样,往往表示的是落差,落差往往让人想起差距,用差距来形容问题是含糊不清的,很难让人一下子就明白问题的本质。

我们拿性能问题举例,我们的目标是RT<1秒的请求占比大于98%,当前的现状是RT<1秒的请求占比为80%,那么这里的差距就是98%-80%=18%,这18%就是问题严重的程度,但是这18%绝对不是问题本身,这18%是问题的严重程度。

3.2 衡量问题严重程度的挑战

要区分问题的严重程度有两个挑战:

现状:对现状有准确的认知,比如该例中某系统RT<1秒的请求占比为80%。
期待(目标):问题解决后的状态有个清晰的表述,比如该例中某系统RT<1秒的请求占比大于98%。

对于数值型的现状,我们要搞清楚这个数值是容易的,只要将你的目标值减去现状的值就可以得到问题的严重程度了。对于难以量化的现状,那要摸清楚问题的严重程度,可能需要一些案例,需要一些数据统计,比如说架构现在不合理是个问题,这个问题严重到什么程度,那可以计算一下最近半年的需求在实现的过程中,花费了多少工时,如果架构合理的情况下哪些工时是可以节省掉的。或者现在的架构上迭代需求故障和bug的情况是怎么样的,评估一下重构之后故障和bug率会降低到多少。

只要现状和目标有一个没清晰,那我们就很难判断出问题的严重程度在哪里。

FBI warning:如果你不能确定问题的严重程度(现在的或者将来的),不要贸然行动去沉迷于方案的设计。

而不定义问题,不评估问题的严重程度,往往是很多工程师的常见思维习惯,大家可以对号入座。

四、问题的分类

3.png

基本上看这三类问题的字面意思就可以知道这三类问题的区别了:

恢复原状型:原本就应该是这样的,但是现在不是,比如说原本轮胎就应该是充满气的,但是现在扎了个钉子,所以我们要让轮胎恢复原状,这就属于恢复原状型问题。
风险防范型:问题可能发生,也可能不会发生,但是一旦发生,带来的危害是巨大的,所以我们不得不费大量的精力来防止这样潜在的问题发生。在安全和可用性方面,很多工作都是属于风险防范型。这里的尴尬之处是做了对数字指标可能没什么提升,但是不做可能会发生特别严重的事故,带来极其负面的影响。
追求理想型:知道未来会发生的矛盾是什么,提前解决未来必然会发生的矛盾。

如果将这三个问题映射到架构上,那么应该是如下的描述:

1)解决架构上未来会遇到的问题:已经明确预知到未来的业务问题,并且可以转换为未来的架构问题,提前做架构准备(功能性&非功能性)。我根据自己的理解又将其划分成两类:

目标是非常明确且可以用数字衡量的:比如性能问题是可以准确定义一个指标来衡量问题当前的具体的量化值的,RT要到降低到多少毫秒,QPS要提高到多少,稳定性要提升到几个9等等,基本上非功能模块都可以用数字来衡量,比如我们系统中出现的数据搬移的功能,都是目标明确,且可以用数字来衡量的。或者比如系统的可扩展性要达到什么程度,是否满足95%以上的需求下不需要进行大量重构。
目标是不明确的:比如将来要走哪个方向,要做什么样的技术准备,很多的类似的场景是很难直接评估出一个度量指标的。可能只有一个愿景和使命,根据这个愿景和使命来分解问题,然后我们才能设定通往这个理想的问题的路径,而探寻到这个理想的过程是相当的复杂,要考虑的因素实在太多,我只能说这个东西我的经验真的不多,我只能尝试用我所学的内容来进行自顶向下的推导,而以目前的功力实在很难保证结果的正确性。

2)解决架构上当前已经发生的问题:架构上的问题已经发生了,要对架构当前的问题进行识别,定义,以及解决(功能性&非功能性)。

3)解决当前架构合理迭代的问题:我们在架构上进行大量迭代,迭代过程中往往容易给架构挖坑埋雷,我们应该尽可能避免这样的情况发生(功能性&非功能性)。

这三大问题正是各线任意一个粒度的架构师需要明察,并时刻提醒团队的三大问题。如果无法定义这三大问题,那么这里可能就是最大的问题。

这里还要阐述一个问题:即使是未来的架构,我们还有分类,一类是你走在最前面,一种是你跟着别人,你跟着别人要怎么跟上去。

这里应该有个决策分支,告诉我们遇到什么场景的时候应该用什么样的思考方法,不过这只是个人总结,每个人脑海里应该都有一套类似的方法,而且这套方法是在不断的突破和修正的。

五、问题定义中的常见问题

1.误把方法/手段当“问题”

接下来,我编了三个小故事,大家从故事中感受一下手段和问题的区别,以及我们如何才能避免把手段当做问题。

案例一:鲧治水着重在堵的方法上,毕生精力都在思考如何更好地堵。

老师:请问这里的问题定义是什么?
小明:这里的问题是如何堵!
老师:其他同学也说说这里的问题定义是什么?
小红:这里的问题是洪水和生命财产的矛盾!堵只是解决这个问题的方法或手段。
老师:如果问题的定义是问题是洪水和生命财产的矛盾,堵只是方法,那么还有什么方法可以解决这个问题?
小王:还可以用疏通的方法来治水。
小白:我们还可以搬走,以避免水患
老师:恩,这也是一个思路

案例二:如果我问我们的客户他们想要什么,他们会告诉我他们需要一匹更快的马。——亨利福特

老师:请问这里的问题定义是什么?
小明:这里的问题是如何让马跑的更快!
老师:还有其他同学能说说这里的问题定义是什么吗?
小红:这里的问题定义是如何更快的到底目的地,马只是一种手段。
老师:是的,如果马只是一种手段,而不是问题的定义,请问还有什么什么手段可以解决我们提到的问题。
小王:根据目的地的距离的不同,我们可以选择坐飞机,坐火车,开汽车。
小明:老师,我不知道自己不知道,我不知道有汽车,火车,飞机,我只知道马,所以我想到的就是如何让马跑的更快。
老师:是的,我们的局限往往是受限于我们的认知,这种情况不可避免,唯一的方法就是不断的学习,提升自己的认知。

案例三:如何做好资金防控?

老师:请问这里的问题定义是什么?
小明:这里的问题是如何做好资金防控,怎么防,怎么控。
老师:还有其他同学能说说这里的问题定义是什么吗?
小红:这里的问题定义是如何避免公司产生资金上损失,防控只是手段。
小白:资损防控解决直接问题是避免公司产生资金和名誉的损失,这个问题背后更深层次的是社会信任的问题。
老师:小白,你的名字虽然叫小白,但是你的思考一点都不小白,显然你在思考问题定义时使用了升层思考的方法,看到了问题背后的问题。
小明:老师,为啥我每次思考的时候,都是在思考解决问题的手段,都没有看到问题定义呢?
老师:那你可以尝试自问自答,比如你可以问自己资损防控是手段吗?自己给个回答,如果回答是yes,那么再问自己:如果资损防控是手段,那么资损防控是解决什么问题的呢?通过这样的自问自答的方式,基本上我们可以较为准确的找到问题的定义
小白:老师,我在想资损防控解决的是社会信任的手段之一,但是解决社会信任问题的手段不止一种啊。
老师:小白,你在思考问题时使用了升层思考,在思考解决方案时使用了升维思考,给你32个赞。
小白:谢谢老师,此时此刻我有点开心啊。
老师:保持心态的平稳,可以看到更多的东西,谦卑的态度没了,那自己的局限也就到了。
小白:谢谢老师提醒,我记住了。

三个故事看完了,总结一下,这三个故事的核心在于:

准确区分手段和我们要解决的问题本身,这种情况非常常见,我review的很多技术方案之所以有问题基本都是问题定义没有搞清楚,所以解决方案的也就不符合需要了。
思考问题背后的问题时使用升层思考,在思考问题包含的子问题时使用升维思考
当升层思考之后,之前的问题可能会变成手段/方法。比如说用堵解决生命财产问题,堵是方法。升层思考之后,生命财产问题背后的问题是民生问题,此时保护生命财产就是解决民生问题的一个手段/方法。

当然当我们无法准确的分辨问题的时候,我们还可以不断缩短描述问题句子,比如提炼主谓宾,如果还不能清晰地描述,那么在这几个词里再找出最最最关键的词,尤其是主语或者宾语中的词汇非常重要,它有可能就是重点,只是我们无情的忽略它了。

把手段或者方案当问题,或者把技术方案中的挑战当做问题是很多同学遇到的问题。

2.误把挑战当"问题"

当我们明确定义出问题之后,我们开始解决方案的升维思考,可以从各个角度来给出解决方案,这些解决方案就是我们前面说的手段/方法。

举例:如果快速到达目的地是目标,而马,汽车,飞机,火车只是手段/方法,那么如何让马跑的更快,如何让汽车跑的更快,如何让飞机飞的更快,如何让火车开的更快就成了挑战。

此时如果你说“让马跑的更快也是个问题啊”,确实,广义上也可以这么理解,但我不建议这样做,原因是这样我容易将问题和手段/方法搅混。

所以这里我尝试给他们一个定义,以明确他们出现的场景:

问题:事物之间在某个时期存在的矛盾,在本文的语境中尤其是指企业的客户和某种事物,趋势之间的矛盾。
挑战:解决矛盾的方案中最困难的几个地方。

接下来我们回到上述的几个案例中,来看看问题和挑战:

回到用堵治水的案例上:

问题定义:洪水和人民生命财产安全的矛盾。
手段/方法:堵水。
挑战:获取息壤,以筑三仞高堤,这是手段/方法的挑战。

回到福特的案例上:

问题定义:如何让人更快的到达目的地。
手段/方法:造汽车来让人们更快的到达目的地。
挑战:设计出更高的扭矩,更高的功率的引擎,更平顺智能的变速箱等等。

这样我们在沟通的时候,就能明确的知道对方到底是在产生客户的问题定义,还是在阐述方案中的难点和挑战。

3.思考问题时缺少时间维度

单个问题在时间轴上的不同时期的严重程度是不一样的,比如说闭关锁国公元后1500年-1700年是看不出太大的问题的,但是,300年后的1800年,闭关锁国的弊端就开始浮现了,当然我们都是事后诸葛亮。

所以任何一个问题的严重程度都有一个时间轴,也许过了某个时间点之后,问题便不再是个问题。比如外卖兴起之后,如何更好的制作一包方便面以满足用户的口味需求就不是一个问题了。

时间维度是一个及其重要的维度,任何事情理论上都必须考虑在时间维度上的影响,所以即使在定义问题上,时间维度是一个不能不考察的维度。所以才需要一个roadmap的路线图,标注不同阶段要解决什么样的问题。

六、升层思考及升维思考

我们不能用问题发生时的同一层次思维来解决问题。——by 爱因斯坦

爱因斯坦阐述了思维存在层次这一现象,这里我发表另外一个观点:

我们不能只局限于问题本身,还需要看到问题背后的问题,然后才能更容易的找到更多的解决方案。

我把这种方法叫做问题的升层思考,接下来我会简称之升层思考,我在网上搜索了一下,之前没有人提起过这个词,所以这个词目前版权在我这里哈,如果你想说服谁需要用这种思考方式,不妨把我这篇文章发给他。

4.jpg

当问题升层思考之后,前面的问题会变成手段/方法,比如说洪水和人民生命财产的矛盾背后的问题是社会的稳定性问题(1和2是升层思考),而升维思考洪水和人民生命财产的矛盾的时候就会发现用疏通治水或者搬走都是方案(3是升维思考)。

这就是升层思考问题,升维思考手段/方法。不过这张图中每个问题到底严重到什么程度,还没有给出量化,不过我们在工作中,我们是要量化这个严重程度,而且要放在时间轴上来进行量化,因为有些问题当前可能并不严重,但是数月后可能会变成大问题。

值得注意的是这里思考的升层是依赖认知升级的,就像一个小朋友,也许也能升层思考,但是其认知的程度决定了他思考能到的层度,所以历史,社会科学,哲学也是我们的必修课,有助于我们认知到更高的层次的存在。当问题的层次不断提升的时候,往往最终会归结为社会问题和人性问题。

重要的话说三遍:

缺乏升层思考的升维思考是不完整的自顶向下;

缺乏升层思考的升维思考是不完整的自顶向下;

缺乏升层思考的升维思考是不完整的自顶向下。

接下来我拿一些网上横向思考的案例,来使用升层思考和升维思考的方式获得相应的解决方案:

例一:游客有时会从帕台农神庙的古老立柱上砍下一些碎片,雅典当局对此非常关心,虽然这种行为是违法的,但是这些游客仍旧把它作为纪念品带走。当局如何才能阻止这一行动呢?

问题定义:如何给客户提供纪念品?
升层思考:客户需要纪念品的背后是想解决什么问题?是不是解决客户的旅游纪念的需求。
对背后的问题升维思考:要满足客户的旅游纪念的需求有没有其他方法?
明信片:明信片也可以做为一种纪念的方式,有了明星片做纪念,游客敲石柱的比例可能会下降。
现场照片:可以安排现场拍照的摄像师,选择特别的角度为这些想要留念的客户拍摄特别的照片,游客敲石柱的比例可能会下降。
帕台农神庙模型:可以制作各种帕台农神庙的模型,让客户购买,以满足客户纪念的需求,游客敲石柱的比例可能会下降。
对原问题升维思考:
在地上洒上大理石碎片:让客户以为这是帕台农神庙的大理石,客户会捡起地上的大理石碎片带回去留念(这是网上的标准答案)。
进入神庙时寄存各种金属物件:让用户无法用金属去砍古老立柱,缺点是成本高,效率低,需要排队检测金属物件
把柱子围起来,让用户只能在一米开外的距离观看:用户碰不到柱子,自然无法去砍柱子,成本比较低,也比较容易实现。
写标语,在入口处,以及门票上明确指出破坏文物是违法行为,会受到法律的制裁,等等。

网上的标准答案是在柱子旁边洒上大理石碎片(其他的都是我使用升层思考和升维思考瞎想出来的,你也可以想出很多)。让游客以为这是神庙已有的碎片。不过这种方案经不起逻辑思维的推敲,比如开放了这么多年,地上的碎石为什么还没有被捡光?于是游客就知道这是人为洒在上面的,那么有些游客会继续破坏石柱。

我想说的是,这里的升层思考,和不同层次的升维思考会给我们带来很多种方案,如果集合全团队的力量,我们甚至还可以想出更多更多的idea。

例二:在美国的一个城市里,地铁里的灯泡经常被偷。窃贼常常拧下灯泡,这会导致安全问题。接手此事的工程师不能改变灯泡的位置,也没多少预算供他使用,工程师应该怎么办?

问题定义:如何不让窃贼拧下灯泡?
升层思考:不让窃贼拧下灯泡是为了解决什么问题?是为了解决预算不足的问题。
对背后的问题升维思考:解决预算不足有没有其他方案?增加预算?募捐?防止窃贼拧下灯泡。
对原问题升维思考:不让窃贼拧下灯泡可以从哪些维度进行考虑?
焊住:缺点是灯泡坏了之后很难更换。
反向螺纹(窃贼在拧下灯泡的时候其实是在拧紧):缺点是窃贼只要使用逆向思维就能破解(反向螺纹是网上的标准答案)。
特别的螺纹(特别螺纹让窃贼拿到灯泡之后也无法在其他地方使用):缺点是需要定制,成本高。
摄像头:缺点是增加了设备,需要更大量的投入。
把灯安装在更高的位置:窃贼得用梯子才能去盗窃灯泡,要看线路是否支持
在灯泡上印上地铁专用标志:别人不敢买这种灯泡,窃贼无法销赃,缺点是多一道工序,灯泡的成本变高。

在这个案例中,反向螺纹是标准答案,缺点是窃贼只要使用逆向思维就能破解。其他都是我自己通过升层思考和升维思考想出来的,其实你也可以想出很多,这里跟逻辑无关。我想说的是通过升层思考和升维思考,我们就会发现很多种创新答案。而不会沿着某个答案一直往下走。

这两个例子是关于横向思维(和升维思考类似)的例子,但是通过我们会发现如果加上升层思考,在每个层次上再进行升维思考,我们会得到很多创新的idea。如果让整个团队使用这一的思考方式,我们就可以得到更多更多idea。

七、是新问题还是新技术解决老问题?

我们做架构的时候,一般都会根据当前流行的技术趋势来解决问题,这些流行的技术趋势其实手段的更新,并不是问题的更新。

尤其是在一些社会性问题以及人性问题上,几千年来问题都没有变化过,只是新的技术手段可以更好的解决这些问题而已。

比如人类有沟通需求,数百年前是通过书信,后来是电报,后来是电话(音频),后来是视频等等。都是技术的革新来更好的解决已有的问题。这就要求我们随时关注新技术,并和当前自己手头的工作产生一定的联想,不同对象之间的联想能力此刻变的无比重要。

当然在一些问题特别明确的领域,比如说数据库领域,要解决的问题基本没有变过,但是问题转换成的指标的值却在一直提升,比如支持的数据量越来越大,插入的速度越来越快,查询速度越来越快,比如最近就有很多通过AI来做自动tunning和AI索引优化的,都属于此列。

类似的例子还有很多,比如Mobile流行的时候,消息的更实时触达是改造各种消息通道的一个契机,会产生新的产品,比如微博,微信,等等。地理位置可以获取之后,也出现一堆新的应用,改造了老的产品。

所以我对自己提了一个要求,任何新技术,哪怕是很小的新技术,都要联想一下可能对现在的工作,以及现在工作的产业链路上下游有咩有什么帮助,这种联想可能不只是个人要做的,而是要驱动团队展开讨论的。目前眼前被提到的新技术有AI,区块链,IOT,5G等等,这些也许可以跟我们的业务产生链接。可以组织团队进行发散型思考。
不过这个事情我自己做的也一般,想多跟大牛们学习学习。

八、小结

区分手段和问题
明确问题定义
对问题背后的问题进行升层思考
对问题的分解进行升维思考

升层思考和升维思考有时候是创新的核心,比如鲧用堵治水,他毕生都在思考如何堵,所以他是从堵这个顶点向下思考的,如果对堵进行升层思考之后再进行升维思考,你会发现除了堵水,还可以用疏通的方式,还可以搬走等等。所以创新的关键在于升层思考和升维思考。

]]>
DataV数据可视化年度峰会——唤醒数据,看见未来 Mon, 16 Dec 2019 05:35:03 +0800

活动主KV.jpg

作为大数据分析的最后一步,数据可视化扮演着越来越重要的一步。它以更加简单直观的呈现方式展现数据的关键信息,帮助人们从海量的信息中发现隐藏信息,提高数据的使用效率。但现在大数据分析还有很多问题亟待解决,客户需求不清晰、产品体验不完善、行业缺乏模板项目等等。

基于这种情况,作为常年深耕于云计算和大数据行业的企业之一,阿里云 DataV数据可视化团队希望借助自身在行业的优势,发起第一届数据可视化行业年度峰会,邀请业界KOL共同探讨可视化商业化应用的前景和机会,深入挖掘数据可视化在各领域的应用、想象空间。

本次峰会将于2019年12月23日阿里巴巴西溪园区访客中心白马山庄举行,期待您的到来。

活动亮点

1.数据可视化开发生态
业界KOL,一线从业人员共同探讨数据可视化生态研发新趋势和新机遇,洞悉技术和商业未来。
2.阿里数据可视化布局
借鉴阿里经济体可视化布局,引发数据可视化研发方向思考,打造创新共赢的数据可视化研发环境。
3.商业级产品生态首发
从用户出发,构建数据可视化用户画像,定位用户需求和心理,针对性布局产品未来规划。
4.数据可视化实践共享
通过合作伙伴实践分享,拓展城市可视化实践界限,赋能数据可视化应用落地。
5.新品发布
最新数据可视化实践公布,多维诠释数据可视化研发生态。

活动概况

主办方:阿里云DataV
时间:2019年12月23日
地点:浙江省杭州市余杭区阿里巴巴西溪园区访客中心白马山庄

活动日程

2019峰会议程.jpg

嘉宾介绍

陈为.png

陈为浙江大学教授,CAD&CG国家重点实验室副主任,中国计算机学会CAD&CG专委会秘书长(候任)、中国图像图形学学会可视化专委会副主任

曾承担国家自然科学基金重点,优青项目等十余项。研究兴趣是大数据可视化分析。发表IEEE/ACM汇刊和CCF-A类会议论文六十余篇,出版著作五部。担任五个国际SCI期刊副主编和编委。

曹楠.png

曹楠同济大学教授,博士生导师,同济大学 “智能大数据可视化实验室” 主任
曹楠毕业自香港科技大学并获得计算机博士学位。曹楠博士在IBM 研究部门工作的近十年中,曾获得IBM杰出技术成就奖、IBM 杰出研究成就奖、以及多项 IBM创新成就奖。曹楠主要研究方向是大数据分析及可视化,其研究成果涵盖了数据可视化、数据挖掘、机器学习、及人机交互多个技术层面,并被应用在信息安全、智慧城市、健康医疗、智能设计等众多应用领域。
宁朗.png

宁朗阿里云智能-数据智能产品事业部-DataV-高级数据技术专家
阿里云数据引擎数据可视化团队DataV 负责人。从最早跟随团队将数据可视化概念引入公司,让公司对外数据展示项目升级换代,到抽象需求建立通用的datav.js数据可视化前端js组件库,并一步步将数据可视化真正落地到数据产品,直到目前将数据可视化作为独立公共云服务对外输出。个人力求帮助数据可视化从一个光鲜炫酷的新兴概念,扎根成为一种帮助数据分析,简化数据理解的本质需求。

李德清.png

李德清, Apache ECharts PPMC Fellow & 可视分析负责人
ECharts 核心研发工程师,Visual DL 核心作者之一。硕士毕业于浙江大学可视化 & 可视分析实验室。主要负责 ECharts 与学术领域的相关合作工作,同时也是 CSIG 可视化专委会委员,专注于数据可视化以及可视化技术在其他领域的应用,多次参与 W3C 以及 CSIG 的可视化标准制定相关工作。

派姐.png

派姐 , 城市数据派CEO
深圳数派互动传媒科技有限公司创始人,公司运营微信公众号城市数据派,获得国家信息中心评选的“全国十大最具影响力的大数据领域微信公众号”。城市数据派是全国首家面向城市大数据的垂直领域平台。数派科技是专业的城市大数据服务商,目前提供服务覆盖媒体宣传、数据技能、数据资源、数据分析、教育培训等领域,致力于打造多方共赢的城市数据创新生态圈;曾主办“全国十大城市数据师个人贡献奖”及“全国规划行业大数据应用十大企业”评选活动,获得各界好评。

报名地址

活动流程

  • 活动报名——报名审核——短信通知——带领入园
  • 有关活动和产品的相关问题,可加入活动钉钉群讨论
    钉钉群.jpg
]]>
还不知道HBase冷热分离的技术原理?看这一篇就够了! Mon, 16 Dec 2019 05:35:03 +0800

作者:郭泽晖(索月),阿里云数据库技术专家

HBase是当下流行的一款海量数据存储的分布式数据库。往往海量数据存储会涉及到一个成本问题,如何降低成本。常见的方案就是通过冷热分离来治理数据。冷数据可以用更高的压缩比算法(ZSTD),更低副本数算法(Erasure Coding),更便宜存储设备(HDD,高密集型存储机型)。

1、HBase冷热分离常见解决方案

1.主备集群

备(冷)集群用更廉价的硬件,主集群设置TTL,这样当数据热度退去,冷数据自然只在冷集群有。
b0b393c4b9d03d513e943b490444ed8d40ca9937.png

优点:方案简单,现成内核版本都能搞
缺点:维护开销大,冷集群CPU存在浪费
1.x版本的HBase在不改内核情况下,基本只能有这种方案。
f2c6f9883229b5e26cc61beb851e6603b5cdebf0.png

2. HDFS Archival Storage + HBase CF-level Storage Policy

需要在2.x之后的版本才能使用。结合HDFS分层存储能力 + 在Table层面指定数据存储策略,实现同集群下,不同表数据的冷热分离。

优点:同一集群冷热分离,维护开销少,更灵活的配置不同业务表的策略
缺点:磁盘配比是个很大的问题,不同业务冷热配比是不一样的,比较难整合在一起,一旦业务变动,集群硬件配置是没法跟着变的。

2,云HBase冷热分离解决方案

上述2套方案都不是最好的方案,对于云上来说。第一套方案就不说了,客户搞2个集群,对于数据量不大的客户其实根本降不了成本。第二套方案,云上客户千千万,业务各有各样,磁盘配置是很难定制到合适的状态。
云上要做 cloud native 的方案,必须满足同集群下,极致的弹性伸缩,才能真正意义上做到产品化。云上低成本,弹性存储,只有OSS了。所以很自然的想到如下架构:
07ecf9cbd61386d4c1a74c58aaa12da3fb03b0a0.png

实现这样的架构,最直接的想法是直接改HBase内核:
1)增加冷表数据标记

2)根据标记增加写OSS的IO路径。

这样做的缺陷非常明显,你的外部系统(如:备份恢复,数据导入导出)很难兼容这些改动,他们需要感知哪些是冷文件得去OSS哪个位置读,哪些是热文件得去部署在云盘上的HDFS上读。

这些本质上都是一些重复的工作,所以从架构设计角度来看必须抽象出一层。这一层能读写HDFS文件,读写OSS文件,感知冷热文件。这一层也就是我最后设计出的ApsaraDB FileSystem,实现了Hadoop FileSystem API。对于HBase,备份恢复,数据导入导出等系统只要替换原先FileSystem的实现即可获得冷热分离的功能。
下面将详细阐述,这套FileSystem设计的细节与难点。

3,ApsaraDB FileSystem 设计

核心难点A

1.OSS并非文件系统

OSS并不是一个真正意义上的文件系统,它仅仅是两级映射 bucket/object,所以它是对象存储。你在OSS上看到类似这样一个文件:
/root/user/gzh/file。你会以为有3层目录+1个文件。实际上只有一个对象,这个对象的key包含了/字符罢了。

这么带来的一个问题是,你要想在其上模拟出文件系统,你必须先能创建目录。很自然想到的是用/结尾的特殊对象代表目录对象。Hadoop社区开源的OssFileSystem就是这么搞的。有了这个方法,就能判断到底存不存在某个目录,能不能创建文件,不然会凭空创建出一个文件,而这个文件没有父目录。

当然你这么做依然会有问题。除了开销比较大(创建深层目录多次HTTP请求OSS),最严重的是正确性的问题。

试想一下下面这个场景:

把目录/root/user/source rename 成 /root/user/target。这个过程除了该目录,它底下的子目录,子目录里的子文件都会跟着变。

类似这样:/root/user/source/file => /root/user/target/file。这很好理解,文件系统就是一颗树,你rename目录,实际是把某颗子树移动到另一个节点下。这个在NameNode里的实现也很简单,改变下树结构即可。

但是如果是在OSS上,你要做rename,那你不得不递归遍历/root/user/source把其下所有目录对象,文件对象都rename。因为你没法通过移动子树这样一个简单操作一步到位。

这里带来的问题就是,假设你递归遍历到一半,挂了。那么就可能会出现一半目录或文件到了目标位置,一半没过去。这样rename这个操作就不是原子的了,本来你要么rename成功,整个目录下的内容到新的地方,要么没成功就在原地。

所以正确性会存在问题,像HBase这样依赖rename操作将临时数据目录移动到正式目录来做数据commit,就会面临风险。

2.OSS rename实则是数据拷贝

前面我们提到了rename,在正常文件系统中应该是一个轻量级的,数据结构修改操作。但是OSS并没有rename这个操作实际上,rename得通过 CopyObject + DeleteObject 两个操作完成。首先是copy成目标名字,然后delete掉原先的Object。

这里有2个明显的问题,一个是copy是深度拷贝开销很大,直接会影响HBase的性能。另一个是rename拆分成2个操作,这2个操作是没法在一个事物里的,也就是说:可能存在copy成功,没delete掉的情况,此时你需要回滚,你需要delete掉copy出来的对象,但是delete依然可能不成功。所以rename操作本身实现上,正确性就难以保证了。

解决核心难点A

解决上面2个问题,需要自己做元数据管理,即相当于自己维护一个文件系统树,OSS上只放数据文件。而因为我们环境中仍然有HDFS存储在(为了放热数据),所以直接复用NameNode代码,让NodeNode帮助管理元数据。所以整体架构就出来了:
121cbb8378a503dce0d6246716629f1c79ddee23.png

ApsaraDB FileSystem(以下简称ADB FS)将云端存储分为:主存(PrimaryStorageFileSystem)和 冷存(ColdStorageFileSystem)。由ApsaraDistributedFileSystem类(以下简称ADFS)负责管理这两类存储文件系统,并且由ADFS负责感知冷热文件。
ApsaraDistributedFileSystem: 总入口,负责管理冷存和主存,数据该从哪里读,该写入哪里(ADFS)。
主存:PrimaryStorageFileSystem默认实现是

DistributedFileSystem(HDFS)
冷存:ColdStorageFileSystem 默认实现是 HBaseOssFileSystem(HOFS) ,基于OSS实现的Hadoop API文件系统,可以模拟目录对象单独使用,也可以只作为冷存读写数据,相比社区版本有针对性优化,后面会讲。

具体,NameNode如何帮助管理冷存上的元数据,很简单。ADFS在主存上创建同名索引文件,文件内容是索引指向冷存中对应的文件。实际数据在冷存中,所以冷存中的文件有没有目录结构无所谓,只有一级文件就行。我们再看下一rename操作过程,就明白了:
6c35f996a3780a2901d9977e924d5b4cff9b3190.png

rename目录的场景也同理,直接在NameNode中rename就行。对于热文件,相当于全部代理HDFS操作即可,冷文件要在HDFS上创建索引文件,然后写数据文件到OSS,然后关联起来。

核心难点B

引入元数据管理解决方案,又会遇到新的问题:是索引文件和冷存中数据文件一致性问题。

00189f99863e4115ed48cf85cfc28a155fd56b55.png

我们可能会遇到如下场景:

主存索引文件存在,冷存数据文件不存在
冷存数据文件存在,主存索引文件不存住

主存索引文件信息不完整,无法定位冷存数据文件
先排除BUG或者人为删除数据文件因素,上诉3种情况都会由于程序crash产生。也就是说我们要想把法,把生成索引文件,写入并生成冷数据文件,关联,这3个操作放在一个事物里。这样才能具备原子性,才能保证要么创建冷文件成功,那么索引信息是完整的,也指向一个存在的数据文件。要么创建冷文件失败(包括中途程序crash),永远也见不到这个冷文件。

解决核心难点B

核心思想是利用主存的rename操作,因为主存的rename是具备原子性的。我们先在主存的临时目录中生产索引文件,此时索引文件内容已经指向冷存中的一个路径(但是实际上这个路径的数据文件还没开始写入)。

在冷存完成写入,正确close后,那么此时我们已经有完整且正确的索引文件&数据文件。然后通过rename一把将索引文件改到用户实际需要写入到目标路径,即可。

如果中途进程crash,索引文件要么已经rename成功,要么索引文件还在临时目录。在临时目录我们认为写入没有完成,是失败的。然后我们通过清理线程,定期清理掉N天以前临时目录的文件即可。所以一旦rename成功,那目标路径上的索引文件一定是完整的,一定会指向一个写好的数据文件。

为什么我们需要先写好路径信息在索引文件里?因为如果先写数据文件,在这个过程中crash了,那我们是没有索引信息指向这个数据文件的,从而造成类似“内存泄漏”的问题。

冷热文件标记

对于主存,需要实现给文件冷热标记的功能,通过标记判断要打开怎样的数据读写流。这点NameNode可以通过给文件设置StoragePolicy实现。这个过程就很简单了,不详细赘述,下面说HBaseOssFileSystem写入优化设计。

HBaseOssFileSystem 写入优化

在说HOFS写设计之前,我们先要理解Hadoop社区版本的OssFileSystem设计(这也是社区用户能直接使用的版本)。

社区版本写入设计

Write -> OutputStream -> disk buffer(128M) -> FileInputStream -> OSS
这个过程就是先写入磁盘,磁盘满128M后,将这128M的block包装成FileInputStream再提交给OSS。这个设计主要是考虑了OSS请求成本,OSS每次请求都是要收费的,但是内网流量不计费。如果你1KB写一次,费用就很高了,所以必须大块写。而且OSS大文件写入,设计最多让你提交10000个block(OSS中叫MultipartUpload),如果block太小,那么你能支持的最大文件大小也是受限。

所以要攒大buffer,另外一个因素是Hadoop FS API提供的是OutputStream让你不断write。OSS提供的是InputStream,让你提供你要写入内容,它自己不断读取。这样你必然要通过一个buffer去转换。

这里会有比较大的一个问题,就是性能慢。写入磁盘,再读取磁盘,多了这么两轮会比较慢,虽然有PageCache存在,读取过程不一定有IO。那你肯定想,用内存当buffer不就好了。

内存当buffer的问题就是前面说的,有费用,所以buffer不能太小。所以你每个文件要开128M内存,是不可能的。更何况当你提交给OSS的时候,你要保证能继续写入新数据,你得有2块128M内存滚动,这个开销几乎不能接受。

HBaseOssFileSystem 写入设计

我们既要解决费用问题,也要解决性能问题,同时要保证开销很低,看似不可能,那么怎么做呢?

这里要利用的就是这个InputStream,OSS让你提供InputStream,并从中读取你要写入的内容。那么我们可以设计一个流式写入,当我传入这个InputStream给OSS的时候,流中并不一定得有数据。此时OSS调read读取数据会block在read调用上。等用户真的写入数据,InputStream中才会有数据,这时候OSS就能顺利读到数据。

当OSS读了超过128M数据时候,InputStream会自动截断,返回EOF,这样OSS会以为流已经结束了,那么这块数据就算提交完成。

所以我们本质只要开发这么一个特殊的InputStream即可。用户向Hadoop API提供的OutputStream中写入数据,数据每填满一个page(2M)就发给InputStream让其可读取。OuputStream相当于生产者,InputStream相当于消费者。

这里的内存开销会非常低,因为生产者速度和消费者速度相近时,也就2个page的开销。最后将这整套实现封装成OSSOutputStream类,当用户要写入冷文件时,实际提供的是OSSOutputStream,这里面就包含了这个特殊InputStream的控制过程。

当然实际生产中,我们会对page进行控制,每个文件设置最多4个page。并且这4个page循环利用,减少对GC对影响。所以最后我们得到下面一个环形缓冲的写入模式:

cebb1a59524cdd96aef6e72e0f243ed7c61aae32.png

性能对比1:社区版本 vs 云HBase版

因为不用写磁盘,所以写入吞吐可以比社区的高很多,下图为HBase1.0上测试结果。在一些大KV,写入压力更大的场景,实测可以接近1倍。这个比较是通过替换ADFS冷存的实现(用社区版本和云HBase版本),都避免了rename深拷贝问题。如果直接裸用社区版本而不用ADFS那性能会差数倍。

c81d253fd3cc36e920c2f23d1b4aa3dd184483e1.png

性能对比2:热表 vs 冷表

热表数据在云盘,冷表数据在OSS。
9b128087f980e532cf29c4e827f16e154944008b.png

得益于上述优化,加上冷表WAL也是放HDFS的,并且OSS相对HBase来说是大集群(吞吐上限高),冷表的HDFS只用抗WAL写入压力。所以冷表吞吐反而会比热表略高一点点。
不管怎么说,冷表的写入性能和热表相当了,这样的表现已经相当不错了。基本是不会影响用户灌数据,否则使用冷存后,吞吐掉很多,那意味着要更多机器,那这功能就没什么意义了。

云数据库HBase降价狂欢

首购爆款6个月仅需9.9元

新购一年低至5折

戳下方]]> 以线及面--进入二维数组的世界 | 带你学《Java面向对象编程》之十六 Mon, 16 Dec 2019 05:35:03 +0800 上一篇:又见引用--数组元素的奇妙之旅 |带你学《Java面向对象编程》之十五
【本节目标】
通过阅读本节内容,你将拓展思维,以线及面,初步了解到数据的魅力,并学会二维数组的定义与初始化相关方法。

二维数组

在之前所定义的数组里面会发现只有一个“[]”,所以这个时候的数组就好像一行数据一样,可以利用下标进行行数据的访问。

  • 传统的数组就好比一行数据,如果要想找到一个数据只需要确定一个下标即可;

表一 传统数组
image.png

  • 如果说现在需要一个多行多列的结构(表),则就需要通过两个下标才可以描述出一个数据,行下标与列下标共同定义才可以找到,所以这样的数组形式就称为二维数组。

表二 二维数组
image.png

对于二维数组可以使用的定义语法如下:

  • 数组的动态初始化

    • 数据类型 数组名称 [][] = new 数据类型 行个数
  • 数组的静态初始化

    • 数据类型 数组名称 [][] =new 数据类型 [][] { {数据,数据,……},{数据,数据,……},{数据,数据,……},……}

范例:定义二维数组

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] []= new int [] []{{1,2,3,4,5},{1,2,3},{5,6,7,8}} ;
     }
}

表三 表示程序结果
image.png

既然二维数组的每一行都属于一个数组,那么这种情况下就可以通过每一行的数组求出数组长度。

public class ArrayDemo {
   public static void main (String args[ ]) {
      int data [] []= new int [] []{{1,2,3,4,5},{1,2,3},{5,6,7,8}} ;
      for (int x = 0 ; x < data.length ; x ++ ){
         for(int y = 0 ;y <data[x].length ; y ++){
        System.out.println(“data[“+x+”][“+y+”] = ”+ data[x][y]) ;
         }
         System.out.println() ;    //换行
      }
   }
}

image.png
图一 执行结果一

如果这时要求使用foreach来进行输出呢?
范例:使用foreach输出二维数组

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] []= new int [] []{{1,2,3,4,5},{1,2,3},{5,6,7,8}} ;
         for (int temp [] : data) {
            for(int num : temp) {
               Sysem.out.println(num + “、”)
             }
             System.out.println() ;    //换行
         }
    }
}

image.png
图二 执行结果二

通过foreach的输出格式可以清楚地观察到,二维数组就是数组的嵌套使用。随着尅发技术的发展,如果要进行一些应用层的程序开发,那么很少会涉及到二维数组,更不用说更高级的多维数组了。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:熟练运用数组,看这篇就够了 | 带你学《Java面向对象编程》之十七
更多Java面向对象编程文章查看此处

]]>
深度学习在商户挂牌语义理解的实践 Mon, 16 Dec 2019 05:35:03 +0800 ​导读:高德地图拥有几千万的POI兴趣点,例如大厦、底商、学校等数据,而且每天不断有新的POI出现。为了维持POI数据的鲜度,高德会通过大量的数据采集来覆盖和更新。现实中POI名称复杂,多变,同时,名称制作工艺要求严格,通过人工来制作POI名称,需要花费大量的人力成本。

因此,POI名称的自动生成就显得格外重要,而机器对商户挂牌的语义理解又是其中关键的一环。本文主要介绍相关技术方案在高德的实践和业务效果。

一、背景
现实世界中,商户的挂牌各式各样,千奇百怪,如何让机器正确的理解牌匾语义是一个难点。商户挂牌的文本种类有很多,如下图所示,我们可以看到一个商户牌匾的构成。
wudongxu1.png

结合POI的名称制作工艺,我们目前将POI的牌匾的文本行分为4大类:主名称、经营性质(包括经营范围,具体的进行项目)、分店名、噪声(包括非POI文字,地址,联系方式),前面3个类别会参与到POI名称制作中。如上图所示的牌匾,它输出的规范名称应该是“世纪宏图不动产 (兴业路店)”。其中“世纪宏图”是主名称,“不动产”是经营范围,而“兴业路店”是分店名。

从牌匾中找出制作名称所需要的文字,不仅仅需要文本行自身的一些特征,还需要通过结合牌匾上下文,以及图像的信息进行分析。单纯的文本行识别会遇到下面的问题,如下图,在两个牌匾中都提到了“中国电信”,但是它们的意义是不一样的,这时必须结合上下文的理解。
wudongxu2.png

二、技术方案

单纯从文本的语义理解的角度出发,那么这个应该是一个文本分类问题。但是直接的分类效果不佳。现实中在理解牌匾文本行语义的时候,需要结合图形,位置,内容,以及上下文关系综合来判断。为此,我们将商户挂牌理解的这个问题分解成两个子问题来解决,1.如何结合图像、文本、以及空间位置;2.如何结合上下文关系。因此,我们提出了Two-Stages级联模型。
wudongxu3.png

2.1 Two-Stages 级联模型

Two-stages级联模型分为两个主要的阶段:第一阶段提取单文本信息特征,包括文本位置和文本内容等,第二阶段提取牌匾中文本行上下文关系特征,消除只用单个文本识别容易造成的歧义,准确识别出该文本属性。

2.1.1 Stage One 单文本行特征提取

单文本行特征可以分为词性结构(token level)特征和句子语义(sentence level)特征。除此之外,位置信息(PV)也是比较重要的信息,需要进行特征提取和编码。将以上特征进行融合,得到了单文本行特征。
wudongxu4.png

token level层的特征提取方面,结合名称的构成以及名称工艺,我们定义了三种词性: 核心词(C)、通用词(U)、结尾词(T)。在这里我们使用LSTM网络来学习名称的词性序列。
wudongxu5.png

sentence leve层的特征提取方面,由于我们的标注量相对比较少,采用了具有大量先验知识的BERT模型。同时,为了更好的符合当前业务场景的需求,我们结合业务中POI的数据集合,在原来Google官方提供的预训练模型基础上继续pre-training,得到新的模型BERT-POI。

预训练的POI文本语料没有太多的上下文环境,在构造样本时,我们将两个POI名称串起来或是同一个POI随机切分,中间都用SEP隔开,进行多任务学习:缺字补全和预测两个文本行是否属于同一POI。经过实验发现,在POI数据上预训练模型BERT-POI 比Google发布模型BERT-Google,缺字补全和同一POI判定两项任务上名,正确率高20%左右。

此外,将预训练的模型用于下游属性识别任务上,BERT-POI与BERT-Google相比,提升主名称,分店名,营业范围的召回3%~6%。

下图展示了我们预训练的过程图:
wudongxu6.png

随后,我们对预训练好的BERT-POI在进行了finetune,提取出sentence leve层的特征。

2.1.2 Stage-Two 文本相互关系提取

Stage One提取到了单文本行的特征,那如何去实现上下文的关联,我们加入了Stage Two的模块,模型结构如下:
wudongxu7.png

Stage Two最主要是用BILSTM(Bidirectional LSTM)处理stage one输出特征,能够将当前文本特征和牌匾内其他文本特征进行学习,消除歧义。

三、业务效果

牌匾通过语义理解后,会根据具体的输出类型来制定名称生成的策略。例如:对于单主+噪声牌匾,我们直接将主名称作为POI名称,而对于单主+分店名+经营性质+噪声的牌匾,我们会分析主名称的结构,看是否需要拼接经营性质。

下图展示了当前我们牌匾语义理解和名称的部分拼接策略:
wudongxu8.png
图3.1单主+噪声场景
wudongxu9.png
图3.2 单主+分店名场景
wudongxu10.png
图3.3单主+经营性质场景(主名称中有经营性质)
wudongxu11.png
图3.4 单主+经营性质场景(主名称中无经营性质)

四、小结

目前商户牌匾语义理解模块的准确率在95%以上,在POI的名称自动生成中起到的重要的作用。商户牌匾的语义理解模块只是POI名称自动化的一部分内容,在POI名称自动化中还会涉及到噪声牌匾过滤、牌匾是否依附建筑物、敏感类别、文本的缺失、名称生成、名称纠错等模块。我们会在图文多模态这块更深入的探索,更多地应用于我们现实场景中,生产更多、更高质量的数据。

]]>
熟练运用数组,看这篇就够了 | 带你学《Java面向对象编程》之十七 Mon, 16 Dec 2019 05:35:03 +0800 上一篇:以线及面--进入二维数组的世界 | 带你学《Java面向对象编程》之十六
【本节目标】
通过阅读本节,你将了解到数组在方法调用中的内存变化,初步了解到程序“设计”的含义,并掌握使用方法完成对数组的操作以满足某些需求的能力。

数组与方法

对于引用数据类型而言,主要的特点是可以与方法进行引用传递,而数组本身也属于引用数据类型,所以自然也可以通过方法实现引用传递操作。
范例:实现一个数组的引用传递

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {1,2,3,4,5} ;
         printArray(data) ;     //传递数组
     }
//要求接收一个int型的数组
     public static void printArray(int temp []) {
         for (int x = 0 ; x < temp.lenght ; x ++) {
            System.out.println(temp[x]) ;
         }
     }
}

image.png
图一 执行结果一

对于此时的引用传递具体的内存关系如下。

image.png
图二 内存分析结果一

既然可以通过方法来接收一个数组,那么也就可以通过方法返回一个数组对象,那么此时只需要在方法的返回值类型上进行控制即可。
范例:定义方法返回数组

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = initArray() ;    //通过方法可以获得数组内容
         printArray(data) ;     //传递数组
     }
     public static int [] initArray () {
     int arr [] = new int [] {1,2,3,4,5} ;
     return arr ;         //返回一个数组
     }
//要求接收一个int型的数组
     public static void printArray(int temp []) {
         for (int x = 0 ; x < temp.lenght ; x ++) {
            System.out.println(temp[x]) ;
         }
     }
}

image.png
图三 执行结果二

接下来针对于此程序进行内存关系分析。

image.png
图四 内存分析结果二

范例:通过方法修改数组内容

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {1,2,3,4,5} 
         changeArray(data) ;    //修改数组内容
         printArray(data) ;     //传递数组
    }
    public static void changeArray(int arr[]) {
        for (int x = 0 ;x < arr.length ; x ++) {
            arr[x] *= 2 ;          //每个元素的内容乘2保存
        }
    }
//要求接收一个int型的数组
    public static void printArray(int temp []) {
        for (int x = 0 ; x < temp.lenght ; x ++) {
            System.out.println(temp[x]) ;
        }
    }
}

image.png
图五 修改数组内容执行结果

本程序的内存关系如下:

image.png
图六 内存分析结果图三

案例

随意定义一个int数组,要求可以计算出这个数组元素的总和、最大值、最小值、平均值。
对于此程序最基本的实现如下:

public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {1,2,3,4,5} 
         int sum = 0 ;
         double avg = 0.0 ;
         int max = data[0] ;       //假设第一个是最大值
         int min = data[0] ;       //假设第一个是最小值
         for(int x = 0 ; x < data.length ; x ++){
            if(data[x] > max) {        //max地位改变
                max = data[x] ;
            }
            if(data[x] < min) {
                min = data[x] ;
            }
         sum += data[x] ;
         } 
         avg = sum / data.length ;
         System.out.println(“数组内容总和:” + sum) ;
         System.out.println(“数组内容平均值:” + avg) ;
         System.out.println(“数组内容最大值:” + max) ;
         System.out.println(“数组内容最小值:” + min) ;
     }
     public static void printArray(int temp []) {
         for (int x = 0 ; x < temp.lenght ; x ++) {
            System.out.println(temp[x]) ;
         }
     }
 }

image.png
图七 求值结果图

主方法所在的类往往被称为主类,那么既然是主类肯定不希望涉及到过于复杂的功能。在进行开发的过程当中,主方法本身就相当于是一个客户端,而对于客户端的代码应该尽量简单一些,所以这个时候最好的做法是将这一系列的计算过程交给单独的程序类去完成。
范例:改善操作设计

class ArrayUtil {          //是一个操作工具的类
   private int sum ;         //保存总和
   private double avg ;      //保存平均值
   private int max ;         //保存最大值
   private int min ;         //保存最小值
   public ArrayUtil(int data[]) {     //进行数组计算
        this.max = data[0] ;       //假设第一个是最大值
        this.min = data[0] ;       //假设第一个是最小值
        for(int x = 0 ; x < data.length ; x ++){
            if(data[x] > max) {        //max地位改变
               this.max = data[x] ;
            }
            if(data[x] < min) {
               this.min = data[x] ;
            }
          this.sum += data[x] ;
        } 
        this.avg = this.sum / data.length ;
    }
    public int getSum() {
       return this.sum ;
    }
    public double getAvg() {
       return this.avg ;
    }
    public int getMax() {
       return this.max ;
    }
    public int getMin() {
       return this.min ;
    }
}
public class ArrayDemo {
     public static void main (String args[ ]) {
         int data [] = new int [] {1,2,3,4,5} 
         ArrayUtil util = new ArrayUtil(data) ;   //数据计算
         System.out.println(“数组内容总和:” + util.getSum()) ;
         System.out.println(“数组内容平均值:” + util.getAvg()) ;
         System.out.println(“数组内容最大值:” + util.getMax()) ;
         System.out.println(“数组内容最小值:” + util.getMin()) ;

     }
}

image.png
图八 求值结果图二

此时的主类就好比我们使用的电脑一样,只关心如何操作,而具体的操作过程被类进行包装了。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:数组排序-触摸算法的门槛 | 带你学《Java面向对象编程》之十八
更多Java面向对象编程文章查看此处

]]>
HBase 2.0.0 META 数据修复工具 Mon, 16 Dec 2019 05:35:03 +0800 问题起因

必须先吐槽一下 Cloudera 6.x 和 Hbase 2.0 太坑了!

不久前生产上的一套Hbase集群出现著名的RIT(Regions in Transition)问题。

查看hbase web ui
1

于是通过hbck命令查看一下集群状态,果然好多inconsistency

 ...
 ERROR: Region { meta => XXX,XXX:,1573019231000.ff2aecaf28917792395c341d01e0b8cc., hdfs => hdfs://nameservice1/hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc, deployed => , replicaId => 0 } not deployed on any region server.
 ...
 ERROR: Found inconsistency in table XXX
 ...
 9 inconsistencies detected.
 Status: INCONSISTENT

看到错误提示问题明显了,这个Region在hdfs中有数据文件但没有依赖任何Region Server,原因可能region被原来的Region Server unassigned了,但是还没有被assigned到一个新的Region Server上。

那么尝试用hbase hbck -repairhbase hbck -fixMeta -fixAssignments来修复吧,于是就有了下面的提示,hbase2.0+以后hbck的所有修复功能全都不支持...

-----------------------------------------------------------------------
NOTE: As of HBase version 2.0, the hbck tool is significantly changed.
In general, all Read-Only options are supported and can be be used
safely. Most -fix/ -repair options are NOT supported. Please see usage
below for details on which options are not supported.
-----------------------------------------------------------------------

NOTE: Following options are NOT supported as of HBase version 2.0+.

  UNSUPPORTED Metadata Repair options: (expert features, use with caution!)
   -fix              Try to fix region assignments.  This is for backwards compatiblity
   -fixAssignments   Try to fix region assignments.  Replaces the old -fix
   -fixMeta          Try to fix meta problems.  This assumes HDFS region info is good.
   -fixHdfsHoles     Try to fix region holes in hdfs.
   ...
  UNSUPPORTED Metadata Repair shortcuts
   -repair           Shortcut for -fixAssignments -fixMeta -fixHdfsHoles -fixHdfsOrphans -fixHdfsOverlaps -fixVersionFile -sidelineBigOverlaps -fixReferenceFiles-fixHFileLinks
   -repairHoles      Shortcut for -fixAssignments -fixMeta -fixHdfsHoles

既然hbck不支持,觉得hbase总得有解决方案吧,科学上网后发现hbase2.0+提供了一个叫hbck2工具,不过得自己编译麻烦了点。
克隆下来准备动手编译发现不对,于是仔细看了一下hbck2的介绍,最低支持版本2.0.3和2.1.1
image

image

WTF......这就是个黑洞啊,还有你就不能把支持的版本号字体放大点吗!

修复方案

吐槽过后,还是得想解决办法啊:

  1. 升级Hbase版本

    • 目前这种情况是根本无法升级的,存量数据怎么办,就算数据可以重入,目前使用的hbase是CDH版,Cloudera 6.x版本集成的hbase只有2.0.0和2.1.0版本,还是黑洞。。。此方案行不通。
  2. 暴力删除hbase数据

    • 暴力删除数据,格式化hdfs,删除hbasemeta数据,删除zookeeper记录,这和重新部署一套hbase差不多了,但是前提是数据可以重入或者允许清除,那以后怎么办,总不能一遇到问题就删库吧,生产上面的数据一般都比较敏感根本不能删。。。此方案行不通。
  3. 写个工具修复hbase

    • 看来只能这样了。。。

修复步骤

回到最初的错误提示,思考一下,如果Region下数据文件在hdfs中存在,那是否可以通过.regioninfo文件(hdfs存储hbase region信息的文件)获取Region信息,同时读取'hbase:meta'表中的Region信息,进行对比取差集就是要修复的Region,然后将需要修复的Region信息再写入到'hbase:meta'中。

按照这个思路,先验证一下hdfs
检测一下hbase的block是否完整 hdfs fsck /hbase

Status: HEALTHY
 Number of data-nodes:  12
 Number of racks:               1
 Total dirs:                    4650
 Total symlinks:                0
...
The filesystem under path '/hbase' is HEALTHY

检查一下.regioninfo文件是否完整 hadoop fs -ls /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc

Found 4 items
-rw-r--r--   3 hbase hbase         65 2019-10-26 18:29 /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc/.regioninfo
drwxr-xr-x   - hbase hbase          0 2019-11-26 09:37 /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc/.tmp
drwxr-xr-x   - hbase hbase          0 2019-11-26 13:59 /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc/0
drwxr-xr-x   - hbase hbase          0 2019-10-26 18:29 /hbase/data/default/XXX/ff2aecaf28917792395c341d01e0b8cc/recovered.edits

再看一下'hbase:meta'中的存储结构:

列名 说明
info:state Region状态
info:sn Region Server Node,由 server和serverstartcode组成,如slave1,16020,1557998852385
info:serverstartcode Region Server启动Code,实质上就是Region Server启动的时间戳
info:server Region Server 地址和端口,如slave1:16020
info:seqnumDuringOpen 表示Region在线时长的一个二进制串
info:regioninfo Region Info,和.regioninfo内容相同

OK,觉得这个方案可行,接下来就开始动手coding吧

获取'hbase:mata'中的Region信息

    public Set<String> getMetaRegions(Configuration conf, String tableName) throws Exception {

        Connection conn = ConnectionFactory.createConnection(conf);
        Table table = conn.getTable(TableName.valueOf(TABLE));

        PrefixFilter filter = new PrefixFilter(Bytes.toBytes(tableName + ","));

        Scan scan = new Scan();
        scan.setFilter(filter);

        Set<String> metaRegions = new HashSet<>();

        Iterator<Result> iterator = table.getScanner(scan).iterator();
        while (iterator.hasNext()) {
            Result result = iterator.next();
            metaRegions.add(Bytes.toString(result.getRow()));
        }

        conn.close();

        return metaRegions;
    }

读取.regioninfo中的Region信息

    public Map<String, RegionInfo> getHdfsRegions(Configuration conf, String tablePath) throws Exception {

        FileSystem fs = FileSystem.get(conf);
        Path path = new Path(hdfsRootDir + "/data/default/" + tablePath + "/");

        Map<String, RegionInfo> hdfsRegions = new HashMap<>();

        FileStatus[] list = fs.listStatus(path);
        for (FileStatus status : list) {
            if (!status.isDirectory()) {
                continue;
            }

            boolean isRegion = false;
            FileStatus[] regions = fs.listStatus(status.getPath());
            for (FileStatus regionStatus : regions) {
                if (regionStatus.toString().contains(REGION_INFO_FILE)) {
                    isRegion = true;
                    break;
                }
            }

            if (!isRegion) {
                continue;
            }

            RegionInfo hri = HRegionFileSystem.loadRegionInfoFileContent(fs, status.getPath());
            hdfsRegions.put(hri.getRegionNameAsString(), hri);

        }
        return hdfsRegions;
    }

两者进行对比取差集

        Set<String> metaRegions = getMetaRegions(configuration, repairTableName);

        Map<String, RegionInfo> hdfsRegions = getHdfsRegions(configuration, repairTableName);

        Set<String> hdfsRegionNames = hdfsRegions.keySet();

        metaRegions.removeAll(hdfsRegionNames);

构造META信息并写入HBase

        ServerName[] regionServers = admin.getRegionServers().toArray(new ServerName[0]);
        
        int rsLength = regionServers.length;
        int i = 0;
        for (String regionName : hdfsRegionNames) {

            String sn = regionServers[i % rsLength].getServerName();
            String[] snSig = sn.split(",");

            RegionInfo hri = hdfsRegions.get(regionName);
            Put info = MetaTableAccessor.makePutFromRegionInfo(hri, EnvironmentEdgeManager.currentTime());
            info.addColumn(Bytes.toBytes(FAMILY), Bytes.toBytes(SN), Bytes.toBytes(sn));
            info.addColumn(Bytes.toBytes(FAMILY), Bytes.toBytes(SERVER), Bytes.toBytes(snSig[0] + ":" + snSig[1]));
            info.addColumn(Bytes.toBytes(FAMILY), Bytes.toBytes(STATE), Bytes.toBytes("OPEN"));

            table.put(info);
            i++;
        }

重启Region Server 和 Hbase Master,重启之后会自动生成'info:seqnumDuringOpen'以及'info:serverstartcode'

工具开发完成后,找了个环境验证了一下,没出什么问题,接下来就部署到生产上试试了,反正hbase已经这个样子,死马当司马懿吧。

先用了个region不多的表试验,发现可以呀,然后陆续把所有错误的表都修复一遍,重启hbase,接下来就是见证BUG的时刻:

...
0 inconsistencies detected.
Status: OK

hbase修复完成 此处有掌声

修复工具

本着开源精神,工具已上传GitHub : hbase-meta-repair

image

]]>
参与DataWorks产品满意度调查,赢取200元无门槛代金券 Mon, 16 Dec 2019 05:35:03 +0800 感谢您对DataWorks的支持,为了更好地提升产品用户体验, 我们将进行一次用户满意度调查,了解产品用户对于产品的使用情况,功能需求,产品满意度等等。我们将从认真填写的用户中随机抽取100份有效问卷,每名用户赠送200元DataWorks无门槛代金券

主账号问卷地址:https://survey.aliyun.com/apps/zhiliao/MgFRpUB3
子账号问卷地址:https://survey.aliyun.com/apps/zhiliao/IZQcAKf0z

我们会认真评估您的每一条建议,感谢!

]]>
重磅首发 |《Elasticsearch 中国开发者调查报告》探索开发者的现状和未来 Mon, 16 Dec 2019 05:35:03 +0800

点击免费下载
《Elasticsearch开发者调查报告》

2012年,Elasticsearch 首个版本发布,经过7年多的发展,Elastic系列开源项目的热度持续升温,Elastic 技术社区的用户量和开发者群体逐步壮大,也在不断进化。那么,这个群体是谁?他们在怎样使用 Elastic Stack ?他们又将如何进阶成长?

为了洞察这个独特开发者群体的发展、技术应用现状,以及整个行业的发展趋势,Elastic 技术社区、阿里巴巴 Elasticsearch 技术团队和阿里云开发者社区联合首发《Elasticsearch 中国开发者调查报告》。

image.png

本次报告从开发者的职业路径、Elasticsearch 的技术演进、技术社区的发展等三个维度,描绘了开发者群体的轮廓和成长路径。

开发者们的典型画像

90后是 Elasticsearch 技术兴起的中坚力量,6成以上开源贡献者管理着TB或PB级的海量数据。

image.png

技术入门进阶之路

从入门到进阶,资深专家的第一手技术指南。

image.png

Elasticsearch 的实践应用TOP5

信息检索和日志分析占实际应用场景的大壁江山,业务数据分析、数据库加速、运维指标监控三者平分秋色。

image.png

大厂的最佳实践

18位资深专家分享在 Elasticsearch 技术领域的案例干货。

image.png

Elastic 技术社区的建设经验

30多场线下活动,触达5000多人次,技术社区如何培育发展?

image.png

Elasticsearch 因轻量级、稳定、可靠、快速等特性成为越来越多开发者的选择,本报告将为从业者们提供更多关于职业、行业以及技术应用的参照依据,一览开发者的现状和未来。

关于本次调查的详细数据分析、案例经验和行业前瞻,请下载《Elasticsearch 中国开发者调查报告》并详细阅读报告全文。

]]>
实战课堂 | 让大数据分析更简单,4步教你玩转MongoDB BI Connector Mon, 16 Dec 2019 05:35:03 +0800 MongoDB使用BI Connector支持BI组件直接使用SQL或ODBC数据源方式直接访问MongoDB,在早期MongoDB直接使用Postgresql FDW实现 SQL到MQL的转换,后来实现更加轻量级的mongosqld支持BI工具的连接。

e411f1b8264781f0e6fcccc1d60ecaf3c8ea61ae.png

安装 BI Connector

参考 Install BI Connector
https://docs.mongodb.com/bi-connector/master/installation/

wget https://info-mongodb-com.s3.amazonaws.com/mongodb-bi/v2/mongodb-bi-linux-x86_64-rhel70-v2.12.0.tgz

$tar xvf mongodb-bi-linux-x86_64-rhel70-v2.12.0.tgz
mongodb-bi-linux-x86_64-rhel70-v2.12.0/LICENSE
mongodb-bi-linux-x86_64-rhel70-v2.12.0/README
mongodb-bi-linux-x86_64-rhel70-v2.12.0/THIRD-PARTY-NOTICES
mongodb-bi-linux-x86_64-rhel70-v2.12.0/example-mongosqld-config.yml
mongodb-bi-linux-x86_64-rhel70-v2.12.0/bin/mongosqld
mongodb-bi-linux-x86_64-rhel70-v2.12.0/bin/mongodrdl
mongodb-bi-linux-x86_64-rhel70-v2.12.0/bin/mongotranslate
  • mongosqld 接受 SQL 查询,并将请求发到 MongoDB Server,是 BI Connector 的核心
  • mongodrdl 工具生成数据库 schema 信息,用于服务 BI SQL 查询
  • mongotranslate 工具将 SQL 查询转换为 MongoDB Aggregation Pipeline

启动 mongosqld

参考 Lauch BI Connector
https://docs.mongodb.com/bi-connector/current/launch/

mongodb-bi-linux-x86_64-rhel70-v2.12.0/bin/mongosqld --addr 127.0.0.1:3307 --mongo-uri 127.0.0.1:9555

--addr 指定 mongosqld 监听的地址
--mongo-uri 指定连接的 MongoDB Server 地址
默认情况下,mongosqld 自动会分析目标 MongoDB Server 里数据的 Schema,并缓存在内存,我们也可以直接在启动时指定 schema 影射关系。schema 也可以直接 mongodrdl 工具来生成,指定集合,可以将集合里的字段 shema 信息导出。

$./bin/mongodrdl --uri=mongodb://127.0.0.1:9555/test -c coll01
schema:
- db: test
  tables:
  - table: coll01
    collection: coll01
    pipeline: []
    columns:
    - Name: _id
      MongoType: float64
      SqlName: _id
      SqlType: float
    - Name: qty
      MongoType: float64
      SqlName: qty
      SqlType: float
    - Name: type
      MongoType: string
      SqlName: type
      SqlType: varchar

使用 MySQL 客户端连接 mongosqld

mongosqld 可直接支持 MySQL 客户端访问,还可以通过 Excel、Access、Tableau等BI工具连接
https://docs.mongodb.com/bi-connector/current/client-applications/

mysql --protocol=tcp --port=3307

mysql> use test
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| coll           |
| coll01         |
| coll02         |
| inventory      |
| myCollection   |
| yourCollection |
+----------------+
6 rows in set (0.00 sec)

mysql> select * from coll01;
+------+------+--------+
| _id  | qty  | type   |
+------+------+--------+
|    1 |    5 | apple  |
|    2 |   10 | orange |
|    3 |   15 | banana |
+------+------+--------+
3 rows in set (0.00 sec)

// 对照 MongoDB 数据库里的原始数据

mongo --port
mymongo:PRIMARY> use test
switched to db test
mymongo:PRIMARY> show tables;
coll
coll01
coll02
inventory
myCollection
yourCollection
mymongo:PRIMARY> db.coll01.find()
{ "_id" : 1, "type" : "apple", "qty" : 5 }
{ "_id" : 2, "type" : "orange", "qty" : 10 }
{ "_id" : 3, "type" : "banana", "qty" : 15 }

SQL 转 Aggregation

比如要将针对 test.coll01 的 SQL 查询转换为 MongoDB Aggregation Pipeline,需要先通过 mongodrdl 分析 schema,然后使用 mongotranslate 工具来转换

// 导出分析的 shema 文件
$./bin/mongodrdl --uri=mongodb://127.0.0.1:9555/test -c coll01 > coll01.schema  

// SQL 转换为 Aggregation
$./bin/mongotranslate --query "select * from test.coll01" --schema coll01.schema
[
    {"$project": {"test_DOT_coll01_DOT__id": "$_id","test_DOT_coll01_DOT_qty": "$qty","test_DOT_coll01_DOT_type": "$type","_id": NumberInt("0")}},
]
]]>
在线教育场景下的点播试看功能实现 Mon, 16 Dec 2019 05:35:03 +0800 业务场景

在线教育场景下,提供视频课程给用户试看一段时间(如前5分钟),用户试看完后如果要继续观看,需要付费购买。

业务流程

|center|500x400

  1. 客户端到应用后台请求试看地址
  2. 应用后台请求阿里云点播服务,获取视频试看地址
  3. 阿里云点播服务返回试看地址
  4. 应用后台返回试看地址给客户端播放
  5. 客户端通过试看地址播放

使用步骤

  • 点播域名开启试看功能
    登陆点播控制台,配置管理-分发加速配置-域名管理-配置(对应域名处)-访问控制-URL鉴权中,开启A方式鉴权,同时,勾选”支持试看”选项。

|center|500x400

  • 试看地址获取
    调用 获取播放地址接口 ,通过参数 PlayConfig 结构中的 PreviewTime 来获取指定时长的播放试看地址。示例代码:
from aliyunsdkvod.request.v20170321 import GetPlayInfoRequest
from aliyunsdkcore import client

access_key_id = "your access_key_id"
access_key_secret = "your access_key_secret"
region = "cn-shanghai"
videoId = "your videoId"

def GetPreviewURL(clt):
    request = GetPlayInfoRequest.GetPlayInfoRequest()
    request.set_VideoId(videoId)
    #设置set_PlayConfig参数指定试看时长为15秒    
    request.set_PlayConfig('{"PreviewTime":"15"}')
    request.set_accept_format('JSON')
    response = clt.do_action(request)
    return response

clt = client.AcsClient(access_key_id, access_key_secret, region)
print GetPreviewURL(clt)

​​|center|500x400

注意事项

试看的基本原理是,播放的CDN加速地址带有试看的指定时长信息,云端会对该信息进行鉴权,鉴权通过会返回指定的文件内容,否则拒绝访问、返回403。

  1. 点播试看功能基于阿里云CDN加速实现,且必须在视频点播(VOD)控制台配置CDN加速域名。
  2. 此方案必须开启A鉴权,同时,为了防止试看参数被篡改,试看参数也作为auth_key计算的一部分。
  3. 域名必须开启 range回源 和 拖拽播放。具体可在域名管理-配置(对应域名处)-视频相关处开启。
]]>
DataV数据可视化-基础版下线公告! Mon, 16 Dec 2019 05:35:03 +0800 温馨提醒:

亲爱的会员,DataV基础版将在12月12号0点后停止新购。
如果您现在使用基础版,请务必在服务到期前续费;如您没有按时续费,将导致后期无法购买和使用基础版。
如果您需要基础版但是现在没有购买,请务必在12月12号0点之前进行新购,否则后期无法购买。
给您造成不便,请您谅解!


DataV还有多个版本供您选择:

DataV企业版(原价6千/年-双12专享7折)
具有较多的数据展示组件,能够极大的丰富数据呈现的多样性,并且支持更多种类的数据来源,适合对数据呈现方式有较高要求、对数据安全性有要求的用户,特别适用于企业级业务分析、数据监控看板等场景。案例如下:

全球贸易案例-企业版.gif

DataV专业版(原价3W/年-双12专享7折)
增加了可交互的特性,可以不受任何限制的开发自定义组件,具有极高的自由度,能够完成复杂的数据可视化应用搭建,对地图数据具有更强的呈现能力,小部分功能需要用户具有一定的专业技术能力,适合对展示效果有较高要求、数据敏感度高、需要快速、自由搭建可交互的可视化数据看板的专业用户使用,特别适用于企业形象展示、对高层领导做业务汇报、企业级项目交付等场景。案例如下:

学区房案例-专业版.gif

购买链接:https://common-buy.aliyun.com/?spm=5176.2020520107.105.2.tqlPtv&commodityCode=datav#/buy

]]>
Service Mesh 是新瓶装旧酒吗? Mon, 16 Dec 2019 05:35:03 +0800 点击下载《不一样的 双11 技术:阿里巴巴经济体云原生实践》

ban.jpg

本文节选自《不一样的 双11 技术:阿里巴巴经济体云原生实践》一书,点击上方图片即可下载!

作者 | 李云(花名:至简) 阿里云高级技术专家

导读:在即将过去的 2019 年,Service Mesh 开源产品的成熟度虽在全球范围内没有发生质的变化,但在国内仍出现了一些值得特别关注的事件。比如:阿里巴巴在 双11 的部分电商核心应用上落地了完整的 Service Mesh 解决方案,借助 双11 的严苛业务场景完成了规模化落地前的初步技术验证。本文作者将结合自己在阿里巴巴落地实践 Service Mesh 过程中的观察与思考,来和大家进行分享。

Service Mesh 是新瓶装旧酒吗?

新技术出现时所主张的价值一定会引发相应的探讨,Service Mesh 也不例外。

以往,怀疑 Service Mesh 价值的观点主要有两大类。

  • 第一类是应用的数量并没有达到一定的规模,在 Service Mesh 增加运维和部署复杂度的情形下,认为所带来的成本和复杂度高于所获得的收益。

从根本上来看,这一类并非真正怀疑 Service Mesh 的价值,而是主张在 Service Mesh 还没有完全成熟和普及的情形下,在未来合适的时机再考虑采纳。当然,我在与外部客户交流时也碰到一些特例,他们即便在应用数很少的情形下,仍希望通过 Service
Mesh 去解决非 Java 编程语言(比方说 Go)的分布式链路追踪等服务治理问题,虽说这些能力在 Java 领域有相对成熟的解决方案,但在非 Java 领域确实偏少,所以很自然地想到了采用 Service Mesh。

  • 第二类怀疑 Service Mesh 价值的,是应用的数量具有相当的规模且对分布式应用的规模问题也有很好的认知,但由于在发展的过程中已经积累了与 Service Mesh 能力相当的那些(非体系化的)技术,造成初识 Service Mesh 时有“老酒换新瓶”的感觉而不认可其价值。阿里巴巴过去也曾属于这一阵营。

阿里巴巴在分布式应用的开发和治理方面的整体解决方案的探索有超过十年的历程,且探索过程持续地通过 双11 这样的严苛场景做检验和孵化,采用单一的 Java 语言打造了一整套的技术。即便如此,应对分布式应用的规模问题依然不轻松,体现于因为缺乏顶层设计而面临体系性不足,加之对技术产品自身的用户体验缺乏重视,最终导致运维成本和技术门槛都偏高。在面临这些阵痛之际,云原生的概念逐渐清晰地浮出了水面。

云原生主张技术产品在最为严苛的场景下仍能提供一定质量的服务而体现良好弹性,同时也强调技术产品本身应当具有良好的易用性,以及将来为企业需要多云和混合云的 IT 基础设施提供支撑(即:帮助实现分布式应用的可移植性)。

云原生的概念不仅很好地契合了阿里巴巴集团在技术发展上亟待解决的阵痛,也迎合了阿里巴巴将云计算作为集团战略、让云计算普惠社会的初衷。在这一背景下,阿里巴巴做出了全面云原生化的决定,Service Mesh 作为云原生概念中的关键技术之一,当然也包含在其中。

Service Mesh 给阿里巴巴带来的价值

Service Mesh 所带来的第一个变化体现于:服务治理手段从过去的框架思维向平台思维转变。

这种转变并非后者否定前者,而是前后者相结合去更好地发挥各自的优势。两种思维的最大区别在于,平台思维不仅能实现应用与技术基础设施更好的解耦,也能通过平台的聚集效应让体系化的顶层设计有生发之地。

框架思维向平台思维转变在执行上集中体现于“轻量化”和“下沉”两个动作。

  • 轻量化是指将那些易变的功能从框架的 SDK 中移出,结果是使用了 SDK 的应用变得更轻,免除了因易变功能持续升级所带来的低效;也彻底让应用的开发者无需关心这些功能,让他们能更好地聚焦于业务逻辑本身;
  • 从框架中移出的功能放到了 Service Mesh 的 Sidecar 中实现了功能下沉。

Service Mesh 作为平台性技术,将由云厂商去运维和提供相应的产品,通过开源所构建的全球事实标准一旦被所有云厂商采纳并实现产品化输出,那时应用的可移植性问题就能水到渠成地解决。

功能下沉在阿里巴巴落地 Service Mesh 的过程中也看到了相应的价值。阿里巴巴的电商核心应用基本上都是用 Java 构建的,在 Mesh 化之前,RPC 的服务发现与路由是在 SDK 中完成的,为了保证 双11 这样的流量洪峰场景下的消费者用户体验,会通过预案对服务地址的变更推送做降级,避免因为频繁推送而造成应用进程出现 Full GC。Mesh 化之后,SDK 的那些功能被放到了 Sidecar(开发语言是 C++)这一独立进程中,这使得 Java 应用进程完全不会出现类似场景下的 Full GC 问题。

软件设计的质量主要体现在“概念”和“关系”两个词上。

同样功能的一个系统,不同的概念塑造与切分将产生完全不同的设计成果,甚至影响到最终软件产品的工程质量与效率。当概念确定后,关系也随之确立,而关系的质量水平体现在解耦的程度上。Service Mesh 使得应用与技术基础设施之间的关系变得更松且稳定,通过流量无损的热升级方案,使得应用与技术基础设施的演进变得独立,从而加速各自的演进效率。软件不成熟、不完善并不可怕,可怕的是演进起来太慢、包袱太重。

阿里巴巴在落地 Service Mesh 的过程中,体会到了松耦合所带来的巨大工程价值。当应用被 Mesh 化后,接下来的技术基础设施的升级对之就透明了,之前因为升级工作所需的人力配合问题可以通过技术产品化的手段完全释放。另外,以往应用进程中包含了业务逻辑和基础技术的功能,不容易讲清楚各自对计算资源的消耗,Service Mesh 通过独立进程的方式让这一问题得以更好地隔离而实现量化,有了量化结果才能更好地对技术做优化。

Service Mesh 所带来的第二个变化在于:技术平台的建设从面向单一编程语言向面向多编程语言转变。

对于初创或小规模企业来说,业务应用的开发采用单一的编程语言具有明显优势,体现于因为个体掌握的技术栈相同而能带来良好的协作效率,但当企业的发展进入了多元化、跨领域、规模更大的更高阶段时,多编程语言的诉求就随之产生,对于阿里巴巴这样的云厂商来说更是如此(所提供的云产品不可能过度约束客户所使用的编程语言)。多编程语言诉求的背后是每种编程语言都有自己的优势和适用范围,需要发挥各自的优势去加速探索与创新。
 
从技术层面,这一转变意味着:

  • 第一,技术平台的能力需要尽可能地服务化,避免因为服务化不彻底而需要引入 SDK,进而带来多编程语言问题(即因为没有相应编程语言的 SDK 而无法使用该编程语言);
  • 第二,在无法规避 SDK 的情形下,让 SDK 变得足够的轻且功能稳定,降低平台化和多编程语言化的工程成本,支持多编程语言 SDK 最好的手段是采用 IDL。

从组织层面,这一转变意味着平台技术团队的人员技能需要多编程语言化。一个只有单一编程语言的团队是很难做好面向多编程语言的技术平台的,不只是因为视角单一,还因为无法“吃自己的狗食”而对多编程语言问题有切肤之痛。

Service Mesh 带来的发展机遇

在这两个变化之下,我们来聊一聊 Service Mesh 所带来的发展机遇。

  • 首先,Service Mesh 创造了一次以开发者为中心去打造面向未来的分布式应用开发平台的机会。

在 Service Mesh 出现之前,各种分布式服务治理技术产品的发展,缺乏强有力的抓手去横向拉通做体系化设计和完成能力复用,因而难免出现概念抽象不一致和重新造轮子的局面,最终每个技术产品有自己的一套概念和独立的运维控制台。当多个运维控制台交到开发者手上时,他们需要做大量的学习,去理解每个运维控制台的概念以及它们之间的关系,背后所带来的困难和低效是很容易被人忽视的。

本质上,Service Mesh 的出现是解决微服务软件架构之下那些藏在应用与应用之间的复杂度的。它的出现使得所有的分布式应用的治理问题被放到了一起去考虑。换句话说,因为 Service Mesh 的出现,我们有机会就分布式应用的治理做一次全局的设计,也有机会将各种技术产品整合到一起而避免重复建设的问题。

未来的分布式应用开发平台一定是基于 Service Mesh 这一基础技术的。为此,需要借这个契机从易用性的角度重新梳理应给开发者塑造的心智。易用性心智的确立,将使得开发者能在一个运维控制台上做最少的操作,通过为他们屏蔽背后的技术实现细节,而减轻他们在使用时的脑力负担,以及降低操作失误带来安全生产事故的可能性。

理论上,没有 Service Mesh 之前这些工作也能做,但因为没有具体的横向技术做抓手而无法落地。

  • 其次,Service Mesh 给其他技术产品创造了重新思考云原生时代的发展机会。

有了 Service Mesh 后,以前很多独立的技术产品(比如,服务注册中心、消息系统、配置中心)将变成 BaaS(Backend as a Service)服务,由 Service Mesh 的 Sidecar 负责与它们对接,应用对这些服务的访问通过 Sidecar 去完成,甚至有些 BaaS 服务被 Sidecar 终结而完全对应用无感。

这些变化并非弱化了那些 BaaS 服务的重要性。相反,因为其重要性而需要与 Service Mesh 做更好的整合去为应用提供服务,与此同时探索做一定的能力增强。比方说,Service Mesh 所支持的应用版本发布的灰度功能(包括蓝绿发布、金丝雀发布、A/B 测试),并非每一个 BaaS 服务在 Mesh 化后就能很好地支持这一功能,而是需要做相应的技术改造才行。请注意,这里主要讲的是应用的灰度能力,而非 BaaS 服务自身的灰度能力。当然,并不妨碍探索通过 Service Mesh 让 BaaS 服务自身的灰度工作变得简单且低风险。

未来很多技术产品的竞争优势将体现于它能否与 Service Mesh 形成无缝整合。

无缝整合的核心驱动力,源于用户对技术产品的易用性和应用可移植性的需要。基于这一认识,阿里巴巴正在将 RocketMQ/MetaQ 消息系统的客户端中的重逻辑剥离到 Envoy 这一 Sidecar 中(思路依然是“下沉”),同时基于 Service Mesh 所提供的能力做一定的技术改造,以便 RocketMQ/MetaQ 能很好地支撑应用的灰度发布。类似这样的思考与行动,相信未来会在更多的技术产品上出现。

  • 再次,Service Mesh 给技术基础设施如何与业务基础技术更好地协同提供了一次探索机会。

每一种业务(比如电商)都会构建基于所在领域的基础技术,这类技术我们称之为业务基础技术。当阿里巴巴希望将某一业务的基础技术搬到外部去服务客户时,面临业务基础技术如何通过服务化去满足客户已选择的、与业务基础技术不同的编程语言的问题,否则会出现基于 Java 构建的业务基础技术很难与 Go 所编写的应用协同。

在 Service Mesh 致力于解决服务化问题的过程中,能否通过一定的技术手段,让业务基础技术的能力通过插件的形式“长”在 Service Mesh 之上是一个很值得探索的点。当业务基础技术以插件的形式存在时,业务基础技术无需以独立的进程存在而取得更好的性能,且这一机制也能被不同的业务复用。阿里巴巴的 Service
Mesh 技术方案所采用的 Sidecar 开源软件 Envoy 正在积极地探索通过 Wasm 技术去实现流量处理的插件机制,将该机制进一步演变成为业务基础技术插件机制是值得探索的内容。

下图示例说明了业务基础技术的插件机制。

图中两个彩色分别代表了不同的业务(比如一个代表电商,另一个代表物流),两个业务的基础技术并非开发了两个独立的应用(进程)然后做发布和运维管理,而是基于 Wasm 所支持的编程语言实现了业务技术插件,这一点可以理解为用多编程语言的方式解决业务服务化问题,而非强制要求采用与 Sidecar 一样的编程语言。插件通过 Service Mesh 的运维平台进行管理,包含安装、灰度、升级、监控等能力。

至简.png

由于插件是“长”在 Service Mesh 之上的,插件化的过程就是业务技术服务化的过程。

另外,Service Mesh 需要提供一种选择能力,让业务的应用开发者或运维者选择自己的机器上需要哪些插件(可以理解为插件市场)。另一个值得关注的点是:插件的运维和管理能力以及一定的质量保证手段由 Service Mesh 平台提供,但运维、管理和质量保证的责任由各插件的提供者承担。这种划分将有效地杜绝所有插件的质量由 Service Mesh 平台去承担而带来的低效,分而治之仍是改善很多工程效率的良方。

  • 最后,Service Mesh 给探索面向未来的异地多活、应用永远在线的整体技术解决方案打开了一扇大门。

服务之间的互联互通,服务流量的控制、观测和安全加固是微服务软件架构下所要解决的关键问题,这些问题与规模化下的服务可用性和安全性紧密相关。未来,通过 Service Mesh 的流量控制能力能做很多改善应用发布和运维效率的文章,那时才能真正看到一个灵动、称手的云平台。

Service Mesh 的“三位一体”发展思路

阿里巴巴作为云计算技术的供应商,在探索 Service Mesh 技术的道路上,不只是考虑如何让云原生技术红利在阿里巴巴内部兑现,同时还思考着如何将技术红利带给更多的阿里云客户。基于此,阿里巴巴就 Service Mesh 的整体发展思路遵循“三位一体”,即阿里巴巴内部、阿里云上的相应商业产品和开源软件将采用同一套代码。

就我们与阿里云客户交流的经验来看,他们乐于尽最大可能采用非云厂商所特有的技术方案,以免被技术锁定而在未来的发展上出现掣肘。另外,他们只有采纳开源的事实标准软件才有可能达成企业的多云和混合云战略。基于客户的这一诉求,我们在 Service Mesh 的技术发展上特别重视参与开源事实标准的共建。在 Istio 和 Envoy 两个开源项目上,我们都会致力于将内部所做的那些优化反哺给开源社区。

未来,我们将在 Service Mesh 领域坚定而扎实地探索,也一定会将探索成果和思考持续地分享给大家。

ban.jpg

本书亮点

  • 双11 超大规模 K8s 集群实践中,遇到的问题及解决方法详述
  • 云原生化最佳组合:Kubernetes+容器+神龙,实现核心系统 100% 上云的技术细节
  • 双 11 Service Mesh 超大规模落地解决方案

阿里巴巴云原生微信公众号(ID:Alicloudnative)关注微服务、Serverless、容器、Service Mesh等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术公众号。”

]]>
Knative Serverless 之道:如何 0 运维、低成本实现应用托管? Mon, 16 Dec 2019 05:35:03 +0800 作者 | 牛秋霖(冬岛)  阿里云容器平台技术专家

关注“阿里巴巴云原生”公众号,回复关键词“1205”即可观看 Knative-Demo 演示视频。

导读:Serverless 无疑是当前最热的云原生话题,那么作为业务的开发人员或者运维人员咱们应该怎么看待这个事情?云原生和 Serverless 到底有什么关系?通过本次分享咱们将逐一揭开这些神秘的面纱。

通过本文您将了解到:

  1. Knative 是如何让普通的应用具备 Serverless 能力的?
  2. 为什么说 Knative 是云原生的应用 Serverless 编排引擎?
  3. Knative 为什么是由 Tekton 、Eventing 和 Serving 三个模块组成,以及这三个模块的协作方式。

本文共有四部分内容:首先咱们一起来看一下云的核心驱动力是什么,接着从这个核心驱动力出发看一下云原生应用是什么样子。然后咱们再一起来看看 Knative 到底给应用的云原生化带来了什么价值,最后咱们通过一个 Demo 亲身感受一下 Knative 带来的这些能力。

云的核心驱动力

在讨论云原生之前我们先来思考一下:为什么企业要上云、为什么技术人员要学习面向云的编程思维以及咱们应该怎么看待云这件事儿。

咱们先来剖析一下发生这些事情的核心驱动力,然后通过这个核心驱动力出发看看整个云原生技术栈是什么样子。

社会分工

1.png

我们先从一顿火锅谈起,一顿火锅虽然很简单,但会涉及到非常多的东西,比如各种蔬菜、牛羊肉等。细想一下,所有的这些东西我们都经常食用,但是其中有哪些东西是我们自己亲手种植或养殖的呢?事实上都没有,我们每天都是坐在办公室,下班的路上到市场或超市买到这些东西,不知道也并不关心这些东西的具体生产过程。

我小时候在内蒙的农村长大,大家都知道,内蒙很大。村里每户人家都有一个大园子,夏天的时候家家户户都会在园子里种植各种蔬菜,如西红柿、黄瓜、茄子、辣椒等;但到了冬天,由于天气很冷,根本见不到新鲜的蔬菜,大家吃的都是咸菜、酸菜,或者是秋天晾晒的一些干菜。我们可以发现:一个地域非常容易受到季节的影响,虽然夏天可以种植各种蔬菜,但是到了冬天就什么都没有了。但是现在就不同了,全国各地随处都能非常容易地买到新鲜蔬菜,这其实是社会分工的结果、是不同地域、不同角色之间通过市场相互协作的成果。

现在因为有专业的人在做这些事情,所以我们大多数人都无需劳心蔬菜是怎么种植的。而我们工程师所做的和计算机打交道的事情也能通过其他的渠道反过来帮助那些种菜的人。

分工提高效率,这是现代经济学之父亚当斯密 200 多年前在他的经典著作《国富论》中的开篇观点。其实现代社会的运行机制也印证了该理论;我认为它也是企业拥抱云计算的根本原因。因为大家需要把一些非业务核心的部分“承包”给专业的人士去完成,那些和自己的业务强相关的部分才是企业的核心竞争力。

应用上云

2.png

接着咱们再来看看一个应用都是由哪些部分构成的。

应用要提供服务首先要有计算、存储和网络资源才能把进程跑起来。当然这些也仅仅是把进程跑起来,如果要承接具体的业务还需要依赖数据库等服务;如果要做分布式架构还需要做微服务拆分,这时候就需要缓存、注册中心、消息各种中间件的服务。

以上的情况都是程序已经存在,如何把程序跑起来承接业务的部分。还有一部分是如何把代码变成可启动的程序,这就是 CICD 部分了。从代码到应用启动再到应用依赖的周边系统支撑都说完了,还有一部分就是日常运维相关的:

  • 比如日志收集、分析
  • 比如监控和告警

虽然我们本来只是想要写一个应用,来为业务提供服务。但是应用周边的这些支撑系统比这个应用自身的消耗还要高上很多。这其实不是我们期望的结果,让业务团队更多的聚焦在业务逻辑本身,而不是周边的这些系统上,这才是我们希望看到的。

3.png

实际上有一定规模的公司,内部的组织架构基本也都是由一个基础平台团队和多个业务团队构成的,基础平台团队负责提供这些应用需要的公共能力支撑,业务团队更聚焦在业务上,直接使用基础平台团队的能力即可。这其实就是社会分工在 IT 组织中的体现,专业的人做专业的事儿,分工提升效率。

现在我们再回顾一下刚才吃火锅的例子。

如果时间倒退 20 年,回到北方的冬天,我们想要吃一顿有肉、有蔬菜、还有金针菇的火锅,根本就不可能,但是现在,我们可以随时随地买到这些东西,而所有这些都是专业的人士生产的,我们无法自给自足这么丰富的资源。

那么对于一家企业而言,也是一样的。虽然每个企业都有自己的基础平台团队,但是由于规模或者资金投入等原因,不可能提供像云这么丰富的平台支撑。如果有,那一定也是一个云厂商。所以对于业务来说,把所有和应用相关的周边系统都使用云的初始设施搭建,把这些周边系统承包给云厂商才是高效率的做法。我理解为这就是云原生出现的背景。

分工提高效率这是大家使用云的根本动力。云原生理念是在各大企业上云的过程中逐渐形成和完善的。这套理念是协调所有参与方对服务上云逐渐形成的统一标准,这个统一的标准可以很好地帮助企业上云、帮助云厂商释放云的能力。从云的客户角度来讲,这个统一标准就是避免云厂商锁定。比如 Kubernetes 就是一个非常好的统一共识,因为所有云平台都支持 Kubernetes。

4.png

那么这个标准的价值是什么呢?为什么云厂商和上云的企业都积极参与这个标准的“制定”呢?这其实是一个互利互惠的结果。在具体谈论这个标准的作用之前,我们先来聊聊两种资源分配模式的差别。

排队(先到先得)

这部分咱们以就医为例进行说明。

去医院看病需要提前挂号,医生的号源这是一种先到先得的资源分配方式。特别是在北上广这些大城市,好医生的号源更是一号难求。如果想保证一定要拿到某个医生的就诊号,就要保证比别人都更早地到医院排队,提前排队可以优先拿到就诊号。我们现在来分析一下,提前排队的人所付出的努力都有什么价值。

  • 对于排队的当事人:当事人付出的努力对于自己是有意义的,自己拿到了就诊号,得到