FreshRSS

🔒
❌ 关于 FreshRSS
发现新文章,点击刷新页面。
今天 — 2022年1月28日编程开发

龙蜥LoongArch GA版正式发布,支持图形界面和多种安装场景

2022年1月28日 10:02
作者 凌敏

1月28日消息,龙蜥 LoongArch GA版正式发布,成为全球首款支持龙芯 LoongArch 架构的同源异构服务器操作系统。

据悉,龙蜥 LoongArch GA版(正式版本)基于 Anolis OS 8.4 版本对 LoongArch 架构提供支持,在Anolis OS LoongArch 预览版的基础上提供了 AppStream、PowerTools 等仓库的支持。

LoongArch®是龙芯中科基于二十年CPU研制和生态经验积累推出的指令系统,包括基础架构部分和向量指令、虚拟化、二进制翻译等扩展部分,有近 2000 条指令。

具体来说,龙蜥LoongArch GA版发布产品包括 ISO、软件仓库、虚拟机镜像、容器镜像。

ISO列表:

LoongArch64架构的安装 ISO 镜像

https://mirrors.openanolis.cn/anolis/8.4/isos/GA/loongarch64/AnolisOS-8.4-GA-loongarch64-dvd.iso

虚拟机镜像列表:

LoongArch64架构的虚拟机镜像

https://mirrors.openanolis.cn/anolis/8.4/isos/GA/loongarch64/AnolisOS-8.4-GA-loongarch64.qcow2

容器镜像列表:

docker pull openanolis/anolisos:8.4-loongarch64

软件仓库列表:

https://mirrors.openanolis.cn/anolis/8.4/BaseOS/loongarch64/os/

https://mirrors.openanolis.cn/anolis/8.4/AppStream/loongarch64/os/

https://mirrors.openanolis.cn/anolis/8.4/PowerTools/loongarch64/os/

龙蜥LoongArch GA版主要有以下几个亮点:

龙芯内核更新到 Linux 4.19.190-4内核版本,适配了部分X86、Arm内核功能,整体稳定性与预期相符,经过功能、性能以及压力等多项测试,质量可靠;修复了 libxcrypt 以及相应的依赖问题;支持图形界面和多种安装场景;使用 docker-ce 20.10.3 为默认的容器管理工具;使用 lbrowser 浏览器和 evolution 邮件客户端,其中,lbrowser 基于 chromium 内核开发,支持 npapi 插件功能,支持国家商用密码算法模块和国产安全协议模块,可修复目前已知所有安全漏洞。

据悉,该版本已上线,可在龙蜥社区官网(https://openanolis.cn/download)下载体验。龙芯中科副总裁、龙蜥社区理事高翔表示,龙蜥 LoongArch GA版的发布,将助推操作系统生态进一步繁荣。

公开信息显示,2021 年,龙蜥社区正式成立 LoongArch SIG(Special Interest Group 特别兴趣小组),为龙蜥操作系统(Anolis OS)提供基于LoongArch芯片的超高性能的支持,助力龙芯生态建设。

2021 年 8 月,LoongArch SIG完成社区LoongArch构建系统支撑;10 月,完成LoongArch龙蜥操作系统预览版本镜像,同月发布龙蜥 LoongArch 预览版,并完成了所有 CVE 致命漏洞修补。

用了五年 VS Code ,我决定换成 JetBrains...

2022年1月28日 08:43
作者 Jeremy Liu

本文最初发布于 Blankly 上,经原作者授权由 InfoQ 中文站翻译并分享。

在编程中,VS Code 作为我的主 IDE 长达 5 年之久。在这个时间点上我决定换掉它,这可能会令人无法理解。本文我将和大家分享我做这个决定的原因。

背景

愿意的话你也可以说我是疯子。你可能会认为,一个用了 VS Code 长达 5 年的人,一定是疯了才会想在此时换掉它。的确,在我接触 JetBrains 生态之前,也是这么认为的。我甚至愿用我的性命证明 VS Code 是目前市场上最好的 IDE,它就如同 PC 行业中的苹果 M1 芯片电脑一样。但请允许我先介绍下事情的背景。

我目前在 Blankly 工作,该公司主提供对冲基金云服务。在我们提供的云服务上,人们只需要几分钟即可创建自己的交易算法。我的一个同事 Emerson,他是 JetBrains 生态的铁杆粉丝。在一次日站会上,他为了说服我们去试一下 JetBrains 的生态,甚至不惜延长了会议时间。我为了让会议对于这件事的讨论早点结束(这样站立会也能早点结束),我勉强同意了。然而谁承想,现在我居然在这里写了一篇关于是什么最终说服我愿意放弃一直陪伴我的 IDE 的文章。因此,如果你正好处在纠结选择用什么 IDE 且完全没有考虑 JetBrains 想法,或你对我为什么放弃 VS Code 感兴趣的话,那么,这篇文章非常适合你继续读完。

本文是根据我使用 VS Code 和 JetBrains 的一些切身体会,将从 5 个方面对它们进行的对比分析。并且阐述了一些使用场景中 JetBrains 优势明显的原因。

代码检查和重构

VS Code:快、简单、支撑多语言

首先,任何编程语言在 VS Code 中都可以简单且快速地启动和运行,所以大家也会称它为“编辑器”。因此,VS Code 对于像我这样的全栈工程师来说是最佳选择。无论你是需要频繁在 Python 和 JavaScript 之间切换,还是需要增加一个基于 NextJS 开发的 React App,还是需要在 Ralis 系统上配置 Ruby 环境,这些能力 VS Code 都能很好地支持,并为这些开发语言提供了包括 lingting 在内的一系列开箱即用的功能。即使碰到某个功能没有,那也只需要在其插件市场上搜索一个,找一个具备此功能的插件进行安装即可。

其次,由于有了诸如 Github Copilot,AI-based linting,auto imports 等一系列插件的支撑,VS Code 具备了强大的 linting 能力。在 VS Code 中,无论你什么时候想要什么功能,配置起来都非常容易。很多时候,只是需要敲个结束符,VS Code 就会将你想要的内容提示出来。不过有些时候,人们也会因为这种 linting 能力的失效而崩溃。实际上,我时常陷入试图弄清楚为什么一个标准的 linting 不能工作的困境中。不管是由于我使用 Anaconda 安装的多 python 环境导致,还是由于少了安装包导致,但很多时候我都无法直接得到答案。此外,VS Code 针对 JavaScript 语言的 linting 能力也非常强大,不过它不会对 JavaScript 进行深入的类型检查,庆幸的是,我们可以通过 TypeScript 来解决这个问题。

如图所示,由于我忘记切换 VS Code 中的 Python 环境,所以即使我本地已经通过 pip 安装了相关依赖包,但 VS Code 的 linting 功能依然提示包未找到。

最后,作为一个编辑器,VS Code 在代码重构上表现的确非常出色。它在诸如变量重命名、文件移动和引用自动修改等基础的重构功能上表现得非常棒。但在诸如函数移动、参数重命名、代码抽取等更高级别的重构功能方面,它就显得有些能力不够了。不过,幸运的是,仅仅一些基础的重构功能就足以满足我们日常大部分重构需求。在我使用 VS Code 的五年中,它满足了我遇到的大多数重构场景。

JetBrains:标准、专业、支撑强大

首先,JetBrains 是一个包含了很多不合理初始设置的强大 IDE。在我第一次接触它的时候,为了让代码显示的比较优雅,不得不在设置上大费周章。不过,在两个为不同使用场景设计的 IDE 之间做切换,付出一些学习的时间成本是不可避免的。如果我的一个 POST 请求突然出问题了,我就得打开 PyCharm,看看是不是我后端 API 服务出问题 了;如果在推荐类项目中,我突然对最佳推荐算法有了新的优化思路,我就需要打开 CLion。不过,由于有了智能识别,在打开不同 IDE 的时候,我只需要花点时间练习下将 code . 切换到诸如 webstorm . 和 pycharm. 等其他脚本。

其次,JetBrains 的引擎性能强大。当我将 IDE 都替换为 JetBrains 之后,它强大的引擎性能让我印象深刻。当我在编辑器中看到一些红线警告的时候,我只需要使用快捷键 comman+p 将当前窗口重新加载一次,这些红线警告就会消失,或者会给出一些有用的提示信息。这种简单和快速响应的代码检查,让我在编程时心情愉快。

如上图,只需要一个快捷键,就能看到所有引用的地方。

最后,在重构能力上,JetBrains 功能强大,这也是它真正吸引我的地方。就在上周,在为公司平台构建最后的内测版本期间,为了让组件未来具备更强的扩展性,我重构和新增了一些组件。期间,我大概移动了 200 个组件,在项目编译的时候,没有一次编译异常是由引用错误、非法或未定义组件引起的。然后,在 VS Code 中,我在一个数据结构类的项目中,仅仅重新组织了两个文件就破坏了整个 cpp 代码。为此,我不得不手动修正一些组件导入和函数引用才能使项目正常运行。另外,JetBrains 为了确保我们能有足够多的重构工具,它还提供了诸如安全删除、全局重命名等多种外部工具。

通过 JetBrains 可以很清楚的看到将被重构或重命名的变量的的全部调用以及上下文情况图

JetBrains 生态 IDE 提供的阅读帮助功能

能力对比

总的来说,我认为在代码检查和代码重构上,VS Code 和 JetBrains 两者能力接近。两者都是通过诸如自动代码检查、代码格式化、主题定制等功能,帮助人们更好地进行代码调试和显示。不过,JetBrains 具备优秀的 linting 引擎和无副作用的重构能力,因此,如果代码分解和重构对你和你的工作流程很重要,那么,我推荐你选择 JetBrains。

调试

VS Code:几乎可以调试一切

VS Code 超强的调试能力,归功于其强大的插件支撑。你每次点击 VS Code 左边的运行按钮,VS Code 都会生成一个.vscode 的文件夹,此文件中存放了一个 settings.json 文件,这个文件包含了调试相关的全部配置。对于诸如 Python、JavaScript 等大多数语言来说,使用 VS Code 作为其调试工具是非常方便的。甚至,如果你的环境配置正确无误的话,通过直接点击调试按钮来进行调试会更加便捷。此外,即使是通过修改 settings.json 文件中的配置来改变你当前的调试内容也是非常简单的。不过,如果你用了特定的构建方式或特定平台语言(如:C/C++ 语言),由于需要设置 gcc 和 clang,因而会大幅增加在 VS Code 中进行调试的难度和复杂度,同时设置这类文件的调试配置也会比较费时费力。为了减少这种时间的投入,我尝试将其他项目的 setting.json 文件拷贝到当前项目中,但是效果不理想,我花了很多天的调整,才使当前的项目正常运行。在我的大学(密歇根大学安娜堡分校),为了减少大家在调试配置上耗费的精力,他们就维护了一个通用的 settings.json 文件提供给所有人使用。但是即使这样,人们还是不得不花时间去调整 settings.json 文件。

上图显示了一个为了在 MacOS 上进行 C/C++ 程序调试所需要的最简配置

在实际进行调试的过程中,VS Code 在调试控制台中可以很好地进行调试断点设置、识别变量和添加变量观察者。不过,如果这些功能可以直接在代码面板而不是侧面板上进行设置,那就好更好了。

庆幸的是,插件和多语言支持是 VS Code 的最大优势,这使得人们可以在几分钟,甚至几秒钟内就完成代码调试的设置工作。对一些简单的调试场景,VS Code 的调试能力表现得非常棒。然而当需要调试特殊语言的时候,VS Code 的调试能力往往会难以胜任。同时,我还发现当程序需要用到更大的堆内存的时候,VS Code 的调试器会一直卡到崩溃。

JetBrains:一个调试怪物

相对于 VS Code,JetBrains 在调试方面功能更强。由于 JetBrains 所有系列的 IDE 都是基于配置运行的,因此你可以通过点击调试按钮开始任何一次程序调试。如果想设置全局的调试断点,只需要在编辑器的行号处按下空格键即可,此功能极大得提高了程序调试的体验。此外,JetBrains 系列的 IDE 在整个调试过程中还有很多其他的功能亮点,例如:当进入调试环节,作用域内的所有变量的定义,对于定义者来说都是可见的。这让我们可以很方面的观察当前变量值的变化情况。几天前用 Pycharm 调试程序的过程令我印象深刻。当我在 Pycharm 中运行调试并试图查看数据帧的值时,只要点击数据帧变量并按下 view 作为数据帧,Pycharm 就会在 SciView 中打开数据帧,并显示所有数据帧值和列标题:

上图显示的是运行调试且变量值变化的监控

如上面截图所示,底部的窗口中显示了作用域内的全部值。history_and_returns 的下拉菜单中显示了字典对象的所有属性值以及嵌套在该字典对象中的数据帧。右边的面板中,则和 SciView 一样,显示了已经嵌套在字典中的数据帧。在不设置任何打印语句或堆栈跟踪的情况下,就能如此深入了解代码,对于开发人员来说是非常有用的。试想一下,当所有变量的赋值都被编辑器显示在其旁边时,我们可以很容易找到循环中的逻辑错误、修复因为索引导致的故障甚至做一些更加深入的逻辑推理。

与其他 IDE 的调试器一样,JetBrains 调试器同样提供了诸如下一行、进入某个函数等步进的调试功能。另外,JetBrains 的 Run to Cursor 是一个非常好用的功能,它允许人们通过放置鼠标,就可以如同设置断点一样,起到调试断点的效果。这种可以随时随地设置断点且立即生效的功能,完全我调试代码的方式并且大幅加速了我编程的速度。

能力对比

程序调试是开发人员每天最常做的事情之一。因此我认为,当开发人员选择 IDE 的时候,IDE 是否拥有一个好的调试器是必须考虑的因素。VS Code 和 JetBrains 都提供了非常可靠的调试器,但是我必须说在这方面 JetBrains 比 VS Code 略胜一筹。因为,JetBrains 可以直接在变量声明的边上直接显示变量值,这使得跟踪大量变量的时候会比较容易管理。此外,JetBrains 的调试器更强大、更稳定,它不像 VS Code 调试器那样需要做复杂的设置。因此,结合这些因素,JetBrains 的调试能帮助我们节约更多的调试时间,这也使得 JetBrains 更具吸引力。

集成 Git

VS Code:内置了一个强大的源码控制管理

需要团队协作或在乎代码安全的人都知道 Git 在他们工作流中的重要性。对于任何现代编辑器来说,基于 Git 的版本控制都是不可或缺的功能。VS Code 和 Git 的集成做的非常好,当你打开一个工作目录的时候,它会自动检测这是否为一个 Git 仓库。如果是,那么它就会立即提供诸如 push、pull、commit 等许多固有的 Git 命令。

在 VS Code 的 Git 面板中,人们可以清楚的看到哪些些文件做了修改,且轻松完成同步。同时,在面板中,也可以创建分支、克隆仓库。VS Code 总能清楚的告诉你该怎么做,这也是我喜欢它的一个原因。当它检测到了文件修改,就会立即提示你提交,并且在提交的时候会提示你需呀附带上提交说明。此外,在提交的时候,它还会对本地分支和远程分支进行检测和同步。与此同时,它还提供了非常稳定的变基功能。

在行内可以清楚的看到哪里需要做冲突合并

合理处理冲突合并的能力,是 VS Code 的一大优势。借助 VS Code 自动提供的冲突解决方案,我可以通过点击按钮来选择使用当前更改还是选择使用传入的更改。这种解决合并冲突的方式,为我节约了很多时间。

JetBrains:再也不需要使用命令行来做源码管理

在全面切换到 JetBrains 之后,我几乎没有碰过我的终端命令行。JetBrains 提供了包括提交、冲突解决、分支切换和分支对比等在内的源码管理等整体功能。从我的体验来看,JetBrains 在源代码控制上比 VS Code 的要好得多。下面我罗列一些使用体验的截图:

在两个分支之间对比某个文件

内置的分支详情展示

详细的 git 日志

能力对比

在 Git 集成上,JetBrains 和 VS Code 都提供了完整且相同的功能。无论你选择哪款 IDE,在源码管理上都有足够的功能支撑。因此这方面不能作为选择 IDE 的考虑因素,只是个人喜好不同而已。例如,在解决合并冲突的时候,相对于 VS Code 将冲突文件堆在一个文件中显示的方式,我更喜欢 JetBrains 将冲突文件分开显示的方式。

扩展性

VS Code:丰富的扩展性

VS Code 是最具扩展性的编辑器之一,而且集成能力和可扩展性是它的核心功能。在众多扩展能力中,Python 扩展、远程开发扩展以及一些智能感知驱动的扩展是目前最热门的。此外,VS Code 也有一些很酷的功能,例如通过 Prettier 进行代码格式化,通过图标和代码编辑器主题进行主题定制等。VS Code 提供的每个事项或功能特性都是完全可扩展的,同时扩展的本身也可能是增强扩展能力的过程。

对远程 docker 容器的支持,是我最喜欢的一个 VS Code 扩展能力。通过此功能,用户可以在 VS Code 中在 docker 容器内部进行远程编程。如果你本地或远程环境安装了 docker,那么在 VS Code 中你就可以轻松的运行你的代码以及完成所有之前需要在 docker 中才能完成的事情。想要一些更有趣的东西?通过 SSH 进行远程开发怎么样?微软开发的扩展插件就允许人们在 VS Code 中通过远程 SSH 进入到服务端开发环境,如同本地一样进行远程开发。在 VS Code 中想要集成这些功能,只需要简单点击安装一下,就可以成功运行,所有的这些功能,成就了 VS Code 的伟大。

JetBrains:集成生态

对于 JetBrains 来说,可扩展性并不是它需要突出的一个点,因为你会发现绝大部分你需要的功能都会随着的 IDE 版本的发布而发布。为某种语言安装一款强大的 IDE 的好处是,当我们需要某些新功能的时候可能只需要升级下 IDE 版本就拥有了,而无需去扩展市场进行寻找。

例如,JetBrains 针对 docker 提供了强大内置支撑。仅通过指定一个诸如 Dockerfile 的配置类型文件,所有的 JetBrains 的 IDE 都会通过一个易用的 GUI 提供对所有参数、名称、标签、端口以及环境变量的完整控制。在运行的时候,IDE 通过集成 docker,为你提供 docker 的构建日志、运行日志、环境变量以及可视化的集成配置信息:

在集成 FastAPI、Flask、shell 等第三方能力上,JetBrains 提供了和集成 docker 一样的能力。

此外,JetBrains IDE 也有一个丰富的插件生态系统。例如,我可以为支持 Verilog 和 Matlab 分别安装特定的插件。不过有趣的是,这些轻量级的插件,居然比本地安装的 Matlab 和 Quartus(Verilog 的开发环境)环境提供了更好的编程体验。

能力对比

毫无疑问,两者在扩展或插件上都有广泛的社区和市场的支撑。两款 IDE 在功能上各有千秋。两款编辑器之间互缺的功能,你可能希望他们各自丰富起来。不过,VS Code 的社区稍微大些,因而拥有更多的扩展和一些诸如远程容器扩展之类的能力,这样使我们迭代的速度更快。因此,如果你日常工作中对诸如 Docker 的定制扩展有比较多的需求,那么 VS Code 可以说是你的专属 IDE 了。

协作能力

VS Code:基于插件实现实时共享

虽然 VS Code 自身没有内置的实时共享功能,但微软为其开发了一个具备此功能的插件。除此之外,现在,人们甚至可以直接通过使用浏览器访问 vscode.dev 进行实时共享。这种需求实现的多样性,正是 VS Code 如此受欢迎的原因。只要你有良好的网络环境,实时共享的体验就会很好。在实时共享的过程中,人们可以如同面对面一样的进行结伴协同工作。同时,在源码控制上,VS Code 还会时时追踪那些帮助作者提交代码的人。这些让我们看到了在 VS Code 中开启实时共享功能是如此的简单。因此,在我看来,VS Code 在实时共享功能上比市面上任何其他的 IDE 和编辑器都要优秀。

不过在使用 VS Code 的实时共享功能,还是有些需要注意的地方。下面我举一个在 Vue.js 项目中使用实时共享功能的例子。在实时共享 Vue 代码时,包括 Vetur(Vetur 是 Vue 可视化的重要插件)在内的部分插件是不会被共享的。这种缺陷,时常会令人们陷入困境和烦躁中。不过还好,这样的缺陷,只会影响到某些特定的用户(如本例中,就只会影响 Vue 的用户)。另外,最令我厌恨的是,在实时共享中,撤销功能居然是绑定到了机器上而不是当前用户上,这导致我的撤销功能会在本地和远程之间发生混乱。

JetBrains:安全、分布式

所有 JetBrains 生态的 IDE 在代码共享和在线协同的功能上,都提供了非常多的设置项。这些设置项根据不同的安全等级而有所不同。我最近发现一个令人印象深刻的能力是,通过 projector(投影)技术,可以在 docker 容器中运行任何 JetBrains 的 IDE,这使得我可以连接到一个基于云服务运行的 JetBrains 的 IDE 上,同时在浏览器中使用完整的 JetBrains 的 IDE 的功能进行编码。因此现在,我可以仅凭一个密码,通过使用一个 headless 的服务,就可以随时随地的安全的进行编码。这还只是 JetBrains 众多共享配置中的一个。

在所有的 JetBrains 的 IDE 中,通过 Code With Me 进行实时共享是主流方式。这种方式使得你可以在本地 IDE 中直接查看其他人的项目。与此同时,你还可以如同使用本地开发环境一样,使用其他人的开发环境运行项目。一个印象深刻的场景是,我的一个团队成员,遇到了一个 python 的问题,他通过 Code With Me 向我发起了一个代码实时共享,我通过此共享,在我自己的 IDE 中,如同本地一样的使用他的配置,经过代码的调试,我很轻松的帮助他解决了这个问题。

各种不同优秀的共享 IDE 的方案,在尝试提高安全、协作能力或分布式团队如何协同工作上的表现是令人惊讶的。

能力对比

如果是在两年前,我可能会认为实时共享功能无足轻重。事实上,两年前我甚至都不知道 IDE 中有代码协同的功能。因为在两年前,当我们需要协同工作的时候,根本不会通过 IDE 发起远程协作,而是直接坐到同一台机器前。但是现在受到新冠疫情的影响,这种面对面的协同工作已经是种奢望且变得极为困难。正因如此,两款 IDE 在实时代码共享上都做了强力的支撑。但是,由于 VS Code 中撤销功能的问题,因此我极力推荐 JetBrains。而且,视频和音频通话的支持和用户间 Git 的追踪能力都是同样重要。

总结

除了上面列出的 5 方面对比之外,我也知道,相对于 VS Code 的完全免费,JetBrains 对于非学生的用户的需要收取一定的费用,这或许也是导致很多人不考虑 JetBrains 的原因之一。但是,对我而言,在使用 JetBrains 生态的几个月的时间里,它给我带来了非常不错的体验。而且,我已经迫不及待的希望在工作中更多的去使用它们了。因此,我希望即使 JetBrains 需要花费一些费用,你也可以考虑一下它。

原文链接:

https://blankly.finance/vscode-vs-jetbrains/

作者介绍:

Jeremy Liu 是一名全栈工程师,目前就职于 Blankly,担任首席工程师。

建一座国际连锁“商场”:openEuler的雄心与蓝图 | 开源访谈《源创者说》首播

2022年1月28日 08:21

​访谈者:马玮,SegmentFault 思否技术编辑

受访者:熊伟

熊伟,南开大学毕业,工学博士,曾在TurboLinux、WindRiver等公司参与操作系统研发。2014年加入华为,现为2012实验室中央软件院服务器操作系统首席架构师,openEuler技术委员会委员,openEuler社区主要创建人之一,当选“2020中国开源杰出贡献人物”。


2010年左右,华为开始研发EulerOS操作系统。经过长达十年的打磨,EulerOS在华为内部已经成熟并大规模应用。操作系统作为IT基础设施的底座,是数字世界的重要基础设施,发挥着承上启下的重要作用。为了和产业界的伙伴们共建这一基础设施,华为在2019年决定将EulerOS开源,命名为openEuler,与行业伙伴共同构筑共建,共享,共治的全面数字基础设施。

https://www.bilibili.com/vide...

从操作系统到数字基础设施,openEuler打造多元开放生态

相对于传统意义上的“软件”而言,操作系统更类似于一个平台系统,向用户提供各种满足多样性需求的各种软件。正因如此,熊伟认为“构建openEuler的过程很类似建设一座大型连锁商场,商场的价值不在于商场本身,而在于内部丰富多彩的服务,比如餐饮、娱乐、电影等等,这些异彩纷呈的服务才使得商场成为大家都喜欢去的一个场所。类比一下,openEuler这样的操作系统平台的重要性也在于其上各种丰富多彩的软硬件系统,openEuler的目标就是不断吸纳各种厂商入驻,不断推出各种服务,不断丰富操作系统的应用,同时不断吸纳各种用户,在用户的持续反馈中不断改进自己,从而最终建立起一个完整的产业生态系统。”

如今,数字基础设施正在向万物互联的方向发展,云、边缘、IoT等场景成为了openEuler的新战场。与以往不同的是,这些新的场景需要面对更加开放、多种硬件平台和架构、更注重端云协作的生态需求。熊伟认为未来openEuler需要对社区的组织形式,整体的技术架构进行全面升级,以满足社区规模不断扩大所带来的挑战,并将操作系统架构从注重服务器,云等场景扩展到IoT、嵌入式,边缘计算等新的场景。

“openEuler作为数字基础设施,形式将会更加开放,吸纳更多厂商、用户与开发者参与其中,共同将openEuler真正构建成为数字世界的底座”,熊伟对于openEuler的未来充满信心。

面对不同的应用场景,openEuler不光提供Linux内核,也针对边缘计算,嵌入式,IoT等场景提供实时性内核等新的选择,为客户提供多种选项,覆盖更为广泛的应用场景,这是openEuler区别于传统操作系统的重要特征。

通过多内核支持,不但使得openEuler能覆盖更多的业务场景,也有利于不同的场景具有统一的开发视图,归一的开发接口,让软件更易于在不同的系统上进行迁移。做到更好的端侧,边缘侧和云侧的协同,大大提升开发效率。基于openEuler平台,同一份应用程序可以在云、边缘、IoT、车联网、工业园区等众多场景中无缝迁移。这种能力会极大降低开发门槛,为繁荣的应用生态创造基础条件。

熊伟认为,除了openEuler社区中的一些硬核技术,openEuler的核心竞争力还体现在社区的“软”实力上。在熊伟看来,openEuler社区的核心目标并不只是做出一两件软件成品,而是打造一个能够良性循环与可持续发展的组织架构,建立一套完善的流程规范,并持续为行业提供人才输出。当组织,流程,人才这些要素都构建起来以后,并辅之以优秀的社区文化,openEuler一定能持续不断的产出符合市场需求的高水平软件,甚至孵化出世界级的软件。

和一个大型购物中心会带动一个区域的消费繁荣与经济成长类似,openEuler建设起一个良好的运行框架体系后,随之崛起的将不仅是一个操作系统社区,更会是包含软件包、基础库、开发框架,工具链、前端交互系统、后端服务系统、用户反馈与交流系统,多语言支持等一系列功能的庞大集合体。社区将形成一个巨大的公共资源池,在统一的资源池上,结合构建工具,可以做到按照用户的不同需求,定制出不同类型操作系统的能力,推动高水平核心软件技术的探索,成为在全球软件产业举足轻重的力量。

以开源开放赢得合作伙伴认同支持,openEuler快速成长的核心动力

从数字世界的基础设施来讲,软硬件需要更坚实的底座;从全球计算产业迭代升级来讲,需要更符合未来计算需求的新操作系统,操作系统在这个特殊的历史机遇节点上,将肩负着转型的重大使命。事实上,对于openEuler而言,通过代码开源加强横向协作,通过基础软硬件适配、应用适配、整机集成适配等工作加强产业链上下游协作,是逐渐形成体系化的技术和产业生态的关键。

这一过程中,离不开社区参与者的参与。根据公开资料显示,自2019年12月31日开放源代码以来,openEuler已经成为国内最具活力的开源社区,下载超过40万次,2021年商业应用超过100万套。短短两年时间里,openEuler 社区吸引了近万名贡献者、300+家合作伙伴,建立近百个SIG组,放眼全球都是极快的速度。

熊伟深刻意识到,中国IT产业其实并不缺乏开源协作的能量和动力,只是之前缺乏一个有足够号召力的平台。当openEuler这样的平台建立起来后,产业蕴藏的能量就能迅速得以聚集、释放,创造出令人惊叹的成果。

在社区发布的第二个版本openEuler 20.09中,有超过30%的工作来自华为以外企业的贡献。20.09版是中国第一个由不同企业共同协作开发完成的大型操作系统平台,这在整个中国操作系统发展史上都一件具有里程碑意义的事件。感谢行业伙伴对openEuler的巨大热情与贡献,没有这样的共同努力,也就没有openEuler今天的优异成绩与无限潜力。

作为开放的社区,openEuler汇聚了企业,科研院所,高校,兄弟社区,个人爱好者,甚至中学生等各种力量。有些企业在商业上是存在竞争关系的,但在社区里,这些商业上竞争的公司能够坐在一起,共同制定技术标准,共同协作,共同完成产品研发,这为中国企业树立了产业合作最好的样板。众多科研院所,高校能够基于openEuler进行科研,教学,这不光为产学研架起了合作的桥梁,打通了科研和产业的通道,也为产业未来储备了更多的人才。这些伙伴在openEuler中所作的一切,都是在为中国的基础产业添砖加瓦。

在最新的openEuler 20.09版本中,华为的整体贡献量已经降到了百分之五十以下。openEuler已经真正成为了产业伙伴共同打造的公共基础平台,未来这一平台还将汇聚越来越多的伙伴,实现共建,共享,共治的社区践言。

从商场到连锁巨头:openEuler的未来图景

“如果把openEuler比作一家大型连锁商场,那么我最大的期望是openEuler能够实现国际化,成长为覆盖全球的连锁店”。谈到openEuler的未来发展,熊伟如此说到。

有些观点认为,未来的操作系统将演变成一个操作系统,也就是一个操作系统能覆盖所有场景。但熊伟的预测恰恰相反:“随着GPU、TPU,DPU等更多芯片种类,多种架构形式的出现,以及云计算、边缘计算、IoT等更多计算场景的差异化需求,操作系统产业可能会更具多样性,迎来更加丰富、更加多样的新时代。”

在技术演进方面,近年,多样化算力成为了芯片产业的热点, openEuler希望进一步加大多样化算力的技术探索,从系统和工具链底层为多样化算力提供优秀的支持。这种支持反过来还可以激励和支撑芯片产业的发展。

随着社区的进一步发展, openEuler社区需要始终秉持“共建、共享、共治”的理念,聚力打造多样性计算场景操作系统。因此,openEuler社区需要持续优化组织架构,保持良好、健康的生态体系运转,并在这一过程中构建良好的开源流程,建设懂开源、懂基础设施、懂芯片,懂体系架构的人才梯队。

openEuler从建立的开始阶段,就将目光投向了全球,openEuler不光在中国,更希望在全球赢得认可。早在2019年,openEuler就开始尝试在全球的一些地区进行拓展,这也为中国开源社区的国际化做出了自己的贡献。据熊伟介绍,openEuler在22年会加大海外拓展的力度,openEuler也希望和全球的合作伙伴,全球的各种开源社区形成国际化协作,开放共赢,力求在全球范围内逐渐构筑起自身影响力。希望在不远的将来,openEuler能够成为被全球企业所广泛使用的操作系统平台,并成为全球开发者和使用者喜欢的开源社区。欢迎大家加入openEuler社区,去参与,去建设,去分享,发出你们的光和热。


关于华为开源

作为可信赖的开源公民,华为通过持续贡献,携手伙伴,提倡包容、公平、开放和更团结的协作,共建世界级基础软件开源社区,加速行业数字化进程。

· 主流开源组织的积极参与者和支持者。目前华为已是数十个国际开源基金会的顶级/初创会员。

· 规模贡献开源基础软件,夯实数字基础设施生态底座,携手伙伴、开发者共建开源生态。近两年来,面向云原生、自动化和智能化,华为先后开源了KubeEdge、Mindspore、openEuler、openGauss、OpenHarmony等多个平台级基础软件开源项目,成为被全球开发者所接受的开源社区,并在各行业商用落地。

· 积极建设可持续发展、有生命力的可信开源社区。华为致力于完善社区生态治理架构,确保社区持续演进。

关注华为开源公众号,了解更多!

点击【此处】,进入华为开源官网了解更多

Hive底层数据存储格式详解

2022年1月27日 06:23

本文讲解 Hive 的数据存储,是 Hive 操作数据的基础。选择一个合适的底层数据存储文件格式,即使在不改变当前 Hive SQL 的情况下,性能也能得到数量级的提升。这种优化方式对学过 MySQL 等关系型数据库的小伙伴并不陌生,选择不同的数据存储引擎,代表着不同的数据组织方式,对于数据库的表现会有不同的影响。

Hive 数据存储常用的格式如下:

行式存储:文本格式(TextFile)二进制序列化文件 (SequenceFile)列式存储:行列式文件(RCFile)优化的行列式文件(ORCFile)Apache Parquet

注:RCFile 和 ORCFile 并不是纯粹的列式存储,它是先基于行对数据表进行分组(行组),然后对行组进行列式存储

我们看下这几种存储结构的优缺点:

水平的行存储结构:

行存储模式就是把一整行存在一起,包含所有的列,这是最常见的模式。这种结构能很好的适应动态的查询。

比如:select a from tableA 和 select a, b, c, d, e, f, g from tableA这样两个查询其实查询的开销差不多,都需要把所有的行读进来过一遍,拿出需要的列。

而且这种情况下,属于同一行的数据都在同一个 HDFS 块上,重建一行数据的成本比较低。

但是这样做有两个主要的弱点:

当一行中有很多列,而我们只需要其中很少的几列时,我们也不得不把一行中所有的列读进来,然后从中取出一些列。这样大大降低了查询执行的效率。基于多个列做压缩时,由于不同的列数据类型和取值范围不同,压缩比不会太高。

垂直的列存储结构:

列存储是将每列单独存储或者将某几个列作为列组存在一起。列存储在执行查询时可以避免读取不必要的列。而且一般同列的数据类型一致,取值范围相对多列混合更小,在这种情况下压缩数据能达到比较高的压缩比。

但是这种结构在重建行时比较费劲,尤其当一行的多个列不在一个 HDFS 块上的时候。比如我们从第一个 DataNode 上拿到 column A,从第二个 DataNode 上拿到了 column B,又从第三个 DataNode 上拿到了 column C,当要把 A,B,C 拼成一行时,就需要把这三个列放到一起重建出行,需要比较大的网络开销和运算开销。

混合的 PAX 存储结构:

PAX 结构是将行存储和列存储混合使用的一种结构,主要是传统数据库中提高 CPU 缓存利用率的一种方法,并不能直接用到 HDFS 中。但是 RCFile 和 ORC 是继承自它的思想,先按行存再按列存。

接下来我们看下在 Hive 中常用的几种存储格式:

本文重点讲解最后两种:Apache ORC 和 Apache Parquet,因为它们以其高效的数据存储和数据处理性能得以在实际的生产环境中大量运用。

一、TextFile

TextFile 为 Hive 默认格式,建表时不指定则默认为这个格式,导入数据时会直接把数据文件拷贝到 hdfs 上不进行处理。

创建一个 TextFile 格式的 Hive 表:

create table if not exists textfile_table (     ueserid STRING,     movieid STRING,     rating STRING,     ts STRING ) row formated delimated fields terminated by '\t' stored as textfile;  -- 可不指定(默认格式)

向 TextFile 表中加载数据:

load data local inpath "/root/rating.csv" overwrite into table textfile_table

TextFile 优缺点:

TextFile 格式因为不对导入的数据文件做处理,所以可以直接使用 load 方式加载数据,其他存储格式则不能使用 load 直接导入数据文件。所以 TextFile 的加载速度是最高的。

TextFile 格式虽然可以使用 Gzip 压缩算法,但压缩后的文件不支持 split。在反序列化过程中,必须逐个字符判断是不是分隔符和行结束符,因此反序列化开销会比 SequenceFile 高几十倍。

二、SequenceFile

SequenceFile 是 Hadoop API 提供的一种二进制文件支持,其具有使用方便、可分割、可压缩的特点。

SequenceFIle 的内部格式取决于是否启用压缩,如果是压缩,则又可以分为记录压缩和块压缩。

无压缩(NONE):如果没有启用压缩(默认设置)那么每个记录就由它的记录长度(字节数)、键的长度,键和值组成。长度字段为 4 字节。

记录压缩(RECORD):记录压缩格式与无压缩格式基本相同,不同的是值字节是用定义在头部的编码器来压缩。注意:键是不压缩的。

块压缩(BLOCK):块压缩一次压缩多个记录,因此它比记录压缩更紧凑,而且一般优先选择。当记录的字节数达到最小大小,才会添加到块。该最小值由 io.seqfile.compress.blocksize 中的属性定义。默认值是 1000000 字节。格式为记录数、键长度、键、值长度、值。Record 压缩率低,一般建议使用 BLOCK 压缩。

创建一个 SequenceFile 格式的 Hive 表:

create table if not exists seqfile_table (     ueserid STRING,     movieid STRING,     rating STRING,     ts STRING ) row format delimited fields terminated by '\t' stored as sequencefile;

设置压缩格式为块压缩:

set mapred.output.compression.type=BLOCK;

向 SequenceFile 表中加载数据:

insert overwrite table seqfile_table select * from textfile_table;

SequenceFile 优点:

支持基于记录(Record)或块(Block)的数据压缩。支持 splitable,能够作为 MapReduce 的输入分片。修改简单:主要负责修改相应的业务逻辑,而不用考虑具体的存储格式。

SequenceFile 的缺点:

需要一个合并文件的过程,且合并后的文件不方便查看。

三、RCFile

RCFile 文件格式是 FaceBook 开源的一种 Hive 的文件存储格式,首先将表分为几个行组,对每个行组内的数据进行按列存储,每一列的数据都是分开存储,正是先水平划分,再垂直划分的理念。

首先对表进行行划分,分成多个行组。一个行组主要包括:

16 字节的 HDFS 同步块信息,主要是为了区分一个 HDFS 块上的相邻行组;元数据的头部信息主要包括该行组内的存储的行数、列的字段信息等等;数据部分我们可以看出 RCFile 将每一行,存储为一列,将一列存储为一行,因为当表很大,我们的字段很多的时候,我们往往只需要取出固定的一列就可以。

在一般的行存储中 select a from table,虽然只是取出一个字段的值,但是还是会遍历整个表,所以效果和 select * from table 一样,在 RCFile 中,像前面说的情况,只会读取该行组的一行。

创建一个 RCFile 的表:

create table if not exists rcfile_table (     ueserid STRING,     movieid STRING,     rating STRING,     ts STRING ) row format delimited fields terminated by '\t' stored as rcfile;

在存储空间上:

RCFile 是行划分,列存储,采用游程编码,相同的数据不会重复存储,很大程度上节约了存储空间,尤其是字段中包含大量重复数据的时候。

懒加载:

数据存储到表中都是压缩的数据,Hive 读取数据的时候会对其进行解压缩,但是会针对特定的查询跳过不需要的列,这样也就省去了无用的列解压缩。

如:

select c from table where a>1;

针对行组来说,会对一个行组的 a 列进行解压缩,如果当前列中有 a>1 的值,然后才去解压缩 c。若当前行组中不存在 a>1 的列,那就不用解压缩 c,从而跳过整个行组。

四、ORCFile

1. ORC相比较 RCFile 的优点

ORC 是在一定程度上扩展了 RCFile,是对 RCFile 的优化:

ORC 扩展了 RCFile 的压缩,除了 Run-length(游程编码),引入了字典编码和 Bit 编码。每个 task 只输出单个文件,这样可以减少 NameNode 的负载;支持各种复杂的数据类型,比如:datetime,decimal,以及一些复杂类型(struct, list, map,等);文件是可切分(Split)的。在 Hive 中使用 ORC 作为表的文件存储格式,不仅节省 HDFS 存储资源,查询任务的输入数据量减少,使用的 MapTask 也就减少了。

采用字典编码,最后存储的数据便是字典中的值,及每个字典值的长度以及字段在字典中的位置;采用 Bit 编码,对所有字段都可采用 Bit 编码来判断该列是否为 null, 如果为 null 则 Bit 值存为 0,否则存为 1,对于为 null 的字段在实际编码的时候不需要存储,也就是说字段若为 null,是不占用存储空间的。

2. ORC的基本结构

ORCFile 在 RCFile 基础上引申出来 Stripe 和 Footer 等。每个 ORC 文件首先会被横向切分成多个 Stripe,而每个 Stripe 内部以列存储,所有的列存储在一个文件中,而且每个 stripe 默认的大小是 250MB,相对于 RCFile 默认的行组大小是 4MB,所以比 RCFile 更高效。

下图是 ORC 的文件结构示意图:

ORC 文件结构由三部分组成:

条带(stripe):ORC 文件存储数据的地方。文件脚注(file footer):包含了文件中 stripe 的列表,每个 stripe 的行数,以及每个列的数据类型。它还包含每个列的最小值、最大值、行计数、 求和等聚合信息。postscript:含有压缩参数和压缩大小相关的信息。

stripe 结构同样可以分为三部分:index data、rows data 和 stripe footer:

index data:保存了所在条带的一些统计信息,以及数据在 stripe 中的位置索引信息。rows data:数据存储的地方,由多个行组构成,数据以流(stream)的形式进行存储。stripe footer:保存数据所在的文件目录。

rows data 存储两部分的数据,即 metadata stream 和 data stream:

metadata stream:用于描述每个行组的元数据信息。data stream:存储数据的地方。

ORC 在每个文件中提供了 3 个级别的索引:

文件级:这一级的索引信息记录文件中所有 stripe 的位置信息,以及文件中所存储的每列数据的统计信息。条带级别:该级别索引记录每个 stripe 所存储数据的统计信息。行组级别:在 stripe 中,每 10000 行构成一个行组,该级别的索引信息 就是记录这个行组中存储的数据的统计信息。

程序可以借助 ORC 提供的索引加快数据查找和读取效率。程序在查询 ORC 文件类型的表时,会先读取每一列的索引信息,将查找数据的条件和索引信息进行对比,找到满足查找条件的文件。

接着根据文件中的索引信息,找到存储对应的查询条件数据 stripe,再借助 stripe 的索引信息读文件中满足查询条件的所有 stripe 块。

之后再根据 stripe 中每个行组的索引信息和查询条件比对的结果,找到满足要求的行组。

通过 ORC 这些索引,可以快速定位满足查询的数据块,规避大部分不满足查询条件的文件和数据块,相比于读取传统的数据文件,进行查找时需要遍历全部的数据,使用 ORC 可以避免磁盘和网络 I/O 的浪费,提升程序的查找效率,提升整个集群的工作负载。

3. ORC 的数据类型

Hive 在使用 ORC 文件进行存储数据时,描述这些数据的字段信息、字段 类型信息及编码等相关信息都是和 ORC 中存储的数据放在一起的。

ORC 中每个块中的数据都是自描述的,不依赖外部的数据,也不存储在 Hive 的元数据库中。

ORC 提供的数据数据类型包含如下内容:

整型:包含 boolean(1bit)、tinyint(8bit)、smallint(16bit)、int(32bit)、bigint(64bit)。浮点型:包含 float 和 double。字符串类型:包含 string、char 和 varchar。二进制类型:包含 binary。日期和时间类型:包含 timestamp 和 date。·复杂类型:包含 struct、list、map 和 union 类型。

目前 ORC 基本已经兼容了日常所能用到的绝大部分的字段类型。另外,ORC 中所有的类型都可以接受 NULL 值。

4. ORC 的 ACID 事务的支持

在 Hive 0.14 版本以前,Hive 表的数据只能新增或者整块删除分区或表,而不能对表的单个记录进行修改。

在 Hive 0.14 版本后,ORC 文件能够确保 Hive 在工作时的原子性、一致性、隔离性和持久性的 ACID 事务能够被正确地得到使用,使得对数据更新操作成为可能。

Hive 是面向 OLAP 的,所以它的事务也和 RDMBS 的事务有一定的区别。Hive 的事务被设计成每个事务适用于更新大批量的数据,而不建议用事务频繁地更新小批量的数据。

创建 Hive 事务表的方法:

设置 hive 环境参数:

 --开启并发支持,支持插入、删除和更新的事务 set hive.support.concurrency=true; --支持ACID事务的表必须为分桶表 set hive.enforce.bucketing=true; --开启事物需要开启动态分区非严格模式 set hive.exec.dynamic.partition.mode=nonstrict; --设置事务所管理类型为org.apache.hive.ql.lockmgr.DbTxnManager --原有的org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager不支持事务 set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager; --开启在相同的一个meatore实例运行初始化和清理的线程 set hive.compactor.initiator.on=true; --设置每个metastore实例运行的线程数 set hive.compactor.worker.threads=1;

创建表:

create table student_txn (id int,  name string ) clustered by (id) into 2 buckets --必须支持分桶 stored as orc TBLPROPERTIES ('transactional'='true'); --在表属性中添加支持事务

插入数据:

--插入id为1001,名字为'student_1001 insert into table student_txn values('1001','student_1001');

更新数据:

update student_txn set name='student_lzh' where id='1001';

查看表的数据,最终会发现 id 为 1001 被改为 sutdent_lzh;

5. ORC 相关的 Hive 配置

表的属性配置项有如下几个:

orc.compress:表示 ORC 文件的压缩类型,可选的类型有 NONE、ZLIB 和 SNAPPY,默认值是 ZLIB。orc.compress.size:表示压缩块(chunk)的大小,默认值是 262144(256KB)。orc.stripe.size:写 stripe,可以使用的内存缓冲池大小,默认值是 67108864(64MB)。orc.row.index.stride:行组级别索引的数据量大小,默认是 10000,必须要设置成大于等于 10000 的数。orc.create.index:是否创建行组级别索引,默认是 true。orc.bloom.filter.columns:需要创建布隆过滤的组。orc.bloom.filter.fpp:使用布隆过滤器的假正(False Positive)概率,默认值是 0.05。

注:在 Hive 中使用布隆(bloom)过滤器,可以用较少的文件空间快速判定数据是否存在于表中,但是也存在将不属于这个表的数据判定为属于这个这表的情况,这个情况称之为假正概率,可以手动调整该概率,但概率越低,布隆过滤器所需要的空间越多。

五、Parquet

Parquet 是另外的一种高性能行列式的存储结构,可以适用多种计算框架,被多种查询引擎所支持,包括 Hive、Impala、Drill 等。

1. Parquet 基本结构:

在一个 Parquet 类型的 Hive 表文件中,数据被分成多个行组,每个列块又被拆分成若干的页(Page),如下图所示:

Parquet的文件结构

Parquet 在存储数据时,也同 ORC 一样记录这些数据的元数据,这些元数据也同 Parquet 的文件结构一样,被分成多层文件级别的元数据、列块级别的元数据及页级别的元数据。

文件级别的元数据(fileMetadata)记录主要如下:

表结构信息(Schema);该文件的记录数;该文件拥有的行组,以及每个行组的数据总量,记录数;每个行组下,列块的文件偏移量。

列块的元数据信息如下:

记录该列块的未压缩和压缩后的数据大小和压缩编码;数据页的偏移量;索引页的偏移量;列块的数据记录数。

页头的元数据信息如下:

该页的编码信息;该页的数据记录数。

程序可以借助 Parquet 的这些元数据,在读取数据时过滤掉不需要读取的大部分文件数据,加快程序的运行速度。

同 ORC 的元数据一样,Parquet 的这些元数据信息能够帮助提升程序的运行速度,但是 ORC 在读取数据时又做了一定的优化,增强了数据的读取效率。在查询时所消耗的集群资源比 Parquet 类型少。

Parquet 在嵌套式结构支持比较完美,而 ORC 多层级嵌套表达起来比较复杂,性能损失较大。

2. Parquet 的相关配置:

可以根据不同场景需求进行适当的参数调整,实现程序优化。

parquet.block.size:默认值为 134217728byte,即 128MB,表示 RowGroup 在内存中的块大小。该值设置得大,可以提升 Parquet 文件的读取效率,但是相应在写的时候需要耗费更多的内存。parquet.page.size:默认值为 1048576byte,即 1MB,表示每个页 (page)的大小。这个特指压缩后的页大小,在读取时会先将页的数据进行解压。页是 Parquet 操作数据的最小单位,每次读取时必须读完一整页的数据才能访问数据。这个值如果设置得过小,会导致压缩时出现性能问题。parquet.compression:默认值为 UNCOMPRESSED(不压缩),表示页的压缩式。可以使用的压缩方式有 UNCOMPRESSED、SNAPPY、GZIP 和 LZO。parquet.enable.dictionary:默认为 true,表示是否启用字典编码。parquet.dictionary.page.size:默认值为 1048576byte,即 1MB。在使用字典编码时,会在 Parquet 的每行每列中创建一个字典页。使用字典编码,如果存储的数据页中重复的数据较多,能够起到一个很好的压缩效果,也能减少每个页在内存的占用。

3. 使用Spark引擎时 Parquet 表的压缩格式配置:

Spark 天然支持 Parquet,并为其推荐的存储格式(默认存储为parquet)。

对于 Parquet 表的压缩格式分以下两种情况进行配置:

对于分区表:

需要通过 Parquet 本身的配置项 parquet.compression 设置 Parquet 表的数据压缩格式。如在建表语句中设置:"parquet.compression"="snappy"。

对于非分区表:

需要通过 spark.sql.parquet.compression.code 配置项来设置 Parquet 类型的数据压缩格式。直接设置parquet.compression 配置项是无效的,因为它会读取 spark.sql.parquet.compression.codec 配置项的值。

当 spark.sql.parquet.compression.codec 未做设置时默认值为 snappy,parquet.compression 会读取该默认值。

因此,spark.sql.parquet.compression.codec 配置项只适用于设置非分区表的 Parquet 压缩格式。

应云而生,一文看懂端到端的可观测体系构建

2022年1月28日 08:22
作者 张雅文

2021 年初,可观测性的概念在国内市场还鲜少有人提到,但到了 2021 年下半年,有关可观测性的研讨和实践却开始如雨后春笋般层出不穷,知名公司 Grafana" 甚至直接将原来的监控工具改成了可观测性技术栈并推了一系列服务。可观测性真的能够解决传统监控体系面临的诸多问题吗?又该如何构建可观测体系?本期,亚马逊云科技 Tech Talk 特别邀请到观测云" CEO 蒋烁淼带来分享《构建端到端的可观测体系最佳实践》。

可观测性为何突然“火出圈”

可观测性看似是个新鲜词,但其实它的起源远比我们的认知要早得多。可观测性最早是匈牙利裔工程师鲁道夫·卡尔曼针对线性动态系统提出的概念。若以信号流图来看,若所有的内部状态都可以输出到输出信号,此系统即有可观测性。1948 年伯特·维纳发表的著作《控制论 - 关于动物和机器中控制和通讯的科学》同样提到了可观测性。控制理论中的可观测性是指系统可以由其外部输出推断其内部状态的程度。

随着云计算的发展,可观测性的概念逐渐走入计算机软件领域。为什么近期可观测性的热度显著提升了呢?

蒋烁淼认为,这很大程度是由于系统复杂性的增强。IT 系统的本质是一个数字化的系统,过去,系统本身结构简单,多为单体式架构,且基础设施相对固定,可以通过监控去查看系统。但随着云原生时代的到了,管理对象从单一主机逐渐变成云,后来又变成云原生的分布式复杂系统,传统的面向基础设施的监控、简单的日志和简单的 APM 没有办法解决问题,因此,需要构建系统完整的可观测性。

可观测性中使用的主要数据类是指标、日志、链路。它们通常被称为“可观测性的三大支柱”。

指标(Metric):指标是连续时间下的系统的值的记录,基础指标通常用于描述两种数据类型,一种是计数(Count),一种是计量(Gauge)。日志(Log):系统 / 应用输出的时间相关的记录,通常由系统 / 软件开发人员输出,方便定位系统的错误和状态。链路(Tracing):基于有向无环图构建的软件各个模块直接地调用关系。

三大支柱至关重要,开发者正是通过这三个维度的数据来判定应用系统的状况。和传统监控相比,可观测体系拥有诸多优势。

传统监控面向已知的问题,只能去发现和通知那些已知可能会发生的故障,如:CPU>90%。主要监控对象是 IT 对象,仅面向服务端的组件,解决基础的运维问题。

而可观测性则能够协助发现并定位未知的问题。其核心是不断收集系统产生的各种核心指标与数据,通过数据分析的方式来保障和优化业务,如:发现小程序客户端在某个城市的支付失败率非常高,从而判断是否是代码层面上导致这样一个异常。可观测性主要监测的对象不仅仅是 IT 对象,还有应用和业务,面向云、分布式系统、APP/ 小程序。

在分享中蒋烁淼谈到,随着基础设施的发展,传统监控将逐步被可观测性所取代。

他将构建可观测性的价值总结为以下五点:

让 SLO 可视化,清晰的目标和现状发现与定位未知问题减少团队间的澄清成本降低业务异常造成的无法预知的经济损失提升最终用户体验和满意度

开源 or SaaS,可观测性构建正确的打开方式是? 

相比于传统监控体系,构建可观测性既然有诸多优势和价值。那么该如何构建可观测性呢?

首先,需要尽可能地收集所有组件系统的所有相关⾯的基础数据,包括云、主机、容器、Kubernetes 集群",应⽤和各种终端。实时收集这些数据的成本并不⾼,但如果没有收集,⼀旦系统故障需要排查分析的时候,就⽆法有效评估当时的状态。

其次,要明确系统可观测性构建的责任。谁是这个组件的构建者,谁负责定义这个组件的 SLI,谁负责收集所有的相关基础数据并构建相应的仪表盘以及谁为相关的组件的 SLO 负责,需要责任到人。

第三,开发者需要为可观测性负责。开发者要将⾃⼰开发系统的可观测性数据暴露作为软件质量⼯程的⼀部分,如果说单元测试是为了保证最⼩单元代码的可⽤性,那么开发者标准化暴露可观测性基础数据也将作为⽣产系统可靠性的必要条件。

第四,需要建⽴统⼀的指标、⽇志、链路规范,统⼀团队的⼯具链。即采取相同的指标命名规范,相同的⽇志格式,相同的链路系统。如果在遵循 OpenTelemetry 标准后,仍有不同,则可定义串联整个系统的统⼀TAG 规范,如:所有错误都是 state:error。

第五,要持续优化改进整体可观测性。针对整个系统的可观测,包括数据收集,视图构建,TAG 体系建⽴,这些步骤均需要时间,不能因为覆盖度或者构建的仪表盘未能在某次事故中发挥作⽤而继续⽤过去的⽅式处理问题。每次未被观测的故障都是进⼀步提升可观测范围的绝佳机会。

从可观测性构建的路径不难看出,其过程是非常复杂的。那么,主流的构建方式有哪些?蒋烁淼介绍了两种最为常见的可观测性构建方式,分别是通过开源的方式构建和采用 SaaS 产品进行构建。

得益于开源生态的蓬勃发展,为可观测性的构建提供了诸多选择。采用开源的方式构建,需要构建者从前端的数据抓取到后端的数据处理,包括数据展示、告警等周边功能的相关知识有非常详尽的了解掌握。因此,这种方式适合于那些有足够实力或者学习成本及时间成本相对充足的团队。

相比于开源的方式,采用成熟的 SaaS 产品构建可观测性是一种更加高效的方式。蒋烁淼以观测云的产品为例,介绍了这种方式的四点优势。

不做缝合怪:在服务器内仅安装一个 agent 就可以收集这台主机所有相关的系统数据,避免成堆的 agent 和配置项。不做小白鼠:能提供端到端的完整覆盖,并能做到开箱即用,避免良莠不齐的集成,如:观测云就能够支持超过 200 种技术栈,实现端到端的覆盖。不封闭、高度可编程:可实现轻松构建任意的可观测场景,甚至将业务数据参数引入到整体的观测中,灵活性强。此外,还能够避免死板的集成,拥有强大的二次开发能力。不留隐患:观察云对用户侧代码永久开源,单向通讯,不会也不能向客户环境下发指令。所有的数据收集默认脱敏且用户可对整个过程进行控制。

前面提到,可观测性的构建是应“云”而生的,不仅如此,观测云本身也是完完全全的云原生产品。观测云中整套产品包括数据平台,都是部署在亚马逊云科技的 EKS 之上的,并基于容器进行编排。观测云的整体架构非常简单,即通过一个 agent 将海量数据进行统一,进入数据平台,然后通过平台的能力提供完整的可观测性。整个系统分为核心平台层、Web 层和数据接入层,核心平台层是完全由观测云进行自研的,没有进行开源。上层的 Web 层,在核心数据处理平台上有一套与平台对接的 API。蒋烁淼说:“对于客户来说,更推荐直接选择观测云的 SaaS 产品,如果愿意,客户也可以在亚马逊上完全孤立地进行部署,也是非常方便的,只不过整体费用要比直接采用 SaaS 产品高得多。

为什么会选择亚马逊云科技?主要是基于以下考量:

观测系统本身要有高一个数量级的可靠性和更高的 SLA:观测云是帮助客户构建可观测性系统的平台,因此需要自身拥有很高的可靠性,如果不能提供足够高的可靠性,一旦观测系统出现故障,便无法及时提醒客户,提供详细的分析更无从谈起。此外,选择云服务本身也能够让一部分观测云平台的 SLA 由亚马逊来提供。更成熟的 Marketplace:用户可通过中国的团队直接在亚马逊上进行产品购买,亚马逊云科技会把产品消费直接在 Marketplace 上记账。需要说明的是,观测云的产品是根据数据规模来付费的,当用户没有数据量的时候几乎是免费的。全球性:亚马逊云科技能够提供比海外产品更好的兼容性,尤其对于中国的技术栈整体成本更低。蒋烁淼在分享中透露:“在春节过后,观测云将会在海外亚马逊云科技节点部署我们的观测平台。观测云希望用中国力量为中国的出海客户提供比海外产品更好的、成本更低的选择。”借力 APN 融入亚马逊云科技全球网络:观测云希望借助亚马逊云科技强大的生态,将可观测性作为最终对客户提供服务的手段,并希望能够借力 APN,帮助更多用户了解可观测性的效果,这个也是观测云选择亚马逊科技非常重要的原因之一。

除了是完完整整的云原生产品,在观测云的系统中,还包含几个非常有趣的设计。首先,在采集侧:

观测云把第三方指标, 日志, 链路采集协议统一转为观测云协议插件式采集栈设计, 各插件之间采用 go 协程隔离, 互不影响主动式资源消耗控制防止 agent 端资源压力过大 (cgroup 控制采集资源占用)被动式资源消耗控制防止 server 端压力过大 (背压机制)潮汐机制的分布式日志解析 (pipeline)

其次,在存储查询侧,观测云统一了查询语法,用户无需关心底层数据存储,简单易上手。

第三,在分析侧,观测云实现了全部数据串联,并构建了统一的查看器,将原始数据以类似多维分析和列表的方式进行分析,用户可以去构建自己的查看器。此外,由于数据量大,为避免前端造成用户浏览器压力过大,观测云可以按照指定百分比来采集数据,并提供 SLO/SLI 的面板,帮助客户构建自己应用系统整体可靠性的度量方式。

构建端到端的可观测体系实践案例

在对概念层和技术层面进行详细的介绍后,蒋烁淼以某电商客户作为案例,就具体该如何构建端到端的可观测体系进行了讲解。

案例中电商客户面临的问题是:交易流程从客户下单到仓库到最后财务记账,一个订单需要将近 10 次接口调用,其中任何环节都有可能出现问题,例如程序问题,网络异常,库存卡住等。目前没有有效的监控工具能够把对订单流程进行监控,出问题一般都是门店员工反馈过来,然后运维人员根据订单去参照流程去查询问题出在哪里,非常被动,且工作量较大,每天需要运维人员去查询业务接口是否走完。

针对该客户构建端到端的可观测体系的过程大致分为四步:第一步,梳理观测对象集成接入。采用观测云的产品,整个接入过程仅需要 30 分钟左右就可以完成。

第二步,统一查看与分析。具体步骤为,首先,对用户体验进行监测,然后查看该行为下的和后端打通的链路,并点击具体的链路进入链路查看器,最后查看相应链路的日志。

第三,通过查看器实现业务的可观测。

第四,通过 SLO 监控器预警。

通过观测云完成端到端的可观测性构建后,该电商客户将订单流程节点状态可视化,可实现以订单号检索订单流程节点状态,流程卡在哪个环节,报错信息是怎样一目了然。从用户操作界面、网络、后端服务到依赖的中间件、操作系统,任意故障都能够提供清晰的溯源与分析。不仅如此,观测云还提供实时异常监控告警,确保问题能够被及时发现并及时处理。

除电商领域的应用外,观测云的 SaaS 产品还适用于非常多应用场景。在观测云的官网有完整的系统可观测性构建的最佳实践,感兴趣的小伙伴可直接去观测云官网查看相应文档。

官网链接 https://www.guance.com/?techtalk="

Java之父独家专访:我可太想简化一下 Java了

2022年1月28日 07:22
作者 张雅文

IEEE Spectrum 2021 年度编程语言排行榜新鲜出炉,不出意料,Java" 仍稳居前三。自 1995 年诞生以来,Java 始终是互联网行业炙手可热的编程语言。近年来,新的编程语言层出不穷,Java 如何做到 26 年来盛行不衰?面对技术新趋势,Java 语言将如何发展?在亚马逊云科技 re:Invent 十周年"之际,InfoQ 有幸对 Java 父 James Gosling 博士进行了一次独家专访。James Gosling 于 2017 年作为“杰出工程师”加入亚马逊云科技,负责为产品规划和产品发布之类的工作提供咨询支持,并开发了不少原型设计方案。在本次采访中,James Gosling 谈到了 Java 的诞生与发展、他对众多编程语言的看法、编程语言的未来发展趋势以及云计算带来的改变等问题。

Java 的诞生与发展

InfoQ:Java 语言是如何诞生的?是什么激发您创建一门全新的语言?

James Gosling:Java 的诞生其实源于物联网的兴起。当时,我在 Sun 公司工作,同事们都觉得嵌入式设备很有发展前景,而且随着设备数量的激增,整个世界正逐渐向智能化的方向发展。我们投入大量时间与不同行业的从业者进行交流,也拜访了众多东南亚、欧洲的从业者,结合交流心得和行业面临的问题,决定构建一套设计原型。正是在这套原型的构建过程中,我们深刻地意识到当时主流的语言 C++ 存在问题。

最初,我们只打算对 C++ 做出一点小调整,但随着工作的推进、一切很快“失控”了。我们构建出不少非常有趣的设备原型,也从中得到了重要启示。因此,我们及时对方向进行调整,希望设计出某种适用于主流业务和企业计算的解决方案,这正是一切故事的开端。

InfoQ:Java 作为一门盛行不衰的语言,直到现在依旧稳居编程语言的前列,其生命力何在?

James Gosling:Java 得以拥有顽强的生命力背后有诸多原因。

首先,采用 Java 能够非常便捷地进行多线程编程",能大大提升开发者的工作效率。

其次,Java 提供多种内置安全功能,能够帮助开发者及时发现错误、更加易于调试,此外,各种审查机制能够帮助开发者有效识别问题。

第三,热修复补丁功能也非常重要,亚马逊开发者开发出的热补丁修复程序,能够在无须停机的前提下修复正在运行的程序,这是 Java 中非常独特的功能。

第四,Java 拥有很好的内存管理机制,自动垃圾收集大大降低了内存泄露或者双重使用问题的几率。总之,Java 的设计特性确实提升了应用程序的健壮性,特别是极为强大的现代垃圾收集器方案。如果大家用过最新的长期支持版本 JDK17,应该对其出色的垃圾收集器印象深刻。新版本提供多种强大的垃圾收集器,适配多种不同负载使用。另外,现代垃圾收集器停顿时间很短、运行时的资源消耗也非常低。如今,很多用户会使用体量极为庞大的数据结构,而只要内存能容得下这种 TB 级别的数据,Java 就能以极快的速度完成庞大数据结构的构建。

InfoQ:Java 的版本一直以来更新得比较快,几个月前发布了最新的 Java17 版本,但 Java8 仍然是开发人员使用的主要版本,新版本并未“得宠”,您认为主要的原因是什么?

James Gosling:对继续坚守 Java8 的朋友,我想说“是时候作出改变了”。新系统全方位性更强、速度更快、错误也更少、扩展效率更高。无论从哪个角度看,大家都有理由接纳 JDK17。确实,大家在从 JDK8 升级到 JDK9 时会遇到一个小问题,这也是 Java 发展史中几乎唯一一次真正重大的版本更替。大多数情况下,Java 新旧版本更替都非常简单。只需要直接安装新版本,一切就能照常运作。长久以来,稳定、非破坏性的升级一直是 Java 的招牌特性之一,我们也不希望破坏这种良好的印象。

InfoQ:回顾当初,你觉得 Java 设计最成功的点是什么?相对不太满意的地方是什么?

James Gosling:这其实是一种博弈。真正重要的是 Java 能不能以更便利的方式完成任务。我们没办法设想,如果放弃某些问题域,Java 会不会变得更好?或者说,如果我现在重做 Java,在取舍上会有不同吗?区别肯定会有,但我估计我的取舍可能跟大多数人都不一样,毕竟我的编程风格也跟多数人不一样。不过总的来讲,Java 确实还有改进空间。

InfoQ:有没有考虑简化一下 Java?

James Gosling:我可太想简化一下 Java 了。毕竟简化的意义就是放下包袱、轻装上阵。所以JavaScript 刚出现时,宣传的就是精简版 Java。但后来人们觉得 JavaScript 速度太慢了。在 JavaScript 的早期版本中,大家只是用来执行外部验证之类的简单事务,所以速度还不太重要。但在人们打算用 JavaScript 开发高性能应用时,得出的解决方案就成了 TypeScript。其实我一直觉得 TypeScript 的定位有点搞笑——JavaScript 就是去掉了 Type 的 Java,而 TypeScript 在 JavaScript 的基础上又把 type 加了回来。Type 系统有很多优势,特别是能让系统运行得更快,但也确实拉高了软件开发者的学习门槛。但如果你想成为一名专业的软件开发者,那最好能克服对于学习的恐惧心理。

Java 之父的编程语言之见

InfoQ:一款优秀的现代化编程语言应该是怎样的?当下最欣赏哪一种编程语言的设计理念?

James Gosling:我个人还是会用最简单的评判标准即这种语言能不能改善开发者的日常工作和生活。我尝试过很多语言,哪种更好主要取决于我想干什么。如果我正要编写低级设备驱动程序,那我可能倾向于选择 Rust。但如果需要编写的是用来为自动驾驶汽车建立复杂数据结构的大型导航系统,那我几乎肯定会选择 Java。

InfoQ:数据科学近两年非常热门,众所周知,R 语言和 Python 是数据科学领域最受欢迎的两门编程语言,那么,这两门语言的发展前景怎么样?因具体的应用领域产生专用的编程语言,会是接下来编程语言领域的趋势之一吗?

James Gosling:我是领域特定语言的铁粉,也深切认同这些语言在特定领域中的出色表现。大多数领域特定语言的问题是,它们只能在与世隔绝的某一领域中发挥作用,而无法跨越多个领域。这时候大家更愿意选择 Java 这类语言,它虽然没有针对任何特定领域作出优化,但却能在跨领域时表现良好。所以,如果大家要做的是任何形式的跨领域编程,肯定希望单一语言就能满足所有需求。有时候,大家也会尝试其他一些手段,希望在两种不同的领域特定语言之间架起一道桥梁,但一旦涉及两种以上的语言,我们的头脑通常就很难兼顾了。

InfoQ:Rust 一直致力于解决高并发和高安全性系统问题,这也确实符合当下绝大部分应用场景的需求,对于 Rust 语言的现在和未来您怎么看?

James Gosling:在我看来,Rust 太过关注安全了,这让它出了名的难学。Rust 解决问题的过程就像是证明定理,一步也不能出错。如果我们只需要编写一小段代码,用于某种固定不变的设备,那 Rust 的效果非常好。但如果大家需要构建一套具有高复杂度动态数据结构的大规模系统,那么 Rust 的使用难度就太高了。

编程语言的学习和发展

InfoQ:编程语言倾向于往更加低门槛的方向发展,开发者也更愿意选择学习门槛低的开发语言,一旦一门语言的学习成本过高,开发者可能就不愿意去选择了。对于这样的现象,您怎么看?

James Gosling:要具体问题具体分析。我到底需要 Rust 中的哪些功能特性?我又需要 Java 中的哪些功能特性?很多人更喜欢 Python,因为它的学习门槛真的很低。但跑跑基准测试,我们就会发现跟 Rust 和 Java 相比,Python 的性能实在太差了。如果关注性能,那 Rust 或 Java 才是正确答案。另外,如果你需要的是只有 Rust 能够提供的那种致密、安全、严谨的特性,代码的编写体量不大,而且一旦出问题会造成严重后果,那 Rust 就是比较合适的选择。只能说某些场景下某些语言更合适。Java 就属于比较折衷的语言,虽然不像 Python 那么好学,但也肯定不算难学。

 InfoQ:当前,软件项目越来越倾向采用多语言开发,对程序员的要求也越来越高。一名开发人员,应该至少掌握几种语言?最应该熟悉和理解哪些编程语言?

James Gosling:我刚刚入行时,市面上已经有很多语言了。我学了不少语言,大概有几十种吧。但很多语言的诞生本身就很荒谬、很没必要。很多语言就是同一种语言的不同方言,因为它们只是在用不同的方式实现基本相同的语言定义。最让我振奋的是我生活在一个能够致力于解决问题的世界当中。Java 最大的吸引力也正在于此,它能帮助我们解决几乎任何问题。具有普适性的语言地位高些、只适用于特定场景的语言则地位低些,对吧?所以到底该学什么语言,取决于你想解决什么问题、完成哪些任务。明确想要解决什么样的问题才是关键。

 InfoQ:2021 年,技术圈最热门的概念非元宇宙莫属,您认为随着元宇宙时代的到来,新的应用场景是否会对编程语言有新的需求?可否谈谈您对未来编程语言的理解?

James Gosling:其实人们从很早开始就在构建这类虚拟世界系统了,所以我觉得元宇宙概念对编程不会有什么影响。唯一的区别是未来我们可以漫步在这些 3D 环境当中,类似于大型多人游戏那种形式。其实《我的世界》就是用户构建型元宇宙的雏形嘛,所以这里并没有什么真正新鲜的东西,仍然是游戏粉加上社交互动机制的组合。我还想强调一点,虚拟现实其实没什么意思。我更重视与真实人类的面对面互动,真的很难想象自己有一天会跟独角兽之类的虚拟形象聊天。

写在最后:云计算带来的改变

InfoQ:您最初是从什么时候或者什么具体事件开始感受到云计算时代的到来的?

James Gosling:云计算概念的出现要远早出云计算的真正实现。因为人们一直把计算机摆在大机房里,再通过网络连接来访问,这其实就是传统的 IT 服务器机房,但这类方案维护成本高、建造成本高、扩展成本也高,而且对于人员技能等等都有着很高的要求。如果非要说,我觉得多租户云的出现正是云计算迎来飞跃的关键,这时候所有的人力与资本支出都由云服务商负责处理,企业客户再也不用为此烦心了。他们可以单纯关注自己的业务重心,告别那些没完没了又没有任何差异性可言的繁重工作。

InfoQ:云计算如今已经形成巨大的行业和生态,背后的根本驱动力是什么?

James Gosling:云计算的驱动力实际上与客户当前任务的实际规模有很大关系。过去几年以来,数字化转型已经全面掀起浪潮,而这波转型浪潮也凸显出新的事实,即我们还有更多的探索空间和机遇,例如,现在人们才刚刚开始探索真正的机器学习能做些什么,能够以越来越有趣且多样的方法处理大规模数据,开展数据分析,获取洞见并据此做出决策,而这一切既是客户需求,也为我们指明了接下来的前进方向。亚马逊云科技做为云科技领导者,引领着云科技的发展,改变着 IT 世界,切实解决了企业客户的诸多痛点。

浅谈传统企业的数据治理

2022年1月28日 06:38

世界论坛宣称,数据作为新的经济资产类别,正在成为一种与能源和材料相提并论的资源,已经关系到了企业未来的生存和发展。我们正在见证着数据从“离线”到“在线”、从“静止”到“流动”,从“封闭”到“开放”。在互联网公司创造了各种“中台”概念后,数据治理也作为一个热词频繁被人提及。

传统企业数据治理的动因

随着国内的数字化不断发展,很多组织已经意识到,他们的数据是一种至关重要的资产,数据信息可以使他们洞察客户、产品和服务,一定程度地帮助他们创新并实现其战略目标。

在很多企业内部,数据团队正逐渐变成一个专业、独立的部门,数据部门的肩上要扛起包括保证数据质量、管理数据架构、提供平台工具与应用等在内的各种数据相关的职责,来支持各方对数据的使用、形成企业的数据资产。作为支撑数字化转型的基础设施,数据治理已经成为数据团队履行数据职责的重要手段。

我们在正式讨论传统企业的数据治理之前,要先厘清一些概念——什么是数据治理,什么是数据管理。数据治理是指在管理数据资产过程中行驶权力和管控,包括计划、监控和实施。数据管理的整体驱动力是确保组织可以从其数据中获取价值。数据治理聚焦于如何制定有关数据决策,以及人员和流程在数据方面的行为方式,而数据管理侧重于数据如何按治理标准进行数据生产、应用。

在了解了数据治理和数据管理的基本概念以后,我们来看看传统企业为什么要做数据治理。传统企业做数据治理有两个基本动机,一个是宏观层面的政策导向,一个是微观层面的业务引领。

2019年11月,党的十九届四中全会在《中共中央关于坚持和完善中特色社会主义制度推进国家治理体系和治理能力现代化若干重大问题的决定》中首次明确数据作为生产要素参与社会分配。2020年3月发布的《中共中央国务院关于构建更加完善的要素市场化配置体制机制的意见》中提出,加快培育数据要素市场,推进政府数据开放共享,提升社会数据资源价值,加强数据资源整合和安全保护。2020年5月发布的《中共中央国务院关于新时代加快完善社会主义市场经济体制的意见》中提出,要加快培育发展数据要素市场,建立数据资源清单管理机制,完善数据权属界定、开放共享、交易流通等标准和措施,发挥社会数据资源价值。推进数字政府建设,加强数据有序共享,依法保护个人信息。

在“十四五”规划发布后,政府渐进明细地为企业数据治理指出了行动路径。国企背景的传统企业在这种大的政策导向下,必然要进行必要的数据治理工作,以满足经营管理要求。

业务方面,随着网络和信息技术的不断普及,传统企业包括工业和制造业产生的数据量正在呈指数级增长。大约每两年翻一番。大量新数据源的出现则导致了非结构化、半结构化数据爆发式的增长。这些由我们创造的信息背后产生的这些数据早已经远远超越了目前人力所能处理的范畴。如何高效且安全地管理这些数据,变成一个越来越重要的命题,于是数据治理概念应运而生。

传统企业数据治理的误区

国内早期的数据平台源自头部互联网科技公司,该类型企业通过平台效应催生了大体量的用户规模。为了流量价值最大化,他们往往会通过整合数据,利用数据挖掘算法来绘制用户画像、分析受众行为、建立监控体系,来优化企业运营或管理策略。此类企业由于多年的积累和沉淀,早已具备了必备的基础设施、技术储备及数据管理体系。

随着各企业信息化军备竞赛的不断升级,传统企业也意识到数据以及平台的重要性,于是开始效仿科技公司的模式进行数据平台建设。受各种因素限制,传统企业多以单一视角的技术升级或IT采购的形式搭建数据平台。这就导致企业虽然建立了数据平台,但是数据并没有被有效利用起来,绝大多数企业并没有将他们的数据作为一项资产来管理,并从中获得持续价值。

对于传统企业来说,数据平台的建设方式应该有别于互联网科技公司。传统企业建设数据平台要聚焦数据资产化,将数据作为生产要素来管理。初步形成符合企业特性的数据管理体系后,再进行敏捷式的平台建设,并持续从中获取业务价值。

如何将企业数据转化成资产

数据的巨大价值,如今已被大众认可,但是关于数据资产,目前仍存在着诸多争议。数据资产毫无疑问是数字经济下越来越重要的一环。经济学的基本假设是认为资源是有限的,所以人们总是尽可能的去寻找占有更多的资源为己所用,当今的时代,资源已经不仅限于传统范畴,数据慢慢变成资源的新内容,2019年10月,中国官方首次增列数据作为生产要素,提出健全劳动、资本、土地、知识、技术、管理、数据等生产要素由市场评价贡献、按贡献决定报酬的机制。

从经济史的视角来看,资产的属性、范畴、种类、范围都经历过一个不断扩张和深化的过程。很长一段时间,资产都主要表现为“实物资产”的形态,随着工业经济的发展,社会经济复杂性不断上升,又出现了“无形资产”的概念,到了数字时代,我们应该如何将企业数据转化成资产呢?

随着数据、算法的发展,近年开始陆续涌现出了以区块链、加密货币和智能合约为代表的狭义数据交易,以及广义从会计数据资产核算为准则,将企业数据转化成实际资产写入财务报表的估值方式。本文将着重讨论广义数据资产和会计核算、估值相关的研究。

数据的会计核算现状

数据本质上是对物品、服务或经济主题相关信息以电子或非电子的形式呈现,随着信息技术的发展,数据的使用深度和广度逐步拓宽。在现行企业会计准则规范下,数据尚未以资产形式列报,仅在企业价值评估中潜在影响企业估值情况。在现行企业会计准则规范下,具体数据账务处理方式大致分为三种:

企业内部运营形成的数据,如公司对生产经营或技术参数整理形成的数据,现行企业会计准则尚未设计科目单独进行归集列报,数据形成过程中发生的支出通常根据数据处理部门的性质,分别归集于企业的营业成本、销售费用、管理费用或研发费用中。因此,该部分成本通常依附于员工薪酬、设备折旧、制造费用等体现。企业外部购买的专业数据,即企业从专业公司购买特定行业数据资料,如市场分析数据、用户行为偏好数据、广告营销数据等。按现行企业会计准则,该类数据通常当期一次性从利润表中予以扣除。企业通过软件抓取的公开数据,即企业通过自身研发设计的软件从公开的数据源中抓取的数据,如公开的政务及金融数据。由于该类数据的权属不明确、自身公允价值难以确定等原因,目前无法单独作为资产列报,其价值无法直接体现在企业价值的估值报告中。

通过这些财务处理方式,我们不难看出,目前我们对于数据的会计核算还处于基于工业生产时代的思维模式,在企业数据资产化的进程中,面临巨大的挑战。先行会计确认与计量方法难以有效满足数据资产的实际需求。

数据资产定价的探索

在数据高速发展的时代,由于数据资产初期不具备实物形态,估值通常类比无形资产进行分析。在资产评估初期,企业价值评估以拥有的房产、设备等实物资产为主。对于效益好、拥有良好信誉、先进专利技术的企业,无形资产的价值影响不可忽视。借用无形资产的评估方法,为基础探索性的为数据资产进行定价:

成本法:资产的价值由产生该无形资产的必要劳动所付出的成本决定,成本法应用时需要重点考虑资产价值与成本的相关程度。对于数据资产来说,可以从数据的生产成本来评估该资产的固定价值。例如,某生产企业,为了保障日常生产工作可以稳定进行,通过工业物联网技术建立了一套指标监控体系,对数据集的动态监控可以反馈或评估生产设备风险情况,在这种情况下的数据资产就可以采用生产该数据集的直接成本、间接成本以及数据带来的机会成本来估价。收益法:资产的价值由其投入使用后的预期收益能力体现,是基于目标资产预期应用场景,对未来产生的经济收益进行求取现值的一种估值方法。数据和货币一样具有时间价值,例如,当前机器学习算法往往需要大量的数据积累才能训练出有价值的模型,当前积累的数据都是为了实现未来价值的一部分,通过未来有价值数据模型的收益,可以求取当前数据资产的现值。银行以及医疗行业的AI模型,目前多数处于数据积累和模型训练阶段,可以通过未来基于海量数据训练金融或医疗模型带来的收益,来评估现有数据的价值。市场法:市场法是基于相同或相似资产市场可比交易案例的一种估值方法。在取得市场交易价格的基础上,来计算数据资产的市场价值。目前,我国已在贵州等地设立了多个数据交易中心,数据交易估值会随着数据交易中心等探索不断完善。

面向资产化的传统企业数据治理路径

前面说了企业做数据治理的动因、误区,以及以数据资产化的一些探索,下面我们来看一下面向资产化的传统企业应该如何做具体的数据治理工作。目前大部分传统企业对于数据治理的通病是数据质量偏低,数据资产定义不明确,数据为业务赋能无力这几个方面。放到实际业务中的现象就是:

存在大量纸质单据,需要用到该数据时再由人工将线下数据整理成电子表格录入IT系统,导致数据质量差,且不容易管理。企业没有对数据有统一的业务描述及口径定义,导致不同的人使用数据时标准、口径不统一,跨部门人员无法理解数据的真实含义。过分的投入资源进行IT平台建设,但是缺乏数据资产方向的顶层设计,形成一个个数据孤岛,导致数据散乱无法产生实际价值。

传统企业面向资产化的数据治理过程一般是从发现数据开始的。先发现数据,再寻找数据的使用方法,探索数据的价值,最后提供相应的技术支撑,可以从“数据化”、“资产化”、“场景化”三个维度来循矩渐进的进行平台建设。

数据化

传统企业的数据治理应该在规范的制度和流程下,通过统一的数据服务能力,将业务数据有效的采集并管理起来,通过不断的演进和迭代,逐步健全企业的数据治理体系。这个统一数据服务能力包含“采”和“管”两个方面。

业务数据是指和企业劳动力、资源、资本、用户、行为相关的数据。企业数据治理的建设过程,就是一个持续挖掘新数据,精进管理老数据的过程。企业采集到的数据,是未来将形成资产的基础。所以业务数据化迈出的第一步应该是:将线下离线的数据,转移至线上采集。在采集的过程中,我们可以辅佐管控措施来提高填报数据的质量。

把数据管起来,需要建立统一的业务术语表和元数据的模型,比如说我们做某个领域客户画像的时候,可能根据客户信息建一些业务术语描述,做服务数据的时候,可能会根据交易接口做一些元数据,做数据仓库的时候,可能会根据这个数据仓库建立一些主数据。我们管的时候,需要建立整个企业层面的元数据以及跟合作伙伴打交道的元数据,通过统一的业务术语把所有的数据和数据之间的关系统一整合起来。

数据的采集和管理的过程中,我们将会渐渐发现一些数据治理体系中缺失的点,我们在逐步完善这些缺失和不足,最终才能构建出一套属于企业自己的数据治理体系。

资产化

当企业已经采集了很多业务数据,也初步形成了与企业自身文化比较契合的数据治理体系后,将会面临的另一个问题就是如何展示自己的当前的工作成果,如何将已有的数据进行资产化处理。

传统企业的一个通病就是普遍认为数据治理或者大数据相关的工作太复杂了,很难在短期让上级领导看到工作成效,投入了很多人力和财力,业务价值难以体现。所以能否让人“看”到数据治理的成效,是我们做数据治理过程中一个非常重要的手段。“看”的部分既能展现数据治理的效果,也能决定将数据转化成资产的成败。

在数据资产化的阶段,除了传统的数据大屏外,企业还可以充分利用数据门户等相关实践。数据门户既能让领导层面的人可以看到数据的整体情况,也能让员工及合作单位层面了解到企业数据资产的具体情况。另外还可以利用数据门户加强对于数据资产的管理能力,根据预先制定的数据质量管理规范,将已识别的数据资产进行编目,落实到数据门户中。企业对数据进行商业估值时,数据门户是一个了解数据现状极佳的工具,数据门户提供了让人”看“家底的能力,通过自动化的方式找到现在有哪些数据,数据间的映射关系是什么样,最终将业务系统到数据门户之间的流转关系打通。

在将数据转化为资产的过程中,数据交易也是一个可以为企业持续创造价值的路径。当企业对数据资产进行了编目,汇集在门户中,外部企业或者跨组织之间如果需要此类专业数据时,就可以进行数据之间的交易。在数据交易的场景下,可以将现有的数据门户演进成数据交易集市,根据不同的业务需求,将数据资产转化成不同交易主题,通过批量作业服务,实时接口服务、文件传输服务等形式,提供在线、离线等不同方式,进行系统之间的数据交易。

数据的资产转化的过程中,企业将会逐步建立数据流程、落地数据标准、提供基础数据资产服务,使数据具有经济价值的同时还可以增强对数据的管理能力。

场景化

随着企业数据资产化建设的推进,数据价值可能会越来越高,不同垂类的数据需求也会接踵而至。此时,针对于不同场景下的业务需求提取,海量数据中的数据关系提取,有限数据中最大的价值提取,价值最大化的数据的场景应用,将会成为企业面临的挑战。

要想实现“取”,首先要进行场景化业务需求分析,这个过程常常是由公司高层牵头,调集生产、销售、研发、财务、人力等多部门联动协作,站在全公司的整体视角解决场景中的业务问题,做出相应决策并上下协同实施。只有形成自组织的团队,才能推动场景化分析的顺利实施。想要从海量数据中“取”到合适的数据,要建立业务元数据跟技术元数据的匹配,通过业务含义来识别数据,找到语义以及语义的上下文的关系,并且做延伸搜索。

“取”到数据之后,要有效地结合场景”用“起来,有效的场景需求分析会指引我们如何最大价值的利用数据,场景化应用的价值大致体现在内部的管理价值和外部的营销价值两个方面。随着场景化应用的推进,可能数据之间的相互依赖变得越来越复杂,传统的数据治理方式见效太慢,为特定用途的BI和数仓而开展的ETL工作,复用性和开放性不够。场景化数据治理期望从一类业务场景出发,运用数据治理的方法和工具,对特定数据领域的数据标准、数据架构、数据治理和数据源头展开治理,快速形成支撑一类业务场景数字化应用的数据资产。

除此之外,面向资产化的数据治理还要考虑到监管、合规、数据质量等要求,传统的相对粗粒度的数据支撑的监控报警以及不能满足数据资产场景化的需求,传统运维逐渐的转变为DevOps,而团队的职能也要从支撑职能向业务化在演进。除了基础的监控报警,还需要更细粒度数据的对系统各种资源的管理、自动的资源分配、以及分布式追踪技术等等。

总结

传统企业的数据治理和互联网科技公司不同,在数字经济时代下,为了快速响应业务需求,提升公司数据资产价值,可以从“采”、“管”、“看”、“取”、“用”五个方面入手,从而健全数据治理体系,增强数据管理能力,加强数据质量控制,提高数据应用能力。

作者介绍

韩陈昊,企业数字化转型架构师,精益敏捷教练,曾在规模超千亿级别的传统企业引入敏捷实践并完成端到端数字化转型。目前韩陈昊是成都新敏捷链科技有限公司的高级咨询师,专注为能源、金融、科技、零售等行业客户提供数字化转型解决方案。

熊节,四川质量发展研究院高级研究员,数字化转型专家,中国敏捷浪潮先驱,曾翻译了《重构》等行业重要著作,《敏捷中国史话》作者,极限编程合作社创始人。

Flutter启动流程分析之插件化升级探索

2022年1月26日 03:39
作者 得物技术

Flutter是Google推出的一款跨平台框架。与Weex等其他跨端框架不同的是,Flutter的界面布局绘制是由自己完成的,而不是转换成对应平台的原生组件。那么各个平台是如何启动它的呢?从Flutter官方提供的架构图上看,Flutter Embedder层提供了底层操作系统到Flutter的程序入口,平台采用适合当前系统特性的方式去各自实现。本文基于flutter 2.0.6版本源码,来探索Android平台上flutter Embedder层对应的启动流程,看看这个过程中做了些什么事情,有什么问题是需要我们在项目中注意的。

这部分源码位于engine源码中的/engine/shell/platform/android/ 目录下。

1.主流程

先来看看整体的流程:

Android以FlutterActivity/FlutterFragment/FlutterView的形式承载flutter界面。当我们使用AndroidStudio创建一个新的flutter工程时,生成的MainActivity是直接继承了FlutterActivity,那么很明显,主要的逻辑都在这个FlutterActivity里面了。从流程图看到,flutter的启动流程也是从FlutterActivity的onCreate方法开始的:

1.FlutterActivity将onCreate主要的操作委托给delegate对象去实现。

2.delegate中调用setupFlutterEngine创建FlutterEngine。

3.FlutterEngine初始化各种channel之后,再创建FlutterLoader去加载资源文件和apk里的打包产物,之后初始化JNI的几个线程和DartVM。

4.delegate之后再通过FlutterEngine注册各个插件。

5.FlutterActivity调用delegate的onCreateView创建FlutterView。

6.最后,onStart生命周期中通过delegate的onStart方法执行DartExecutor.executeDartEntrypoint,这个方法会在jni层执行Dart代码的入口函数。至此启动完成。

1.1.FlutterActivity

FlutterActivity也是继承的Activity,但是它把主要的功能都委托给了FlutterActivityAndFragmentDelegate类去实现,实现的Host接口主要是支持在delegate中获取FlutterActivity的一些参数,比如configureFlutterEngine,这些方法可以由子类去重写,实现自定义配置。

接下来,我们看看FlutterActivity的onCreate(),主要的两个步骤是:

1.delegate.onAttach(this): 初始化FlutterEngine、注册各个插件。(注意,这里传的this即是delegate中的host对象)

2.setContentView(createFlutterView() ): 创建FlutterView并绑定到FlutterEngine。

这两个步骤都是委托给 FlutterActivityAndFragmentDelegate 去实现的。

1.2.FlutterActivityAndFragmentDelegate

1.2.1.onAttach

总结一下,onAttach中主要做了一下几件事情:

1.设置flutterEngine:

1.1.判断是否从缓存中获取;

1.2.判断是否有自定义flutterEngine;

1.3.new 一个新的flutterEngine对象;

  1. 将插件attach到host activity,最终会调用各个插件的onAttachedToActivity方法。

3.创建PlatformPlugin

4.注册插件。

1.2.2.configureFlutterEngine

这里说一下configureFlutterEngine(flutterEngine)主要是干什么的,这个方法是在FlutterActivity中实现的,代码如下:

它通过反射找到了GeneratedPluginRegistrant类,并调用了其registerWith方法。这个类我们可以在工程中的 /android/java/目录下找到,是flutter tool自动生成的,当我们在pubspec.yaml中添加一个插件,并执行pub get命令后即会生成。

系统默认使用反射实现,我们也可以在MainActivity中重写这个方法,直接调用registerWith方法。

1.3.FlutterEngine

再来看看FlutterEngine的构造函数。FlutterEngine是一个独立的flutter运行环境,通过它能使用DartExecutor执行Dart代码。

DartExecutor可以跟FlutterRenderer配合渲染UI,也可以在只在后台运行Dart代码,不渲染UI。

当初始化第一个FlutterEngine时,DartVM会被创建,之后可以继续创建多个FlutterEngine, 每个FlutterEngine对应的DartExecutor执行在不同的DartIsolate中,但同一个Native进程只有一个DartVM。

可以看到,这里面做的事情还是很多的:

1.初始化AssetsManager。

2.创建DartExecutor并设置对应PlatformMessageHandler

3.初始化一系列的系统channel。

4.初始化FlutterLoader,加载Resource资源和libflutter.so、libapp.so等apk产物。

5.创建FlutterRenderer、FlutterEngineConnectionRegistry。

6.如果需要,自动注册pubspec.yaml中声明的插件。

接下来看一下FlutterLoader相关的内容。

1.4.FlutterLoader

FlutterLoader以单例的形式存在,一个进程只用初始化一次。用来加载apk安装包中的资源文件和代码产物,必须在主线程中进行。

startInitialization()方法中主要做了以下几件事情:

1.加载传给activity的meta配置信息;

2.提取apk安装包中的assets资源,主要是在DEBUG和JIT_RELEASE模式下的产物 ,比如vmSnapshotData、isolateSnapshotData等;

3.加载flutter engine C++部分源码,即在flutterJNI执行System.loadLibrary("flutter")

public void ensureInitializationComplete(
    @NonNull Context applicationContext, @Nullable String[] args) {
  //多次调用无效
  if (initialized) {
    return;
  }
  ...
  try {
    //startInitializatioz中得到的几个资源文件目录
    InitResult result = initResultFuture.get();
    //这个列表中动态配置了flutter启动需要加载的一些资源的路径
    List<String> shellArgs = new ArrayList<>();
    shellArgs.add("--icu-symbol-prefix=_binary_icudtl_dat");
    //libflutter.so的路径
    shellArgs.add(
        "--icu-native-lib-path="
            + flutterApplicationInfo.nativeLibraryDir
            + File.separator
            + DEFAULT_LIBRARY);
    if (args != null) {
      //方法参数中传来的,可以在重写FltterActivity::getFlutterShellArgs()来自定义参数
      Collections.addAll(shellArgs, args);
    }
    String kernelPath = null;
    //DEBUG和JIT_RELEASE模式下只加载snapshot数据
    if (BuildConfig.DEBUG || BuildConfig.JIT_RELEASE) {
      ...
      shellArgs.add("--" + SNAPSHOT_ASSET_PATH_KEY + "=" + snapshotAssetPath);
      shellArgs.add("--" + VM_SNAPSHOT_DATA_KEY + "=" + flutterApplicationInfo.vmSnapshotData);
      shellArgs.add(
          "--" + ISOLATE_SNAPSHOT_DATA_KEY + "=" + flutterApplicationInfo.isolateSnapshotData);
    } else {
    //RELEASE模式下加载libapp.so文件,这是Dart代码编译后的产物
    //默认是相对路径
      shellArgs.add(
          "--" + AOT_SHARED_LIBRARY_NAME + "=" + flutterApplicationInfo.aotSharedLibraryName);
      //同一个key可以存多个值,当根据前面的相对路径找不到文件时,再尝试用绝对路径加载
      shellArgs.add(
          "--"
              + AOT_SHARED_LIBRARY_NAME
              + "="
              + flutterApplicationInfo.nativeLibraryDir
              + File.separator
              + flutterApplicationInfo.aotSharedLibraryName);
    }
    ...
    //到jni层去初始化Dart VM和Flutter engine,该方法只可以被调用一次
    flutterJNI.init(
        applicationContext,
        shellArgs.toArray(new String[0]),
        kernelPath,
        result.appStoragePath,
        result.engineCachesPath,
        initTimeMillis);

    initialized = true;
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

这个方法的作用是动态配置flutter引擎启动前的各种资源路径和其他配置,以 --key=value 的方式统一添加到shellArgs中,然后调用flutterJNI.init到C++层去处理,C++层会将传入的配置保存到一个setting对象中,之后根据setting创建FlutterMain对象,保存为一个全局静态变量g_flutter_main。之后初始化DartVM等步骤就可以用到这里保存的配置信息了。

1.5.onStart

根据Android中Activity的生命周期,onCreate执行完之后就是onStart了。同样的,FlutterView还是将onStart中的操作委托给了delegate对象去完成。

可以看到,onStart生命周期就做了一件事情:执行Dart代码的入口函数。这里有一些需要注意的地方:

  1. DartExecutor只会执行一次,这意味着一个FlutterEngine对应的DartExecutor不支持重启或者重载

2.Dart Navigator的初始路由默认是"/"。我们可以重写getInitialRoute来自定义。

3.Dart 入口函数 默认是main(),重写 getDartEntrypointFunctionName 方法可以自定义。

  1. executeDartEntrypoint最终会通过FlutterJNI的方法来调用JNI方法来执行。在UI Thread中执行DartIsolate.Run(config),根据entrypoint_name找到Dart入口的句柄后运行_startIsolate执行入口函数,之后执行main函数的runApp()。

至此,Flutter项目成功在Android平台上启动完成。

2.应用-热更新

其实我这次探索Flutter启动流程的一个主要目的是寻找Flutter在Android侧的热更新方案。那么看完了整个流程之后,我们要如何做到热更新呢?

flutter app的apk安装包的几个主要产物是,flutter_assets、libflutter.so和libapp.so:

flutter_assets:包含flutter应用项目中的资源文件,font、images、audio等;

libflutter.so:flutter embedder层相关的C++代码。

libapp.so:我们写的Dart代码编译后的产物

只要可以在加载之前动态替换掉libapp.so这个文件,即可实现flutter代码的热更新。

2.1.方法一:反射修改FlutterLoader

那么libapp.so是在哪里加载的呢?其实上面 1.4.FlutterLoader 已经提到了,在ensureInitializationComplete()方法中,有一个shellArgs列表存储了资源路径配置信息。libapp.so对应的key是 "aot-shared-library-name"

那么,只要替换掉这一块代码,将路径设置成自定义的路径即可让框架去加载新的libapp_fix.so文件。具体步骤是:

1.继承FlutterLoader,重写ensureInitializationComplete(),将 "aot-shared-library-name" 对应的路径设置成自定义的路径。

2.我们看看flutterEngine中是怎么创建的FlutterLoader实例的:

flutterLoader = FlutterInjector.instance().flutterLoader();

那么,我们只要实例化自定义的FlutterLoader类,并通过反射的方式将FlutterInjector中的flutterLoader实例替换成新的实例即可。

2.2.方法二:重写getFlutterShellArgs()

我们注意到ensureInitializationComplete()方法中往AOT_SHARED_LIBRARY_NAME这个key里面添加了2个值,只有当相对路径下找不到文件的情况下才回去寻找绝对路径下的文件。那么我们只要将自定义的so文件路径设置成 "aot-shared-library-name" 第一条value就可以让框架只加载最新的安装包了。

由于ensureInitializationComplete()方法会将参数String[] args中的内容全部加入shellArgs列表,那么我们只要在args中加上 "aot-shared-library-name=自定义路径" 这一条配置就行了,我们看看这个args参数怎么来的:

host.getFlutterShellArgs().toArray()即使args参数的来源了。从之前的分析,我们已经知道了,delegate中的host对象是FlutterActivity的引用,我们再来看看FlutterActivity是怎么实现的:

这是一个public方法,那么我们只要在MainActivity中重写这个方法,并在获取到FlutterShellArgs之后将需要的配置添加进去即可:

很明显,这个方法更加简单有效。需要注意的是,这个配置只会在RELEASE模式下加载,所以DEBUG和JIT_RELEASE模式模式下调试是不起作用的。

3.总结

最后,大致进行一下总结:

1.纯flutter项目中,Android默认以FlutterActivity的形式承载flutter界面。Native-Flutter混合工程中还可以使用FlutterFragment/FlutterView2种方式,具体看使用场景。

2.FlutterActivity将绝大部分工作委托给FlutterActivityAndFragmentDelegate实现。

3.启动过程主要是FlutterActivity的onCreate()和onStart()方法。

onCreate() 会初始化FlutterEngine、注册各个插件,之后创建FlutterView并绑定到FlutterEngine。

onStart() 主要是通过DartExecutor去执行Dart代码的入口函数。

4.初始化第一个FlutterEngine时会创建和初始化DartVM。可以创建多个FlutterEngine,一个FlutterEngine对应一个DartExecutor,每个DartExecutor在自己的DartIsolate中执行。

5.DartExecutor可以和FlutterRender配合渲染UI,也可以只执行Dart代码不渲染UI。

6.FlutterView有两种模式:FlutterSurfaceView和FlutterTextureView。顾名思义,即分别使用surfaceView和textureView来承载flutter视图。FlutterSurfaceView渲染性能更好,但是视图在Native-Flutter混合工程中不支持灵活的z-index设置。

文/KECHANGZHAO

关注得物技术,做最潮技术人!

警惕!这个潜伏了12年的高危漏洞,将影响大多数主流Linux发行版

2022年1月28日 05:35
作者 DAN GOODIN

PwnKit 被攻击者们实际利用恐怕将只是时间问题。

本周二,突然曝出的坏消息令Linux用户们错愕不已 —— Polkit系统工具中存在一项已有12年“悠久历史”的大bug,攻击者能够借此在大多数主流Linux发行版中获得至高无上的root权限。

Polkit之前曾被称为PolicyKit,负责在类Unix操作系统中管理系统内各项权限。它的作用是为非特权进程与特权进程提供一种彼此安全交互的机制。另外,Polkit还允许用户在命令中配合使用名为pkexec的组件,借此执行高权限操作。

易于利用、百分百可靠

与大多数操作系统一样,Linux也拥有一套明确的权限层级结构,用以控制哪些应用程序或用户在哪些情况下可以与敏感的系统资源进行交互。

有了这套体系,我们就能避免网络管理控制权落入不受信任的用户手中,或者应用程序遭到黑客入侵或恶意篡改时造成严重后果。

但自2009年以来,pkexec中就一直包含一个内存破坏漏洞,因此恶意人士完全可以利用此漏洞在目标设备上一路将权限提升至root级别。而且根据相关消息,这个漏洞不仅利用难度低、而且发挥相当稳定,可靠性高达100%。

只要在存在漏洞的设备上完成了初步驻留,攻击者就能利用这个bug以最高系统权限运行恶意载荷或者命令。更可怕的是,研究人员们发现即使Polkit守护程序本身并没有启动,其中的这个PwnKit漏洞也能发挥作用。

PwnKit最初于去年11月被安全厂商Qualys的研究人员所发现,并在大部分Linux发行版完成补丁更新后于本周二被正式披露。PwnKit现已被记录为CVE-2021-4034。

在采访邮件中,Qualys公司漏洞威胁研究总监Bharat Jogi回复道:

可能性最大的攻击场景来自内部威胁,恶意用户可以一路从无权限升级至完全root权限。而从外部威胁的角度来看,只要攻击者能够通过其他漏洞或密码泄露方式在系统上初步驻留,接下来就能利用这项漏洞提升至完全root权限。Jogi还提到,攻击者需要对存在漏洞的设备进行本地身份验证访问,之后才能真正利用这个bug。如果未经身份验证,则此bug无法远程运行。

点击此处"可查看漏洞利用视频。

目前,Qualys公司并未发布漏洞利用概念验证代码,这主要是担心说得太多会给黑客们可乘之机。但另一来源"已经发布了概念验证代码,研究人员们还表示PownKit被攻击者们实际利用恐怕将只是时间问题。

SANS渗透测试员兼漏洞处置人员Bojan Zdrnja表示,“预计这项漏洞将很快广为人知,攻击者也会着手加以利用。所以任何允许用户访问shell的多用户系统都要当心了。”这位研究人员还强调,他已经成功在运行有Ubuntu 20.04的设备上验证了漏洞利用效果。

发现这项漏洞的还不止是Qualys公司的研究人员们,之前也有人发现了同样、至少是非常相似的bug。2013年,研究员Ryan Mallon公开报告了几乎相同的问题":,甚至为此编写了修复补丁",但他一直找不到成功利用该漏洞的方法。而去年6月,Github安全研究员Kevin Backhouse报告了另一个权限提升漏洞",最终被收录为CVE-2021-3560并由各大Linux发行商创建了修复补丁。

我在2013年就写过一篇关于polkit漏洞的博文: https://t.co/a6ciqwCmyt"。我一直没能找到实际利用这个漏洞的办法,但已经发现了引发漏洞的根本原因。— Ryan Mallon (@ryiron) 2022年1月26日"

各大Linux发行版已经针对此漏洞发布了补丁,安全专家们强烈敦促管理员们尽快安装。如果无法立即修复,用户也应使用chmod 0755 /usr/bin/pkexec命令将pkexec中的SUID位删除,以防止它在非特权用户的执行操作中以root身份运行。感兴趣的朋友可以点击此处"、此处"和此处"分别参考Debian、Ubuntu与Red Hat发布的处理建议。

如果大家想审查自己的系统是否已经被入侵,可以查看日志条目中是否存在“The value for the SHELL variable was not found the /etc/shells file(在/etc/shells文件中找不到SHELL变量的值)”或者“The value for environment variable […] contains suspicious content(环境变量的值…包含可疑内容)”之类的异常信息。

但Qualys也提醒大家,攻击者完全有办法在利用PwnKit的同时不留下任何痕迹。总之小心为上,祝好运。

原文链接:

https://arstechnica.com/information-technology/2022/01/a-bug-lurking-for-12-years-gives-attackers-root-on-every-major-linux-distro/"

谷歌AI提出分类器视觉解释方法StylEx,可自动检测分离的属性

2022年1月28日 02:43
作者 谷歌AI

神经网络可以非常出色地执行某些任务,但它们做出决策的方式——例如,图像中的哪些信号导致模型认为它属于一类而不是另一类——通常是一个谜"。如果能解释神经模型的决策过程,可能会在某些领域产生重大的社会影响",例如医学图像分析和自动驾驶等;在这些领域,人工监督是至关重要的。这些见解还有助于指导医疗保健服务方、揭示模型偏差、为下游决策者提供支持,甚至能帮助科学发现过程。

 

以前对分类器进行视觉解释的方法(例如Grad-CAM"这样的注意力图)会强调图像中的哪些区域影响分类结果,但它们没有解释这些区域中的哪些属性决定分类结果,例如,是它们的颜色?它们的形状?还有一类方法通过在一类和另一类之间平滑转换图像来提供解释(例如GANalyze")。然而,这些方法往往会同时改变所有属性,因此难以隔离影响个体的属性。

 

在ICCV 2021上发表的“Explaining in Style: Traininga GAN to explaina classifier in StyleSpace”这篇文章"中,我们提出了一种视觉解释分类器的新方法。我们的方法名为StylEx,可自动发现和可视化影响分类器的解耦(disentangled)属性。它允许通过单独操作这些属性来探索单个属性的影响(更改一个属性不会影响其他属性)。StylEx适用于广泛的领域,包括动物、树叶、面部和视网膜图像。我们的结果表明,StylEx找到的属性与语义属性非常吻合,可生成有意义的、特定于图像的解释,并且在用户研究中可以被人们解释。

例如,要了解一个猫与狗的分类器在给定图像上的效果,StylEx可以自动检测分离的属性,并通过可视化展示操作每个属性是如何影响分类器概率的。然后用户可以查看这些属性并对它们所代表的内容进行语义解释。例如,在上图中,可以得出“狗比猫更容易张开嘴”(上图GIF中的属性#4)、“猫的瞳孔更像狭缝”(属性#5)、“猫的耳朵不倾向于折叠”(属性#1),等等结论。

 

下面的视频提供了该方法的简短说明:

https://youtu.be/mbrka3vBjH8"

StylEx的工作原理:训练StyleGAN来解释分类器

给定一个分类器和一个输入图像,我们希望找到并可视化影响其分类的各个属性。为此,我们使用了StyleGAN2"架构,该架构以生成高质量图像而闻名。我们的方法包括两个阶段:

第1阶段:训练StyleEx

最近的一项工作"表明,StyleGAN2包含一个名为“StyleSpace”的解耦潜在空间,其中包含训练数据集中图像的单个语义上有意义的属性。但是,由于StyleGAN训练不依赖于分类器,它可能无法代表那些对我们要解释的特定分类器的决策很重要的属性。因此,我们训练了一个类似于StyleGAN的生成器来满足分类器,从而鼓励它的StyleSpace适应分类器特定的属性。

 

这是用两个附加组件训练StyleGAN生成器来实现的。第一个是编码器,与具有重建损失的GAN一起训练,它强制生成的输出图像在视觉上与输入相似。这允许我们将生成器应用于任何给定的输入图像。然而,图像的视觉相似性是不够的,因为它可能不一定捕获对特定分类器(例如医学病理学)重要的细微视觉细节。为了确保这一点,我们在StyleGAN训练中添加了一个分类损失,它强制生成图像的分类器概率与输入图像的分类器概率相同。这保证了对分类器很重要的细微视觉细节(例如医学病理学)将包含在生成的图像中。

TrainingStyleEx:我们联合训练生成器和编码器。在生成的图像和原始图像之间应用重建损失以保持视觉相似性。在生成图像的分类器输出和原始图像的分类器输出之间应用分类损失,以确保生成器捕获对分类很重要的细微视觉细节。

第2阶段:提取分离的属性

训练完成后,我们会在经过训练的生成器的StyleSpace中搜索显著影响分类器的属性。为此,我们操纵每个StyleSpace坐标并测量其对分类概率的影响。我们寻求使给定图像的分类概率变化最大化的顶级属性。这样就有了top-K图像特定属性。通过对每个类的大量图像重复这个过程,我们可以进一步发现top-K类特定属性,这告诉我们分类器对特定类是如何理解的。我们称我们的端到端系统为“StylEx”。

图像特定属性提取的可视化说明:一旦训练,我们搜索对给定图像的分类概率影响最大的StyleSpace坐标。

StylEx适用于广泛的领域和分类器

我们的方法适用于各种领域和分类器(二元和多类)。下面是一些特定类的解释示例。在所有测试的领域中,我们的方法检测到的顶级属性在由人类解释时对应于连贯的语义概念,并通过人类评估得到验证。

 

对于感知的性别和年龄分类器,以下是每个分类器检测到的前四个属性。我们的方法举例说明了自动选择的多个图像上的每个属性,以最好地展示该属性。对于每个属性,我们在源图像和属性操作图像之间来回切换。操作属性对分类器概率的影响程度显示在每个图像的左上角。

请注意,我们的方法解释的是分类器,而不是现实。也就是说,该方法旨在揭示给定分类器从数据中是如何学会所利用的图像属性的;这些属性可能不一定代表现实中的类别标签(例如年轻或年长)之间的实际物理差异。特别是,这些检测到的属性可能会揭示分类器训练或数据集中的偏差,这是我们方法的另一个关键优势。它可以进一步用于提高神经网络的公平性,例如,通过增加训练数据集的示例来补偿我们的方法揭示的偏差。

 

在分类过程依赖于精细细节的领域中,将分类器损失添加到StyleGAN训练中是非常重要的。例如,在没有分类器损失的情况下在视网膜图像上训练的GAN,不一定会生成与特定疾病相对应的精细病理细节。添加分类损失会导致GAN生成这些微妙的病理学信息作为分类器的解释。下面以视网膜图像分类器(DME疾病")和病/健康叶子分类器为例。StylEx能够发现与疾病指标一致的属性,例如“硬渗出物”(这是众所周知的视网膜DME标记),以及叶子疾病的腐烂现象。

自动检测到的病/健康叶子图像分类器的Top-4属性。

 

最后,该方法也适用于多类问题,如200路鸟类分类器所示。

CUB-2011"上训练的200路分类器中,自动检测到的(a)“brewer blackbird”类和(b)“yellow bellied flycatcher”类的Top-4属性。事实上,我们观察到StylEx检测到与CUB分类中的属性相对应的属性。

更广泛的影响和后续计划

总的来说,我们引入了一种新技术,可以为给定图像或类上的给定分类器生成有意义的解释。我们相信,我们的技术是朝着检测和缓解分类器和/或数据集中先前未知的偏差迈出的有希望的一步,符合谷歌的AI原则。

此外,我们对基于多属性的解释的关注是提供关于以前不透明的分类过程的新见解和帮助科学发现过程的关键。最后,我们的GitHub存储库"包括了一个Colab和我们论文中使用的GAN的模型权重。

 

原文链接:https://ai.googleblog.com/2022/01/introducing-stylex-new-approach-for.html"

清除 useEffect 副作用

2022年1月27日 15:06
作者 公子

在 React 组件中,我们会在 useEffect() 中执行方法,并返回一个函数用于清除它带来的副作用影响。以下是我们业务中的一个场景,该自定义 Hooks 用于每隔 2s 调用接口更新数据。

import { useState, useEffect } from 'react';

export function useFetchDataInterval(fetchData) {
  const [list, setList] = useState([]);
  useEffect(() => {
    const id = setInterval(async () => {
      const data = await fetchData();
      setList(list => list.concat(data));
    }, 2000);
    return () => clearInterval(id);
  }, [fetchData]);

  return list;
}

🐚 问题

该方法的问题在于没有考虑到 fetchData() 方法的执行时间,如果它的执行时间超过 2s 的话,那就会造成轮询任务的堆积。而且后续也有需求把这个定时时间动态化,由服务端下发间隔时间,降低服务端压力。

所以这里我们可以考虑使用 setTimeout 来替换 setInterval。由于每次都是上一次请求完成之后再设置延迟时间,确保了他们不会堆积。以下是修改后的代码。

import { useState, useEffect } from 'react';

export function useFetchDataInterval(fetchData) {
  const [list, setList] = useState([]);
  useEffect(() => {
    let id;
    async function getList() {
      const data = await fetchData();
      setList(list => list.concat(data));
      id = setTimeout(getList, 2000);
    }
    getList();
    return () => clearTimeout(id);
  }, [fetchData]);

  return list;
}

不过改成 setTimeout 之后会引来新的问题。由于下一次的 setTimeout 执行需要等待 fetchData() 完成之后才会执行。如果在 fetchData() 还没有结束的时候我们就卸载组件的话,此时 clearTimeout() 只能无意义的清除当前执行时的回调,fetchData() 后调用 getList() 创建的新的延迟回调还是会继续执行。

在线示例:CodeSandbox

可以看到在点击按钮隐藏组件之后,接口请求次数还是在继续增加着。那么要如何解决这个问题?以下提供了几种解决方案。

🌟如何解决

🐋 Promise Effect

该问题的原因是 Promise 执行过程中,无法取消后续还没有定义的 setTimeout() 导致的。所以最开始想到的就是我们不应该直接对 timeoutID 进行记录,而是应该向上记录整个逻辑的 Promise 对象。当 Promise 执行完成之后我们再清除 timeout,保证我们每次都能确切的清除掉任务。

在线示例:CodeSandbox

import { useState, useEffect } from 'react';

export function useFetchDataInterval(fetchData) {
  const [list, setList] = useState([]);
  useEffect(() => {
    let getListPromise;
    async function getList() {
      const data = await fetchData();
      setList((list) => list.concat(data));
      return setTimeout(() => {
        getListPromise = getList();
      }, 2000);
    }

    getListPromise = getList();
    return () => {
      getListPromise.then((id) => clearTimeout(id));
    };
  }, [fetchData]);
  return list;
}

🐳 AbortController

上面的方案能比较好的解决问题,但是在组件卸载的时候 Promise 任务还在执行,会造成资源的浪费。其实我们换个思路想一下,Promise 异步请求对于组件来说应该也是副作用,也是需要”清除“的。只要清除了 Promise 任务,后续的流程自然不会执行,就不会有这个问题了。

清除 Promise 目前可以利用 AbortController 来实现,我们通过在卸载回调中执行 controller.abort() 方法,最终让代码走到 Reject 逻辑中,阻止了后续的代码执行。

在线示例:CodeSandbox

import { useState, useEffect } from 'react';

function fetchDataWithAbort({ fetchData, signal }) {
  if (signal.aborted) {
    return Promise.reject("aborted");
  }
  return new Promise((resolve, reject) => {
    fetchData().then(resolve, reject);
    signal.addEventListener("aborted", () => {
      reject("aborted");
    });
  });
}
function useFetchDataInterval(fetchData) {
  const [list, setList] = useState([]);
  useEffect(() => {
    let id;
    const controller = new AbortController();
    async function getList() {
      try {
        const data = await fetchDataWithAbort({ fetchData, signal: controller.signal });
        setList(list => list.concat(data));
        id = setTimeout(getList, 2000);
      } catch(e) {
        console.error(e);
      }
    }
    getList();
    return () => {
      clearTimeout(id);
      controller.abort();
    };
  }, [fetchData]);

  return list;
}

🐬 状态标记

上面一种方案,我们的本质是让异步请求抛错,中断了后续代码的执行。那是不是我设置一个标记变量,标记是非卸载状态才执行后续的逻辑也可以呢?所以该方案应运而生。

定义了一个 unmounted 变量,如果在卸载回调中标记其为 true。在异步任务后判断如果 unmounted === true 的话就不走后续的逻辑来实现类似的效果。

在线示例:CodeSandbox

import { useState, useEffect } from 'react';

export function useFetchDataInterval(fetchData) {
  const [list, setList] = useState([]);
  useEffect(() => {
    let id;
    let unmounted;
    async function getList() {
      const data = await fetchData();
      if(unmounted) {
        return;
      }

      setList(list => list.concat(data));
      id = setTimeout(getList, 2000);
    }
    getList();
    return () => {
      unmounted = true;
      clearTimeout(id);
    }
  }, [fetchData]);

  return list;
}

🎃 后记

问题的本质是一个长时间的异步任务在过程中的时候组件卸载后如何清除后续的副作用。

这个其实不仅仅局限在本文的 Case 中,我们大家平常经常写的在 useEffect 中请求接口,返回后更新 State 的逻辑也会存在类似的问题。

只是由于在一个已卸载组件中 setState 并没有什么效果,在用户层面无感知。而且 React 会帮助我们识别该场景,如果已卸载组件再做 setState 操作的话,会有 Warning 提示。

再加上一般异步请求都比较快,所以大家也不会注意到这个问题。

所以大家还有什么其他的解决方法解决这个问题吗?欢迎评论留言~

注: 题图来自《How To Call Web APIs with the useEffect Hook in React》

“在线设计”网络资源管理的源头活水

2022年1月26日 06:29
作者 鲸品堂

为什么要在线设计?

“白天是旅行家,晚上是画家”——这是业内从事通信设计行业者的自嘲。作为通讯网络工程的设计师,白天需要各个工程场地勘察现场的环境和网络具备的情况,用卷尺测量,用小本本绘录草图或文字记录下来。勘察过程中,少不了扒一扒井盖,扯一扯光缆,盘一盘光交,避免不了风吹日晒,过得像个旅行家。晚上回到办公室或家中,再根据白天勘察到的情况,伏案设计绘制CAD图纸,以指导后续的工程施工,以出图为工作成果,活得像个画家。

即使这样辛苦,对于运营商来说,还是存在各种各样的问题:

雇佣设计院人员参与,运营商配套人员、汽车,全日制陪同设计人员外勘,外勘率几乎高达100%,二次外勘率达到43%。工程设计图纸与现场不符,经常不能指导施工,需要二次甚至多次调整,图纸变更率高,实时性不强。由于摸不清楚实际情况,出现重复投资建设的现象,建设冗余生产过剩,造成资金浪费。交资资料主要是工程施工的竣工图纸,转化成系统数据还需要人工再次处理。在工程建设完成之后,县级公司指派至少1至2人,专职进行数据录入,即需要安排专人把竣工图纸中的资源信息,一点一点得“挑”出来,再一点一点录入系统,工作量巨大且准确性和及时性还难以保障。由于设计、施工、录入各个阶段的工作各自开展,成果难以线上复用,导致有较大的概率与现场不一致,导致业务开通故障。

传统的设计工作,采用离线方式,人力和物力浪费严重,数据管理质量和业务开效率得不到保障,一直困扰着周边的工作者,需要通过创新和变革彻底改变现状。

在线设计总体介绍

浩鲸科技早在2012年某某电信资源项目时就开始研究通过“在线设计”的方式,改变网络设计与资源管理之间脱节断点的问题,逐步脱胎出“在线设计”产品,核心思想是从全生命周期管理的源头解决用人成本高和数据不准确的难题。后续经过在多个省分的推广和不断地改进和完善,逐步形成了一套完善的在线设计产品,特别是近期在某某移动项目的落地,设计单位可使用在线设计APP或PC端功能进行资源查勘预占并完成设计录入;施工单位可通过APP完成现场施工资源修正、AI质检及完工回单,填补资源规划设计施工阶段的管理空白,完善资源全生命周期管理流程。

在线设计产品功能架构图

1 区分不同数据状态,流程驱动管理

在线设计产品,通过流程的闭环管理,将外勘、设计、施工、数据入库几个环节有机的串联在一起,端到端的指导在资源就绪阶段的体系化管理。特别是数据的整体流向管理,从勘察、利旧老的资源数据,到规划设计新的网络数据,到按图施工,再到生产数据入库,通过不同的状态控制数据在不同层面的管理,做到井然有序。当施工时发现需要变更时,可以退回设计环节,设计师重新设计后再进行按单施工。一切业务上的互动都可通过流程的变更来驱动,降低线下互动带来的信息不完整,数据丢失等严重的问题。

新老流程对比

2 提供丰富的在线设计工具

在线设计产品以GIS化操作风格为主,大部分功能在GIS地图上,绘画的方式进行设计工作。操作界面与百度地图类似,集成了大量的绘图工具控件,参考了业内CAD图纸绘制的操作习惯等,将之搬到系统功能中。注重使用者的操作感知,有着较低的使用门槛。

为一线人员提供APP勘察、设计的功能,有一些小的设计工作,在现场就可以进行调整,无需等到晚上回到办公点再进行修正,极大提升了工作效率。

在线设计做了哪些变革?

1 做减法,设计即录入

工程设计与资料录入一个是设计师从工程需求的角度进行网络的规划,另一个是数据管理员根据设计和施工的结果将资料录入到IT系统,本质上这两个工作有很大的重复性,如果将设计和录入两个环节合并,达到设计即录入的效果,工作效率将会极大的提升。在线设计产品将设计的数据根据流程的驱动,在施工完成后,系统自动转换成生产数据,减少人工录入的环节。数据录入环节的减少,数据管理员将没有必要再进行复杂的数据录入,可以将精力用在更重要的数据质量管理上,从而达到更好的支撑效果。

设计数据无缝转换到生产数据

2 线上化,GIS勘察逐步替换线下勘察

通过建立完善的GIS地理大数据的管理库,将所有的网络资源纳入位置化管理。通过资源上图、网格管理、手机APP等功能应用,将户外资源的维护管理能力GIS化,方便在地图上进行搜索定位,位置调整和基础数据的维护。最终可以达到通过GIS地图上实现外勘的目的,降低户外勘察的频率。这个转变是一个过程,需要依赖准确的基础数据,从两个方面入手:①减少户外勘察的频率,线上勘察为主,减少用人用车成本,在线设计产品提供在线勘察工具。②提高户外勘察的效率,提供手机APP支撑工具,降低勘察的难度。

手机APP户外勘察打点

3 位置化,基于GIS的图形化设计

离线设计最大的问题是脱离了在线生产数据,没有将现有的管理系统最大化利用起来,造成了在数据上的脱离,是使用习惯上上造成的数据孤岛效应,可以说离线设计是游离于运营商体制外的另一套体系。在中国大基建的背景下,网络资源的建设实际上也是日新月异,离线方式的设计,完全赶不上建设的变化。只有建立一整套能够跟随网络变化,根据数据世界实时变化的设计系统,才能够跟上数字化转型的步伐。

在线设计提供基于GIS图形化的设计,通过图形拖拽的方式,即可实现网络资源的设计工作。系统将资源设施的网络规格统一做成图标插件,在设计的时候选中,拖拽上图即可。设计的门槛相对比较低,经过简单的培训既可上手。按照设计人员操作习惯在线设计,并提供便捷操作手段,如管道杆路批量创建,光缆路由自动搜索,光缆批量穿缆,图形化批量成端等快速设计功能。缩短设计人员设计时间,减少设计工作量。

基于GIS地图进行设计

4 做标准,统一标准施工图纸管理

在GIS地图上,任意框选区域,即可导出标准的工程图纸,兼容CAD的格式,既支持传统工具上打开观看,又能够满足实时导出。通过不同的颜色区别老资源和新规划设计的资源,清晰的展示不同的状态,并且图标和标准根据企业规范可灵活的配置,统一了标准。在线设计产品支持“路由图”、“缆线图”、“接续图”、“设备面板图”、“管道截面图”等业内标准的图纸管理。支持在线预览和导出管理,图纸根据系统数据实时生成,区别于传统的静态图纸,可真实反馈当前网络的实际情况,使得更具有参考价值。

标准出图之“路由图”

标准出图之”接续图”

标准出图之“设备面板图”

5 自核查,网络数据自动核查

在工程设计完成之后,系统将自动汇聚统计设计的资源清单,并且根据业务逻辑分析设计数据是否完整,如果不完整则审核不通过。需要设计人员补全设计才能进一步走工单。从传统的“随机抽样检查”,到“系统自动审核报告”实现全面核查,全面提升了数据的准确性。

对于设计完的工程,支持主材清单的列表导出,并支撑相应的二维码(或条码)标签打印。并对设计的数据可支持完整的数据校验,以保障设计工作的完整性,从源头把控资源数据的质量。

在线设计主材列表核查&条码标签打印

6 智慧化,路由自动导航

在线设计采用“空间路径算法”,例如:从可用的资源节点拉一条光缆将宽带能力引入用户家是常见的设计场景,系统支持从起始点到用户家的光缆路由自动判断,如果有多条路径则可自动列出给设计人员选择。推荐最优路由,最短、最空闲,节点最少等,通过颜色来表示管孔利用率。

路由导航式自动铺缆

产品案例情况

某某电信

2012年以管线GIS系统为基础,扩容在线设计管理模块,经过多的项目建设,CAD图纸已用于生产,指导实际网络工程建设,取得丰硕的应用成果。经过三万多张设计单考验,且在不断优化,业务和技术方面都非常成熟。

在线设计系统上线时,考虑到系统使用者是第三方设计和工程实施人员,如果出图效果不能满足施工,就意味着创新失败。所以电信的领导下了一个硬任务作为考验,要求“虎丘山庄”为设计试点,小区建筑布局非常复杂,即使人工绘图都有非常大的难度。产品线专家通过一个月的技术攻关,解决了文字重叠、出图不美观、截面图制定放置、图纸裁剪等问题,当系统导出的图纸到设计和施工人员手上时,得到了一致的认可,客户满意统一上线。系统出图更加规范和高效,完全可以解决复杂的工程设计,打消了客户和使用者的顾虑。

虎丘山庄工程设计出图

上线后,设计工作得到很大的提升,以250户左右的FTTH改建小区工程建设项目为例,应用在线设计流程后,设计、录入整体效率和资源入库准确性都得到提升:

上线前涉及资源环节时长为45小时,在线设计优化后,时长可缩至12小时左右;在管理方面彻底解决了资源预占、编码重复、重复设计、标签与系统不符等难点问题,操作上从先前13个环节缩减为8个环节,资源录入前置,减少资源入库时长,提升整个资源的准确性。

表:在线设计上线前后用时对比

某某移动

2021年8月27日上线,设计单位可使用在线设计APP或PC端功能进行资源勘查及预占并完成设计录入;施工单位可通过APP完成现场施工资源修正、AI质检及完工回单,填补资源规划设计施工阶段的管理空白,完善资源管理全生命周期流程。目前日活跃用户1100人次,月均5200张设计工单。

某某移动资源建设过程包括规划设计、工程施工、数据入库、工程验收等环节,其中最突出的问题是整个建设过程没有流程贯穿支撑,特别是在规划和设计阶段,规划支撑系统与现有资管系统脱节,设计工作还是靠人工画图,前期的设计数据采集和后期资源录入主要是靠人工,数据质量难把控,也没有积累,影响前端业务发展,也增加后续网络维护的难度。

“在线设计”系统上线3个月后,逐步解决了客户的痛点难点问题,取得了一系列应用成果:

解决存量资源的补充录入

在线设计对于现网历史欠缺的资源可以补充到资源系统中,提升了资源的完整率,解决现阶段资源整治人力不足的问题,同样也提高后期调度的能力。例如,系统上线北海分公司光路调度完整率只有34.84%,全市还有约1万条POS、800个传输设备未调度,新增业务累计1400条未调度。在线设计应用3个月后,补全了历史缺失的大部分资源,光路调度完整率高达92.58%。

改进了资源录入方式提升效率

在线设计完成新增资源就直接在系统呈现,可以解决现有的资源录入繁琐问题、改善工程提单慢而影响业务调度的情况。原来,工程往往完工后3、4天才开始安排人员进行数据录入,且录入的数据质量难以保障;系统上线后已实现14个地市所有管线工程准备阶段的设计(录入)、施工、质检、入网验收等环节的线上化管理,提高了传输管线哑资源录入的准确性与及时性。

资源共享达到降本增效作用

现有设计方式各专业独立开展工作,对资源的覆盖、上联资源的到位情况都不能及时共享,经常会出现不清楚网络的覆盖而导致资源重复建设情况,增加了网络建设成本。系统上线后,在设计阶段统筹考虑各层级、各专业的全部资源,避免资源冲突或重复建设的问题,大幅提升资源利用率,实现“降本增效”。

规范设计管理和支撑业务快速接入

设计进度、质量审核、设计变更都可以线上管理,规范设计工作。现场勘查完毕就可以现场开展线上设计工作,直接推送审核和施工,大大提高工作效率,缩短业务开通时长。

总结

在线设计产品是从源头上解决数据不准的一套完整的解决方案,补全了资源管理就绪阶段的管理手段,将线下的管理工作搬到线上,完善了资源管理大的生态环境。在线设计不仅是简单的工具支撑,也是在管理手段上的变革,是管理手段革新结合IT应用的创新之举,是企业“数字化转型”的又一最佳实践。

昨天 — 2022年1月27日编程开发

2022年数据库技术未来趋势展望

2022年1月27日 17:11
作者 李冬梅

2020年以来,企业数字化转型进入深水区,行业数字化场景爆发式增长,数据以指数级数量增长。就在去年,我国也明确了数据在市场化配置过程中成为了继土地、劳动力、技术、资本之后的第五大生产要素,数据在社会发展进程中的重要性不言而喻。

先是数据仓库Snowflake以史上最大软件IPO的700亿美元上市,接着PingCAP、思维纵横等数据库科创公司接连刷新融资记录,传统大厂如腾讯、华为等也在数据库产品上不断发力。纵观国内数据库市场,可谓百花齐放、欣欣向荣。

那么,在过去的2021年,数据库领域又有哪些重要进展?在未来的发展中又面临着哪些机遇与挑战?1 月 13 日,InfoQ 大咖说栏目特别邀请到了腾讯云数据库技术负责人潘安群,请他来和大家聊聊 2022 年数据库的技术趋势。

潘安群,腾讯云数据库技术负责人,2007年研究生毕业于华中科技大学,同年加入腾讯,早期主要作为核心技术负责人开展企业级分布式数据库TDSQL自主研发,拥有超过14年分布式计算和分布式数据库研发经验,研发成果多次入选国际顶会VLDB等,历年多次代表腾讯出席CNCC、VLDB、SIGMOD等重要大会。

专访阿里云全局高可用技术团队:2022年了,怎样才能做到真正的“永不宕机”?

2022年1月27日 12:16
作者 Tina

互联网技术发展到了2021年,上云也更加普遍,但宕机事件却似乎没怎么减少。

 

这一年10月,拥有30亿用户的脸书(Facebook)遭遇大规模宕机,中断服务约7小时后大部分服务才重新上线。据说,这是 Facebook 创办以来最严重的一次网络访问事故,导致脸书一夜之间市值蒸发约473亿美元(约合3049亿元人民币)。

 

而在更早些时候,国内某视频网站也因机房故障导致网站崩溃,大量用户“流浪”到其他网站,巨大的流量洪峰又让其他平台也连锁式瘫痪了。此外,拥有15万家客户的Salesforce 在这一年也遭遇了一次长达 5 个小时的全球性质的宕机事故,在线游戏平台 Roblox 还曾发生过长达 73 小时的宕机事故......

 

互联网技术发展到现在,理论上来说是可以做到“永不宕机”的,但为什么还有这么多规模大、时间长的系统故障发生?如何减少宕机事故的发生?InfoQ采访了阿里云全局高可用技术团队,谈谈如何保证复杂系统中的业务可持续性。

从众多宕机事件说开去

云计算的蓬勃发展,催生了越来越多的“国民级应用”,但传统的灾备架构已很难满足业务快速恢复的需要。

 

有统计数据表明",96% 的企业曾在过去三年中至少经历过一次系统中断。对于小型企业来说,一小时的宕机时间会平均造成 25,000 美元的损失。对于大型企业来说,平均成本可能高达 540,000 美元。如今,停机时间越长,这意味着产生永久性损失的可能性越大。

 

然而宕机事故又不可预测,因此它也被称为系统中的“黑天鹅”。阿里云全局高可用技术团队负责人周洋表示,当前大型互联网系统架构日趋复杂,稳定性风险也在升高,系统中一定会有一些没被发现的黑天鹅潜伏着。

 

虽然预测不了“黑天鹅”什么时候会出现,但是能从故障中去寻求一些分类,并有针对性地对一类问题进行防御。比如现在的容灾架构就是一种灾难防御手段,它主要针对的是机房级的故障场景。

 

机房级的故障场景,从IDC的维度上看,主要有机房入口网络故障、机房间网络故障以及机房掉电。如果精细化到应用层,又可以分为接入网关故障、业务应用故障以及数据库故障等,背后的故障原因可能是软件BUG或者部分硬件故障,比如机柜掉电、接入交换机故障等等。

 

容灾架构的目标是,在单机房出现任何故障的情况下,能够快速恢复业务,保障RTO和RPO。

 

RTO(恢复时间目标)是指用户愿意为从灾难中恢复而花费的最长时间。一般来说,数据量越大,恢复所需的时间就越长。

 

RPO(恢复点目标)是指在发生灾难时用可以承受的最大数据丢失量。例如,如果用户可以承受 1 天的数据丢失,RPO 就是 24 小时。

 

 

RTO 和 RPO

 

针对不同种类的故障,灾备行业有三种不同等级的防御方式:数据级、应用级、业务级。现在业内主流的容灾架构还是灾备容灾,属于数据级的容灾方案。由于灾备中心平时不工作,应用服务的完整性和运行状态未知,在发生故障的关键时刻会面临敢不敢切的问题。

 

有些企业会因为无法确定能否承载流量而不敢切,有些决定切换的企业也可能因为备用机房的应用状态不对而不能完全恢复业务,最终造成的影响就是RTO或者RPO较长,反应给外界就是大型“宕机”事件。

来源自阿里实践的AppActive 

2021年,国内外多家知名公司、云平台出现较严重服务中断、宕机事件,为企业敲响了警钟,越来越多的企业把容灾建设提上日程。在解决容灾问题的同时,为保持对成本的控制、支撑未来的多云架构演进和灾难容灾的确定性,许多企业选择尝试采用多活容灾的方式。

 

当灾难发生时,多活容灾可以实现分钟级的业务流量切换,用户甚至感受不到灾难发生。应用多活针对不同的部署场景有三大典型架构:在同城机房物理距离小于100公里的场景下建设同城应用多活,在异地机房物理距离大于300公里的场景下建设异地应用多活,在混合云多云融合的场景下建设混合云应用多活。在多活模式下,资源不闲置不浪费,而且能够突破单地域的机房容量限制,从而获得跨地域的容量扩展性。

 

多活容灾在阿里内部实践了多年。

 

早在2007年到2010年,阿里巴巴就采用同城多活架构支撑业务容量和可用性。

 

到了2013年,由于机房容量有限以及杭州机房有限电风险,阿里巴巴开始探索异地多活的架构方案,那就是后来大家都知道的所谓“单元化”。单元化架构在2014年完成了试点验证,2015年正式在千里之外实现三地四中心,从而具备了生产级别的异地多活能力,2017年完成了在双11凌晨切流。

 

2019年,阿里巴巴系统全面上云,异地多活架构跟随上云的节奏孵化成阿里云云原生产品AHAS-MSHA,服务阿里巴巴和云上客户,先后帮助数字政府、物流、能源、通信、互联网等十余家不同行业中的大型企业成功构建应用多活架构,包括菜鸟乡村同城应用多活、联通新客服异地应用多活、汇通达混合云应用多活等。

 

在采访阿里云全局高可用技术团队时,大家普遍的感受是,“业内对于多活没有统一的认知,并且重视度不够。”

 

首先,不同的人对于“多活”这个词会有不同的定义,人人都说自己是“多活”,可当故障来临的时候,才发现当前系统并不是真正的多活。其次,有些企业并不了解异地多活,有些了解的企业会认为异地多活的成本高、难落地。还有些企业在了解“多活”之后,下意识想要先在企业内部投入资源进行技术预研,抗拒云厂商的商业化产品输入。

 

“多活”的认知偏差会让使用者错用或者不用,从而享受不到“多活”带来的稳定性红利。

 

在阿里云全局高可用技术团队看来,应用多活将成为云原生容灾领域的趋势,与其等待趋势到来,不如通过开源来推动应用多活的发展。他们希望通过开源协同,形成一套应用多活的技术规范和标准,使得应用多活技术变得更易用、通用、稳定和可扩展。

 

2022年1月11日,阿里云将 AHAS-MSHA 代码正式开源,命名为 AppActive。(项目地址:https://github.com/alibaba/Appactive")这也是开源领域首次提出“应用多活”概念。

 

AppActive的实现与未来规划  

阿里云也曾在2019 年开源了自己的混沌工程项目ChaosBlade(https://github.com/chaosblade-io/chaosblade"),旨在通过混沌工程帮助企业解决云原生过程中的高可用问题。AppActive 更偏防御,ChaosBlade更偏攻击,攻防结合,形成更加健全的落地安全生产机制。

 

AppActive的设计目标是多站点生产系统同时对外提供服务。为了达到这一目标,技术实现上存在流量路由一致性、数据读写一致性、多活运维一致性等难点。

 

为应对以上挑战,阿里云全局高可用技术团队做了各类技术栈的抽象以及接口标准定义。

 

周洋介绍,他们将AppActive 抽象为应用层、数据层和云平台3个部分:

应用层是业务流量链路的主路径,包含接入网关、微服务和消息组件,核心要解决的是全局流量路由一致性问题,通过层层路由纠错来保障流量路由的正确性。其中,接入网关,处于机房流量的入口,负责七层流量调度,通过识别流量中的业务属性并根据一定流量规则进行路由纠错。微服务和消息组件,以同步或异步调用的方式,通过路由纠错、流量保护、故障隔离等能力,保障流量进入正确的机房进行逻辑处理和数据读写。数据层核心要解决的是数据一致性问题,通过数据一致性保护、数据同步、数据源切换能力来保障数据不脏写以及具备数据容灾恢复能力。云平台是支撑业务应用运行的基石,由于用云形态可能包含自建IDC、多云、混合云、异构芯片云等形态,云平台容灾需要进行多云集成和数据互通,在此基础来搭建和具备云平台、云服务PaaS层的容灾恢复能力。

应用多活应对的6大灾难故障

 

目前 AppActive 处于v0.1版本,开源内容包括上述应用层和数据层在数据平面上的所有标准接口定义,并基于Nginx、Dubbo、MySQL提供了基础实现。开发者可基于当前的能力,进行应用多活的基本功能运行和验证。

 

短期内,AppActive的规划会对齐应用多活标准,提升AppActive的完整性,具体包括以下几点:

 

1. 丰富接入层、服务层、数据层插件,支持更多技术组件到AppActive支持列表。

2. 扩充应用多活的标准和实现,比如增加消息应用多活的标准和实现。

3. 建立AppActive控制平面,提升AppActive应用多活实现的完整性。

4. 遵循应用多活LRA标准扩展支持同城多活形态。

5. 遵循应用多活HCA标准扩展支持混合云多活形态。

 

未来,阿里云将不断打磨AppActive,努力使之成为应用多活标准下的最佳实践,以达到规模化生产可用的严格要求;也会顺应云的发展趋势,探索分布式云,实现跨云、跨平台、跨地理位置的应用多活全场景覆盖。

 

随着“无容灾不上云”共识的逐渐达成,阿里云希望帮助更多企业的应用系统构建应对灾难故障的逃逸能力,也希望能跟GitHub社区里的开发者共建应用多活容灾标准,

 

延伸阅读:

阿里云《应用多活技术白皮书》:https://developer.aliyun.com/topic/download?spm=a2c6h.12873639.0.0.5b222e55fukQsa&id=8266"

 

Aqua Security 报告:供应链攻击大幅增加,软件开发环境的安全水平仍然很低

2022年1月27日 11:24
作者 Tina

Aqua Security"最近"发布了一份供应链安全报告。该报告指出,从 2020 年到 2021 年,供应链攻击增长了 300%,软件开发环境的安全水平仍然很低。在供应链攻击威胁日益增加的情况下,谷歌"和云原生计算基金会 (CNCF)"也相继发布论文详细介绍提高供应链安全性的方法。

 

这份报告由 Aqua Security 旗下的供应链安全公司Argon Security"编写。Aqua Security总共历时六个月,调查了许多客户的供应链,确定了企业应该重点关注的三个风险领域。

 

第一个是使用易受攻击的软件包。该报告指出几乎所有商业软件中都会使用开源代码,这些代码可能含有漏洞,需要不断投入时间和精力来进行软件更新。主要有两种利用方式:利用现有漏洞和通过中毒的软件包(package poisoning)。最近的Log4j 漏洞"的例子属于前者,而ua-parser.js 包"的入侵则属于后面这种情况。

 

第二个是通过一些受损的管道工具。Codecov供应链漏洞"就是一个例子。攻击者通过一个 Docker 映像破坏了Codecov bash uploader,从而能够从 CI 过程中提取环境变量,进而暴露 Codecov 客户的敏感数据。

 

第三个与代码和工件完整性有关,包括将不良或敏感代码上传到源代码存储库。该团队在调查的客户环境中发现了许多问题,包括容器映像漏洞、将敏感数据发布到代码存储库以及代码质量问题。

 

该研究指出,大多数团队缺乏资源来应对这些挑战。Argon Security 首席营收官Eran Orzel"说:“大多数 AppSec 团队缺乏充分应对供应链攻击风险的资源、预算和知识。由于需要开发人员和 DevOps 团队的合作,这就将问题进一步复杂化了。”

 

谷歌和云原生计算基金会 (CNCF) 都发布了帮助提高软件包完整性的指南。谷歌的软件工件供应链级别 (SLSA) 框架"建立在Borg的二进制授权基础之上。"它声明所有软件工件都应该是非统一的和可审计的。如果怀疑有攻击发生,理想情况下的自动化审计有助于调查。CNCF 的论文《软件供应链安全最佳实践"》定义了供应链安全的四个关键原则:信任、自动化、清晰度和相互身份验证:每个步骤都必须是可信任的,使用自动化可以减少人为错误和配置漂移,应明确定义构建过程和环境,使用定期密钥轮换强化认证机制。

eBPF与Wasm:探索服务网格数据平面的未来

2022年1月27日 09:18
作者 Vivian Hu

随着eBPF和WebAssembly(WASM)等轻量级运行时的发展,我们现在看到了新一代的服务网状数据平面解决方案,它们更轻便、更安全、更快速。

2021年12月2日,Cilium项目宣布了Cilium服务网格"的beta测试计划。在谷歌云基于eBPF的谷歌Kubernetes服务(GKS)Dataplane V2(于2020年8月发布)所开创的概念基础上,Cilium服务网格倡导“无sidecar服务网格”的理念。它扩展了Cilium eBPF产品,以处理服务网格中大部分sidecar代理的功能,包括L7路由和负载均衡、TLS终止、访问策略、健康检查、日志与跟踪,以及内置的Kubernetes ingress。

Cillium的创建者Isovalent在一篇题为“eBPF将如何解决服务网格的问题--再见Sidecar”的文章中阐述了使用eBPF代替sidecar代理的理由。

它能够将我们从sidecar模型中解放出来,允许我们将现有的代理技术集成到现有的内核命名空间概念中,从而使它们成为我们每天都在使用的容器抽象的一部分。

简而言之,eBPF承诺会解决服务网格中的一个主要痛点,那就是当存在数量众多的微服务时,会导致较差的性能。但是,使用eBPF来取代sidecar是一个新的想法,并非没有争议。

(来源:eBPF将如何解决服务网格的问题--再见Sidecar")

在服务网格中,数据平面指的是基础设施服务,它会管理数据流量如何路由和投递给微服务应用。目前,这主要是通过使用服务代理实现的。这种设计模式通常被称为sidecar模式。sidecar能够允许其关联的微服务以透明的方式向服务网格中的其他组件发送和接收请求。

sidecar一般会包含一个L7的网络代理,比如Envoy"、Linkerd"或MOSN"。代理要处理流量路由、负载平衡、健康检查、认证、授权、加密、日志、跟踪和统计数据收集。sidecar还可以包含一个基于SDK的应用框架,比如Dapr",以提供网络代理之外的应用服务。举例来讲,这种应用服务包括服务注册、服务发现、资源绑定、基于名字的服务调用、状态管理、actor框架和secret存储。

sidecar代理和服务通常会在Kubernetes pod或容器中运行。微服务应用也会在容器中运行,它们通过网络接口关联到sidecar上。但是,这种容器化应用的方式有一个明显的问题那就是资源的消耗。sidecar服务会随着微服务的数量呈几何级数增加。当一个应用有数百个相关连接和负载均衡的微服务时,所带来的开销就会变得难以承受。服务网格代理供应商在性能方面展开了竞争。正如InfoQ最近所报道的",Linkerd使用Rust重写了原本基于Go实现的代理,并取得了明显的性能提升。

不出意料的是,现有的服务网格供应商并不相信eBPF会是解决我们所有问题的灵丹妙药。来自Solo.io(一个基于Envoy Proxy和Istio的领先的服务网格供应商)的Idit Levine等人撰写了一篇文章来回应Cilium的公告。该文章的标题就是“用于服务网格的eBPF?是的,但Envoy代理将会继续存在"”。

在Solo.io,我们认为eBPF是一个优化服务网格的强大方式,同时,我们也认为Envoy代理是数据平面的基石。

Solo.io作者提出的关键点是,sidecar代理现在的作用远远超过了简单的网络流量管理。如今的服务网格部署有复杂的要求,远远超过了eBPF所支持的有限的编程模型,eBPF是图灵不完备的,对内核的安全有许多限制。Cilium eBPF的产品可以解决许多sidecar代理所能处理的各种任务,但不是全部。此外,Solo.io的作者指出,eBPF的每个节点一个代理(one-proxy-per-node)的设置提供了更少的灵活性,因此与传统代理的每个pod一个代理(one-proxy-per-pod)的设置相比,会增加整体的开销。如果开发者必须编写应用程序特定的流量路由、负载平衡和授权等逻辑并将其部署到服务网格中的话,那么eBPF的这些缺点会更加明显。

Terate.io的开发人员在对Cilium公告的回应中提出了类似的论点,他们撰写了一篇名为“社区中关于Istio和服务网格的争论"”的博客文章。他们指出,如今的sidecar代理的性能是合理的,开源社区已经想出了进一步提高性能的方法。同时,对于开发者来说,在eBPF这样一个新颖的、图灵不完备的技术中构建应用程序特定的数据平面逻辑是非常困难的。

Istio架构是稳定的,可以投入生产的,而且生态系统正在蓬勃发展。

eBPF的很多问题都与它是一种内核技术有关,因此必须要有安全限制。有没有一种方法可以在不使用使用用户空间技术(这会导致性能下降)的情况下,将复杂的应用程序特定的代理逻辑纳入数据平面中?事实证明,WebAssembly(Wasm)可能是一个选项。Wasm运行时可以安全地隔离并以接近原生的性能执行用户空间代码。

Envoy Proxy开创了一种方式,支持使用Wasm作为扩展机制实现数据平面编程。开发人员可以用C、C++、Rust、AssemblyScript、Swift和TinyGo等语言编写应用程序特定的代理逻辑,并将模块编译到Wasm中。通过proxy-Wasm标准,代理可以在高性能运行时(如Wasmtime"和WasmEdge")中执行这些Wasm插件。目前,Envoy Proxy"、Istio Proxy"、MOSN和OpenResty"都支持proxy-Wasm。

(容器生态系统中的Wasm。来源:WasmEdge Book")

此外,Wasm可以作为一个通用的应用容器。在服务网格的数据平面方面,它的应用并不局限于sidecar代理。关联到sidecar的微服务可以在它自己的轻量级Wasm运行时中运行。WasmEdge WebAssembly运行时是一个安全、轻量级、快速、可移植和支持多语言的运行时,可以直接由Kubernetes作为容器管理"。截止2021年12月,WasmEdge社区的贡献者证明了基于WasmEdge的微服务可以与Dapr"和Linkerd"的sidecar一起工作,能够替代重量级的完整Linux容器,而这种完整的容器通常都需要guest OS和完备的软件栈。与Linux容器应用相比,WebAssembly微服务仅消耗1%的资源,冷启动时间为1%。

eBPF和Wasm是服务网格应用在数据平面上实现高性能的新生力量。它们仍然是新生的技术,但有可能成为今天微服务生态系统中Linux容器的替代品或补充。

关于作者

Vivian Hu

Vivian是来自亚洲的一个开源爱好者和开发者倡导者。她是Second State的产品经理。她非常关注如何通过更好的工具、文档和教程来改善开发者的体验和生产力。Vivian在WebAssembly.today上为WebAssembly、Rust和无服务器技术撰写了一份每周新闻通讯。

查看英文原文:eBPF and Wasm: Exploring the Future of the Service Mesh Data Plane"

展望架构的 2022:热度居高不下的云原生,如何撑起架构的未来

2022年1月27日 08:41
作者 辛晓亮

软件架构发展至今,经历了从单体架构、垂直架构、SOA 架构到现在的以微服务、服务网格等云原生技术为主的演变过程,云原生技术发展势不可挡,老生常谈的“云原生”将依然会是未来的热门话题。而且随着数字化转型加速,企业对于云的使用将会达到新的水平,云原生架构和云原生应用也将会持续迭代演进。

那么在云原生等技术的加持下,2022 年的架构领域有哪些值得关注的趋势?云原生如何撑起架构的未来?本期直播,阿里云 MSE 负责人李艳林(彦林)、阿里云高级技术专家李云(至简)一起做客 InfoQ 视频号,为你带来云原生架构领域最新趋势解读。以下根据直播内容整理,InfoQ 做了不改变愿意的编辑,完整内容可点击查看回放视频"。

软件架构演进过程

InfoQ:软件架构经历了从单体架构到 SOA 架构再到后面以微服务云原生为代表的架构形态,中间有哪些关键的节点?

 

至简:讲今天的云原生我觉得我们还是需要回顾一下历史,去了解一下它是怎么一回事。

 

2000 年的时候,还没有虚拟化的概念,大家看到的都是物理机;

 

2001 年 VMware 横空出世,不过这个时候交付的还是一个虚拟机;

 

之后 2006 年亚马逊推出 IaaS(基础设施即服务)平台 AWS,这个时候的思路已经是把 CAPEX(资金投入成本) 变成 OPEX(运营成本)。就是我不需要再买一大堆机器,而是用到了再去云上买;

 

2009 年 Heroku 提出 PaaS,这个时候不再是用虚拟机来交付,变成了 Buildpacks,也开始了有了容器化的概念,还有 12 要素应用程序的一套规则;

 

2010 年,出现了 OpenStack,它其实是通过开源的方式来做 IaaS,目的是跟 AWS 做竞争,它构建的 building block 还是一个 VM;

 

2013 年,Docker 的出现带来了比较大的变化,这个时候交付就变成了容器。

 

今天讲的 Cloud Native 其实是 2015 年出现的,当时称之为 CNCF(Cloud Native Computing Foundation),这个时候就在定义云原生。

 

其实整个过程中我们能很明显的看到一些变化,从大型机、Server 到 VM、Buildpacks,再到容器,隔离的单元也是越来越小,从很重很大到后面通过微服务软件架构把它变得很小,这中间最重要的目的是什么?其实就是为了做解耦。大家可能对 Cloud Native 有很多想法,但我觉得关键的一点就是 Cloud Native 的核心是什么,从我自己的认知来看,我觉得所有的软件都有一个至理名言,我们叫做分而治之,也可以叫做解耦,或者高内聚低耦合。通过不断的解耦,变成微服务,让整个交互更加的敏捷。而不是像以前单体应用耦合在一起,很难协同,很难交付。

 

Cloud Native 还有一个重要的要素就是 no lock in,避免锁定。从 CNCF 定义标准说起,CNCF 不会直接说某个东西是一个标准,他们会认为这个东西是一个关键的组件,并表示这个组件是被广泛采纳的,也是我们 CNCF 认可的。这样的话就会有更多的人去用,也知道这个软件会有长期的维护,自然而然它就会标准化,而这种标准化带来的好处就是 no lock in,我觉得可以从不同的维度去理解它。

 

从厂商的角度来讲,你可以灵活的选择不同的云供应商;另一种就是对于工程师讲,你在 A 公司的平台上做业务开发,很有可能离开离开 A 公司后就没有办法施展了,no lock in 带来的好处就是不会把员工锁定在一家技术公司,只要你掌握的是 Cloud Native 技术,你就可以在市场上做流通。

 

彦林:刚才至简是从整个软件行业的角度去讲的,我从产业角度简单说一下我的理解。

 

现在的云原生技术,包括软件架构的形态跟互联网 1.0、2.0、3.0 是有很大关系的。最早互联网 1.0 时代都是静态页面,这个时候多数网站承载的内容比较简单,单体应用基本上加 CDN 就能解决;随着互联网进入 2.0,各种门户网站、Web 应用涌现出来了,也开始有交互了,更多的交互、更多的渲染对技术的整体要求变高了,单体应用已经不能满足日益复杂的业务需求,软件变得复杂,场景变得复杂,人力协同数字化程度变得越来越高,这个时候就进入了 SOA 和微服务的时代;之后整个产业又发生了一个比较大的变革,就是移动互联网,第三个时代的到来对实时性提出了更高的要求,包括“主动获取、被动推送”。信息的获取量、实时渲染量更大,整个 IT 系统在这个阶段也是爆发性的增长,对数字化系统要求更高。

 

随着整个云计算的一个发展,其实更多的随着云的发展,随着软件的发展,在 2015 年左右的时候,按照刚至简说的,通用化和标准化这个事情基本上在逐渐的形成,在 15 年之后,行业中的关于各种各种的容器化,比如 Docker、K8s 包括 Spring Cloud 都是在这个时代陆续的产生,大概是这么一个情况。

 

InfoQ:经历了这么多年软件行业和产业的变化,云原生架构现在发展到了一个什么样的阶段呢?

 

至简:我觉得今天来看的话,可以说云原生架构已经被业界被行业广泛接受。

 

以 Service Mesh 为例,服务网格现在都在逐步的接受。讲云原生架构之所以拿 Service Mesh 来举例,是因为云原生整体的概念已经被广泛接受,比如像云原生下的 K8s 毫无疑问已经是一统江湖的局面,而相比之下 Service Mesh 是偏晚的。像 Service Mesh 曾经被质疑的问题比如性能等,到今天已经都已被逐步接受。

 

从这个层面就可以看出来,大家对整个云原生架构的接受度已经很高了。今天很多企业考虑的问题是我如何去落地云原生这个技术。我觉得云原生不管是理念也好设计模式也好,它是一个组合在一块的。我不会简单的说云原生发展到整个历程的 50% 或者 60%,不会用这个思维去看待它,而是说我们能不能先上到云原生,随着云原生技术的演进,我也能跟着这个节奏去往前走。

 

我觉得好的地方是整个大众对云原生技术有很好的认知和理解,然后云原生整体趋势也是乐观和蓬勃发展的。

 

彦林:我讲一下我对这个事情的理解,首先从软件技术上分层去讲的话,今年大家可以看到,包括阿里云和其他所有的云都在讲容器 Anywhere,其实容器已经慢慢成为一种基础设施,随着未来三到五年的发展,保有容器的量可能比单独跑在 ECS 上的要多。从容器角度来看,基本上已经要成为新一代的一个基础设施。

 

从微服务角度去看,因为我们最近在做两年规划,大家应该也看到了一些关键的数据,比如中国程序员的平均工资多少多少,平均工资那就是人力成本,其实已经远远高于 IT 的算力成本资源成本。容器更多解决的是资源调度成本、运维成本,微服务更多解决的是研发成本、协同成本。因为大家在一个代码上去共建人太多的话,效率是非常低的。所以第一个面临的问题就是人力与效率越来越重要,而且随着整个行业竞争的加剧,你跑得快就有优势,跑慢了就会错过这个机遇,互联网行业就是“快鱼吃慢鱼”。

 

我在关注的数据中还有一个比较新的事情是整个程序员的年龄分布,90 后已经成为构建数字化经济的核心中坚力量,他们的协作模式和工作风格与老成员已经不太一样了。他们喜欢更敏捷更独立的协作模式,微服务其实就是更符合他们的一个协作模式。

 

目前从整个行业来看的话,微服务已经成为一种主流的选择。而且我们从另外的两个数据也可以看到,第一个就是从整个行业看微服务每年有差不多 20% 以上的一个增长,就是说整个行业每年有数万家企业在做整个微服务的一个改造,第二个就是除了互联网公司进行容器化和微服务改造,许多传统行业,比如零售、医疗、金融等等,陆续开始进行数字化升级,微服务在整个行业也有了更广发的一个演进。

 

从另外一个技术角度来看,不管是单体应用、微服务,还有未来的服务网格、Serverless 等,都有自己的应用场景,今天可能是因为人力成本的提升,整体年轻化对协作要求更自由、更独立,容器跟微服务在这个大趋势下越来越重要了。

 

InfoQ:刚才我们聊的过程中也看到了不少观众表示受认可的情况,也提到了一些落地的案例,两位老师有没有相关落地案例分享?

 

彦林:落地案例其实非常多,我简单举几个可以对外讲的例子吧。

 

来电科技在前几年就完成了整个云原生的技术改造,容器化、微服务都做了,在研发效率、资源利用率上都得到了比较大的提升。现在他们已经走到了云原生的第二个阶段,当下比较大的问题是服务治理,比如优雅上下线、无损下线,同时也会面临高可用的问题,比如它实际场景,线上线下融合,对线上稳定性有更高的要求,就需要一套高可用体系,包括限流、降级、熔断、回滚、全链路灰度。他们目前是已经走到了这个阶段,在服务治理上也是比较高的一个层次,代表了一些传统企业和互联网有交集的一个案例。

 

另一个就是斯凯奇,他们也赶上了数字化转型,他们知道数字化经济在国内已经是势不可挡的趋势, 不加入这个趋势就可能会被淘汰。他也联系我们准备做整个中台系统,差不多几个月的时间里快速复用阿里中台技术架构,构建他的整个零售系统,当然在这个过程中也遇到了一些问题。就是做微服务系统的时候,之前他的整个系统有 POS 机、Web、App 多端接入,包括有一些传统架构,一部分是新的微服务架构,这个过程中,通过新的云原生网关解决了内网到外网的安全问题,比如证书管理、Web 防护、安全认证等。

 

另外斯凯奇也会做大促,峰值是平时的好几倍,他们复用了阿里整个三季度的高可用体系,从入口到后端,做了一个端对端全链路的限流降级熔断的机制,保证整个交易过程中的高可用。也通过整个全链路压测系统去演练,提前一个月就演练成功,支撑了整个斯凯奇在双 11 当天交易的电商系统。

 

几个月的时间能打造这样的一个系统,这就是整个云原生给大家带来的一个红利,我就简单分享这两个案例。

 

至简:我简单补充一下,今天讲云原生架构的落地不是很小的数字了,已经是成千上万的概念。

 

如果你经常关注整个行业,就可以看到,几乎有一点名气的互联网大厂,都不是说在探索了,已经是深度用了,我认为在这点上是没有任何疑问的。

 

InfoQ:在这个过程中或者说新技术的落地和应用会遇到什么问题,又该如何面对?

 

至简:我认为我们在面对新技术的时候,“新”不是最大的问题。

 

我恰恰认为每个新技术的出现,伴随着的是会让我们重新去审视每个企业在发展过程中留下来的技术债务。包括我们之前在集团内部做 Service Mesh 落地,我感受最痛的不是这个技术新不新,你不能把它做出来,而是你要花大量的精力和时间先去把把历史包袱和适配处理好。

 

所以在落地的过程中,我看到的一个最大的痛点其实还是改造的成本,包括以前的架构搬到云原生上来,可能要做服务的拆分等。因为云原生架构不是简单的说你把它搬到容器上这个事情解决了,而是说我们要借这个过程,该做微服务化的做微服务化,至少在效率上我们要有所体现。

 

彦林:我讲一下我在实践中的一些具体感受,首先大家对新技术要抱一个开放的态度。举个例子,不管是微服务还是容器的改造,它改变的不仅仅是软件的架构,还有组织的架构。比如我们把阿里的软件架构输出到一些传统企业时发现,阿里整个组织都是扁平的,微服务也是扁平的分布式的,所以大家协同效率比较高,是敏捷开发模式。但是很多组织还是金字塔的形式,跨部门协作效率会比较低。当然随着软件架构的改变,组织架构也会随着软件架构去改变,这个大家可以慢慢体会。

 

然后当大家解决心态问题迈出第一步之后,确实会陆续面对一些问题,因为软件行业没有银弹,没有万能的架构,比如微服务架构它确实是超过 10 个人的团队,超过 5 个子系统才会在整个生产力上有更大的优势。大家在做微服务本身改造的过程中更多的问题是我的系统拆到什么力度?我认为“一主一备”是比较合适的一个区间,拆的太细会带来更多的协同成本跟运维成本。当然也不是说拆的细了就是方式不行,有一些业务场景偏离线计算型的,它更轻就可以拆的更细,这个就需要有经验的专家去做领域的切分。

 

具体说微服务拆分,我当时遇到的第一个问题就是定位,微服务之后你会发现日志跑到十几台机器中去了,查看所有日志代价是非常大的,出问题的诊断代价也是非常大。现在行业链路追踪,包括 APM,还有监控报警就是解这个领域的问题。

 

另外我们看到一个数据,就是容器里 70% 都非常容易的去实施微服务,为什么呢?因为微服务之后,你应用的部署更细更多,运维成本会上升。容器很大部分通过自动化的模式解决了运维成本,起到了就是相辅相成的结果。通过容器的一个演进,解决了微服务拆分之后的一个部署成本的问题。

 

从整体上来看,我能慢慢感受到的是,现在整个容器跟微服务的使用的门槛已经比之前低多了。今天通过开源和云计算的发展,降低了这些技术的门槛,剩下的可能更多的是决策者在寻找合适的时机。比如我知道业务要爆发性增长了,复杂度变高了,我要做云原生架构的演进,把问题解决掉,大概是这样。

未来架构趋势展望

 

InfoQ:可以简单聊聊多云架构是怎么回事吗?

 

至简:在我们看来云原生很重要的一个驱动力就是防止锁定,也是企业比较在意和希望有一个标准化的东西。

 

多云的话,对于我们当前的客户,对于管理多云会有一些挑战。我觉得这会是一个过程,从最开始大家讲要上云原生,到多云、混合云,我觉得毫无疑问的是云原生有一个特别关键的点,它是让开发者越来越方便使用这个技术,它是以开发者为中心的角度去做的,所以未来肯定是会有相关的技术和产品陆续出来,包括现在已经有一些了。

 

另外,我理解短期内大家可能会觉得没有那么好用,但是我认为这个会越来越好用,这肯定是各个云厂商都会去重点关注的,因为我们发展的重点还是看我们能解决客户的哪些痛点,帮助客户更好地发展他的业务。

 

彦林:多云这个可能不同的厂商有不同的叫法,比如跨云、混合云,我们这边更多的强调分布式云。我能感受到的是,行业里为什么选择多云,大家有不同的理念。

 

海外的情况可能是有一些高可用的需求,国内就是大家希望有更便宜的资源,打价格战。海外就是希望利用每家云的优势,比如 AI 大数据谷歌云强一点,传统 ADC 领域 AWS 强一点,这样就可以混合去使用,在线业务在 AWS,离线的放在谷歌,诸如此类,配合使用。

 

我举这个例子就是说,对于大部分的厂商,跨云一定是有成本的。国内部分企业可能希望选择多家云厂商,谈一些折扣,但带来的结果是,跨云之后的运维复杂度上升和管理成本上升,我了解到的国内互联网行业在这方面投入了比较大的人力去抹平。

 

InfoQ:我们之前收集了一些社区问题,想问一下未来五年软件架构会出现什么样的新形态?

 

至简:架构究竟是什么我觉得我们需要先捋一捋,我理解的架构是由三个要素组成的,核心就是概念,第二个是概念跟概念之间的关系,在概念和关系之上施加的第三个要素就是约束。

 

云原生的出现其实讲的是一种架构的实践,这种实践它是基于我们过去所看到的面临的问题,重新回顾和反思,把之前的概念打破、拆分,再重新去塑造这个概念,最后形成了今天所讲的 Best Practices(最佳实践),包括很多设计模式比如 Sidecar、Operator 等等。

 

如果说未来五年完全没有新的架构理念出来也不太可能,但是颠覆性的,我个人认为不太会。如果要颠覆云原生架构,首先云原生技术需要应用到一定程度,然后遇到了还有更极致的追求的状况。至于变化,有新的概念提出来是很正常的,行业的发展就是不断的有人塑造概念,这恰恰是技术发展的现象和自然而然的一个状态。

 

彦林:除非量子计算发声,我认为这个时代来临之前分布式时代会长期的存在。然后在长期存在的分布式时代里,我们能感受到一些趋势在发生。

 

因为有了容器,有了微服务,业务变成无状态了,今天整个灵活调度的弹性能力做到极致的话,未来 Serverless 是有可能的。从我们今年的技术架构中间件客户端轻量化,业务侧会 Serverless 化的去演进,因为业务现在是越来越无状态了。随着底层基础设施的完备,弹性能力的具备,有往上去演进的可能性,但从我们今年角度就是说偏前端比如离线计算的一些任务 Serverless 会比较容易。我相信随着基础技术的不断突破,包括硬件加速的技术等,我相信包括很多大厂对 Serverless 都有布局,之前大家谈 Serverless 都是说应用架构,现在比如消息存储都有对应的 Serverless 产品,所以 Serverless 可能就是未来的一个技术思想。

 

另外,我能感受到的是容器以下,更多的是关心 DevOps,解决运维效率,云原生前半场解决 Ops 的问题,就是运维的问题,未来更多的是解决 Dev 的问题,就是怎么让研发效率更高,开发迭代更快。当然在这个过程中,中间件包括微服务可能更多的解决默认的安全可信和稳定性问题。

架构师成长经验分享

 

InfoQ:不少程序员在从普通开发者转向架构师的时候会遇到一些瓶颈,两位老师有什么架构师成长上的经验可以分享给大家吗?

 

至简:其实架构师领域有很多东西可以讲的,我先说一下我的想法,简单分享几点,彦林可以做补充。

 

首先做架构师第一点就是对技术要有追求,需要在技术上有一些积累,对软件设计的追求,也就是我们讲的《架构之美》。

 

第二点就是懂得切换视角,站在不同的角度去看待事情。我做架构师最大的感受就是,如何站在用户、客户或者说使用者的角度去看待我们正在做的事情。当你站在使用者用户或者客户角度去看事情的时候,会发现完全不一样的东西。

 

从我自己在过去一年做商业化这件事情上来讲,是有蛮大一个感触的。无论是开发交付给客户用一个产品,还是做一个哪怕是内部的一个模块,你如何站到对方的角度去看,切换视角,你会发现我们熟悉的一个术语,我们关心的内容,客户或者用户并不这么想。然后就容易陷入一种情况,就是我认知的东西是对的,但实际上当我们如果跳出来去站到客户的角度去看的时候,发现想法完全不一样。

 

我个人觉得比较重要的就是思维的不断升级,从关注个人,到关注的是更大的团队、组织,是一个不断突破的过程,做一个好的架构师,要有持续抽象能力,需要很务实,需要有商务思维。我认为是认知不断升级的过程,越往高处走,会发现技术只是一部分,但是我要强调的是不要认为技术不重要,恰恰是把基础技术打扎实了,才能有自信往前去突破。

 

彦林:刚才至简讲的很好,切换视角是很多人从程序员变成架构师或者是PD、领导者的时候,都绕不过的一个坎儿。然后我补充以下我这边的几个想法,我经常面试,所以会结合这个来讲一下我比较关心的几个事情。

 

首先,就基础技术或者软件开发来说,我比较喜欢有好奇心的人,对技术感兴趣,就能不断把技术作深,反之做技术就容易浮在表面,很难有长期的技术沉淀。好奇心驱动,才能在软件技术行业深耕发展,走的更远。

 

第二,就是工作中主动担当。我也经常跟团队的同学讲,你搞不定我帮你一起做。在这个过程中,你可以得到更多的资源和帮助,获得更快的成长。很多的成长都是往高区域跳一下,挑战一下更有难度的事情,这样才能不断锻炼自己,站在更高层面思考问题。

 

第三,就是思考维度。刚才至简提到了用户视角和技术视角,还有一个视角也比较重要,就是全局观。

 

举例来说,比如刚入职的员工看问题、拆解问题,不会想特别多,能把 10 个问题拆解成 5 个需求,5 个问题就已经上了一个层级,能从这 5 个需求中找出不合理的同时避开,这就有了产品的思维,再平衡排期把剩余合理需求做完就锻炼了投入产出比与优先级思维。而当你完整做完一整个产品的时候,你会不断跟前后端、运营等做协同,协同的过程中能力就会慢慢锻炼出来。同理,再往上走就是更多的周边资源协同的能力等等。

 

简单总结一下,入职 2-3 年,核心技术的深度积累是非常重要的,有了深度才能走的更远;技术扎实之后,第二点就是培养产品思维,产品思维很重要,不要只是做技术;具备产品思维之后,第三个要做的就是上下游人的协同,做做架构师需要跟多个角色打交道才能把事情做好;等到协同做好了要解决的问题就是领导力与规划未来的能力,这个要求就会比较高了。

 

InfoQ:非常两位老师的解答,因为时间关系今天的直播就差不多到这里结束了,非常感谢大家的观看,也很感谢至简和彦林带给我们的精彩分享。

 

嘉宾介绍:

 

李云(花名:至简),阿里云服务网格混合云产品技术负责人。2018 年开始在阿里集团带领团队从事服务网格技术的发展与建设工作,在 QCon 做过多次云原生与服务网格的技术分享。

 

李艳林(花名:彦林),Nacos PMC,阿里云 MSE 产品创始人,阿里云软负载团队负责人。

从 0 到 1,我的分布式数据库落地经验谈

2022年1月27日 08:34
作者 任传英

 

采访嘉宾:周传凯。天津银行股份有限公司,数据中心系统软件组组长、数据中心云数据库架构师、数据中心云系统架构师。

 

对于金融行业而言,IT 系统的每一次架构换代升级都是关系到企业整体业务安全性、可靠性,甚至可能影响金融市场稳定性的重大事项。与此同时,金融企业面对迅速增长的业务规模与日新月异的市场需求又必须紧跟趋势,及时完成 IT 系统技术升级,从而保持自身的市场地位与竞争力,满足用户多元需求。在这样的背景下,企业 IT 部门就要充分把握好技术架构换代过程中的平衡,在确保安全可靠的前提下尽快充分利用新兴技术的各项优势。

 

近年来,随着云计算、微服务等技术理念逐渐取代传统的单体架构,数据库领域也开始迎来由分布式数据库主导的变革潮流。对于银行等金融企业而言,分布式数据库可以带来很多显而易见的收益,但出于金融准确性、安全性、稳定性的极高要求,如何在不影响业务可靠性的前提下平稳落地这一新兴技术,是很多企业管理者和 IT 部门面对的挑战。在国内,天津银行自 2018 年起就开始了分布式数据库落地的实践探索,至今已经取得了值得称道的成果,完成了项目立项之初设定的各个目标。近日,InfoQ 采访了天津银行数据中心系统架构师周传凯;他从个人经验出发,分享了金融企业从 0 到 1 落地分布式数据库的完整历程。

 

从传统数据库到分布式数据库,转型的驱动力源自何处?

 

2018 年之前,天津银行主要使用的数据库分别是 Informix 和 Oracle 两种单体数据库。前者运行在 AIX 小型机上,主要处理记账类业务。后者运行在较新的服务器上,处理的业务更加全面。

 

回顾历史,金融行业的 IT 系统曾经长期被 IOE(IBM、Oracle、EMC)的单体软硬件架构统治。国内各大银行每年都要投入巨资维护和更新基于 IOE 产品的 IT 系统,天津银行所使用的 Informix 与 Oracle 数据库就是一个典型案例。在云时代到来之前,IOE 体系以其强大的性能、极高的稳定性/可靠性和广泛深厚的功能积累深得金融企业信赖,很少有人试图对这一局面发起质疑和挑战。

 

但随着时间推移,尤其是云原生潮流席卷全球 IT 行业后,IOE 体系遭遇到了前所未有的冲击。由于 IOE 软硬件架构本质上仍以传统的单体设计为主,难以适应云时代去中心化、分布式的设计开发理念;相关产品高昂的购买升级与维护成本也令企业愈加不堪重负;最重要的是,IOE 软硬件很难满足新时代金融业务快速增长和变化的业务需求,逐渐成为企业竞争力提升道路上的“绊脚石”。正因如此,近年来金融行业开始探索利用围绕云原生理念的 IT 系统架构,逐渐替换传统的 IOE 解决方案。

 

在天津银行的运营实践中,Informix 与 Oracle 两种传统数据库就随着业务增长而逐渐暴露出了一系列问题:

 

1. Informix 的维护、迭代和演进高度依赖 IBM,存在对接维护人员经常更换、长期维护较为困难的问题;

2. Informix 不具备横向扩展能力,只能通过硬件更新实现性能提升;

3. 数据量达到 PB 量级后,Oracle 会出现性能瓶颈,需要做分区表等优化;

4. Oracle 对双活切换不够友好,双线切换延迟较大。

 

与此同时,天津银行正在与蚂蚁集团等外部企业展开合作,并引入敏捷开发、分布式事务等技术理念,自然就需要将数据库从传统的单体架构升级为分布式架构,与整体的开发变革步伐相适应和匹配。2019 年,天津银行引入阿里云的整套产品线打造专有云,周传凯由此接触到了100%自主研发的 OceanBase 原生分布式数据库产品,开始带领银行 IT 部门正式踏上了分布式数据库落地之路,开启了银行在数据库领域对传统架构的升级的旅程。

 

回顾银行选择分布式数据库产品的经历,周传凯认为这里的关键在于专有云的架构选项。在他看来,分布式数据库与专有云是一个整体,分布式的数据场景、微服务化的业务和分布式数据库可以共同形成 1+1 大于 2 的效应。因此,很少有金融企业会单独购买某种分布式数据库产品,更多情况下还是会像天津银行这样,将分布式数据库作为专有云架构的一个捆绑解决方案。但与之前的 IOE 时代相比,企业在云原生升级选型时可选的解决方案提供商数量要多很多,厂商之间的竞争更为激烈,技术迭代升级步伐更快,这样的局面自然更符合行业客户的长期利益。

 

分布式数据库落地实践,步步为营才是成功之道

 

如前所述,金融企业在落地新兴技术架构时都会采取非常谨慎的态度,天津银行自然也不例外。选定 OceanBase 后,银行为分布式数据库的落地安排了三期工程,分为三年实施。一期工程主要以技术验证为目的,承载一些银行二类产品的开户、记账等功能。在这一期间,周传凯带领的团队遇到了非常多的问题,往往需要与OceanBase技术团队共同探讨和解决。

 

2020 年的二期工程中,银行将 OceanBase 从 1.4.79 升级到了 2.2.76,引入了一些 Oracle 相关特性。二期工程开始将银行自营网贷、风控和门户转移到 OceanBase,并规划了同城双活架构。这一过程中涉及的主要问题更多是架构和规划层面,周传凯会经常与阿里团队探讨诸如链路延时、多副本冗余度等细节和技术目标。

 

2021 年三期工程开始后,天津银行在某次宕机时间中发现在单体时代传统的业务上线、审批流程不一定适应云原生、分布式数据库的使用场景,并通过此次事件对业务上线流程做了优化。经过打磨调优后,OceanBase与业务开发端的协同能力得到增强,可用性、安全性进一步提升,也为未来更多业务逐步上云巩固了基础。天津银行上线了一个重要的银行卡系统。该系统涉及的业务场景需要对每一笔与银联系统的交易做流水表查销,交易量达到 1100 万规模。然而上线半个多月后系统突然宕机,结果发现原因在于缺少字段统一索引。虽然问题很快得到了解决,但这也暴露出了新业务上线把关存在的审查漏洞。为此,周传凯团队与 OceanBase 团队做了深入讨论、调优和培训,最终圆满解决问题的同时,为后续的迁移工作保障提前打好了基础,这也得益于OceanBase数据库是100%自主研发的国产原生分布式数据库,在遇到一些核心应用的问题的时候,原厂研发人员可以快速定位进行优化,通过快速的迭代精准解决用户痛点。

 

归根结底,企业从传统单体数据库转向分布式数据库的最终目的是要更好地解决业务实践中遇到的种种问题和挑战。从 2019 年的第一期工程开始到现在,周传凯团队对分布式数据库的优势与收益有了更加深入的体会:

 

1. OceanBase 高度兼容Oralce和MySQL引擎,实际使用中非常便利。

2. OceanBase 的数据同步方式很好用。与传统数据库往往只能在两个副本之间同步的设置相比,OceanBase 可以实现三个、五个、七个副本的同步,获得灵活的扩展能力。

3. OceanBase 的透明迁移能力可以在业务运行状态下完成很多升级事项,对于强监管的金融行业来说非常便利。业务不中断意味着不需要根据监管要求提前报备,可以有效改善客户体验。

4. OceanBase 对容灾建设有着很强的支持能力,可以轻松实现多活、副本迁移等工作。

5. OceanBase 具备灵活的资源扩展能力,一个租户可以迅速无停机扩展 CPU 核心数量,在高压力交易场景实现实时扩容,很好地应对未来的业务增长要求。

 

除此之外,周传凯还发现 OceanBase 的运行效率与优化改进是息息相关的。例如现有的分库分表的具体实现方式、索引方案等等,都可以根据 OceanBase 的实际运行情况做针对性配置调整和优化。经过实践中的逐渐优化过程,OceanBase 就能发挥出很高的效率,相应的优化措施也可以沉淀为具体的技术规范。企业使用 OceanBase 的时间越久,积累下来的领域知识也会越丰富,从分布式数据库中获得的收益自然就能水涨船高。在实际使用过程中,也发现OceanBase的LSM Tree压缩技术可以极大的节省原先的存储资源成本,某些特定场景下甚至可以节省90%以上,这也给整个项目组带来实实在在的成本节省。

 

展望未来,分布式数据库的改进方向

 

谈到对分布式数据库未来发展的期待,周传凯希望相关产品的定价能够更加实惠便宜。从天津银行的实践过程来看,业务系统的云端迁移花费的成本巨大,系统改造、重构和新业务开发都需要资源投入。在这样的背景下,留给分布式数据库的预算必然吃紧,这时如果产品本身的价格能够更加优惠,银行就能加快原有业务的升级步伐。

 

另一方面,如果分布式数据库能够更多兼容传统数据库的功能、语法和特性,也能有效节省客户上云改造的成本和时间。例如 Oracle 的 AWR 运维性能分析报告,以及调优功能逻辑模块,都是分布式数据库可以参考借鉴的技术特性。从产品层面,周传凯也期待与 OceanBase 团队的合作能够不断引入更多前沿技术理念和新的产品功能,并更早转化为实际的业务收益,实现降本增效的目的。

 

总结:分布式数据库是行业大势所趋

 

从行业层面来看,周传凯认为分布式数据库的全面普及已经是不可阻挡的趋势。即便在金融行业这样业务要求非常高的领域中,分布式数据库也已经具备了替代传统核心的能力。在云原生浪潮的推动下,分布式数据库作为云原生架构不可分割的一环,必然会逐渐取代传统单体数据库成为企业数据库的主流选项。但在具体的落地过程中,分布式数据库产品开发商和客户仍需要通力合作,根据实际业务需求和实践中遇到的挑战对产品进行持续打磨和优化,不断降低产品成本和部署难度。

 

长远来看,从单体架构发展到微服务、云原生、分布式软件体系,背后都是不断增长和愈加复杂多变的业务需求推动的。随着业务规模的扩张,企业对数据价值和安全性更加重视,分布式数据库天然具备的高可扩展性、高可用性、灵活性、高性价比等优势会越来越凸显。在金融行业,金融科技兴起,行业全面转向云原生的大背景下分布式数据库成为主流也只是时间问题。天津银行与OceanBase的合作经验为行业在这一领域的探索提供了很好的榜样参考,也标志着分布式数据库在金融领域即将迎来大规模普及,为企业数字化转型带来可观价值与驱动力。

cURL开源作者怒怼“白嫖”企业:我不删库跑路,但答疑得付钱!

2022年1月27日 06:11
作者 褚杏娟

cURL 作者 Daniel Stenberg 在1 月 21 日"收到了一家美国《财富》500 强企业发来的电子邮件,要求 Stenberg 回答关于 cURL 是否受到 Log4Shell 漏洞影响以及如何处理等问题。随后,他将邮件内容截图发到了推特上,并写道:

 

如果你是一家价值数十亿美元的公司还关注 Log4j,怎么不直接给那些你从未支付过任何费用的 OSS 作者发邮件,要求他们 24 小时内免费回复你这么多问题?

 

这件事迅速引发了网友们的关注。

把开源当成供应商

根据公开的邮件内容,这家《财富》500 强企业(暂且称为“NNNN”)将 Daniel 团队当成了产品供应商,并要求其24小时内免费提供关于Log4j 漏洞的解决方案。下面是NNNN要求 Stenberg 回答的问题:

 

如果您在应用程序中使用了 Java 日志库,那么正在运行的是哪些 Log4j 版本?贵公司是否发生过任何已确认的安全事件?如果是,哪些应用程序、产品、服务和相关版本会受到影响?哪些 NNNN 产品和服务受到影响?NNNN 的非公开或个人信息是否会受到影响?如果是,请立即向 NNNN 提供详细信息。什么时候完成修复?列出每个步骤,包括每个步骤的完成日期。NNNN 需要采取什么行动来完成此修复?

 

cURL(client URL 请求库的简称)是一个命令行接口,用于检索可通过计算机网络访问资源的内容。资源由 URL 指定,并且必须是软件支持的类型。cURL 程序实现了用户界面,基于用 C 语言开发的 libcurl 软件库。

 

Apache Log4j 日志库被 Java/J2EE 应用开发项目和基于 Java/J2EE 的现成软件解决方案的供应商大量使用。去年12 月 9 日,Log4j 中被发现了一个漏洞,攻击者通过该漏洞能够进行远程代码执行,具体包括通过受影响的设备或应用程序访问整个网络、运行任何代码、访问受影响设备或应用程序上的所有数据、删除或加密文件等。可以说,cURL 开源代码与 Log4j 漏洞事件毫不相干。

 

虽然 Stenberg 从未参与过任何 Log4j 的开发工作,也没有任何使用了 Log4j 代码的版权产品,但 Stenberg 还是回复道,“你不是我们的客户,我们也不是你的客户。”并略带调侃地表示,只要双方签了商业合同就很乐意回答所有的问题。

 

“发邮件”只是例行公事?

 

“这封电子邮件显示出来的无知和无能程度令人难以置信。”Stenberg 在博文里写道,“很奇怪他们现在才发送关于 Log4j 的查询邮件,这似乎有点晚了。”

 

“这很可能只是一封发送给数十或数百个其他软件供应商/开发人员的模板电子邮件。如果确实来自像我过去工作过的那些大型企业,他们很可能会要求各种 IT 支持和开发团队编制一份企业使用的所有软件/工具的列表以及每个软件/工具的电子邮件地址。所以,很大可能只是有人按照项目计划中的要求向供应商发送电子邮件以延缓问题,并勾选他们的方框,说明已联系该供应商/开发人员。”有网友猜测道。

 

网友“Jack0r”介绍,其所在公司规定要有一个记载依赖项的Excel 列表,列表里大多数是开源软件,还有一些封闭源代码和付费产品。开发人员要为每个依赖项设置一个联系人,因此与某软件相关的电子邮件可能会被放入列表中。但这个列表通常非常过时,也没有人专门更新。

 

“我曾经被要求填写一份3页关于Oracle数据库的详细资料表,但我们从未使用过Oracle。有的软件运行在Postgres上,有的运行在MySQL上,有的运行在NoSQL上,但他们说,‘MySQL是从Oracle来的,不是吗?’”网友现身说法。

 

而当出现严重安全漏洞时,负责Excel 工作表的人员(非开发人员,也不知道这些依赖项如何使用,甚至不知道它们是什么)必须联系每个依赖项的所有者并向他们提出相同的问题。他们这样做不是为了做有用的事情,只是为了告诉他们的客户“我们正在竭尽全力修复这个漏洞”。大多数情况下,这些甚至要被写进合同中。

 

Reddit"上也有网友表示,Stenberg 收到的邮件来自对计算机或开源一无所知的律师助理。他只是有一长串的名字要联系,这样就可以为公司建立防御,防止因黑客攻击而被起诉。他甚至不在乎公司是否被黑,也不在乎会不会被起诉,他只关心自己的工作,那就是做好准备,以防万一。

 

因此,有人庆幸道,这就是为什么开源许可证非常重要的原因。开源许可证保护了作者的权益,同时确保了治理到位是企业的责任。

 

“只盖房子而不关心地基”

 

“我认为,这可能是开源金字塔"的一个很好例证,上层用户根本不考虑底层设施的维护。只盖房子而不关心地基。”Stenberg 写道。

 

开源金字塔的最底部是基础组件、操作系统和库,上面所有的东西都是在此基础上建立的。

 

越往上走,产品更多是面向终端用户,企业能赚更多的钱,同时产品迭代更快、语言要求层次更高,开放源码的份额也不断减少。在最上面,很多东西已经不是开源的了。反之,越往下走,产品使用寿命更长,语言要求不好,但bug的影响更大,修复需要的时间更长,因此维护比重构更重要。在最底部,几乎所有的东西都是开源的,每个组件都被无数的用户所依赖。

 

只要有可能在不为“公共基础设施”付出很多就能赚到很多钱,那么企业就没有什么动力去投资或支付某些东西的维护费用。但足够好的软件组件也会偶尔出现bug,但只要这些漏洞没有真正威胁到赚钱的人,这种情况就不会改变。

 

Stenberg 认为,为依赖项的维护付费有助于降低未来在周末早上过早发出警报的风险。底层组件的开发者们的工作就是要让依赖其组件功能的用户相信,如果他们购买支持,就能更加放心,避免任何隐藏的陷阱。

 

根据Linux 基金会和学术研究人员对 FOSS(免费和开源软件)贡献者进行的调查,开发者们花在安全问题上时间低于3%,同时受访者并不希望增加花在安全上的时间。“安全事业是一项令人沮丧的苦差事”“安全是令人难以忍受的无聊程序障碍”。有足够的资金让工程师将时间花在代码维护上,或许可以降低严重故障的发生率。

 

与此同时,底层开发者与上层使用者之间的矛盾日益加深。1 月 11 日, Apache PLC4X 的创建者 Christofer Dutz 在 GitHub 发文称,由于得不到任何形式的回报,他将停止对 PLC4X 的企业用户提供免费的社区支持。若后续仍无企业愿意站出来资助项目,他将停止对 PLC4X 的维护和任何形式的支持。

 

有的组件可能被成千上万家公司用于一项很小而重要的任务,有的是与Apache PLC4x 一样,可能只有一个少数组织形成的自然市场。但目前没有具体办法来衡量使用组件给企业带来的收益,更没有一个通用方案可以用来收集和分配企业对开源项目的捐款。

 

开源可持续性问题的解决已经迫在眉睫。

❌