WebStorm 2022.3 正式发布,该版本带来了新的 UI 预览、Vitest 支持、适用于 Vite 和 Next.js 的项目模板、针对 JavaScript 和 TypeScript 的 Code Vision、适用于 Angular 模板的类型缩小支持以及 Vue 更新。
框架和技术
更新了项目模板
我们重做了 WebStorm 欢迎屏幕中的 New Project(新建项目)向导。 在 v2022.2 中,我们移除了适用于 AngularJS、Cordova 和 Meteor 的项目模板。 在此版本中,我们添加了适用于 Vite 和 Next.js 的新项目模板,并更新了 Vue 模板,使其符合最新标准。
Vitest 支持
WebStorm 现在支持 Vitest,这是一个 Vite 原生单测试框架! 您可以用所有您能想到的主要方式运行、重新运行和调试测试,包括通过间距图标。 此外,监视模式在所有测试场景下默认均已启用。 在监视模式下还支持快照测试和覆盖率,从而在编码时为您提供几乎即时的覆盖率反馈。
Vue 更新
WebStorm 现在可以处理未解析的导入,并为导入 Vue 组件提供建议。 我们也已支持 props 析构语法,改进了针对 Vue 库组件 props 的代码补全和类型检查行为,并修正了几个 Nuxt 3 问题。
Vue 的新代码段
此版本中,还有一项针对 Vue 的改进值得仔细研究 – 新代码段,也就是 WebStorm 中的实时模板。 您可以使用它们更快添加常见构造,例如 或 。 转到 Preferences / Settings | Editor | Live Templates(偏好设置/设置 | 编辑器 | 实时模板),展开 Vue 部分即可浏览可用代码段。
Angular 模板中的类型缩小
我们在 Angular 模板中添加了对类型缩小的支持,这将提供更精确的类型信息和更好的代码补全建议。 此外,WebStorm 现在会从全局搜索中排除 缓存文件夹,帮助提供更好的搜索结果。
关于 Svelte 支持的更新
对 Svelte 支持(作为单独插件提供)的改进现在将随新 IDE 构建一起推出,就像 Angular 和 Vue 一样。 这将帮助我们避免不兼容版本范围的问题并更快获得反馈。
对新 CSS 功能的支持
WebStorm 2022.3 支持新的 CSS 功能,例如 at-rule,它将语句块与 条件相关联。 视口单、范围媒体查询、容器查询、级联层和颜色修改函数现在也已获得支持。
JavaScript 和 TypeScript
针对 JavaScript 和 TypeScript 的 Code Vision
来自 Rider 和 IntelliJ IDEA 的 Code Vision 功能现已加入 WebStorm! Code Vision 可以收集类型和类型成员的各种指标,并在声明附近显示此信息。 这将使代码中各种类、方法、类型别名和接口的用法更易跟踪。 转到 Preferences / Settings | Editor | Inlay Hints(偏好设置/设置 | 编辑器 | 内嵌提示)配置 Code Vision。
更出色的 monorepos 和 TypeScript 体验
我们为在 WebStorm 中处理 monorepos 和 TypeScript 发布了多个修正。 导航、自动导入和重命名重构功能都将更可靠地运行。 这适用于所有主流软件包管理器,包括 npm、Yarn 和 pnpm。
字母排序意图
WebStorm 2022.3 包含按字母顺序对 JavaScript 和 TypeScript 对象进行排序的新意图。 运行此意图时,它将按字母顺序重新格式化对象内所有属性的代码。 要使用此意图,首先高亮显示方法中的对象,按 ⌥⏎,然后选择 Sort properties alphabetically(按字母顺序对属性排序)。
用户体验
通过设置使用新 UI
今年早些时候,我们宣布了 JetBrains IDE 中新 UI 的封闭预览计划。 对于这第一步,我们的目标是向有限数量的用户提供重做的 IDE 外观。 我们邀请您在 Preferences / Settings | Appearance & Behavior / New UI(偏好设置/设置 | 外观与行为/新 UI)中切换到新 UI 并告诉我们您的想法。
将工具窗口停靠到浮动编辑器选项卡的选项
为了让您可以更轻松地安排工作空间并在多个显示器上与 WebStorm 交互,我们实现了将工具窗口拖出主窗口并将其停靠到浮动编辑器选项卡的选项。
改进了 Search Everywhere(随处搜索)结果
Search Everywhere(随处搜索)结果列表背后的算法经过微调,行为更加可预测和准确。 IDE 将冻结出现的第一个搜索结果,并且不会在找到更多选项时对其重新排序。 此外,ML 排名现在对 Files(文件)选项卡启用,可以提高查找结果的准确性。
新的 Settings Sync(设置同步)解决方案
新的 Settings Sync(设置同步)插件现在可用于 WebStorm。 新的解决方案能够同步来自平台、捆绑插件和一些第三方插件的大部分可共享设置。 请注意,我们将停止支持旧的 IDE Settings Sync(IDE 设置同步)插件并取消捆绑 Settings Repository(设置仓库)。
改进了每日小技巧
WebStorm 的内置学习工具 Tip of the Day(每日小技巧)得到微调。 我们添加了技巧评分功能,并重做了技巧显示方式的算法。 这应该使它们与您的 IDE 体验和您手头的项目更加相关。
适用于 Windows 和 Linux ARM64 的安装程序
现在,可以在带有 ARM64 处理器的 Windows 和 Linux 机器上运行 WebStorm。 IDE 安装程序处于测试版阶段,网站和 JetBrains Toolbox App 均提供 Windows 版,但 Linux 版仅可从网站获得。
针对书签的 UI 改进
我们为 Bookmarks(书签)功能实现了多项 UI 改进。 例如,右键选项卡并从上下文菜单中选择 Bookmarks(书签)即可从编辑器选项卡为文件添加书签。
编辑器
改进了复制剪切粘贴行为
我们重做了粘贴操作 (⌘V) 的行为。 现在,如果在没有选择代码的情况下复制 (⌘C) 或剪切 (⌘X) 一行,粘贴操作会将剪贴板的内容添加到当前行上方,而不是像旧版本一样添加到文本光标处。 您可以在 Preferences / Settings | Advanced Settings(偏好设置/设置 | 高级设置)中禁用此行为。
意图操作预览
我们添加了新功能来预览和解释应用所选操作会发生什么。 打开可用意图操作列表并将鼠标悬停在不同选项上时会显示预览。 在意图操作列表打开时,您可以按 F1 禁用此功能。
软件包的漏洞检查器
WebStorm 2022.3 将对照 Checkmarx SCA 数据库和 National Vulnerability Database 检查软件包,检测项目中所用软件包的漏洞。 IDE 将高亮显示被认为易受攻击的软件包,并在可用时建议修正。
针对 YAML 的编辑改进
新增的快速修复可以通过 YAML 文件中的注释禁止检查,包括 docker-compose.yml、Kubernetes 文件和 OpenAPI 规范。 我们还引入了一个方便的选项,用于折叠组成 3 行或更多行的块并以 开头的多行注释 – 使用注释左侧的加号和减号图标。
集成开发者工具
针对 Docker 的改进
WebStorm 现已支持连接到 WSL 中运行的 Docker。 此外,还有新增的 Pull Docker image(拉取 Docker 镜像)意图、对 文件和 heredoc 语法的完全支持,以及使用 Docker 上下文设置 Docker 连接的功能。
为 GitHub 和 Space 重新设计了 Review list(审查列表)
我们重做了 Review list(审查列表)UI,帮助减少认知负担并清晰提供有关请求的最重要信息。 其中,我们还确保在所有受支持的审查平台上保持一致的外观。
处理 WSL2 中的项目的新方式
WebStorm 2022.3 带来了处理在 WSL2 文件系统中运行的项目的替代方式。 您可以直接在 WSL2 中启动 IDE 后端,而不是在 Windows 上运行完整的 IDE。 然后,您可以像在 WebStorm 中使用远程开发时连接到远程机器一样连接到它。
针对 HTTP 客户端的新功能
HTTP 客户端现在支持在请求之前执行的脚本块。 您可以在请求执行之前生成一些数据,并使用变量将其放入最终请求。 WebStorm 现在还提供 сrypto API,使代码能够计算 HTTP 请求的 md5 或 sha1 哈希值。
针对 HTTP 客户端的代码样式改进
HTTP 客户端现在为具有长 URL 的请求提供了更好的格式设置选项。 您也可以使用 Put query parameters on separate lines(将查询形参置于单独的行中)意图操作,将查询拆分成不同行中的小片段。 转到 Preferences / Settings | Editor | Code Style | HTTP Request | Wrapping and Braces(偏好设置/设置 | 编辑器 | 代码样式 | HTTP 请求 | 换行和大括号)即可控制有关 HTTP 请求格式设置的偏好设置。
更多详情可查看:https://blog.jetbrains.com/webstorm/2022/11/webstorm-2022-3/
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
漏洞描述
Apache Fineract 是一个用于金融服务的开源软件。
Apache Fineract 在 1.8.1 之前的版本中由于 FileSystemContentRepository.java 类对用户传入的文件路径名限制不当从而存在路径遍历漏洞,经过身份验证的攻击者可利用此漏洞上传包含恶意代码的文件到系统任意目录,在 Fineract 加载恶意文件时远程执行恶意代码。
影响范围
apache/fineract@(-∞, 1.8.1)
修复方案
升级apache/fineract到 1.8.1 或更高版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-62935
https://nvd.nist.gov/vuln/detail/CVE-2022-44635
https://github.com/apache/fineract/commit/90f854ba466b048807c26ccf31a6f555
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
背景
字节跳动特征存储痛点
当前行业内的特征存储整体流程主要分为以下四步:
特征存储的整体流程
-
业务在线进行特征模块抽取;
-
抽取后的特征以行的格式存储在 HDFS,考虑到成本,此时不存储原始特征,只存抽取后的特征;
-
字节跳动自研的分布式框架会将存储的特征并发读取并解码发送给训练器;
-
训练器负责高速训练。
字节跳动特征存储总量为 EB 级别,每天的增量达到 PB 级别,并且每天用于训练的资源也达到了百万核心,所以整体上字节的存储和计算的体量都是非常大的。在如此的体量之下,我们遇到了以下三大痛点:
-
特征抽取周期长。在特征抽取上,当前采用的是在线抽取的方式。大量的算法工程师,每天都在进行大量的特征相关的试验。在当前的在线抽取模式下,如果有算法工程师想要调研一个新的特征,那么他首先需要定义特征的计算方式,等待在线模块的统一上线,然后需要等在线抽取的特征积累到一定的量级后才可以进行训练,从而判断这个特征是否有效果。这个过程通常需要2周甚至更长的时间。并且,如果发现特征的计算逻辑写错或想要更改计算逻辑,则需重复上述过程。在线特征抽取导致当前字节特征调研的效率非常低。基于当前的架构,离线特征调研的成本又非常高。
-
特征存储空间占用大。字节的特征存储当前是以行存的形式进行存储。如果基于当前的行存做特征调研,则需要基于原来的路径额外生成新的数据集。一方面需要额外的空间对新的数据集进行存储,另一方面还需要额外的计算资源去读取原来的全量数据生成新的数据,且很难做数据的管理和复用。行存对于特征存储来说,也很难进行优化,占用空间较大。
-
模型训练带宽大,数据读取有瓶颈。字节当前将每个业务线的绝大部分特征都存储在一个路径下,训练的时候会直接基于这个路径进行训练。对于每个模型,训练所需的特征是不一样的,每个业务线可能存有上万个特征,而大部分模型训练往往只需要几百个特征,但因为特征是以行存格式进行存储,所以训练时需要将上万特征全部读取后,再在内存中进行过滤,这就使得模型训练的带宽需求非常大,数据的读取成为了整个训练的瓶颈。
基于痛点的需求梳理
基于上述问题,我们与业务方一同总结了若干需求:
-
存储原始特征:由于在线特征抽取在特征调研上的低效率,我们期望能够存储原始特征;
-
离线调研能力:在原始特征的基础上,可以进行离线调研,从而提升特征调研效率;
-
支持特征回填:支持特征回填,在调研完成后,可以将历史数据全部刷上调研好的特征;
-
降低存储成本:充分利用数据分布的特殊性,降低存储成本,腾出资源来存储原始特征;
-
降低训练成本:训练时只读需要的特征,而非全量特征,降低训练成本;
-
提升训练速度:训练时尽量降低数据的拷贝和序列化反序列化开销。
字节跳动海量特征存储解决方案
在字节的整体架构中,最上层是业务层,包括抖音、头条、小说等字节绝大部分业务线;
其下我们通过平台层,给业务同学提供简单易用的 UI 和访问控制等功能;
在框架层,我们使用 Spark 作为特征处理框架(包括预处理和离线特征调研等),字节自研的 Primus 作为训练框架;
在格式层,我们选用Parquet 作为文件格式,Iceberg 作为表格式;
最下层是调度器 Yarn & K8s 以及存储 HDFS。
下面我们重点针对格式层进行详细介绍。
技术选型
为了满足业务方提到的6个需求,我们首先想到的是通过 Parquet 列存的格式,降低行存的存储成本,节省的空间可用来存储原始特征。同时由于 Parquet 选列可以下推到存储层的特性,在训练时可以只读需要的特征,从而降低训练时反序列化的成本,提升训练的速度。
但是使用 Parquet 引入了额外的问题,原来的行存是基于 Protobuf 定义的半结构化数据,不需要预先定义 Schema,而使用 Parquet 以后,我们需要先知道 Schema,然后才能进行数据的存取,那么在特征新增和淘汰时,Schema 的更新就是一个很难解决的问题。Parquet 并不支持数据回填,如果要回填历史几年的数据,就需要将数据全量读取,增加新列,再全量写回,这一方面会浪费大量的计算资源,另一方面做特征回填时的 overwrite 操作,会导致当前正在进行训练的任务由于文件被替换而失败。
为了解决这几个问题,我们引入了 Iceberg 来支持模式演进、特征回填和并发读写。
Iceberg 是适用于大型数据集的一个开源表格式,具备模式演进、隐藏分区&分区演进、事务、MVCC、计算存储引擎解耦等特性,这些特性匹配了我们所有的需求。因此,我们选择了 Iceberg 作为我们的数据湖。
整体上 Iceberg 是一个分层的结构,snapshot 层存储了当前表的所有快照;manifest list 层存储了每个快照包含的 manifest 云数据,这一层的用途主要是为了多个 snapshot 可以复用下一层的 manifest;manifest 层,存储了下层 Data Files 数据;最下面的 Data File 是就是实际的数据文件。通过这样的多层结构,Iceberg 可以支持上述包括模式演进等几个特性。
下面我们来一一介绍 Iceberg 如何支持这些功能。
字节跳动海量特征存储解决方案
并发读写
在并发读取方面,Iceberg 是基于快照的读取,对 Iceberg 的每个操作都会生成新的快照,不影响正在读取的快照,从而保证读写互不影响。
在并发写入方面,Iceberg 是采用乐观并发的方式,利用HDFS mv 的原子性语义保证只有一个能写入成功,而其他的并发写入会被检查是否有冲突,若没有冲突,则写入下一个 snapshot。
模式演进
Iceberg 的模式演进原理
我们知道,Iceberg 数据和 Parquet 数据都有 Column,而中间的映射关系,是通过 ID 字段来进行一对一映射。
例如上面左图中,Iceberg 和 Parquet 分别有 ABC 三列,对应 ID 1、2、3。那最终读取出的 Dataframe 就是 和 Parquet 中一致包含 ID 为1、2、3的 ABC 三列。而当我们对左图进行两个操作,删除旧的 B 列,写入新的 B 列后, Iceberg 对应的三列 ID 会变成1、3、4,所以右图中读出来的 Dataframe,虽然也是 ABC 三列,但是这个 B 列的 ID 并非 Parquet 中 B 列的 ID,因此最终实际的数据中,B 列为空值。
特征回填
- 写时复制
如上图所示,COW 方式的特征回填通过一个 Backfill 任务将原快照中的数据全部读出,然后写入新列,再写出到新的 Data File 中,并生成新的快照。
这种方式的缺点在于虽然我们只需要写一列数据,但是需要将整体数据全部读出,再全部写回,不仅浪费了大量的计算资源用来对整个 Parquet 文件进行编码解码,还浪费了大量的 IO 来读取全量数据,且浪费了大量的存储资源来存储重复的 ABC 列。
因此我们基于开源 Iceberg 自研了 MOR 的 Backfill 方案。
- 读时合并
如上图所示,在 MOR 方案中,我们仍然需要一个 Backfill 任务来读取原始的 Data File 文件,但是这里我们只读取需要的字段。比如我们只需要 A 列通过某些计算逻辑生成 D 列,那么 Backfill 任务则只读取 A 的数据,并且 Snapshot2 中只需要写包含 D 列的 update 文件。随着新增列的增多,我们也需要将 Update 文件合并回 Data File 文件中。
为此,我们又提供了 Compaction 逻辑,即读取旧的 Data File 和 Update File,并合并成一个单独的 Data File。
MOR原理如上图,假设原来有一个逻辑 Dataframe 是由两个 Data File 构成, 现在需要回填一个 ColD 的内容。我们会写入一个包含 ColD 的 Update File,这样 Snapshot2 中的逻辑 Dataframe 就会包含ABCD 四列。
实现细节:
- Data File 和 Update File 都需要一个主键,并且每个文件都需要按照主键排序,在这个例子中是 ID;
- 读取时,会根据用户选择的列,分析具体需要哪些 Update File 和 Data File;
- 根据 Data File 中主键的 min-max 值去选择与该 Data File 相对应的 Update File;
- MOR 整个过程是多个 Data File 和 Update File 多路归并的过程;
- 归并的顺序由 SEQ 来决定,SEQ 大的数据会覆盖 SEQ 小的数据。
-
COW与 MOR 特性比较
相比于 COW 方式全量读取和写入所有列,MOR 的优势是只读取需要的列,也只写入更新的列,没有读写放大问题。在计算上节省了大量的资源,读写的 IO 也大大降低,相比 COW 方式每次 COW 都翻倍的情况, MOR 只需要存储新增列,也大大避免了存储资源浪费。
考虑到性能的开销,我们需要定期 Compaction,Compaction 是一个比较重的操作,和 COW 相当。但是 Compaction 是一个异步的过程,可以在多次 MOR 后进行一次 Compaction。那么一次 Compaction 的开销就可以摊销到多次 MOR 上,例如10次 COW 和10次 MOR + 1次 Compaction 相比,存储和读写成本都从原来的 10x 降到当前的 2x 。
MOR 的实现成本较高,但这可以通过良好的设计和大量的测试来解决。
而对于模型训练来说,由于大多数模型训练只需要自己的列,所以大量的线上模型都不需要走 MOR 的逻辑,可以说基本没有开销。而少数的调研模型,往往只需读自己的 Update File 而不用读其他的 Update File ,所以整体上读取的额外资源也并未增加太多。
训练优化
从行存改为 Iceberg 后,我们也在训练上也做了大量的优化。
在我们的原始架构中,分布式训练框架并不解析实际的数据内容,而是直接以行的形式把数据透传给训练器,训练器在内部进行反序列化、选列等操作。
原始架构
引入 Iceberg 后,我们要拿到选列带来的 CPU 和 IO 收益就需要将选列下推到存储层。最初为了保证下游训练器感知不到,我们在训练框架层面,将选列反序列化后,构造成原来的 ROW 格式,发送给下游训练器。相比原来,多了一层序列化反序列化的开销。
这就导致迁移到 Iceberg 后,整体训练速度反而变慢,资源也增加了。
列式改造
为了提升训练速度,我们通过向量化读取的方式,将 Iceberg 数据直接读成 Batch 数据,发送给训练器,这一步提升了训练速度,并降低了部分资源消耗。
向量化读取
为了达到最优效果,我们与训练器团队合作,直接修改了训练器内部,使训练器可以直接识别 Arrow 数据,这样我们就实现了从 Iceberg 到训练器端到端的 Arrow 格式打通,这样只需要在最开始反序列化为 Arrow ,后续的操作就完全基于 Arrow 进行,从而降低了序列化和反序列化开销,进一步提升训练速度,降低资源消耗。
Arrow
优化收益
最终,我们达到了最初的目标,取得了离线特征工程的能力。
在存储成本上,普遍降低了40%以上;在同样的训练速度下,CPU 降低了13%,网络IO 降低40%。
未来规划
未来,我们规划支持以下4种能力:
-
Upsert 的能力,支持用户的部分数据回流;
-
物化视图的能力,支持用户在常用的数据集上建立物化视图,提高读取效率;
-
Data Skipping 能力,进一步优化数据排布,下推更多逻辑,进一步优化 IO 和计算资源;
-
基于 Arrow 的数据预处理能力,向用户提供良好的数据处理接口,同时将预处理提前预期,进一步加速后续的训练。
字节跳动基础架构批式计算团队持续招聘中,批式计算团队负责字节跳动离线数据处理&分布式训练,支撑公司内离线 ETL&机器学习等业务场景,涉及的组件包括离线计算引擎 Spark/自研分布式训练框架 Primus /特征存储 Feature Store(如Iceberg/Hudi)/Ray 等。面对字节超大规模的场景,在 Spark/Primus/Feature Store 等方面都做了大量的功能&性能优化,同时支持新一代分布式应用框架 Ray 在公司相关场景的落地。
工作地点:北京/杭州
联系方式:微信 bupt001,或发送简历至邮件 qianhan@bytedance.com
HSE 是一个快速可嵌入的键值存储,专为 SSD 和持久化内存设计。HSE 通过协调跨 DRAM 和多类固态存储的数据放置,优化了性能和耐久性。
HSE 是支持数据库、软件定义存储(SDS)、高性能计算(HPC)、物联网(IoT)和机器学习(ML)的理想选择。
主要特征:
- 丰富的键值运算符集
- 用于优化单个数据存储中的混合用例工作负载的数据模型
- 键值压缩
- 灵活的耐久性控制
- 可配置的数据编排方案
- 可以嵌入任何应用程序的本地 C 库
优势:
- 每个存储可扩展到数 TB 的数据和数千亿个密钥
- 高效处理数千个并发操作
- 显着改善吞吐量、延迟、写放大、 和读取放大
- 可选地组合多种固态存储类别,以优化性能和耐久性
构建 HSE
克隆 仓库并 checkout 最新的发布标签。 此标签必须适用于 HSE 2.0 或更高版本。
例如
git clone https://github.com/hse-project/hse.git cd hse git checkout <release tag>
使用 Meson 和 Ninja 构建和安装。
可以在 meson.build 目录中找到构建 HSE 所需的最低版本的 Meson。 在那里,你会在文件开头发现一个 关键字参数的 函数。
如果你的系统没有提供足够新的 Meson 版本来构建 HSE,请参阅安装说明 。
meson setup build meson compile -C build meson install -C build
IEEE 发布了一项最新的调查结果,主要研究技术对 2023 及未来发展的影响。该调查基于来自美国、英国、中国、印度和巴西的 350 名首席技术官、首席信息官和 IT 主管等全球技术领导者的反馈。
调查指出,云计算 (40%)、5G (38%)、宇宙 (37%)、电动汽车 (EV) (35%) 和工业物联网 (IIoT) (33%) 将成为 2023 年最重要的五个技术领域。其中,宇宙尚处于起步阶段;71% 的受访者认为“5G 和无处不在的连接”对推动宇宙发展非常重要,还有 58% 的认为 VR 耳机和 AR 眼镜也同样重要。
2023 年受技术影响最大的行业部门有:
- (40%) 电信
- (39%) 汽车和运输
- (33%) 能源
- (33%) 银行和金融服务
另一方面,2023 年的网络安全问题也依旧是各方关注的重点。数据表明,2022 年上半年,全球共发生 28 亿次恶意软件攻击和 2.361 亿次勒索软件攻击。截至 2022 年底,预计将发起 60 亿次网络钓鱼攻击。技术领导者们对网络安全的关注更甚于往年,51% 的受访者将云漏洞列为头等大事 (高于 2022 年的 35%),还有 43% 的担忧数据中心漏洞 (高于 2022 年的 27%)。
网络安全专业人员关注的其他领域还包括:
- 勒索软件攻击 (30%)
- 对组织网络的协同攻击 (30%)
- 缺乏对安全解决方案的投资 (26%)
IT 部门在 2023 年可能遇到的 10 大安全威胁有:
- 恶意软件:可以提取机密信息、拒绝服务并获得对系统的访问权限。
- 勒索软件:截至 2022,勒索软件对公司的攻击比 2021 年高出 33%。许多公司同意支付赎金以恢复其系统,结果却再次遭到同样的勒索软件攻击者的攻击。
- 供应链漏洞:可以采取的步骤之一是审核其供应商和供应商使用的安全措施,以确保端到端供应链的安全。
- 网络钓鱼:网络钓鱼是企业所面临的主要威胁。对员工进行关于如何识别虚假电子邮件、报告它们以及永远不要打开它们的培训将很有帮助。IT 应与 HR 合作,以确保培养良好的电子邮件使用习惯。
- 物联网:2020 年,有 61% 的公司在使用物联网,这一比例还在继续增加。随着物联网的扩展,安全风险也在增加。
- 内部员工:心怀不满的员工可能会破坏网络或窃取知识产权和专有信息,而养成不良安全习惯的员工可能会无意中共享密码并使设备不受保护。
- 数据中毒:数据中毒是进入企业系统的新攻击媒介。
- 新技术:一些组织正在采用生物识别等新技术。这些技术带来了巨大的好处,但它们也引入了新的安全风险,因为 IT 对它们的经验有限。
- 多层安全:IT 部门可以通过为工作流程中的每个安全漏洞点建立一个检查清单来加强安全。
- 云安全
Linus 近日对内核维护者表示,由于项目的开发周期节奏将与即将到来的圣诞夜产生冲突,维护者要确保在假期之前完成他们的开发工作。
Linus 在刚刚过去的周末发布了 Linux 6.1-rc7。他在邮件中表示,本以为感恩节会影响内核的开发工作,但现实情况与他的判断相反——假期并没有减缓开发进度。因此,Linus 决定再为 Linux 6.1 发布一个 rc8。若按照这个节奏,Linux 6.2 合并窗口刚好处于圣诞节假期期间。
对此,Linus 表示在下一个合并窗口期间,自己会比平时更“强硬”地执行规则。按照社区规则,开发者应该在合并窗口开启之前就准备好要提交的补丁。但现在,他希望所有要提交的补丁在圣诞节之前就完成,如果他收到的 PR 比这个时间晚。他将推迟到下一个周期在合并。
最后,Linus 希望大家对此达成完全一致的共识,并且不要再给他发送明显不是错误的信息。
延伸阅读
- Linus 批评内核开发者赶 Deadline
U-Boot 是一个开源引导加载程序,主要用于嵌入式系统。它支持多种不同的结构,包括 PPC、ARM、AVR32、MIPS、x86、68k、Nios 与 MicroBlaze。
此前,U-Boot 引导加载程序只支持 UDP 协议,仅限通过 tftp(简单文件传输协议) 或 NFS(网络文件系统) 进行文件传输。在开发人员的长期努力之下,如今 U-Boot 终于提供了 TCP 协议支持,可通过 HTTP 下载文件或其他内容。
经过五年开发,整整二十轮的修改,对 U-Boot 网络的 TCP 基础支持补丁终于完成并合并到主线。除了对 TCP 协议的兼容,该系列补丁还添加了一个基础的 wget 应用程序。U-Boot 上的的 wget 应用是一个命令行下载器,允许通过 TCP 从 HTTP 服务器下载文件到指定的内存地址,目前 wget 仅支持 80 端口上的 HTTP 服务器,且不支持 HTTPS。
提供 HTTP 和 TCP 支持意味着 U-Boot 可以从 HTTP 服务器下载内核或其他文件,而不仅限使用 NFS 或 TFTP 进行远程加载,它可以简化一些 U-Boot 嵌入式设备的部署。
开源固件基金会(Open-Source Firmware Foundation, OSFF)近日在社交平台宣布,Coreboot 将正式加入 OSFF,共同推进开源固件的开发。
Coreboot 原名 LinuxBIOS,是一个旨在取代计算机中专有固件(BIOS 或 UEFI)的软件项目,它采用轻量级固件设计,只执行加载和运行现代 32 位或 64 位操作系统所需的最少量任务。
由于 Coreboot 要初始化硬件,所以必须为所要支持的每个芯片组和主板做移植。因此 Coreboot 只适用于有限的硬件平台和主板型号。
开源固件基金会由 9elements Cyber Security 和 Mullvad VPN 共同成立,在官方网站的介绍中他们写道:
开源固件基金会(OSFF)是一个非营利组织,其总体目标是加强开源固件领域各方的沟通。OSFF 于 2021 年由业界领先的开源固件公司成立。
该基金会将其目标设定为通过共享知识资源、基础设施、服务、活动和培训,研究并教育企业和个人了解开源固件。
目前,除了两位创始成员和刚刚加入组织的 Coreboot,OSFF 的成员还有今年年中加入组织的 LinuxBoot。作为一家刚刚成立没多久的基金会,希望 OSFF 未来一切顺利。
Midori 是一个基于 Chromium 的轻量级开源网络浏览器,并以 Electron 构建,虽然基于 Chromium,但 Midori 去掉了很多来自 Google 的服务和一些涉及隐私的内容。它的目标是快速、隐私、简洁的 UI、可扩展和功能性。
注:Midori 曾是 Xfce 桌面环境 Goodies 组件的一部分,也是 elementary OS “Freya” 和 “Luna”,以及其他很多 Linux 发行版的默认浏览器。
2019年,Midori 项目与 Astian 基金会合并,然后已经完全改头换面,并从 WebKitGTK 转为使用 Electron。
由于该浏览器最新的稳定版本还停留在 2020 年,不少用户都觉得该项目已经停止维护了。
近日,官方带来了一些新的消息,首先 Midori 网络浏览器没有停止维护,仍然在持续开发中;此外,在即将到来的浏览器更新中,他们计划将自己的开源搜索引擎 AstianGO 整合到浏览器中。这与 Brave 跟 Brave Search 整合有些类似,但 Brave Search 并不是开源的。
在 Reddit 的帖子中,Astian 的工作人员表示他们计划在 Midori 网络浏览器的下一次更新中增加一个集成的开源搜索引擎,即 AstianGO。目前这项开发工作的细节并不多,但 Astian 提到:
我们已经实现并开发了一个完全开源的搜索引擎,没有使用第三方 API,也不存储用户的 IP 地址、不存储搜索历史。我们把这个搜索引擎称为 AstianGO,这个搜索引擎是用 PHP 开发的,它是自托管的,尽管它还没有一个集成的更新系统,不过人们可以把它部署在他们的服务器上。
AstianGO 搜索引擎使用来自 Google、Qwant 和 Brave Search 的数据提供结果,并且托管在冰岛、挪威、瑞士、罗马尼亚、荷兰、瑞典等多个国家,这样可以确保用户的数据并不总是流经一个国家。
目前 Astian 已经在 GitLab 上放出了开源搜索引擎 AstianGO 的源代码,用户还可以直接访问 https://astiango.com/ 这个网址来使用搜索引擎,尝试搜索一些内容来验证这个搜索引擎是否好用。
大家好,我是张晋涛。
上周在我的交流群里有个小伙伴问到了 Overlay2 相关的问题,这篇就来介绍一下。(想进群的可以留言)
本节,我将为你介绍 Docker 现在推荐使用的存储驱动 Overlay2,在开始之前,你可以执行以下命令来查看 Docker 正在使用的存储驱动:
如果你看到的结果也是 说明你的 Docker 已经在使用 overlay2 存储驱动了。我在个人工作站上用的是 btrfs,这是因为自从 Fedora 33 开始,btrfs 就成为了 Fedora 默认的文件系统。不过服务器上就都是 overlay2 了。
你也可能会看到其他不同的结果,可以在启动 docker daemon 的时候,通过 参数进行指定,也可以在 文件中通过 字段进行配置。
目前对于 Docker 最新版本而言,你有以下几种存储驱动可供选择:
但它们对于你使用的文件系统之类的都有不同的要求,且实现方式也不尽相同。我以本节的重点 存储驱动为例,它需要你使用 Linux 4.x 以上版本的内核,或者是对于 RHEL/CentOS 等需要使用 3.10.0-514 以上的内核(旧版本中存在一些兼容性问题,我在之前的文章中有提到过)。
同时,它支持你使用 ext4 的文件系统,或者增加了 的 xfs 文件系统。可以通过 进行得到文件系统相关的信息。
存储驱动的作用
前面虽然已经聊了如何设置和检查当前在用的存储驱动,但尚未介绍为何一定要使用存储驱动,以及它的作用。
还记得我在之前的文章《万字长文:彻底搞懂容器镜像构建》中为你介绍的 Docker 如何存储镜像相关的内容吗,如果忘了可以回头复习一下。
Docker 将容器镜像做了分层存储,每个层相当于包含着一条 Dockerfile 的指令。而这些层在磁盘上的存储方式,以及在启动容器时,如何组织这些层,并提供可写层,便是存储驱动的主要作用了。
另外需要注意的是:不同的存储驱动实现不同,性能也有差异,同时使用不同的存储驱动也会导致占用的磁盘空间有所不同。
同时:由于它们的实现不同,当你修改存储驱动后,可能会导致看不到原有的镜像,容器等,这是正常的,不必担心,切换回原先的驱动即可见。
OverlayFS
了解完前面的背景知识后,你也看到了我刚才列出的可用存储驱动中有两个 和 ,其实 算是 的升级版,这两个存储驱动所用的都是 。
驱动是在 2014 年 8 月份首次进入 Docker 的,而 则是在 2016 年 6 月份被合并,并首次出现在 Docker 1.12 中的。它的出现是为了解决 存储驱动可能早层 inode 耗尽的问题。
简单介绍完 和 ,我们将重点回归到 上。
我们启动一个容器,以此为切入点来认识下 OverlayFS,注意:以下内容使用 Linux 5.4 内核以及 Docker 20.10.21,不同环境下可能结果略有差异。
可以看到,在启动容器后,系统上多了一个 OverlayFS (overlay) 的挂载。注意看其中的几个内容:
-
挂载点在:
其中的内容,看着很熟悉,是我们所启动容器根目录中的内容。为了验证这一说法,我在容器中新写一个文件:
再次查看此挂载点中的内容:
可以看到刚才写的内容已经在这个挂载点的目录中了。
-
: 这是 OverlayFS 中必要的目录。
这个 中包含两个目录,这是使用了内核对 OverlayFS multi layer 特性的支持,我们分别查看下其中内容:
这两个目录,是不是看着很熟悉?
是的,它们就是我们所启动容器根目录中的大部分内容。为什么说是大部分内容呢?当我们查看其中的内容时,你也会发现它们的内容也并不完整。比如我们刚才新写入的 文件,或者当我们查看 目录下的文件,你也会发现其中都只是常规系统 目录下的部分内容。
-
是另一个重要的目录,我们来看看其中的内容
我们发现这个目录中包含着刚才创建的 文件。同时,其中也包含一个 目录,这个目录便是我们默认使用的 用户的家目录。
如果去查看其中的内容,也会发现刚才我们执行命令的历史记录。
-
这个目录和 在同一个父目录下,查看其内容发现里面只有一个 目录
看完以上的介绍,想必你已经发现了它们之间的部分联系,在此之前,我们在额外看一个目录,那就是 和 以及挂载点共同的父目录:
你会发现这个目录下的内容就比较直观了。我们刚才已经看了其中 , 和 目录的内容了,现在看看 中的内容吧:
我们发现, 文件中的内容是以 分隔的两个 的目录名称。
至此,我们可以得到以下结论:
-
是基础层,可以包含多个 ;
-
是可写层,即挂载时的 ,在容器内变更的文件都在这一层存储;
-
是最终的合并结果,即容器给我们呈现出来的结果;
Overlay2
经过前面对 Docker 启动容器后挂载的 OverlayFS 的介绍后,Overlay2 的工作流程想必你也就比较清楚了。
将镜像各层作为 基础层,同时增加 这个可写层,通过 OverlayFS 的工作机制,最终将 作为容器内的文件目录展示给用户。
你可能会有疑问,如果只是这样简单的组织,会不会有什么限制呢?答案是肯定的,当然有限制,我们可以通过 Overlay2 的代码来看
可以看到其对 lower 的深度有硬编码的限制,当前硬编码的限制是 128 。如果你在使用的过程中遇到这个错误,那表示你超过了最大深度限制,你就需要找些办法来减少层级了。
总结
本节,我为你介绍了 OverlayFS 及 Overlay2 存储驱动相关的内容。通过实际启动容器生成的相关目录来介绍 overlay2 的工作流程,想必通过这种方式能更易理解。
欢迎订阅我的文章公众号【MoeLove】
hello,大家好,我是张张,「架构精进之路」公号作者。
1、前言
随着互联网从简单的单向浏览请求,发展为基于用户个性信息的定制化以及社交化的请求,这要求产品需要做到以用户和关系为基础,对海量数据进行分析和计算。对于后端服务来说,意味着用户的每次请求都需要查询用户的个人信息和大量的关系信息,此外大部分场景还需要对上述信息进行聚合、过滤、排序,最终才能返回给用户。
CPU是信息处理、程序运行的最终执行单,如果它的世界也有“秒”的概念,假设它的时钟跳一下为一秒,那么在CPU(CPU的一个核心)眼中的时间概念是什么样的呢?
可见I/O的速度与CPU和内存相比是要差几个数量级的,如果数据全部从数据库获取,一次请求涉及多次数据库操作会大大增加响应时间,无法提供好的用户体验。
对于大型高并发场景下的Web应用,缓存更为重要,更高的缓存命中率就意味着更好的性能。缓存系统的引入,是提升系统响应时延、提升用户体验的唯一途径,良好的缓存架构设计也是高并发系统的基石。
缓存的思想基于以下几点:
-
时间局限性原理 程序有在一段时间内多次访问同一个数据块的倾向。例如一个热门的商品或者一个热门的新闻会被数以百万甚至千万的更多用户查看。通过缓存,可以高效地重用之前检索或计算的数据。
-
以空间换取时间 对于大部分系统,全量数据通常存储在MySQL 或者Hbase,但是它们的访问效率太低。所以会开辟一个高速的访问空间来加速访问过程,例如Redis读的速度是次/s,写的速度是81000次/s 。
-
性能和成本的Tradeoff 高速的访问空间带来的是成本的提升,在系统设计时要兼顾性能和成本。例如,在相同成本的情况下,SSD 硬盘容量会比内存大 10~30 倍以上,但读写延迟却高 50~100 倍。
引入缓存会给系统带来以下优势:
-
提升请求性能
-
降低网络拥塞
-
减轻服务负载
-
增强可扩展性
同样的,引入缓存也会带来以下劣势:
-
毫无疑问会增加系统的复杂性,开发复杂性和运维复杂性成倍提升。
-
高速的访问空间会比数据库存储的成本高。
-
由于一份数据同时存在缓存和数据库中,甚至缓存内部也会有多个数据副本,多份数据就会存在数据双写的不一致问题,同时缓存体系本身也会存在可用性问题和分区的问题。
在缓存系统的设计架构中,还有很多坑,很多的明枪暗箭,如果设计不当会导致很多严重的后果。设计不当,轻则请求变慢、性能降低,重则会数据不一致、系统可用性降低,甚至会导致缓存雪崩,整个系统无法对外提供服务。
2、缓存的主要存储模式
三种模式各有优劣,适用于不同的业务场景,不存在最佳模式。
● Cache Aside(旁路缓存)
写: 更新db时,删除缓存,当下次读取数据库时,驱动缓存的更新。
读: 读的时候先读缓存,缓存未命中,那么就读数据库,并且将数据回种到缓存,同时返回相应结果
特点:懒加载思想,以数据库中的数据为准。在稍微复杂点的缓存场景,缓存都不简单是数据库中直接取出来的,可能还需要从其他表查询一些数据,然后进行一些复杂的运算,才能最终计算出值。这种存储模式适合于对数据一致性要求比较高的业务,或者是缓存数据更新比较复杂、代价比较高的业务。例如:一个缓存涉及多个表的多个字段,在1分钟内被修改了100次,但是这个缓存在1分钟内就被读取了1次。如果使用这种存储模式只删除缓存的话,那么1分钟内,这个缓存不过就重新计算一次而已,开销大幅度降低。
● Read/Write Through(读写穿透)
写: 缓存存在,更新数据库,缓存不存在,同时更新缓存和数据库
读: 缓存未命中,由缓存服务加载数据并且写入缓存
特点:
读写穿透对热数据友好,特别适合有冷热数据区分的场合。
1)简化应用程序代码
在缓存方法中,应用程序代码仍然很复杂,并且直接依赖于数据库,如果多个应用程序处理相同的数据,甚至会出现代码重复。读写穿透模式将一些数据访问代码从应用程序转移到缓存层,这极大地简化了应用程序并更清晰地抽象了数据库操作。
2)具有更好的读取可伸缩性
在多数情况下,缓存数据过期以后,多个并行用户线程最终会打到数据库,再加上数以百万计的缓存项和数千个并行用户请求,数据库上的负载会显著增加。读写穿透可以保证应用程序永远不会为这些缓存项访问数据库,这也可以让数据库负载保持在最小值。
3)具有更好的写性能
读写穿透模式可以让应用程序快速更新缓存并返回,之后它让缓存服务在后台更新数据库。当数据库写操作的执行速度不如缓存更新的速度快时,还可以指定限流机制,将数据库写操作安排在非高峰时间进行,减轻数据库的压力。
4)过期时自动刷新缓存
读写穿透模式允许缓存在过期时自动从数据库重新加载对象。这意味着应用程序不必在高峰时间访问数据库,因为最新数据总是在缓存中。
● Write Behind Caching(异步缓存写入)
写:只更新缓存,缓存服务异步更新数据库。
读:缓存未命中由封装好的缓存服务加载数据并且写入缓存。
特点:写性能最高,定期异步刷新数据库数据,数据丢失的概率大,适合写频率高,并且写操作需要合并的场景。使用异步缓存写入模式,数据的读取和更新通过缓存进行,与读写穿透模式不同,更新的数据并不会立即传到数据库。相反,在缓存服务中一旦进行更新操作,缓存服务就会跟踪脏记录列表,并定期将当前的脏记录集刷新到数据库中。作为额外的性能改善,缓存服务会合并这些脏记录,合并意味着如果相同的记录被更新,或者在缓冲区内被多次标记为脏数据,则只保证最后一次更新。对于那些值更新非常频繁,例如金融市场中的股票价格等场景,这种方式能够很大程度上改善性能。如果股票价格每秒钟变化 100 次,则意味着在 30 秒内会发生 30 x 100 次更新,合并将其减少至只有一次。
3、缓存7大经典问题
问题的常用解决方案
1 缓存集中失效
缓存集中失效大多数情况出现在高并发的时候,如果大量的缓存数据集中在一个时间段失效,查询请求会打到数据库,数据库压力凸显。比如同一批火车票、飞机票,当可以售卖时,系统会一次性加载到缓存,并且过期时间设置为预先配置的固定时间,那过期时间到期后,系统就会因为热点数据的集中没有命中而出现性能变慢的情况。
解决方案:
-
使用基准时间+随机时间,降低过期时间的重复率,避免集体失效。即相同业务数据设置缓存失效时间时,在原来设置的失效时间基础上,再加上一个随机值,让数据分散过期,同时对数据库的请求也会分散开,避免瞬时全部过期对数据库造成过大压力。
2 缓存穿透
缓存穿透是指一些异常访问,每次都去查询压根儿就不存在的key,导致每次请求都会打到数据库上去。例如查询不存在的用户,查询不存在的商品id。如果是用户偶尔错误输入,问题不大。但如果是一些特殊用户,控制一批肉鸡,持续的访问缓存不存在的key,会严重影响系统的性能,影响正常用户的访问,甚至可能会让数据库直接宕机。我们在设计系统时,通常只考虑正常的访问请求,所以这种情况往往容易被忽略。
解决方案:
-
第一种方案就是,查询到不存在的数据时,首次查询数据库,即便数据库没有数据,仍然回种这个 key 到缓存,并使用一个特殊约定的value表示这个key的值为空。后面再次出现对这个key的请求时,直接返回null。为了健壮性,设置空缓存key时,一定要设置过期时间,以防止之后该key被写入了数据。
-
第二种方案是,构建一个 BloomFilter 缓存过滤器,记录全量数据,这样访问数据时,可以直接通过 BloomFilter 判断这个 key 是否存在,如果不存在直接返回即可,压根儿不需要查询缓存或数据库。比如,可以使用基于数据库增量日志解析框架(阿里的canal),通过消费增量数据写入到BloomFilter 过滤器。BloomFilter的所有操作也是在内存里实现,性能很高,要达到 1% 的误判率,平均单条记录占用 1.2 字节即可。同时需要注意的是BloomFilter 只有新增没有删除操作,对于已经删除的key可以配合上述缓存空值解决方案一起使用。Redis提供了自定义参数的布隆顾虑器,可以使用bf.reserve进行创建,需要设置参数error_rate(错误率)和 innitial_size。error_rate越低需要的空间越大,innitial_size表示预计放入的素数量,当实际数量超过这个值以后,误判率会上升。
3 缓存雪崩
缓存雪崩是缓存机器因为某种原因全部或者部分宕机,导致大量的数据落到数据库,最终把数据库打死。例如某个服务,恰好在请求高峰期间缓存服务宕机,本来打到缓存的请求,这是时候全部打到数据库,数据库扛不住在报警以后也会宕机,重启数据库以后,新的请求会再次把数据库打死。
解决方案:
-
事前:缓存采用高可用架构设计,redis使用集群部署方式。对重要业务数据的数据库访问添加开关,当发现数据库出现阻塞、响应慢超过阈值的时候,关闭开关,将一部分或者全都的数据库请求执行failfast操作。
-
事中:引入多级缓存架构,增加缓存副本,比如新增本地 ehcache 缓存。引入限流降级组件,对缓存进行实时监控和实时报警。通过机器替换、服务替换进行及时恢复;也可以通过各种自动故障转移策略,自动关闭异常接口、停止边缘服务、停止部分非核心功能措施,确保在极端场景下,核心功能的正常运行。
-
事后:redis持久化,支持同时开启两种持久化方式,我们可以综合使用 AOF 和 RDB 两种持久化机制,用 AOF 来保证数据不丢失,作为数据恢复的第一选择; 用 RDB 来做不同程度的冷备,在 AOF 文件都丢失或损坏不可用的时候,还可以使用 RDB 来进行快速的数据恢复。同时把RDB 数据备份到远端的云服务,如果服务器内存和磁盘的数据同时丢失,依然可以从远端拉取数据做灾备恢复操作。
4 缓存数据不一致
同一份数据,既在缓存里又在数据库里,肯定会出现数据库与缓存中的数据不一致现象。如果引入多级缓存架构,缓存会存在多个副本,多个副本之间也会出现缓存不一致现象。缓存机器的带宽被打满,或者机房网络出现波动时,缓存更新失败,新数据没有写入缓存,就会导致缓存和 DB 的数据不一致。缓存 rehash 时,某个缓存机器反复异常,多次上下线,更新请求多次 rehash。这样,一份数据存在多个节点,且每次 rehash 只更新某个节点,导致一些缓存节点产生脏数据。再比如,数据发生了变更,先删除了缓存,然后要去修改数据库,此时还没修改。一个请求过来,去读缓存,发现缓存空了,去查询数据库,查到了修改前的旧数据,放到了缓存中。随后数据变更的程序完成了数据库的修改,数据库和缓存中的数据不一样了。
解决方案:
-
设置key的过期时间尽量短,让缓存更早的过期,从db加载新数据,这样无法保证数据的强一致性,但是可以保证最终一致性。
cache更新失败以后引入重试机制,比如连续重试失败以后,可以将操作写入重试队列,当缓存服务可用时,将这些key从缓存中删除,当这些key被重新查询时,重新从数据库回种。
延时双删除策略,首先删除缓存中的数据,在写数据库,休眠一秒以后(具体时间需要根据具体业务逻辑的耗时进行调整)再次删除缓存。这样可以将一秒内造成的所有脏数据再次删除。
缓存最终一致性,使客户端数据与缓存解耦,应用直接写数据到数据库中。数据库更新binlog日志,利用Canal中间件读取binlog日志。Canal借助于限流组件按频率将数据发到MQ中,应用监控MQ通道,将MQ的数据更新到Redis缓存中。
更新数据的时候,根据数据的唯一标识,将操作路由之后,发送到一个 jvm 内部队列中。读取数据的时候,如果发现数据不在缓存中,那么将重新执行“读取数据+更新缓存”的操作,根据唯一标识路由之后,也发送到同一个 jvm 内部队列中。该方案对于读请求进行了非常轻度的异步化,使用一定要注意读超时的问题,每个读请求必须在超时时间范围内返回。因此需要根据自己的业务情况进行测试,可能需要部署多个服务,每个服务分摊一些数据的更新操作。如果一个内存队列里居然会挤压 100 个业务数据的修改操作,每个操作操作要耗费 10ms 去完成,那么最后一个读请求,可能等待 10 * 100 = 1000ms = 1s 后,才能得到数据,这个时候就导致读请求的长时阻塞。
5 竞争并发
当系统的线上流量特别大的时候,缓存中会出现数据并发竞争的现象。在高并发的场景下,如果缓存数据正好过期,各个并发请求之间又没有任何协调动作,这样并发请求就会打到数据库,对数据造成较大的压力,严重的可能会导致缓存“雪崩”。另外高并发竞争也会导致数据不一致问题,例如多个redis客户端同时set同一个key时,key最开始的值是1,本来按顺序修改为2,3,4,最后是4,但是顺序变成了4,3,2,最后变成了2。
解决方案:
分布式锁+时间戳
可以基于redis或者zookeeper实现一个分布式锁,当一个key被高并发访问时,让请求去抢锁。也可以引入消息中间件,把Redis.set操作放在消息队列中。总之,将并行读写改成串行读写的方式,从而来避免资源竞争。对于key的操作的顺序性问题,可以通过设置一个时间戳来解决。大部分场景下,要写入缓存的数据都是从数据库中查询出来的。在数据写入数据库时,可以维护一个时间戳字段,这样数据被查询出来时都会带一个时间戳。写缓存的时候,可以判断一下当前数据的时间戳是否比缓存里的数据的时间戳要新,这样就避免了旧数据对新数据的覆盖。
6 热点Key问题
对于大多数互联网系统,数据是分冷热的,访问频率高的key被称为热key,比如热点新闻、热点的评论。而在突发事件发生时,瞬间会有大量用户去访问这个突发热点信息,这个突发热点信息所在的缓存节点由于超大流量而达到理网卡、带宽、CPU 的极限,从而导致缓存访问变慢、卡顿、甚至宕机。接下来数据请求到数据库,最终导致整个服务不可用。比如微博中数十万、数百万的用户同时去吃一个新瓜,秒杀、双11、618 、春节等线上促销活动,明星结婚、离婚、出轨这种特殊突发事件。
解决方案:
要解决这种极热 key 的问题,首先要找出这些 热key 。对于重要节假日、线上促销活动、凭借经验可以提前评估出可能的热 key 来。而对于突发事件,无法提前评估,可以通过 Spark或者Flink,进行流式计算,及时发现新发布的热点 key。而对于之前已发出的事情,逐步发酵成为热 key 的,则可以通过 Hadoop 进行离线跑批计算,找出最近历史数据中的高频热 key。还可以通过客户端进行统计或者上报。找到热 key 后,就有很多解决办法了。首先可以将这些热 key 进行分散处理。redis cluster有固定的16384个hash slot,对每个key计算CRC16值,然后对16384取模,可以获取key对应的hash slot。比如一个热 key 名字叫 hotkey,可以被分散为 hotkey#1、hotkey#2、hotkey#3,……hotkey#n,这 n 个 key 就会分散存在多个缓存节点,然后 client 端请求时,随机访问其中某个后缀的热key,这样就可以把热 key 的请求打散。
其次,也可以 key 的名字不变,对缓存提前进行多副本+多级结合的缓存架构设计。比如利用ehcache,或者一个HashMap都可以。在你发现热key以后,把热key加载到系统的JVM中,之后针对热key的请求,可以直接从jvm中获取数据。再次,如果热 key 较多,还可以通过监控体系对缓存的 SLA 实时监控,通过快速扩容来减少热 key 的冲击。
7 大Key问题
有些时候开发人员设计不合理,在缓存中会形成特别大的对象,这些大对象会导致数据迁移卡顿,另外在内存分配方面,如果一个key特别大,当需要扩容时,会一次性申请更大的一块内存,这也会导致卡顿。如果大对象被删除,内存会被一次性回收,卡顿现象会再次发生。在平时的业务开发中,要尽量避免大key的产生。如果发现系统的缓存大起大落,极有可能是大key引起的,这就需要开发人员定位出大key的来源,然后进行相关的业务代码重构。Redis官方已经提供了相关的指令进行大key的扫描,可以直接使用。
解决方案:
-
如果数据存在 Redis 中,比如业务数据存 set 格式,大 key 对应的 set 结构有几千几万个素,这种写入 Redis 时会消耗很长的时间,导致 Redis 卡顿。此时,可以扩展新的数据结构,同时让 client 在这些大 key 写缓存之前,进行序列化构建,然后通过 restore 一次性写入。
-
将大 key 分拆为多个 key,尽量减少大 key 的存在。同时由于大 key 一旦穿透到 DB,加载耗时很大,所以可以对这些大 key 进行特殊照顾,比如设置较长的过期时间,比如缓存内部在淘汰 key 时,同等条件下,尽量不淘汰这些大 key。
希望今天的讲解对大家有所帮助,谢谢!
Thanks for reading!
关注公众号,免费领学习资料
如果您觉得还不错,欢迎关注和转发~
作者:乔克
引言
自动化已经常态化,99% 的公司或多或少都实现了部分自动化功能,比如应用的打包部署、服务器的批量维护、自动化测试等。
在实际工作中,我基本完成了前端、后端、移动端的自动化,但是一直没有涉及到小程序,主要原因在于:
-
小程序的开发受限平台的开发工具。
-
在开发小程序过程中,编译以及部署,都是开发通过可视化开发工具实现。
-
小程序应用比较少,容易忽略。
这就导致在开发小程序过程中,构建发布程序到生产或测试环境的时候,都是开发人员手动操作,发布不同的环境可能需要切换不同的分支,这样不仅增加了重复性工作,也大大增加了出错的概率。
鉴于此,我们决定将小程序实现自动化,减少开发的工作量,提升工作效率。
工具介绍
要实现小程序的自动发布并不难,我们可以借助 miniprogram-ci 工具实现,在改工具之前,大佬们大都是自己开发各种自动化脚本,现在我们就不用那么麻烦了。
miniprogram-ci 是从微信开发工具中抽离的关于小程序/小游戏项目代码的编译模块,开发者可以不使用一些开发者工具,独立使用它就可以完成小程序代码的上传、预览等操作。其主要提供以下功能:
1. 上传代码,对应小程序开发者工具的上传。
2. 预览代码,对应小程序开发者工具的预览。
3. 构建 npm,对应小程序开发者工具的:菜单 – 工具 – 构建 npm。
4. 上传云开发云函数代码,对应小程序开发者工具的上传云函数能力。
5. 上传云托管代码,对应小程序开发者工具的上传云托管能力。
6. 上传云存储/静态托管文件,对应小程序开发者工具 – 云开发 – 云存储和静态托管文件管理。
7. 代理,配置 miniprogram-ci 的网络请求代理方式。
8. 支持获取最近上传版本的 sourceMap。
9. 支持 node 脚本调用方式和命令行调用方式。
前置工作
申请 APP ID
APP ID 是在微信后台申请,开发一般会提供。
制作构建镜像
要使用 miniprogram-ci ,需要我们安装该模块,安装命令如下:
为此,我们准备好具有 miniprogram-ci 命令的镜像。
然后制作镜像并推送到镜像仓库。
PS:根据实际情况选择 node 版本。
Zadig 配置
前置条件
-
拥有可用的 Zadig 服务,版本>=1.15.0
-
已经关联好代码仓库
开始配置
1、添加构建镜像
在 Zadig 的 系统配置 -> 构建镜像管理 处添加上面制作出来的构建镜像,如下:
2、创建项目
在 Zadig 中,选择 项目 -> 新建项目 ,添加一个小程序专属的项目,如下:
然后跳过向导,我们不需要环境,如下:
3、添加服务
添加服务的方式根据自己的情况来,不论是 YAML 项目还是 Helm Chart 项目,实际中我们都不会使用这些方式进行部署,随意选择就好,比如我这里选择的是 Helm Chart 项目。
之所以配置 Helm values,是为了让服务组件显示正常。
4、添加构建脚本
首先选择 构建环境 以及 代码信息 ,如下:
我们选择的是自定义的构建镜像。
然后添加一个构建变量,该变量的作用是设定推送机器人编号,我定义为 ROBOT_NUM,如下:
我选择的是枚举类型,定义了三个机器人代码(机器人可选 1 ~ 30),如下:
最后,我们编写构建脚本,如下:
注意:
-
我们是将小程序版本以及描述信息放在了 project.config.json 文件中,每个企业用法可能不一样。
-
我将小程序的密钥放在代码仓库的 secret 文件夹下。
然后保存构建退出。
5、添加工作流
现在,我们添加工作流进行应用发布,我这里选择的是自定义工作流,如下:
新增阶段,如下:
然后新增任务,选择构建,如下:
选择对应的服务组件,如下:
固定 ROBOT_NUM 参数(我们约定测试环境用机器人 1,生产环境用机器人 6),如下:
配置默认分支,测试环境用 test 分支,如下:
最后,配置触发器,实现开发将代码推送到对应分支,则自动触发流水线进行发布,如下:
然后保存退出即完成配置。
6、添加 IM 通知
IM 通知有助于团队小伙伴及时知道工作流的结果状态,不至于每次都需要在 Zadig 上查看,节约时间,提升效率。
选择工作流->配置->通知,如下:
填写具体的 IM 信息,配置完保存即可。
到这,执行工作流就可以在钉钉群里接收到工作流消息了。
7、测试
配置完成后,需要测试工作流是否正常。
首先进行手动测试。在工作流中选择对应的服务并执行,如下:
待流水线运行成功表示配置正常,如下:
再次进行 webhook 测试,我们需要在代码仓库更改代码并推送。
我在测试分支添加一个文件并推送,如下:
然后在 Zadig 上发现流水线正常被触发,如下:
不论是手动触发还是 webhook 触发,都能在钉钉群里接收到任务状态,如下:
到此我们完成了小程序测试环境的自动化,其他应用和环境相似操作即可。
最后
单纯想实现小程序自动化并不难,只要适配到企业本身的架构,使用哪种方式都可以,我们之所以选择 Zadig,主要还是因为其操作简单、使用便捷以及开发测试人员使用成本比较低。
目前我们已经将所有的发布工作都迁移到 Zadig 上了。
不过在使用自定义工作流配置小程序自动发布过程中,还是需要一些优化:
-
类似 App、小程序这种类型的应用,不属于 Helm、Yaml、主机类服务,在选择添加服务的时候容易产生混淆(虽然开发并不关心)
-
执行工作流的时候,默认是勾选了所有应用,当应用很多且不需要发布所有的时候,需要挨个去取消(个人觉得手动勾选比手动取消更容易接受)
整体使用上面没有太大的问题,小伙伴们在测试小程序自动发布的时候和我的可能有所区别,根据实际情况来做调整即可。
Zadig,开放,链接,专业。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
作者:郝建伟
k3s 简介
官方文档:k3s
什么是k3s
-
打包为单个二进制文件。
-
使用基于 sqlite3 的轻量级存储后端作为默认存储机制。同时支持使用 etcd3、MySQL 和 PostgreSQL 作为存储机制。
-
封装在简单的启动程序中,通过该启动程序处理很多复杂的 TLS 和选项。
-
默认情况下是安全的,对轻量级环境有合理的默认值。
-
添加了简单但功能强大的batteries-included功能,例如:本地存储提供程序,服务负载均衡器,Helm controller 和 Traefik Ingress controller。
-
所有 Kubernetes control-plane 组件的操作都封装在单个二进制文件和进程中,使 k3s 具有自动化和管理包括证书分发在内的复杂集群操作的能力。
-
最大程度减轻了外部依赖性,k3s 仅需要 kernel 和 cgroup 挂载。 k3s 软件包需要的依赖项包括:
为什么叫 k3s?
适用场景
k3s 适用于以下场景:
-
边缘计算-Edge
-
物联网-IoT
-
CI
-
Development
-
ARM
-
嵌入 k8s
架构介绍
单节点架构
高可用架构
-
k3s Server 节点:两个或更多的server节点将为 Kubernetes API 提供服务并运行其他 control-plane 服务
-
外部数据库:与单节点 k3s 设置中使用的嵌入式 SQLite 数据存储相反,高可用 k3s 需要挂载一个external database外部数据库作为数据存储的媒介。
k3s高可用架构:
固定 worker 节点的注册地址
如下图所示:
注册 worker 节点
自动部署的清单
k3s默认容器运行时
验证:
准备工作
关闭SELinux
关闭swap
设置主机名
离线安装
概述
离线安装的过程主要分为以下两个步骤:
步骤 1:部署镜像
步骤 2:安装 k3s
离线升级 k3s 版本: 完成离线安装 k3s 后,您还可以通过脚本升级 k3s 版本,或启用自动升级功能,以保持离线环境中的 k3s 版本与最新的 k3s 版本同步。
部署私有镜像仓库
前提条件
搭建参考Harbor安装
创建镜像仓库 YAML
手动部署镜像
前提条件
假设已经在离线环境中创建了节点。
这种方法需要您手动将必要的镜像部署到每个节点,适用于运行无法部署镜像仓库的边缘部署场景。
操作步骤
请按照以下步骤准备镜像目录和 k3s 二进制文件
-
从k3s GitHub Release页面获取你所运行的 k3s 版本的镜像 tar 文件。
-
将 tar 文件放在images目录下,例如:
-
将 k3s 二进制文件放在 /usr/local/bin/k3s路径下,并确保拥有可执行权限。完成后,现在可以转到下面的安装 k3s部分,开始安装 k3s。
安装 k3s
更多安装选项参考 安装选项介绍 | Rancher文档
前提条件
-
在安装 k3s 之前,完成上面的部署私有镜像仓库或手动部署镜像,导入安装 k3s 所需要的镜像。
-
从 release 页面下载 k3s 二进制文件,k3s 二进制文件需要与离线镜像的版本匹配。将二进制文件放在每个离线节点的 /usr/local/bin 中,并确保这个二进制文件是可执行的。
-
下载 k3s 安装脚本:https://get.k3s.io 。将安装脚本放在每个离线节点的任意地方,并命名为 install.sh。
当使用 INSTALL_K3S_SKIP_DOWNLOAD 环境变量运行 k3s 脚本时,k3s 将使用本地的脚本和二进制。
单节点安装
server节点
worker节点
注意:k3s 还为 kubelets 提供了一个–resolv-conf标志,这可能有助于在离线网络中配置 DNS
![image-](/Users/haojianwei1/Library/Application Support/typora-user-images/image-.png)
添加worker角色标签
kubectl命令行补全
高可用安装
需要调整安装命令,以便指定INSTALL_K3S_SKIP_DOWNLOAD=true并在本地运行安装脚本。您还将利用INSTALL_K3S_EXEC=’args’为 k3s 提供其他参数。
例如,使用外部数据库实现高可用安装指南的第二步提到了以下内容:
由于在离线环境中无法使用curl命令进行安装,所以您需要参考以下示例,将这条命令行修改为离线安装:
升级 k3s
通过脚本升级
离线环境的升级可以通过以下步骤完成:
-
从k3s GitHub Release页面下载要升级到的 k3s 版本。将 tar 文件放在每个节点的/var/lib/rancher/k3s/worker/images/目录下。删除旧的 tar 文件。
-
复制并替换每个节点上/usr/local/bin中的旧 k3s 二进制文件。复制https://get.k3s.io 的安装脚本(因为它可能在上次发布后发生了变化)。再次运行脚本。
-
重启 k3s 服务。
启用自动升级功能
除了可以通过脚本升级 k3s 以外,您还可以启用自动升级功能,以保持离线环境中的 k3s 版本与最新的 k3s 版本同步。
从 v1.17.4+k3s1 开始,k3s 支持自动升级。要在离线环境中启用此功能,您必须确保所需镜像在您的私有镜像仓库中可用。
-
你将需要与你打算升级到的 k3s 版本相对应的 rancher/k3s-upgrade 版本。
注意,镜像标签将 k3s 版本中的+替换为-,因为 Docker 镜像不支持+。
-
你还需要在你要部署的system-upgrad-controller manifestYAML 中指定的 system-upgrad-controller和kubectl的版本。
在这里检查 system-upgrad-controller 的最新版本,并下载 system-upgrad-controller.yaml来确定你需要推送到私有镜像仓库的版本。例如,在system-upgrade-controller的 v0.4.0 版本中,在 manifest YAML 中指定了这些镜像:
-
将必要的 rancher/k3s-upgrade、rancher/system-upgrade-controller 和 rancher/kubectl 镜像添加到您的私有镜像仓库中以后 ,就可以按照k3s 自动升级指南进行操作。
停止k3s
server节点停止k3s
worker节点停止k3s
卸载 k3s
卸载 k3s 会删除集群数据和所有脚本。
要使用不同的安装选项重新启动集群,请使用不同的标志重新运行安装脚本。
server 节点卸载 k3s
worker 节点卸载 k3s
Helm简介
Helm 是 Kubernetes 生态系统中的一个软件包管理工具。本文将介绍 Helm 中的相关概念和基本工作原理,并通过一个具体的示例学习如何使用 Helm 打包、分发、安装、升级及回退 Kubernetes 应用。
Kubernetes 应用部署的挑战
Kubernetes 是一个提供了基于容器的应用集群管理解决方案,Kubernetes 为容器化应用提供了部署运行、资源调度、服务发现和动态伸缩等一系列完整功能。
Kubernetes 的核心设计理念是: 用户定义要部署的应用程序的规则,而 Kubernetes 则负责按照定义的规则部署并运行应用程序。如果应用程序出现问题导致偏离了定义的规格,Kubernetes 负责对其进行自动修正。例如:定义的应用规则要求部署两个实例(Pod),其中一个实例异常终止了,Kubernetes 会检查到并重新启动一个新的实例。
用户通过使用 Kubernetes API 对象来描述应用程序规则,包括 Pod、Service、Volume、Namespace、ReplicaSet、Deployment、Job等等。一般这些资源对象的定义需要写入一系列的 YAML 文件中,然后通过 Kubernetes 命令行工具 Kubectl 调 Kubernetes API 进行部署。
以一个典型的三层应用 WordPress 为例,该应用程序就涉及到多个 Kubernetes API 对象,而要描述这些 Kubernetes API 对象就可能要同时维护多个 YAML 文件。
从上图可以看到,在进行 Kubernetes 软件部署时,我们面临下述几个问题:
-
如何管理、编辑和更新这些这些分散的 Kubernetes 应用配置文件。
-
如何把一套相关的配置文件作为一个应用进行管理。
-
如何分发和重用 Kubernetes 的应用配置。
Helm 的出现就是为了很好地解决上面这些问题。
Helm 是什么?
Helm 是Deis开发的一个用于 Kubernetes 应用的包管理工具,主要用来管理 Charts。有点类似于 Ubuntu 中的 APT 或 CentOS 中的 YUM。
Helm Chart 是用来封装 Kubernetes 原生应用程序的一系列 YAML 文件。可以在你部署应用的时候自定义应用程序的一些 Metadata,以便于应用程序的分发。
对于应用发布者而言,可以通过 Helm 打包应用、管理应用依赖关系、管理应用版本并发布应用到软件仓库。
对于使用者而言,使用 Helm 后不用需要编写复杂的应用部署文件,可以以简单的方式在 Kubernetes 上查找、安装、升级、回滚、卸载应用程序。
Helm 组件及相关术语
- Helm
Helm 是一个命令行下的客户端工具。主要用于 Kubernetes 应用程序 Chart 的创建、打包、发布以及创建和管理本地和远程的 Chart 仓库。
- Tiller
Tiller 是 Helm 的服务端,部署在 Kubernetes 集群中。Tiller 用于接收 Helm 的请求,并根据 Chart 生成 Kubernetes 的部署文件( Helm 称为 Release ),然后提交给 Kubernetes 创建应用。Tiller 还提供了 Release 的升级、删除、回滚等一系列功能。
- Chart
Helm 的软件包,采用 TAR 格式。类似于 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一组定义 Kubernetes 资源相关的 YAML 文件。
- Repoistory
Helm 的软件仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。
- Release
使用命令在 Kubernetes 集群中部署的 Chart 称为 Release。
注:需要注意的是:Helm 中提到的 Release 和我们通常概念中的版本有所不同,这里的 Release 可以理解为 Helm 使用 Chart 包部署的一个应用实例。
Helm 工作原理
这张图描述了 Helm 的几个关键组件 Helm(客户端)、Tiller(服务器)、Repository(Chart 软件仓库)、Chart(软件包)之间的关系。
Chart Install 过程
-
Helm 从指定的目录或者 TAR 文件中解析出 Chart 结构信息。
-
Helm 将指定的 Chart 结构和 Values 信息通过 gRPC 传递给 Tiller。
-
Tiller 根据 Chart 和 Values 生成一个 Release。
-
Tiller 将 Release 发送给 Kubernetes 用于生成 Release。
Chart Update 过程
-
Helm 从指定的目录或者 TAR 文件中解析出 Chart 结构信息。
-
Helm 将需要更新的 Release 的名称、Chart 结构和 Values 信息传递给 Tiller。
-
Tiller 生成 Release 并更新指定名称的 Release 的 History。
-
Tiller 将 Release 发送给 Kubernetes 用于更新 Release。
Chart Rollback 过程
-
Helm 将要回滚的 Release 的名称传递给 Tiller。
-
Tiller 根据 Release 的名称查找 History。
-
Tiller 从 History 中获取上一个 Release。
-
Tiller 将上一个 Release 发送给 Kubernetes 用于替换当前 Release。
Chart 处理依赖说明
Tiller 在处理 Chart 时,直接将 Chart 以及其依赖的所有 Charts 合并为一个 Release,同时传递给 Kubernetes。因此 Tiller 并不负责管理依赖之间的启动顺序。Chart 中的应用需要能够自行处理依赖关系。
部署 Helm
安装 Helm 客户端
Helm 的安装方式很多,这里采用二进制的方式安装。更多安装方法可以参考 Helm 的官方帮助文档。
- 使用官方提供的脚本一键安装
- 手动下载二进制包安装
Tiller 是以 Deployment 方式部署在 Kubernetes 集群中的,只需使用以下指令便可简单的完成安装。
注:storage.googleapis.com默认是不能访问的,该问题请自行解决。如果不清楚是否能访问,当你把这行命令cp linux-amd64/helm /usr/local/bin/完,看一下是否都是ok的
由于 Helm 默认会去storage.googleapis.com拉取镜像,如果你当前执行的机器不能访问该域名的话可以使用以下命令来安装:
接下来查看状态
上图可看出:现在,已经能够查看到服务器的版本信息了,部署完成
后面下载包会报错,是因为从 Kubernetes 1.6 版本开始,API Server 启用了 RBAC 授权。目前的 Tiller 部署时默认没有定义授权的 ServiceAccount,这会导致访问 API Server 时被拒绝。所以我们需要明确为 Tiller 部署添加授权。
生成.kube配置
安装NFS
部署说明
Kubernetes网络文件系统,主要用于ES、Kafka、Minio等持久化存储。
nfs搭建
配置共享目录
部署Pod遇到的问题
Helm部署Chart时报错
部署 nfs pod时报错
Pod拉取镜像超时报错
常用命令行
kubectl命令
node的标签操作
ctr 命令使用
containerd 相比于docker , 多了namespace概念, 每个image和container 都会在各自的namespace下可见
ctr,crictl,docker命令对比
crictl 命令使用
配置containerd镜像加速
其他命令:
几种Containerd常用命令对比
作者:毛辰飞
背景
在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究竟有什么坏处?今天我们就来分析这个问题,探讨一下内部的原因。
数据展示
user_auto_key,user_uuid,user_random_key,分别表示自动增长的主键,uuid作为主键,随机key作为主键,其它我们完全保持不变。根据控制变量法,我们只把每个表的主键使用不同的策略生成,而其他的字段完全一样,然后测试一下表的插入速度和查询速度:
注:这里的随机key其实是指用雪花算法算出来的前后不连续不重复无规律的id:一串18位长度的long值
可以看出在数据量100W左右的时候,uuid的插入效率垫底,并且在后续增加了130W的数据,uuid的时间又直线下降。
时间占用量总体可以打出的效率排名为:auto_key>random_key>uuid,uuid的效率最低,在数据量较大的情况下,效率直线下滑。
原因分析
对比一下mysql关于两者索引的使用情况.
自增的主键的值是顺序的,所以Innodb把每一条记录都存储在一条记录的后面。当达到页面的最大填充因子时候(innodb默认的最大填充因子是页大小的15/16,会留出1/16的空间留作以后的修改):
①下一条记录就会写入新的页中,一旦数据按照这种顺序的方式加载,主键页就会近乎于顺序的记录填满,提升了页面的最大填充率,不会有页的浪费
②新插入的行一定会在原有的最大数据行下一行,mysql定位和寻址很快,不会为计算新行的位置而做出额外的消耗
③减少了页分裂和碎片的产生
因为uuid相对顺序的自增id来说是毫无规律可言的,新行的值不一定要比之前的主键的值要大,所以innodb无法做到总是把新行插入到索引的最后,而是需要为新行寻找新的合适的位置从而来分配新的空间。这个过程需要做很多额外的操作,数据的毫无顺序会导致数据分布散乱,将会导致以下的问题:
①:写入的目标页很可能已经刷新到磁盘上并且从缓存上移除,或者还没有被加载到缓存中,innodb在插入之前不得不先找到并从磁盘读取目标页到内存中,这将导致大量的随机IO
②:因为写入是乱序的,innodb不得不频繁的做页分裂操作,以便为新的行分配空间,页分裂导致移动大量的数据,一次插入最少需要修改三个页以上
③:由于频繁的页分裂,页会变得稀疏并被不规则的填充,最终会导致数据会有碎片
在把随机值(uuid和雪花id)载入到聚簇索引(innodb默认的索引类型)以后,有时候会需要做一次OPTIMEIZE TABLE来重建表并优化页的填充,这将又需要一定的时间消耗。
自增ID的缺点:
那么使用自增的id就完全没有坏处了吗?并不是,自增id也会存在以下几点问题:
①. 别人一旦爬取你的数据库,就可以根据数据库的自增id获取到你的业务增长信息,很容易分析出你的经营情况
②. 对于高并发的负载,innodb在按主键进行插入的时候会造成明显的锁争用,主键的上界会成为争抢的热点,因为所有的插入都发生在这里,并发插入会导致间隙锁竞争
③. Auto_Increment锁机制会造成自增锁的抢夺,有一定的性能损失
TIS整合ChunJun实操
B站视频:
https://www.bilibili.com/video/BV1QM411z7w5/?spm_id_from=333.999.0.0
一、ChunJun 概述
ChunJun是一款易用、稳定、高效的批流统一的数据集成框架,可基于实时计算引擎Flink实现多种异构数据源之间的数据同步与计算,既可以采集静态的数据,比如MySQL,HDFS等,也可以采集实时变化的数据,比如Binlog,Kafka等。
目前的核心功能包括:
· 多源异构数据汇聚
作为一个开放式系统,用户可以根据需要开发新的插件,接入新的数据库类型,也可以使用内置的数据库插件。目前兼容30+异构数据源的数据读写与SQL计算。
· 断点续传
针对网络波动等异常情况,导致数据同步失败的任务,在下一次任务时自动从上一次失败的数据点进行数据同步,避免全部重跑。
· 数据还原
除了DML操作以外,一些源端数据库的DDL操作也能做到同步,最大程度保证源端数据库和目标端数据库的数据统一和结构统一,做到数据还原。
· 脏数据管理
数据传输过程中,因数据质量或主键约束等其他因素导致数据无法同步到目标数据库,针对这些脏数据进行统计和管理,便于后续进行脏数据分析。
· 速率控制
数据同步过程中,数据传输效率是关键。ChunJun针对各种场景,有的放矢地控制速率,最大程度保证数据同步的正常进行。
更多详见:
Github:https://github.com/DTStack/chunjun
Gitee:https://gitee.com/dtstack_dev_0/chunjun
官网:https://dtstack.github.io/chunjun/
ChunJun架构:
二、TIS 概述
TIS最早是基于Solr为用户提供一站式开箱即用、自助服务的搜索引擎中台产品。在2020年之前,当Flink和MPP引擎还没有形成影响力时 ,TIS就已经在为互联网企业内部提供实时OLAP分析需求的服务。
为满足大数据业务需求,快速将工具栈进行整合。TIS从2019年底开始转型,开始全方位支持现有实时数仓中台,从原先与搜索引擎强耦合的技术架构进行重构。从只处理搜索引擎一个场景,兼容到所有数据端的大数据生态场景。
经过TIS开发者的努力,现在的TIS内部有一套强大的数据管理系统,根据用户需求大部分的工作脚本可自动生成(TIS是基于模型的DataOps,区别于市面上其他基于脚本任务的DevOps系统,摒弃掉所有繁琐的脚本操作),等到任务所需资源准备好,用户轻点数据系统就开始运行。
另外更为关键的是,TIS能够将专业大数据技术人员和大数据分析师这两种角色解耦。一个实时数仓中台,使用它的人并不需要了解里面的技术细节,并不需要知道Flink、Hive、Hadoop的技术细节,只要知道他们是干什么的就行。基于以上,TIS改造之初并没有针对实时数仓进行编码,而是花了将近一年时间对TIS产品底座进行构建,着重进行了以下几方面的构建:
插件仓库/热生效机制
现有行业中提供的工具栈,需要在后台系统中自行部署,TIS则简化了这一流程,TIS在构建项目之时会统一将第三方的依赖包进行打包,预先部署到远端仓库中,用户在TIS中可以查看到可用插件清单。在使用时,只需鼠标下载且热生效就可使用,操作体验流畅。
全流程建模
针对ETL的各流程进行建模,将可变因素进行抽象,抽取成一个TIS系统中的扩展点,统一归档到TIS的主工程中,在主工程中没有任何具体业务代码的实现,这样在进行具体业务逻辑实现中就不需要更改任何主工程的代码,在架构层面最大限度地贯彻了OCP原则。
例如以下是对ETL中,针对结构化(支持JDBC接口)和非结构化数据源的执行流程图:
构建UI-DSL系统
随着整合进TIS的功能组件越来越多,需要单独开发的UI工作量巨大且风格难以统一,大量重新代码维护困难,同时由于行业分工精细化,流程需要前后端工程师相互协作,导致开发效率低,如何让没有前端开发经验的后端开发工程师,能够独立且畅快地完成一个UI组件的开发,成为一个重要的课题。为解决这个问题,TIS在底座中实现了一个UI-DSL的系统,后端开发工程师使用JAVA语言编写一个表单对应的MetaData脚本,里面定义表单的布局,输入项的校验等信息,运行期会自动将MetaData脚本渲染成前端的表单,从而完美解决这个课题。
如上,是TIS中定义的MySQL数据源插件,只需要在对应POJO上为对应的属性添加FormFieldAnnotation标识,在配上字段对应的默认值、label等信息描述文件:
DataSourceFactory.json
三、整合 ChunJun 完善 TIS 生态
经过几个月时间的研发,TIS V3.6.0-alpha版本终于发布了。该版本的最大亮点,即整合了大数据领域数据同步工具的翘楚ChunJun,将TIS的业务能力提升到了新高度。
TIS的最新版本:
https://github.com/qlangtech/tis/releases/tag/v3.6.0-alpha
早在 V3.6.0-alpha之前,TIS已经整合了Alibaba DataX和 Flink-CDC。离线批量同步利用DataX组件实现,而在实时数据变更Source组件方面,TIS是基于Flink-CDC来实现的。至于Sink部分,则一直是基于各种数据端提供的生态API包经过二次开发完成的。
其中存在的问题是,开发周期长,调试困难,例如,仅仅为了实现StarRocks一个Sink端实现一个基于StreamFunction的Sink实现,连开发带测试花去了整整三个星期的时间。
直到整合ChunJun之后才解决了这些问题。ChunJun已经很好地支持了大数据领域的大部分数据端,包括Source和Sink。它的Source端基于Polling轮询机制来实现,相较与Flink CDC实现的Source端是有自己的特色的。
例如,并不是所有的端都支持类似MySQL binlog这样的实时同步机制,即使支持类似Oracle的LogMiner,如需开启,也需要专业Oracle DBA协助,不然设置权限就会吓退很多用户。而基于Polling机制的实时更新订阅却可以支持所有的Source端,只要实现了JDBC接口就行。
所以ChunJun的Source端通用性非常好,比之于Flink CDC的唯一劣势是实时性要低,不过一般在大部份OLAP的场景下用户对实时性的要求并没有那么高,所以一般情况下推荐使用ChunJun的Source来监听实时数据变更。
另外,ChunJun的Sink端实现也是一大特色,一般情况下数据端的生态产品中会提供Flink Sink的实现,例如:ElasticSearch的Flink官网提供了一个基于SinkFunction的实现,StarRocks在官网也提供了Sink实现。但是各家实现方式各不相同,没有一个统一的抽象模型。另外各厂商提供的实现中基本上只是一些半成品,像容灾、监控等都没有提供,导致TIS在整合各家Sink端时着实花了不少精力且很难做得完美。
因此在 TIS v3.6.0 中利用 ChunJun v1.12.5 全面改写了TIS原有的Sink端实现,由于ChunJun实现是一个封装好并且已经在生产环境中经过检验的,并且在实现方式上已经通过统一建模,每种端的接入方式可以统一,对TIS来说大大提高了整合开发效率,而且将容灾、监控、脏数据管理也一并实现。
ChunJun支持的Connector端非常丰富,TIS v3.6.0 中只是拣取了几个用户高频使用的端来封装,其他端的封装会在后续版本中逐步实现。以下是 v3.6.0版本中实现的端类型:
四、TIS 是如何整合 ChunJun
利用 TIS数据管理系统接管 ChunJun流数据类型控制
ChunJun 流处理中构建的RowData实例是通过目标端Jdbc MetaData自动生成的(用户不需要在JSON配置文件中设置),内部需要通过目标端(Source/Sink)字段JDBC中的数据信息的fieldType作为参数来映射 flink的DataType实例,调用的接口是com.dtstack.chunjun.converter.RawTypeConverter,
在实际处理过程中发现,仅仅利用 JDBC col metaDatafieldType作为参数还是不够, 例如:MySQL的表定义为bigint,int,smallint的整型,当用户添加unsigned修饰,bigint在Flink中的映射类型需要从BigIntType变成DataTypes.DECIMAL,原smallint类型需要变成IntType,不然执行就会出错。另外像 Oracle的Jdbc内部实现了一套区别于Jdbc标准的类型规范oracle.jdbc.OracleTypes,当得到Oracle的类型之后需要归一化成Jdbc的类型java.sql.Types,不然没法正常执行。
类型映射虽然很简单,但由于Java是强类型语言,在流处理执行过程中稍有不慎就会出现ClassCastException,所以得格外小心地处理,因此TIS在ChunJun中引入了一个新的类型抽象com.qlangtech.tis.plugin.ds.ColMeta来封装Jdbc MetaData的列信息,在具体执行过程中可以更加细腻地控制Flink 内部的列类型。
取代基于JSON配置驱动的任务变为基于数据模型驱动任务
有了TIS底层数据关系管理的支持,数据同步任务定义的大部分工作可以自动生成,用户只需要做一些辅助工作,例如,用户需要导入一个张表,表有10列,用户需要做的是辅助确认:对于Source端确认表主键,Polling策略的轮询间隔时间及轮询列名,对于Sink端选取Insert的插入策略,这些都只需要鼠标就能完成,页面UI中的显示逻辑和ChunJun的规则相一致。
为ChunJun添加新的TIS扩展点
想要在 v3.6.0 版本顺利地将ChunJun Connector整合进TIS,需要添加两个功能扩展点,一是为增量Source端表的属性设置com.qlangtech.tis.plugins.incr.flink.chunjun.source.SelectedTabPropsExtends,二是为Sink端表的属性设置com.qlangtech.tis.plugins.incr.flink.chunjun.sink.SinkTabPropsExtends
五、开源共建,繁荣生态
TIS的构建理念是坚决避免重复造轮子,必须站在行业的巨人的肩膀上,做大数据行业中优秀工具栈的粘合剂。TIS V3.6.0alpha 有幸能按时发布,得益于行业中有像ChunJun、DataX、Flink-CDC、Flink这样优秀的开源项目存在 ,使得TIS整体可靠性得到保障。特别要感谢Apache Flink,提供了一个强大的实时计算生态,Flink CDC、ChunJun和TIS都是生长在这个生态中的茁壮成长的小树苗,每个项目都专注于自己擅长的领域,且相互补充。
临近发布,发现一个很有意思的使用场景,那就是用户可以选择基于Flink-CDC的MySQL Source插件来监听MySQL 表的增量变更,将数据同步到以 ChunJun 构建的 Sink中去,这样的混搭使用方式给用户带来了更多的选择自由度,也避免了在Flink-CDC和ChunJun各自的框架内部重复造轮子从而造成生态内卷。
六、拥抱CloudNative
云原生(CloudNative)时代的到来为我们描绘了一副美好的画卷,对于终端用户来说提供了低成本、可靠的IT基础服务,可以专注于业务开发,这非常好。
但对于互联网技术从业者来说,似乎有隐忧,那就是互联网红利将会被阿里云这样的云厂商通吃,小厂商只有干瞪眼的份,那我们煞费苦心构建的像TIS这样的开源项目在云时代还有用武之地吗?其实这样的担心是多余的。
一个健康的生态,必须要保证生物多样性,生态中各个物种并不是独立,他们之间存在相互依存的关系。同样在大数据生态中如果只有像阿里云、亚马逊这样互联网大厂活得很滋润,并且构成了一个人才黑洞,把其他小厂的资源全部吸干了,想必这样的生态也不可能长远。
从本质来说,促成任何个人或组织之间的合作都有一个前提,那就是存在比较优势,就如同瞎子背瘸子相互协助前行,国家之间的合作也是,中国具有廉价劳动力和广阔的市场与发达国家的技术优势进行互补,这种合作是可持续的。
云大厂可以把昂贵的互联网基础设置,用集约化采购的规模优势大大地降低成本,然后用技术手段将这些设备云化成IAAS服务提供给客户,小厂技术具有灵活高效与较低的技术人员薪资成本优势,以这种优势在IAAS之上构建PAAS服务,类似任务调度,实时数仓非常合适。国外也已经有成功的案例,比如Snowflake提供的云原生实时数仓和亚马逊等云厂商之间的合作,有同学肯定会问:”为啥亚马逊不能自己搞一个像snowflake呢?”,其实答案前面已经提到。
想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=szkyzg
添加【小袋鼠:dtstack001】入qun,免费获取大数据&开源干货
同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术qun」,交流最新开源技术信息,qun号码:,项目地址:https://github.com/DTStack
从录音带、MP3到专业的耳机、音箱,随着音乐消费方式的不断升级,音乐创作的专业“门槛”也在AI技术的加持下逐渐大众化,创作者的创新设计、创作频率也在持续增强,能降低创作门槛且智能化的创作工具就显得尤为重要。
怀揣着“人人都能玩点音乐”的初衷,唱鸭搭建了自己的音乐社区,希望为普通用户提供智能有趣的音乐“玩法”。唱鸭是一款将乐器和曲谱标记融合的新型弹唱软件,用户通过 App内的图标提醒,不需要乐器知识,就可以轻松实现创作、弹唱音乐,降低了非专业音乐人“玩音乐”的难度。
在华为开发者大会2022(Together)智慧AI技术论坛中,唱鸭作为一款作为深受用户喜爱的音乐社区软件,讲述为满足用户不断增强的创意设计,如何与HMS Core音频编辑服务合作,打造更具创意的音乐“玩法”。11月5日唱鸭正式推出,由HMS Core音频编辑服务歌声合成技术打造的“AI创作歌姬”功能。基于华为独创的AI Singer模型,歌声合成可以精准预测颤音、扰动和换气声等演唱技巧,让拟真的呼吸音与歌曲节奏完美契合,实现歌手级的高水准演唱,给用户带来了令人惊喜的新奇体验,释放更具创意的音乐创作力。
用户选择“AI创作歌姬”后,只需输入歌词,选择喜欢的音乐风格,就会自动生成动听的歌曲,并通过细腻自然、情感充沛的歌声演唱出来。在演唱节奏方面,“AI创作歌姬”实现了歌词和曲谱在“字”级别的对齐,提升了演唱自然度和节奏准确性。
唱鸭创始人李阳说到:“与HMS Core音频编辑服务的合作后,唱鸭让用户能够通过简单地输入歌词即可合成歌声,轻松完成各种类型的演唱,让没有专业学习音乐的人也能够享受到音乐互动的乐趣。AI技术赋能提升了我们的用户体验,也助力了唱鸭的业务创新。”
HMS Core音频编辑服务提供的歌声合成能力还可广泛应用于音视频创意制作、影音娱乐、音乐教育、虚拟偶像等领域。例如,在短视频或音乐创作中为用户提供歌词歌曲合成、演唱等能力,激发更多创作灵感;或是为虚拟偶像选择独特音色,使其形象更加生动逼真;或是设定为不同情景的参考声音,提高音频制作效率。
未来,HMS Core将为音乐创作者,提供更高效智能、新奇有趣的音乐“玩法”。让灵感,成就创作,真正实现“让每一个人都成为音乐家!”的愿景。
Data Catalog 通过汇总技术和业务数据,解决大数据生产者组织梳理数据、数据消费者找数和理解数的业务场景。本篇内容源自于火山引擎大数据研发治理套件 DataLeap 中的 Data Catalog 功能模块的实践,主要介绍 Data Catalog 在公有云部署和发布中遇到挑战及解决方案。
背景
-
Data Catalog 是一种数据管理的服务,会收集技术数据,并在其基础上提供更丰富的业务上下文与语义,通常支持数据编目、查找、详情浏览等功能。目前 Data Catalog 作为火山引擎大数据研发治理套件 DataLeap 产品的核心功能之一,经过多年打磨,服务于字节跳动内部几乎所有核心业务线,解决了数据生产者和消费者对于数据和资产管理的各项核心需求。
-
DataLeap 作为一站式数据中台套件,汇集了字节内部多年积累的数据集成、开发、运维、治理、资产、安全等全套数据中台建设的经验,助力 ToB 市场客户提升数据研发治理效率、降低管理成本。
-
Data Catalog 作为 DataLeap 的核心功能之一,本文汇集了 Data Catalog 团队在最近一年公有云从 0 到 1 实践的整体经验,主要讲解遇到的各项挑战和对应的解决方案。
Data Catalog 公有云发展历程
Data Catalog 已经随着 DataLeap 一起作为公有云产品正式在火山引擎对外发布,下面是 Data Catalog 在功能演进上的一些重要时间节点:
-
2021 年 9 月,Data Catalog 随着 DataLeap 完成在火山引擎公有云首个版本部署和发布,包含 60%内部核心功能,支持 EMR Hive 数据源数据管理。
-
2022 年 2 月,Data Catalog 随着 DataLeap 完成火山引擎公有云 Beta 版本发布,吸引了一批客户试用。
-
2022 年 5 月,Data Catalog 随着 DataLeap 完成火山引擎公有云 GA 版本发布,正式对外开放。
-
2021 年 9 月至 2022 年 5 月,Data Catalog 发布 10+版本,对齐 95%内部核心功能以及发布新功能 20+,包括支持 LAS/ByteHouse 数据源、OpenAPI 和数据采集等 ToB 场景新特性。
Data Catalog 公有云整体架构
Data Catalog 支持综合搜索、血缘分析、库表管理、数据采集、备注问答、专题管理、OpenAPI 等功能,和 DataLeap 其他功能模块(如数据开发、数据集成、数据质量、数据安全等)一起提供了大数据研发和治理场景的一站式解决方案。同时,Data Catalog 公有云产品是基于火山引擎提供的数据引擎和云基础设施来部署和服务的,下面会简单介绍下我们所依赖和使用的产品和服务:
-
数据引擎:是火山引擎提供的数据分析、数据仓库和数据湖相关产品,包括 ByteHouse/EMR/LAS 等产品。通常 Data Catalog 会从这类系统内采集并存储数据,进行处理加工后,再提供搜索、血缘分析等功能;另外,库表管理模块也会依赖这类系统提供对应的接口来做建库建表等操作。
-
内部公共服务:是火山引擎为支持公司内部产品上公有云提供的若干公共基础服务,主要作用是方便内部产品能快速在公有云部署,提供和公司内部兼容性比较高的公共服务,降低改造和迁移成本。其中 Data Catalog 使用较多的包括:API 网关、网络代理、访问控制、安全认证、监控报警等。
-
基础服务:这类服务或产品相较于上面说的内部公共服务主要区别是,他们是火山引擎对外售卖的标准云服务,内外部用户都可使用,且和业界主流云厂商能力是基本对齐的,不过会和公司内部一些类似的基础服务会有不少差异。Data Catalog 主要使用这类基础服务来进行自身服务的部署运维,并且进行较多的兼容性改造,包括容器部署、网络打通、内外部 CICD 和监控报警流程一致性等方面。
-
数据库和中间件:是和业界主流云厂商对齐的存储和中间件领域的标准云服务,和公司内部对应组件也会有若干差异,Data Catalog 为此也做了多版本的兼容。Data Catalog 在数据存储上使用到了 Hbase/MySQL/ES/Redis,然后在数据采集和同步场景使用了 Kafka,同时用到了日志服务来提高研发运维效率。
Data Catalog 公有云遇到的挑战
Data Catalog 经历了一个从 0 到 1 在火山引擎公有云部署并逐步优化和迭代发布 10+版本的过程,在这个过程中经历不少挑战,下面将介绍其中比较典型的问题以及我们探索并实践的一些解决方案。
网络和数据安全
为保证网络安全和多租户数据安全,火山引擎上公有云产品部署的环境划分为“公共服务区”和“售卖区”,同时售卖区又分割为若干私有网络(即 VPC),然后公共服务区和售卖区以及售卖区的 VPC 之间都是网络隔离的。
Data Catalog 会依赖一些内部公共服务,这类服务通常都部署在公共服务区,而按照网络和数据安全规范,Data Catalog 作为独立云产品需要部署在售卖区独立 VPC 内,类似的情况 Data Catalog 依赖的数据中台产品也需部署在独立 VPC 内,例如 EMR、LAS 和 Bytehouse。另外,Data Catalog 对外会提供 OpenAPI,外部客户可以通过火山引擎的 API 网关来访问这些 API,但 API 网关服务是在公共服务区,无法直接访问到 Data Catalog 服务,基于以上情况,为了正常对外提供服务,我们需要解决网络隔离问题同时还要保证安全性。
解决方案:
服务部署:为了能够在售卖区部署,经过调研我们选择火山引擎提供的容器服务(VKE)和负载均衡(CLB)来进行基础服务部署和构建,其中 CLB 提供四层负载均衡能力,容器服务是高性能 Kubernetes 容器集群管理服务。Data Catalog 基于容器服务提供的无状态负载(Deployment)、定时任务(CronJob)、服务(Service)等云原生容器管理功能进行基本服务和调度任务部署,同时也使用火山引擎的存储和中间件,以上组件均在同一个 VPC 内,能够保证网络连通以及数据安全。
-
网络打通:为解决上文所说的网络隔离问题,经过调研我们使用了公司通用的网络代理服务(PLB/Shuttle),该网络代理可做到网络打通的同时保证四层网络流量的安全,从而达到我们和各依赖方如公共服务(API 网关、IAM 等、独立部署的云服务(EMR/LAS 等)的网络连通目标。
-
数据安全:火山引擎部署环境做网络隔离,主要是保证安全性,我们虽然使用网络代理打通网络,但是仍需保证各个环节的安全性,考虑到服务间交互都是通过 HTTP 请求,我们对和外部交互的接口都增加了 SSL 和双向认证的机制,同时在安全认证方面,我们没有使用 Nginx 或 Java 原生的方案,而是借助于火山引擎内部安全服务中的 ZTI 团队的 envoy 组件来实现,同时使用 sidecar 模式和我们后端服务容器集成部署,既降低了服务端部署改造成本,也解耦了服务端业务逻辑和安全认证逻辑。
多租户适配
这里先对多租户相关概念做一些解释:
-
租户:一个客户、公司、个人开通或购买了火山引擎的云产品,火山引擎就会通知对应的服务提供者,对应云产品会感知到他的开通,这个客户就是这个云产品的一个租户,实际场景可以类比于一个公司是一个租户,不同的公司是不同的租户。
-
多租户服务:云服务要为多个租户提供服务,需要做到租户隔离,保证各租户的访问控制、数据、服务响应等各方面的使用都是隔离的,彼此互不感知互不影响的。要做到租户隔离,就需要云服务能通过逻辑或物理隔离的方式来将各租户对应数据和访问隔离开来,避免互相影响。
此前,在字节跳动内部实践中不存在多租户场景,所以面向公有云用户服务时,Data Catalog 针对支持多租户服务的能力,需要进行专门适配。
解决方案:
Data Catalog 在数据存储层借用了 Apache Atlas 的设计与实现。Atlas 的底层使用 JanusGraph 做图引擎,JanusGraph 是基于 Gremlin 图查询语义实现的计算引擎,而社区版 Atlas 不支持多租户场景。我们通过在 Atlas 上增加 JanusGraph Partition Strategy 适配,实现存储层租户逻辑隔离。
参考以上示例,JanusGraph 的 Partition Strategy 可以支持设置的 read/write Partition 的 value,并保证只读/写指定 Partition 的数据,从而达到数据隔离,我们将租户信息和 Partition Strategy 相结合,实现了多租户场景下读写数据的逻辑隔离,保证了数据安全性。
内外部功能一致
Data Catalog 在字节跳动内部已打磨多年,产品形态和技术架构比较成熟,但随着公有云部署和 ToB 产品迭代,因内部外基础服务差异和 ToB 引入新的使用场景和上下游组件导致内外部产品功能和技术实现的差异也越来越多。
在前几个版本中,我们尝试使用独立的代码分支和版本来支持 ToB 功能,避免内部新功能对 ToB 产生影响,但我们发现随着版本差异越来越大,代码和功能的合并和兼容就变得非常困难,在其中一次整体代码合并时,出现了好几千的文件 diff 和上百处 merge conflict,我们花费了一周时间多的时间合并代码和进行多环境测试回归验证,最终完成了合并。功能和代码的不一致已经成为影响研发效率和需求交付进度的很重要因素,必须要进行优化。
解决方案:
我们主要从产品功能和代码版本两方面来处理内外部一致性问题:
产品功能
-
产品功能的标准化:原则上所有功能都应做到内外部一致,只允许部分功能点的实现区别。我们期望能将各功能都进行标准化,基础模块和通用能力(如数据模型、搜索、血缘)原则上需保持内外一致,内外部依赖或需求场景差异较大的功能(如数据接入和采集、库表管理)改造为标准化流程,将差异部分尽量减小,做到只通过配置、插件、版本控制工具等方式就能适配,减少研发和运维成本。
-
明确的一致性规划:从模块到功能点逐个对比内部外实现情况,制定长期 roadmap,明确差异点的支持排期,并提高对齐内部功能的工作优先级,逐步减少差异。
-
新功能的兼容性:新功能的设计需考虑内外部一致性,包括产品的交互和研发的技术方案都需考虑外部场景并明确兼容方案,原则上对特殊场景定制化功能都需考虑通用场景适配,尽量保持多环境的兼容性。
技术实现
-
统一的代码分支管理规范:原则上内外部的代码是一致的即统一的分支。具体来说,不管域内外功能都需兼容多环境并在多环境验证才能合并代码,外部如公有云在发版周期中会基于内部主分支代码(如 master 分支)创建一个新的 release-x.x.x 分支,进行回归验证和公有云上线,同时线上持续使用 release-x.x.x 分支以保证线上环境稳定,release-x.x.x 分支需定期合回主分支。新的版本会继续基于主分支开发,并持续保持该规范。
-
明确的发版规划:根据实际情况,内部通常迭代比较敏捷发版频率较快,而外部通常要求稳定性,会定期发版(如每月一个版本),考虑到发版周期的差异,我们会以外部固定周期为标准,细粒度控制需求评估、功能开发、QA 测试、回归测试等各环节所在时间段,明确封板时间,降低内外部互相影响。
-
一致性意识和自动化多环境验证:通过多轮分享和培训在技术团队内部对齐一致性意识,清楚内外部差异点 FAQ 等,另外,如上所说新功能技术设计方案需明确多环境兼容性。同时,引入自动化的多环境验证环节,尽早发现不兼容或不一致的问题,减少人工判断和测试的成本。
OpenAPI
在 DataLeap Beta 版本发布之后,有内外部客户在试用,当时就有客户提出 OpenAPI 的需求,但在 Beta 版本我们还未支持 OpenAPI。公司内部有 OpenAPI 规范和平台,Data Catalog 也借助相关平台实现了内部的 OpenAPI,但是 ToB 场景的公共平台不同且会遇到 ToB 场景特定的问题(如安全认证、多租户、API 开通计费等),需要综合考虑来对外提供解决方案。
解决方案:
如前文介绍,火山引擎内部公共服务有 API 网关的通用服务(TOP),并有若干 API 发布规范,Data Catalog 调研了该 API 网关并解决以上核心问题来支持 ToB OpenAPI。以下介绍一下主要流程和关注点:
API 管理
-
Data Catalog 借助于 API 网关管理 OpenAPI,包括注册和开通、访问控制、限流等。
-
API 规范:火山引擎 OpenAPI 有明确的参数规范,Data Catalog 也需符合该规范,但因内部 OpenAPI 参数格式不同,需做兼容,考虑到新 API 的支持成本,借助于 Spring 的 Interceptor 和 Advice 以及定制 JSON 序列化和反序列化逻辑,实现了自动的参数格式转化,降低 API 格式兼容的开发成本。
-
访问控制:火山引擎作为云服务提供商,使用业界规范的 AKSK 密钥管理规范,API 使用者需创建 AKSK 并通过该信息来访问 API 才可通过访问控制,而 API 网关会通过 IAM 进行鉴权,通过后会给服务提供者也就是 API 注册者透传用户的身份(如租户 ID,用户 ID),方便 API 提供者使用。
-
安全认证:处理 API 网关提供的基础鉴权,Data Catalog 也增加了更多机制来保障安全性,包括双向认证、租户开通状态检测等。
-
API 文档:对于每一个 OpenAPI 都根据火山引擎规范编写了详细的参数说明,汇总为一个正式 API 文档,方便用户查阅使用。
API 请求流程
-
用户或服务通过 AKSK 访问 API,或者通过前端控制台间接访问 API。
-
API 网关通过 IAM 进行鉴权,将识别到的用户身份通过 HTTP header 透传给服务提供者。
-
服务提供者接收到请求并通过 HTTP header 获取用户身份,进行下一步处理。
总结
火山引擎 Data Catalog 产品是基于字节跳动内部平台,经过多年打磨业务场景和产品能力,在公有云进行部署和发布,期望帮忙更多外部客户创造数据价值。目前公有云产品已包含内部成熟的产品功能同时扩展若干 ToB 核心功能,正在逐步对齐业界领先 Data Catalog 云产品各项能力。
文中提及的内容其实还有继续优化的空间,以及随着客户的使用,还有面临一些新的问题,包括多租户性能优化、服务稳定性保障等,我们都在持续探索和解决,期望能更好的支持 ToB 客户的业务诉求并实现商业价值的同时,提供优质稳定的服务和丰富的扩展能力。
跳转火山引擎大数据研发治理套件DataLeap了解更多
值得信赖
为什么使用
桌面软件(办公方向、 个人工具),仍然是未来十几年 PC 端需求之一,提高工作效率
electron 技术是流行趋势,百度翻译、阿里网盘、迅雷、有道云笔记 ……
ee 框架使用 b(浏览器)s(主进程)s(远程后端服务)开发思想
前端、服务端同学都能快速入门
愿景
所有开发者都能学会桌面软件研发
简单
只需懂 JavaScript
开源
gitee:https://gitee.com/wallace5303/electron-egg 2200+
github:https://github.com/wallace5303/electron-egg 500+
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
腾讯 APIJSON 生态项目 SQLAuto 1.1.0 更新内容:
- 新增回归测试完继续深度测试等功能;
- 新增 Headless 模式 Node 环境无 UI 测试;
- 自动生成文档:解决不显示数据字典,解决名称不是原始的表名;
具体见 Release 发布版本。
SQLAuto-智能零代码数据库功能测试工具
☔ 智能零代码测试 SQL、任意增删改查、任意 SQL 模板变量、一键批量生成
本项目前端工具是基于 APIAuto 改造的纯静态 SPA 网页,下载源码解压直接浏览器打开。
后端需要部署 APIJSON-Demo 5.2.5+ 的 APIJSONBoot-MultiDataSource。
感谢开源
- jsonon
- editor.md
- vue.js
技术交流
关于作者
如果有什么问题或建议可以 提ISSUE,交流技术,分享经验。
如果你解决了某些bug,或者新增了一些功能,欢迎 贡献代码,感激不尽。
其它项目
APIJSON 腾讯零代码、全功能、强安全 ORM 库 🏆 后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构
APIAuto 敏捷开发最强大易用的 HTTP 接口工具,机器学习零代码测试、生成代码与静态检查、生成文档与光标悬浮注释
UnitAuto 机器学习单测试平台,零代码、全方位、自动化 测试 方法/函数 的正确性和可用性
APIJSON.NET C# 版 APIJSON ,支持 MySQL, PostgreSQL, SQL Server, Oracle, SQLite
apijson-go Go 版 APIJSON ,支持单表查询、数组查询、多表一对一关联查询、多表一对多关联查询 等
apijson-hyperf PHP 版 APIJSON,基于 Hyperf 支持 MySQL
apijson-node Node.ts 版 APIJSON,提供 nestjs 和 typeorm 的 Demo,由字节跳动工程师开发
uliweb-apijson Python 版 APIJSON,支持 MySQL, PostgreSQL, SQL Server, Oracle, SQLite 等
apijson-practice BAT 技术专家开源的 APIJSON 参数校验注解 Library 及相关 Demo
Android-ZBLibrary Android MVP 快速开发框架,Demo 全面,注释详细,使用简单,代码严谨
我要赞赏
创作不易,右上角点 ⭐Star 支持下本项目吧,谢谢 ^_^
https://github.com/TommyLemon/SQLAuto
OMP平台(Operation Management Platform)是云智慧公司自主设计、研发的轻量级、聚合型、智能运维管理平台。是一款为用户提供便捷运维能力和业务管理的综合平台。具备纳管、部署、监控、巡检、自愈、备份、恢复等功能。在提高运维人员等工作效率的同时,也提升了业务的连续性和安全性。
更新内容:
[新增] 主题配置 – 菜单配置 – 菜单分组。
[新增] 主题配置 – 菜单配置 – 侧边分栏 与 顶部分栏 选项。
[新增] 菜单数据 type 属性,model 与 blank 可选值, 菜单项支持弹层打开外部链接。
[新增] 工作空间 – 控制台新增选项卡案例。
[新增] 选项卡 工具栏, 增加关闭当前,关闭全部,关闭其他。
[修复] 选项卡切换,导致页面状态重置的问题。
[修复] 选项卡 在 router 刷新后不存在的问题。
[修复] echarts 图表在切换标签后,变为空白。
[修复] 顶部菜单前景色为白色的问题。
[优化] 移动端布局兼容,更好的适配 768px 下的设备。
[优化] 顶部菜单项 hover 效果。
[集成] npm run build 打包分析, 支持报告打印。
[升级] layui-vue 1.7.10。
详细内容:
本次的重要更新,我们新增了分栏布局,并且支持在顶部 或 侧边显示。
你可以通过主题配置页面来切换两种不同的分栏布局,或直接关闭分栏模式使用传统的布局方式。
更多详情:https://gitee.com/layui-vue/layui-vue-admin
MrDoc 觅思文档是基于 Python 语言的 Django 框架开发并开源的在线文档系统。
其功能类似于国内的语雀平台、看云平台、为知笔记和飞书文档,国外的 GitBook 平台。
如果你在寻找可私有化部署的在线文档系统,那么 MrDoc 觅思文档可以说是不二之选。
MrDoc 以「文档」作为系统的主要承载形式,支持用 Markdown 和富文本进行「普通文档」的写作,支持类似 Excel 的在线表格用来「表格文档」的记录。
同时以书籍形式的结构化文集作为文档的呈现形式,非常适合个人和小型团队作为私有化的文档、笔记和知识管理工具。
全平台多终端支持
浏览器扩展
MrDoc 通过官方浏览器扩展 ——MrDoc 速记(支持 Chromium 系列浏览器和火狐浏览器)(项目地址为:https://gitee.com/zmister/mrdoc-webclipper)和接入「简悦」扩展,实现了网站内容剪藏,可以化身成为互联网内容收藏神器。
桌面客户端
MrDoc 还提供了基于 Electron 开发的桌面客户端,跨平台支持 Windows、Linux 和 macOS。
移动端 APP
通过移动端 APP,你可以在手机上快速新建文集、文档,修改文档、上传图片、阅读文档……
总而言之,你所写的一切都在你自己的掌控之中,不用担心哪家的产品突然宣布停止服务,不用担心收藏在互联网平台上的内容被各种原因清理掉。
根据 MrDoc 交流 群里的使用反馈,很多朋友用来做个人私有云笔记、团队知识库、公司产品手册、组织规章制度和办事指南等
更新内容
在 2022 年 11 月 30 日,MrDoc 归版发布了 0.8.5 版本,本次版本发布带来了一大波的更新、优化和 Bug 修复,详细的更新内容如下:
- [新增]邮箱配置信息测试发送功能;
- [新增]禁用更新检测功能及其配置项;
- [修复]修复部分设备importlib-metadata版本变动导致项目运行失败的问题;
- [优化]取消iframe白名单相关配置及限制;
- [优化]增加card类型代码块颜色位;
- [优化]合并PR#153;
MrDoc 官网:
https://mrdoc.pro
MrDoc 文档站点:
https://doc.mrdoc.pro
开源仓库地址:
https://gitee.com/zmister/MrDoc
https://github.com/zmister2016/MrDoc
浏览器扩展:
https://gitee.com/zmister/mrdoc-webclipper
桌面客户端:
https://gitee.com/zmister/mrdoc-desktop-release
移动 APP:
https://gitee.com/zmister/mrdoc-app-release
示例站点:
http://mrdoc.zmister.com/
测试账号:test1 测试密码:
作者 | 张乐、张皓天
Spring Framework 6.0 已于11月份上旬正式发布 GA 版本。Spring Boot 3.0 也于11月25日正式发布 GA 版本。那么 Spring Cloud 2022 它还远吗?
前言
Java 8 目前是国内主流生产环境 Java 版本之一。虽然近几年陆续发布了 Java 11、Java 17 官方 LTS 版本,但是 “你发任你发,我用Java8” 的声音反应了大部分开发者的心声。不过 Java 17 版本在性能上做了大量的优化特别是 ZGC 的发布,促进了国内不少企业升级到 Java 17。
Spring 在 Java 语言的作用不言而喻,Spring Framework 5.0 发布已至今五年,是时候需要一个大的版本来革新技术栈了。借着 Java 17 的东风我们认为
“Java 17 + Spring Framework 6.0 + Spring Boot 3.0 + Spring Cloud 2022”
组合一定会在不久的将来被大家所接受,成为主流技术栈。当然任何新技术大规模被认可、落地都会有一定的滞后性,技术的发展 “稳”字当头。
Spring Cloud Tencent 是基于腾讯开源的一站式微服务平台北极星(集服务注册发现、配置中心、服务限流熔断、服务路由于一身)实现的 Spring Cloud 微服务解决方案套件。真正做到 “All In One”、 开箱即用,极大的降低企业的微服务实践门槛。
无论北极星还是 Spring Cloud Tencent 当前都在积极的修复 Bug、完善用户体验、迭代新功能。所以 Spring Cloud Tencent 也第一时间适配了 Spring Cloud 2022 版本。此篇文章详细讲述了 Spring Cloud Tencent 从 2021 版本升级到 2022 版本的改动点,为尝鲜 2022 版本的广大开发者提供一些参考。
一、升级过程
1.1 升级安装 JDK 17
Oracle 官网下载 JDK 17 并安装。安装之后,本地修改 JAVA_HOME 环境变量,如下以我的 Mac 为例:
安装好 JDK 17 之后,同时需要在 Idea 里设置项目的编译和运行环境为 SDK 17。
1.2 升级依赖版本
Spring Cloud Tencent 项目引用的 Parent Pom 是 spring-cloud-build,所以需要升级到最新版本。
可以看到 Spring-cloud-build 4.0.0-RC2 版本里定义的 Java 和 Spring Boot 版本已是最新的 Java 17 和 Spring Boot 3.0
普通项目一般不需要继承 spring-cloud-build ,而是通过 bom 的方式引入 Spring 全家桶。如果你的项目里定义了 Java、Spring Framework、Spring Boot、Spring Cloud 版本则需要同时升级。如下所示:
注意:Spring 非 GA 版本会先发布到 Spring 自己的 Maven 仓库,而不会发布到中央仓库。所以如果拉不到包 ,则需要在项目根 Pom 或者本地 ~/.m2/settings.xml 里配置 Spring Maven 仓库。
在升级过程中,大概率会出现包冲突的情况,例如 SCT 在升级过程中发现日志依赖有问题导致 example 启动失败。最后排查到原因:SCT 自己定义了 logback版本为 1.2.11,但是升级 Spring Boot 3.0 里传递依赖的版本为 1.4.5,所以导致版本冲突。最后解决方案就是把 SCT 定义的版本去掉,只用传递依赖的版本。
Tips:解决版本冲突大概率会占用比较多的时间,升级过程需要有耐心 😭
1.3 修改不兼容代码
javax 包替换为 jakarta 包
这是Java17 最大变更点之一,代码所有 import javax 都要替换为 jakarta。编译不通过的地方直接通过 Idea 自动导入的方式变更即可。
spring-web 6.0 不兼容升级
SCT 在升级过程中发现 spring-web 包下有些 API 不兼容,例如 ClientHttpResponse.getStatusCode() 老版本返回 HttpStatus,新版本返回的是 HttpStatusCode,改动量很小。
AutoConfiguration 自动装配方式变更
在 Spring Boot 3.0 以前的版本,通过在 META-INF/spring.factories 文件中定义需要自动装配类,Spring Boot 在启动过程中就会执行装配 Bean,如下所示:
但是在 Spring Boot 3.0 中,则是通过在
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件定义需要自动装配的类。所以迁移过程就是把org.springframework.boot.autoconfigure.EnableAutoConfiguration 下配置的类都放到新的文件中。
这里需要注意的是原来在 spring.factories 可以定义多种类型的自动装配例如:
-
org.springframework.boot.autoconfigure.EnableAutoConfiguration
-
org.springframework.cloud.bootstrap.BootstrapConfiguration
-
org.springframework.context.ApplicationListener
-
… …
只需要把 org.springframework.boot.autoconfigure.EnableAutoConfiguration 部分迁移到 org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,其它部分还是放在 spring.factories 中无需迁移。
至此 SCT 2022 升级适配工作即已完成,可以看出升级工作量并不大。
1.4 升级总结
SCT 属于比较底层的基础框架组件,依赖的第三方库少,所以整体适配工作量较少。如果您的应用是上层业务应用依赖了大量的组件,例如: spring-security、spring-stream等。那升级的成本也会高很多。
下面是 github 网友 @herodotus-cloud 总结的升级关键点:
-
更换 JDK 17 后,少部分第三方依赖包版本选择和控制问题
-
新依赖包过时代码替换。大多数没问题,就怕遇到像 spring security 6 用法的变化
-
starter 自动配置注册格式不同导致的,大多数第三方依赖都倒在这里
-
最怕的就是核心机制的变化,比如说反射。好像一些反射在 JDK 17 会有问题
-
最大的问题就是基础设置组件升级不同步或者缓慢问题,比如依赖的某个 SDK 没有升级 SDK 17,如果传递依赖了就会导致编译问题。
-
如果还要考虑向下的兼容性,怕就难了
Spring 官方建议先升级到 Spring Boot 2.7 小版本,然后再升级到 Spring Boot 3.0 版本。通过小步升级的方式,可以更加的平滑。
二、尝鲜使用 Spring Cloud Tencent 2022.0 版本
Spring Cloud Tencent 1.8.1-2022.0.0-RC2 版本已发布。通过引入 SCT BOM 的方式即可引入,如下所示:
在此解释一下 SCT 的版本号规则,版本号分为两段:
${SCT 版本}-${对应的 Spring Cloud 版本}
SCT 版本号在各个 Spring Cloud 版本之间对齐,例如 1.8.1-Hoxton.SR12 和 1.8.1-2022.0.0-RC2 ,SCT 版本号都是 1.8.1,功能完全对齐,只是引用的 Spring Cloud 不同。1.8.1-Hoxton.SR12 对应的是 Spring Cloud Hoxton.SR12 版本,而 1.8.1-2022.0.0-RC2 对应的是2022.0.0-RC2 版本。版本号中引入 Spring Cloud 版本为了一眼就能识别 Spring Cloud 版本对应关系。开发者优先选择跟自己版本一致的 Spring Cloud 版本,再选择最新的 SCT 版本。
使用 SCT 各个子模块的功能,请参考 SCT Github Wiki 文档。
三、 呼吁
第三方基础组件的升级节奏会直接影响上层应用的升级,在此也呼吁第三方基础组件的维护者能够尽快跟进适配。为广大愿意尝鲜的开发者和企业提供便利。
四、欢迎共建
如果您对微服务、Spring Cloud 技术感兴趣,欢迎加入我们。您的一个建议、Issue、Pull Request 甚至只是一个小小的 Star 都是对 Spring Cloud Tencent 社区极大的支持。
SCT Github 地址:https://github.com/Tencent/spring-cloud-tencent
北极星官网:https://polarismesh.cn/
Forest + IDEA = 双倍快乐! ForestX 隆重登场
Forest 是一款声明式的 Java 开源 HTTP 框架,相比它的前辈 Httpclient 和 OkHttp 更简明易懂、也更容易维护
废话不多说,先让我们康康用它写出来的代码长什么样子
轻轻松松完成了从高德地图获取经纬度所在的地理信息的 Rest API 接口定义,之后只要调用这个 Java 方法即可自动发送 HTTP 请求,并接受响应数据,然后转换成 Map 类型对象再交到你手上
这样做确实比以前手动组装 OkHttp 的 Client 对象、 OkRequest 对象好上很多倍,就算要调用的 HTTP 接口很多、结构再复杂,也不用怕了
但当一个项目中有成千上万个 HTTP 请求要调用,接口的管理和维护成本也会上升到一个吃力的高度
比如哪个接口对应哪个网站平台哪个URL往往不能一眼看出、项目中散落的接口具体有哪些也没法一下子就知道
另一个问题是 Forest 中的模板字符串中的占位符可以方便的引用配置文件中定义的变量已经通过标签定义的参数,但语法高亮和一个表达式语言应用的基本支持(如代码补全和提示)
这在代码少的时候不算问题,代码接口躲到一定程度,字符串模板中的变量引用写错的概率就大大增加,因为配置也多了,就容易搞不清楚谁再调用谁
这个时候就有请我们今天的主角 ForestX 登场啦~~
专为 Forest 量身定做的 IDEA 插件
ForestX 是一款专为 Forest 提供支持的 IDEA 插件
它能大幅提高您使用 Forest 框架时的开发体验
仓库地址: https://gitee.com/CHMing7/ForestX
接下来,就让我们康康它有哪些功能:
侧边导航工具栏
右边的logo小鸟图标,可打开的导航工具栏,它会把项目中定义的 Forest 接口都罗列在一起,方便管理
- 接口列表分三个层次:最顶层的项目(目录)、Forest 接口(小鸟图标)、请求方法
- 在 Forest 接口列表中,方法名左侧的图标代表了该请求的类型(/)
- 方法名/接口的右侧,则是用灰色字体展示的 URL 路径 (一般不是全路径,而是定义在方法上的路径)
代码补全
- 根据配置文件中下定义的全局变量来补全代码
- 根据YAML配置文件中定义的YAML配置项来补全代码
- 根据请求方法的参数定义来补全代码
- 根据注解定义的方法来补全代码
- 在编程式的代码中,也可出现代码补全的智能提示
不过目前仅对 、 等请求方法开放次功能
代码跳转
按住键盘键,将鼠标移动到 Forest 模板表达式中的标识符上(比如变量名),并悬停一小段时间,就会跳出该标识符所引用的配置变量或Java属性的简短信息
此时鼠标左键,即可跳转到该标识符所引用的变量/配置的定义代码
结语
程序猿的工作是创造工具,而工具亦可以用来服务程序猿,这是一种正向循环,也是一次次迭代的缩影,正是在一次次的迭代中,程序猿们不断地创造出很好、更完善、更可能改变世界的工具
而 ForestX 的迭代才刚刚开始!
漏洞描述
exporter-toolkit 是 Prometheus 的导出工具包,
exporter-toolkit 为减少使用 bcrypt 哈希验证用户身份所需要的时间和资源,从而采用缓存 cacheKey = hex(username + hashed password + input password)验证用户身份信息。为了避免侧信道攻击,对于缓存中不存在的用户(validUser)采用固定 hashed password 进行缓存验证。
攻击者在已知散列密码(hashed password)的情况下可通过毒化缓存进行身份绕过:
- 发动请求毒化缓存:
username = username+hashed password
password = “fakepassword”
- 身份绕过:
username = username
password = bcrypt(fakepassword)+”fakepassword”
Prometheus 是一个开源的系统和服务监控系统,目前在 GitHub 具有 45.7k stars,Prometheus 在 2.37.4 和 2.40.4 之前的版本中受此漏洞影响。
影响范围
github.com/prometheus/exporter-toolkit@(-∞, 0.7.2)
github.com/prometheus/exporter-toolkit@[0.8.0, 0.8.2)
修复方案
升级github.com/prometheus/exporter-toolkit到 0.7.2 或 0.8.2 或更高版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-65539
https://github.com/prometheus/exporter-toolkit/security/advisories/GHSA-7rg2-cxvp-9p7p
https://github.com/prometheus/exporter-toolkit/commit/5b1eab34484dddbce736cd119d863e4ff5
https://nvd.nist.gov/vuln/detail/CVE-2022-46146
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
2022年11月,经openKylin社区技术委员会审议通过,Phytium内核补丁特别兴趣小组—PhytiumKernelPatch SIG正式成立。
PhytiumKernelPatch SIG由openKylin社区共建单位飞腾信息技术有限公司发起成立,在openKylin社区中负责为搭载飞腾系列处理器的服务器及桌面平台提供支持飞腾特性的内核补丁,包括但不限于双路特性支持补丁、Kdump功能修复补丁、中断堆积修复补丁、SMMU特性支持补丁以及系统驱动适配补丁等。
01
SIG目标
- 维护已提交至社区的飞腾内核补丁代码;
- 完善飞腾高性能服务器芯片内核适配并同步最新补丁代码;
-
提交并维护飞腾高效能桌面芯片内核补丁代码。
02
SIG职责
1、面向飞腾高性能服务器芯片的Linux内核适配
提交并维护面向飞腾高性能服务器芯片的Linux内核功能适配及修复补丁,为搭载飞腾腾云S2500、FT-2000+/64等处理器的服务器提供高效、可靠的运行环境及完善、健全的功能支持。
2、面向飞腾高效能桌面芯片的Linux内核适配
提交并维护面向飞腾高效能桌面芯片的Linux内核功能适配及修复补丁,为搭载飞腾腾锐D2000、FT-2000/4等处理器的桌面端提供系统驱动的功能适配与性能优化。
03
欢迎加入SIG
PhytiumKernelPatch SIG负责openKylin社区中面向飞腾服务器及桌面平台的操作系统内核相关的功能适配及性能优化,为拓展openKylin的操作系统内核生态提供支撑,欢迎各位小伙伴们的加入!
- 邮件列表:
-
phytiumkernelpatch@lists.openkylin.top
- SIG主页:
- https://gitee.com/openkylin/community/tree/master/sig/PhytiumKernelPatch
openKylin(开放麒麟)社区旨在以“共创”为核心,在开源、自愿、平等、协作的基础上,通过开源、开放的方式与企业构建合作伙伴生态体系,共同打造桌面操作系统顶级社区,推动Linux开源技术及其软硬件生态繁荣发展。
社区首批理事成员单位包括麒麟软件、普华基础软件、中科方德、麒麟信安、凝思软件、一铭软件、中兴新支点、心科技、中国电科32所、技德系统、北京麟卓、先进操作系统创新中心等13家产业同仁和行业机构。
审核:openKylin
“大数据时代”的概念最早由著名咨询公司麦肯锡提出。麦肯锡表示:”数据已渗透到今天的每个行业和业务功能领域,并已成为重要的生产要素。” 数据在精巧的算法中被挖掘,数据分析变得至关重要,大家开始达成一个共识:”数据计算,能够找到新发现。”
博思艾伦咨询公司的合伙人 Josh Suillivan 在其著作《数字时代的企业进化》一书中提到,其团队研究了数百个组织,提炼出构成未来成功组织模型的要素,这类成功组织被称为”数据公司”。而进化成”数字公司”的关键,是”组织是由数据驱动的”。 在大数据时代,企业不再随便删除数据,而是希望把数据存储起来用于分析。数据库也成为了企业基础架构必不可少的一部分。
什么是MPP?
MPP(Massive Parallel Processing,大规模并行处理),一直被誉为当今数据库的主流架构,被广泛用于众多数据库产品中,包括Greenplum、Teradata、Vertica等。MPP数据库是针对分析工作负载进行了优化的数据库,以满足用户聚合和处理大型数据集的需求。 MPP分析型数据库将任务并行的分布到多个服务器和节点上,并在完成计算后,将结果返回并汇总,从而完成对海量数据的分析处理。
MPP数据库的优势
MPP数据库集群有可扩展性、高可用性、高性能等众多优势。MPP数据库的诞生解决了单个SQL数据库无法存放海量数据,很难在一台物理机器上完成分析需求的难题。
海量数据处理能力
MPP架构的数据库以PC服务器为单位,通过如下图所示的集群方式来扩展存储和计算。假设一个宽表有3亿条记录,MPP数据库会尝试在每台PC服务器的硬盘上分布1亿条记录。数据计算时,所有机器同时并行计算,理论上最高可以把计算时间降低到单机部署的1/n(n为机器数量),节省了海量数据的处理时间。
对SQL的完美兼容
大部分传统MPP数据库均实现了对SQL的完美兼容,包括ANSI SQL 2008标准,以及 SQL 2003 OLAP 扩展。对SQL的全面支持使得MPP数据库可以无缝集成业内常见的提取/转换/加载(ETL)和BI(商业智能)工具,完全支持和认证标准数据库接口。企业只需安排少量的集成工作,就可以使用现有的使用标准 SQL 结构和接口的分析工具让应用在 数据库上运行,从而避免了企业受制于供应商,帮助企业在抑制业务风险的同时推动创新。
计算的高度并行化
MPP架构给数据库的高并发性带来了极大的弹性。架构赋予数据库数据和查询的自动并行化能力,数据可以做到自动在数据库的所有节点上分区,并以高度协调的方式使用所有节点来规划和执行查询。企业可以根据自身的并发需求扩展集群,达到所需的并发需求。
水平扩展能力
MPP数据库具有良好的水平扩展能力,企业可以根据业务需求,通过增加服务器,用更多的节点支撑更大的分析需求。
传统MPP数据库的瓶颈
虽然MPP数据库有众多优势,因而成为众多分析型数据库产品的主流架构。然而,传统MPP数据库也有众多瓶颈和限制。
存算耦合
传统数据仓库的计算和存储是紧密耦合的,计算资源和存储资源按某一比例强绑定,因此用户在扩容时,必须同时扩容计算资源和存储资源,在扩容、运维、迁移上都存在一定的挑战。企业业务发展的不确定性,当企业遇到负载高峰时刻,传统数据仓库无法及时扩资源,可能会导致大数据系统无法及时分析业务数据,错失了充分挖掘数据价值所带来的商业机会。
业务受限
传统的 MPP 数据库虽然实现了水平扩展,但是由于存算耦合,水平扩展流程复杂且缓慢。随着用户的数据规模增长,每次扩缩容进行增加节点的操作时,大量的I/O请求会影响业务的处理速度,对业务的持续性会造成一定的影响。当用户负载突然增大时,无法迅速提高算力以响应业务变化,在负载降低时也无法收缩以节约成本。存算的紧密耦合,导致用户无法根据实际需求申请资源,动态扩展,导致用户的业务受限。
成本高昂
传统数据库价格高昂的软硬件导致巨大的前期投入。随着存储和工作负载需求的日益增长,面临数据库的扩容和升级时,由于传统MPP数据库架构存储和计算的紧密耦合,往往需要企业花费巨大的运维和时间成本,且操作繁琐。
木桶效应
传统MPP数据库架构存在”木桶效应”,数据库整体执行速度取决于最”短板”单机(Straggler)的性能。单机故障会”拖垮”整个数据库的性能,导致查询速度变慢。 因此传统的MPP架构往往要求新增的PC机和之前的PC机是一样的老配置,不然任何一个集群的”短板”就会影响整个数据库的性能,也就说摩尔定理不管多厉害,MPP集群拿老机器的存储和性能”一刀切”而取低值。
数据孤岛
随着业务的发展,数据量的增加,和信息化建设的需求,企业会为不同部门建设相应的业务信息化系统。然而MPP的水平”扩展“能力和事实上的”静态“项目实施是矛盾的。“扩展”理论上是和时间关联的一个概念,而基于PC机的MPP设计并不是”时间的朋友“。由于前面提到的存算耦合和”木桶效应”,企业在购买新机器的时候,往往会选择”另起炉灶”,新建一个集群,从而造成”数据孤岛”,严重阻碍了企业实现大数据目标。
全新的eMPP:传统MPP数据库的进阶版
面对传统MPP数据库的短板,OpenPie 团队打造的云原生数据库 PieCloudDB,创造了全新的eMPP分布式架构,构建以云原生、分析型分布式数据库为引擎数据计算平台。
什么是eMPP?
eMPP由OpenPie团队打造,全称是 Elastic Massive Parallel Processing(Elastic MPP,弹性大规模并行计算)。
eMPP超越传统MPP架构,更符合云时代的需求。云平台在信息技术发展过程中具有划时代意义,它带给用户的不仅仅是快捷和便利,更是极大的灵活性和可配置性。用户可以自行定义云主机的配置,定义云主机的数量等,并且可以便捷的增加和删除云主机。一句话来说,云平台给企业应用架构带来了极大的弹性。
MPP架构和云平台相结合,就诞生了eMPP。为了适应云平台的弹性,新的eMPP架构实现了云上存储计算分离。也就是说,计算资源和存储资源可以在云上实现独立的进行水平扩展。
eMPP的优势
存算分离赋予 eMPP 数据库 ”真正” 的弹性。eMPP架构继承了前文中提到的MPP数据库所有优势,并从根本上规避了传统MPP数据库的缺陷,拥有众多优势。
弹性扩展
基于云计算平台、存算分离的eMPP(弹性大规模并行计算)架构赋予数据库多维度、智能弹性扩展能力,让用户能够根据业务需求进行横向或纵向的弹性伸缩。
存储侧支持标准对象存储,可以充分利用云计算平台的优势,让对象存储接近无限的容量,避免了企业对集群进行扩容时,因计算资源和存储资源的绑定而造成的资源浪费,可单独进行计算或者存储资源的扩展,存储扩容性价比高。
计算侧在设计上充分考虑无状态实现,计算节点可以充分利用云平台海量的计算节点池,可以按需扩容和缩容。企业可以灵活考虑业务和数据量的变化,动态调整 数据库集群中计算节点的数量,用最适合的资源量来满足其业务需求。
灵活敏捷
eMPP架构计算和存储分离,避免了资源的浪费。企业可根据对资源的需求,灵活的以低成本和高效的方式,单独地进行存储或计算资源的弹性扩展,提高了资源的利用率,节省空间成本和能耗开销。
降本增效
eMPP架构带来的动态扩展能力,企业可根据自己对资源的需求进行扩展,避免了资源的浪费,相比于传统数据库,具有更高的性价比。
高可用性
eMPP架构中,计算节点不存储用户数据,保证了计算节点的无状态性。无状态的计算节点启动和停止非常容易,企业可以根据自身的需求启动足够的冗余计算节点保证eMPP数据库的高可用性。在 eMPP 数据库 中,用户数据存储在云计算平台的对象存储中,充分利用云存储的优势保障用户数据高可用性。
PieCloudDB Database:基于云计算的全新 eMPP 架构
PieCloudDB,采用基于云计算的全新 eMPP(Elastic MPP)弹性并行计算架构,集成了MPP数据库的众多优点,并完美解决了基于PC的传统MPP数据库的缺陷。计算和存储分离。存储和计算作为两个独立变量,可以在云端进行独立的弹性伸缩,避免了资源的浪费。企业可根据业务对资源的需求,灵活的以低成本和高效的方式,单独地进行存储或计算资源的弹性扩展,提高了资源的利用率,节省空间成本和能耗开销。
数据-计算-数据分离的三层独立架构让 PieCloudDB 实现了将数据集中存储,而数据独立存储。企业可以像管理商品数据一样来管理自己的数据产品的数据。企业可以将所有数据在云中存储,为已有和未来的应用真正实现数据共享。
一、Kafka存在哪些方面的优势
1. 多生产者
可以无缝地支持多个生产者,不管客户端在使用单个主题还是多个主题。
2. 多消费者
支持多个消费者从一个单独的消息流上读取数据,而且消费者之间互不影响。
3. 基于磁盘的数据存储
支持消费者非实时地读取消息,由于消息被提交到磁盘,根据设置的规则进行保存。当消费者发生异常时候,意外离线,由于有持久化的数据保证,可以实现联机后从上次中断的地方继续处理消息。
4. 伸缩性
用户在开发阶段可以先试用单个broker,再扩展到包含3个broker的小型开发集群,然后随着数据量不断增长,部署到生产环境的集群可能包含上百个broker。
5. 高性能
Kafka可以轻松处理巨大的消息流,在处理大量数据的同事,它还能保证亚秒级的消息延迟。
二、Kafka常见的使用场景
1. 消息
kafka更好的替换传统的消息系统,消息系统被用于各种场景(解耦数据生产者,缓存未处理的消息等),与大多数消息系统比较,kafka有更好的吞吐量,内置分区,副本和故障转移,这有利于处理大规模的消息。
根据我们的经验,消息往往用于较低的吞吐量,但需要低的端到端延迟,并需要提供强大的耐用性的保证。
在这一领域的kafka比得上传统的消息系统,如ActiveMQ或RabbitMQ等。
2. 网站活动追踪
kafka原本的使用场景是用户的活动追踪,网站的活动(网页游览,搜索或其他用户的操作信息)发布到不同的话题中心,这些消息可实时处理,实时监测,也可加载到Hadoop或离线处理数据仓库。
3. 指标
kafka也常常用于监测数据。分布式应用程序生成的统计数据集中聚合。
4. 日志聚合
许多人使用Kafka作为日志聚合解决方案的替代品。日志聚合通常从服务器中收集物理日志文件,并将它们放在中央位置(可能是文件服务器或HDFS)进行处理。Kafka抽象出文件的细节,并将日志或事件数据更清晰地抽象为消息流。这允许更低延迟的处理并更容易支持多个数据源和分布式数据消费。
5. 流处理
kafka中消息处理一般包含多个阶段。其中原始输入数据是从kafka主题消费的,然后汇总,丰富,或者以其他的方式处理转化为新主题,例如,一个推荐新闻文章,文章内容可能从“articles”主题获取;然后进一步处理内容,得到一个处理后的新内容,最后推荐给用户。这种处理是基于单个主题的实时数据流。从0.10.0.0开始,轻量,但功能强大的流处理,就可以这样进行数据处理了。
除了Kafka Streams,还有Apache Storm和Apache Samza可选择。
6. 事件采集
事件采集是一种应用程序的设计风格,其中状态的变化根据时间的顺序记录下来,kafka支持这种非常大的存储日志数据的场景。
7. 提交日志
kafka可以作为一种分布式的外部日志,可帮助节点之间复制数据,并作为失败的节点来恢复数据重新同步,kafka的日志压缩功能很好的支持这种用法,这种用法类似于Apacha BookKeeper项目。
三、Kafka架构深度剖析
1. Kafka数据处理步骤
1.1 Producer产生消息,发送到Broker中
1.2 Leader状态的Broker接收消息,写入到相应topic中
1.3 Leader状态的Broker接收完毕以后,传给Follow状态的Broker作为副本备份
1.4 Consumer消费Broker中的消息
2. Kafka 核心组件
2.1 Producer:消息生产者,产生的消息将会被发送到某个topic
2.2 Consumer:消息消费者,消费的消息内容来自某个topic
2.3 Topic:消息根据topic进行归类,topic其本质是一个目录,即将同一主题消息归类到同一个目录
2.4 Broker:每一个kafka实例(或者说每台kafka服务器节点)就是一个broker,一个broker可以有多个topic
2.5 Zookeeper: Zookeeper集群不属于kafka内的组件,但kafka依赖 Zookeeper集群保存meta信息,所以在此做声明其重要性。
3. broker和集群
一个独立的Kafka服务器称为broker,broker接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存。broker为消费者提供服务,对读取分区的请求作出响应,返回已经提交到磁盘上的消息。根据特定的硬件及其性能特征,单个broker可以轻松处理数千个分区以及每秒百万级的消息量。
broker是集群的组成部分。每个集群都有一个broker同时充当了集群控制器的角色(自动从集群的活跃成员中选举出来)。控制器负责管理工作,包括将分区分配给broker和监控broker。在集群中,一个分区从属于一个broker,该broker被称为分区的首领。一个分区可以分配多个broker,这个时候会发生分区复制。这种复制机制为分区提供了消息冗余,如果一个broker失效,其他broker可以接管领导权。不过,相关的消费者和生产者都要重新连接到新的首领。
4. Consumer与topic关系
kafka只支持Topic
• 每个group中可以有多个consumer,每个consumer属于一个consumer group;通常情况下,一个group中会包含多个consumer,这样不仅可以提高topic中消息的并发消费能力,而且还能提高”故障容错”性,如果group中的某个consumer失效那么其消费的partitions将会由其它consumer自动接管。
• 对于Topic中的一条特定的消息,只会被订阅此Topic的每个group中的其中一个consumer消费,此消息不会发送给一个group的多个consumer;那么一个group中所有的consumer将会交错的消费整个Topic,每个group中consumer消息消费互相独立,我们可以认为一个group是一个”订阅”者。
• 在kafka中,一个partition中的消息只会被group中的一个consumer消费(同一时刻); 一个Topic中的每个partions,只会被一个”订阅者”中的一个consumer消费,不过一个consumer可以同时消费多个partitions中的消息。
• kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息,而处于空闲状态。
kafka只能保证一个partition中的消息被某个consumer消费时是顺序的;事实上,从Topic角度来说,当有多个partitions时,消息仍不是全局有序的。
5. Kafka消息的分发
• Producer客户端负责消息的分发
• kafka集群中的任何一个broker都可以向producer提供metadata信息,这些metadata中包含*”集群中存活的servers列表”、“partitions leader列表”*等信息;
• 当producer获取到metadata信息之后, producer将会和Topic下所有partition leader保持socket连接;
• 消息由producer直接通过socket发送到broker,中间不会经过任何”路由层”。事实上,消息被路由到哪个partition上由producer客户端决定,比如可以采用”random””key-hash””轮询”等。
• *如果一个topic中有多个partitions,那么在producer端实现”消息均衡分发”*是必要的。
• 在producer端的配置文件中,开发者可以指定partition路由的方式。
• Producer消息发送的应答机制
设置发送数据是否需要服务端的反馈,有三个值0,1,-1
0: producer不会等待broker发送ack
1: 当leader接收到消息之后发送ack
2: 当所有的follower都同步消息成功后发送ack
request.required.acks=0
6. Consumer的负载均衡
当一个group中,有consumer加入或者离开时,会触发partitions均衡.均衡的最终目的,是提升topic的并发消费能力,步骤如下:
-
假如topic1,具有如下partitions: P0,P1,P2,P3
-
加入group A 中,有如下consumer: C0,C1
-
首先根据partition索引号对partitions排序: P0,P1,P2,P3
-
根据consumer.id排序: C0,C1
-
计算倍数: M = [P0,P1,P2,P3].size / [C0,C1].size,本例值M=2(向上取整)
本文由教研团队发布。
如果本文对您有帮助,欢迎和;如果您有任何建议也可或,您的支持是我坚持创作的动力。
转载请注明出处!
作者:于雄雄 陈其友 | 旷视 MegEngine 架构师
背景
在 CV 领域中,卷积计算是扩充像素的感受野的有效方法,模型大多数的计算量都是卷积操作贡献的。因此在 CV 模型的推理性能优化中,最重要的一项工作是对卷积的优化。MegEngine 在长期的工业界实践和反馈的基础上总结得出卷积优化的基本方法有:
- 直接卷积计算优化
该方法的计算过程为逐通道进行卷积滑窗计算并累加,该优化方法对卷积的参数敏感,为了达到最优的性能,会根据各个卷积参数分别进行 kernel 优化,通用性弱,但是在 Depthwise 的卷积中却是最高效的方法。
- FFT 卷积计算优化
根据卷积的性质,利用傅立叶变换可以将卷积转换为频域上的乘法,在频域上的计算对应乘法,再使用傅立叶变换逆变换,就可以得到卷积对应的计算结果。该方法使用高性能的傅立叶变换算法,如 FFT,可以实现卷积计算的优化,算法性能完全取决于傅立叶变换的性能以及相应卷积参数。
- Im2col+matmul 卷积计算优化
由于卷积计算中有大量的乘加运算,和矩阵乘具有很多相似的特点,因此该方法使用 Im2col 的操作将卷积运算转化为矩阵运算,最后调用高性能的 Matmul 进行计算。该方法适应性强,支持各种卷积参数的优化,在通道数稍大的卷积中性能基本与 Matmul 持平,并且可以与其他优化方法形成互补。
- Winograd 卷积计算优化
Winograd 方法是按照 Winograd 算法的原理将卷积运行进行转变,达到减少卷积运算中乘法的计算总量。其主要是通过将卷积中的乘法使用加法来替换,并把一部分替换出来的加法放到 weight 的提前处理中,从而达到加速卷积计算的目的。Winograd 算法的优化局限为在一些特定的常用卷积参数才支持。
由于 direct 卷积可以直接由公式得来,而 FFT 卷积对于当前业界用到的各种参数的卷积,其性能优势远没有其他优化方法明显,对于这两者本文不做详细展开。这里主要讲述 Im2col 和 Winograd 算法的实现以及优化方法。
Im2col+Matmul 优化
Im2col 算法简介
Im2col+Matmul 方法主要包括两个步骤:
- 使用 Im2col 按照卷积核的需要将输入矩阵展开一个大的矩阵,矩阵的每一列表示卷积核需要的一个输入数据。
- 使用上面转换的矩阵进行 Matmul 运算,得到的数据就是最终卷积计算的结果。
具体 Im2col 的步骤如上图所示:
- 将输入数据按照卷积窗进行展开并存储在矩阵的列中,多个输入通道的对应的窗展开之后将拼接成最终输出 Matrix 的一列。
- 以卷积的 stride 为步长展开后续的卷积窗并存在 Matrix 的下一列中。
完成 im2col 的操作之后会得到一个输入矩阵,卷积的 weights 也可以转换为一个矩阵,此时对 weights 的矩阵和 Im2col 的输出矩阵进行 Matmul 计算,就可以得到最终的卷积计算结果。
算法优化
上面介绍的过程是原始 Im2col+Matmul 的过程,实际处理器在执行上面的过程中性能达不到最优,以输入 Tensor 的 shape 为 (1, IC, IH, IW),weights 的 shape 为 (OC,IC,Fh,Fw),输出 Tensor 的 shape 为 (1, OC, OH, OW) 为例,主要原因在于:
- Im2col 的输入 Tensor 需要的 CPU 内存大小为 IC*IH*IW,而按照上面 Im2col 之后所需要的内存大小为 IC*Fh*Fw*OH*OW,当卷积的 stride=1 的时候,Im2col 之后需要的内存比之前大很多。
- 由于 Im2col 之后的数据量比较大,难以全部保存在 CPU 的 Cache 中,造成后续 Matmul 计算时,读取数据会存在 Cache Miss。
- Im2col 过程中会将输入进行 relayout 操作,而在后续 Matmul 的计算中,需要对该数据进行 Pack,Pack 操作会引入非必要的读写过程。影响算法实际性能。
优化 1:对 Im2col+Matmul 过程进行分块
上面提到在 Im2col 之后,消耗的内存会超过 CPU 的 Cache 的容量,为了使这部分数据能够保存在 Cache 中,需要对 Im2col+Matmul 的整个过程进行分块,每次 Im2col+Matmul 都只对一个分块进行操作,这样就可以解决内存占用过大,超过 CPU Cache 后造成 Cache Miss 的问题。
分块优化如上图所示:Im2col 每次只对 block_size 大小的数据进行计算,得到的 Fh*Fw*IC*block_size 的数据可以保存在 Cache 中。Im2col 得到数据后,对其直接进行 Matmul 计算,将计算得到的结果写入到输出 Tensor 对应的 block_size 处就可以得到该分块处卷积的计算结果。计算完该分块之后,依次进行下一个 block_size 的计算,直到整个输入计算完成。
结合 Matmul 的相关优化知识,在进行 Matmul A*B=C 计算时将分块 Im2col 得到的数据视作 B 矩阵,A 矩阵为卷积的权重矩阵,根据 sgemm 的分块规则,以及 cache 的性质,A 矩阵会被调度并保存在 L2 上,B 矩阵基于最内层分块的一列和 A 矩阵基于最内存分块的一行以及 C 矩阵基于最内层的部分分块会被调度保存在 L1 上,因此可以通过 L1,L2 的大小以及 A 矩阵的大小,计算出所有的分块大小。下面是分块优化性能的试验结果,可以看出分块优化能有效的减少存储使用,而且还可以提升算子的计算性能。
优化 2:融合 Im2col 和 Matmul PACK 数据操作部分
Im2col 过程中将多个窗的展开同时进行时,实际上是对内存的 copy 以及数据的 relayout 的过程,后续 Matmul 的 Pack 操作业是对数据的 copy 的 relayout,因此可以将上面两次数据的 copy 和 relayout 进行合并优化,减少该过程中对内存的读写次数。
如上图所示 Im2col+Matmul 的 algo 中实现了将 Im2col 和 Matmul 的 Pack 融合的优化,这样能够减少一次数据的读写操作。由于该 fuse 过程和卷积的参数直接相关,不同的卷积参数将对应不同的融合 kernel,所以不具备通用性。通用情况下我们会使用之前的 Im2col+Matmul 的做法,另外针对一些通用的卷积如:kernel=3×3,stride=2 等,因为参数固定,因此可以直接进行上述融合优化,利用这样的组合优化,既可以保证 im2col 算法的通用性,也可以确保大部分常见的卷积的性能。
对融合之后的卷积进行性能测试,如下所示为对应的计算吞吐:
可以看出,大多数情况下,融合之后卷积会有明显的性能提升。
Winograd 优化
Winograd 算法简介
Winograd 算法能够优化卷积计算的乘法计算量,乘法计算量的优化原理可以参考相关论文。在此就不做过多介绍了。虽然 Winograd 可以优化乘法的计算量,但是会增加加法的计算量,优化这些加法的存在可以进一步提高 Winograd 算法的性能。如可以把一部分加法计算提前到 weights 的预处理中,可以把部分加法隐藏在 Winograd 预处理中的 relayout 中。类似这样的优化可以达到减少卷积计算量的目的。
如下图所示为 Winograd 卷积算法的基本步骤,主要包括:
- 把输入的 feature map 和 weight 进行 Winograd 转换;
- 把转换后 feature map 和 weight 做批量 Matmul;
- 把矩阵乘的结果进行输出转换,得到最终结果。
在这些主要步骤中,要如何进行 Winograd 转换,如何 relayout,以及如何进行输出转换呢?下面以 Winograd F(2×2, 3×3) 为例,详细说明下这些过程。
如上图所示,上半部分是 weights 的转换,下半部分是输入 FeatureMap 的转换。其中包括了 Winograd 转换以及 relayout 的过程。
对于 weights 的转换,首先通过 Winograd 变换矩阵 G 和 GT 分别将 3×3 的 weight 转换为 4×4 的矩阵,然后将该矩阵中相同位置的点(如图中蓝色为位置 1 的点)relayout 为一个 IC*OC 的矩阵,最终形成 4×4=16 个转换之后 weights 矩阵。
对于 FeatureMap 的转换,首先将输入 FeatureMap 按照 4×4 tile 进行切分,然后将每个 tile 通过 B 和 BT 转换为 4×4 的矩阵,矩阵 B 和 BT 为 FeatureMap 对应的 Winograd 变换矩阵,然后进行与 weight 处理相似的 relayout,转换为 16 个 nr_tiles*IC 的 FeatureMap 矩阵。
如上图所示,将上述转换后两批矩阵做矩阵乘,得到 16 个 nr_tiles*OC 的矩阵,然后将相同位置的 16 个点转换为 nr_tiles*OC 个 4×4 矩阵,再使用输出的 Winograd 变换矩阵 A 和 AT 将这些 4×4 的矩阵转换为 2×2 的输出矩阵,最后将这些矩阵写回输出矩阵中就可以得到 Winograd 卷积的最终结果。
算法优化
优化 1:weight 提前处理
在上述 Winograd 算法的基础上,鉴于模型中的权重数据在整个 Inference 的时候已经是常量不会再改变,因此可以在真正 Inference 之前就可以对模型进行了 weights 的转换,这样可以优化在 Inference 的时候 weights 转换的开销,特别是在 IC 和 OC 较大时,weight 转换的开销非常大,所以 weights 提前转换,尤其对 Winograd 优化特别重要,下图是 Winograd 中进行 weight 提前转换和不进行 weight 提前转换时各自的性能:
从上图可以看出 weight 转换在 Winograd 中耗时占比很大,进行 weight 提前转换可以带来很大的性能收益。
优化 2:Winograd 分块优化
上述的 Winograd 算法,还会有以下缺点:
- 输入转换需要跨 channel 读写整个 feature map,数据读写对 Cache 不友好。
- feature map 转换之后,矩阵乘时需要再 PACK,数据访存增加。
针对这些问题,可以对 Winograd 算法的整个计算流程做进一步的优化,这些优化主要包括:
- 输入转换时,分块 feature map 的 tiles 进行分块,每次只进行一定数量的 tiles 计算;
- 调整分块大小适配 CPU L1 Cache,使得矩阵乘不需要 PACK;
对整个输入 feature map 进行分块后,每次只计算一个分块的 nr 个 tiles,这样就可以保证每个批量矩阵的输入数据(除了转换之后的 weight 数据)保存于 L1 Cache,不会出现 Cache miss, 而且矩阵乘时不需要 PACK。
下面是分块优化前后的速度对比,可以看出分块优化对性能有显著的提升。
总结
CPU 上 Inference 中有关卷积的优化有很多的途径,这里我们主要介绍了 Im2col+matmul 卷积以及 Winograd 卷积中的一些进一步优化的技术手段,通过这些方法可以进一步加速卷积计算的性能,从而加速整个模型的 Inference 性能。如下图所示是 float32 的经典网络开启相关优化后,在骁龙 855 上的测试速度:
对于具体的优化细节,大家可以结合 MegEngine 的代码实现进行研究,欢迎大家提出宝贵意见。
更多 MegEngine 信息获取,您可以:查看文档、 深度学习框架 MegEngine 官网和 GitHub 项目,或加入 MegEngine 用户交流 群:
弹指瞬间,转眼 2022 年已经来到了尾声。在过去的一年里,国内开源力量继续蓬勃发展、稳步向前;与此同时,越来越多的团队开始聚焦于开源社区的运营。
作为本土开源技术社区,OSCHINA 也一直在不遗余力地助力着国内开源发展,为构建良好的中国开源生态献一分微薄之力;平台有一套完整的模式与能力帮助开源项目社区进行运营。
开源项目社区与技术团队是开源生态发展进程中不可或缺的中坚力量,OSCHINA 矢志不渝地为这些群体提供发声渠道,不断向开发者传播最新开源与开发技术的信息,让更多开发者关注到优秀的开源项目与技术。
2022 年,我们综合了 OSCHINA 平台上各大认证官方技术团队、开源社区帐号年度发表的内容频率及质量、开展各种活动运营积极性等多方面的表现,颁发 OSCHINA“2022 年度优秀开源技术团队”奖项,以鼓励大家的积极性与辛勤付出,一起让中国的开源生态更加乐观向上。开源生态的发展离不开你们。这也是 OSCHINA 推出该奖项的第二年,欢迎有更多的技术团队、开源项目社区参与到 OSCHINA 的交流当中来。
具体名单如下(按首字母顺序排名,不分先后):
Alluxio 官方
阿里巴巴终端技术
阿里云云原生:与你并肩探索云原生技术点滴,分享你需要的
百度Geek说
CloudWeGo:构建企业云原生中间件的领先实践
得物技术:邀请你一起做最潮技术人
袋鼠云数栈DTinsight:以技术为核心,让我们一起将未来变成现在
Dromara开源组织
dubbo-go开源社区
FIT2CLOUD飞致云:软件用起来才有价值,才有改进的机会
HMS Core:与开发者一起,同成长,共精彩
华为云开发者联盟:分享华为云前沿资讯动态,方便开发者快速成长与发展
JetBrains中国:致力于打造世界上最强大、最高效的开发者工具
Juicedata:做最易用的云端共享文件系统
京东云开发者:为 AI、云计算、IoT 等相关领域提供技术分享交流
开务数据库
KubeSphere:一个开源的以应用为中心的容器云平台,支持多云与多集群管理
Kvrocks
MASA技术团队:专注于 .NET 现代应用开发解决方案
NebulaGraph:开源分布式图数据库,千亿顶点和万亿边仅毫秒级查询延时
NGINX开源社区
openKylin:开源聚力,共创未来
OneFlow深度学习框架
Orillusion:致力于打造一款完全开源基于 WebGPU 标准的轻量级渲染引擎
PostgreSQLChina
Rainbond:支持管理多种 Kubernetes 集群,提供企业级应用的全生命周期管理
RT-Thread
SeaTunnel:非常易用的支持海量数据实时同步的超高性能分布式数据集成平台
SelectDB
ShardingSphere社区:第一时间更新知名 Apache 顶级项目 ShardingSphere 技术新闻
声网:全球实时互动云服务开创者和引领者
Shopee技术团队:与你一起探讨前沿技术思考与应用
StarRocks:致力于打造世界顶级的新一代极速全场景 MPP 数据库
StoneDB:企业级一体化实时 HTAP 开源数据库
TakinTalks稳定性社区
涛思数据TDengine
TiDB:定位于 HTAP (Hybrid Transactional/Analytical Processing) 的融合型数据库产品
腾讯云中间件
优麒麟
vivo互联网技术:分享 vivo 互联网技术干货与沙龙活动,推荐最新行业动态与热门会议
VMware中国研发中心
WasmEdge:由 CNCF (云原生计算基金会) 托管的 WebAssembly runtime,是为边缘计算应用程序优化的执行沙箱
微众开源
网易数帆:专注数字化基础软件技术传播
又拍云:加速在线业务
云智慧AIOps社区:秉承 Make Digital Online 的使命,致力于通过先进的产品技术,为企业数字化转型和提升 IT 运营效率持续赋能
云杉网络:DeepFlow 云及云原生可观测性平台
Zadig云原生交付
Zilliz
字节跳动云原生计算:构建新一代海量数据计算平台
中移物联OneOS
作者名称&关注我们
独立站OpenCart——外贸平台自建站/跨境电商独立站专用系统。安装方便,功能强大,操作简单
前言:从2021年8月到2022年11月,历时1年多的时间。我们终于迎来了重大的版本升级,OpenCart专业版正式从v3.8升级到v4.1!
接下来看看我们从 v4.1 的版本中,新增、优化、修复了哪些功能?
✦✦
01 | 新增功能
(1)全新主题模板
首页:
产品展示页:
多功能模块:
OpenCart 专业版4.1中,我们将主题模板做了全新的升级,看上去更加“欧美范儿”让客户更有购买欲!
(2)Tiktok 购物车对接
配置路径:模块管理→通用模块→TikTok Business Extension
新增的TikTok购物车功能,让跨境卖家轻松在TikTok卖货转化客户
用户可以在短视频下方,购物车直接购买商品!
(3)客户组折扣优惠功能
配置路径:营销推广→会员组折扣→添加(编辑)
该功能可以让运营人员,轻松的对不同的客户群,设置不同的折扣优惠力度
该功能还可以选择折扣生效的“分类”。卖家轻松选择参与优惠的商品范围,运营起来更加灵活
(4)Track718 / 17Track 物流跟踪查询
配置路径:模块管理→通用模块→搜索“快递跟踪”
为了满足跨境消费用户,查看物流信息的需求,我们在这次升级中加入了市面上流行的17Track、Track718——国际物流追踪工具
(5)订单删除到回收站功能
配置路径:订单销售→订单管理→回收站
为了避免后台运营人员误操作导致的数据丢失,我们新增了回收站功能
删除订单后,可以在右上角“回收站”中找回、或彻底删除订单
✦✦
02 | 升级功能
(1)升级 第三方PHP包
升级的第三方PHP包有:Illuminate ORM、阿里云短信、腾讯验证码、AWS存储等第三发包
(2)升级 前端框架/组件
升级前端框架/组件到Bootstrap5、jQuery v3.6.0、Font Awesome 6、Swiper 8
✦✦
03 | 优化功能
(1)多语言url伪静态地址唯一
为了进一步提升独立站商品,在搜索引擎中的收录比率。我们将url伪静态地址,设置成了唯一,避免了多个地址指向同一个页面导致的降权!
(2)左侧菜单栏性能提升
左侧菜单起来,更加的“顺滑”不卡顿!
(3) admin 路径修改后兼容问题
admin的路径可进行修改,进一步提升安全性。
修改后兼容性问题得到了优化!
修改前:
修改后:
(4) 退换货流程优化
我们根据客户提出的优化建议,结合跨境电商退换货场景,优化了退换货流程
用户可以在退换货时,客户直接可以填写寄回快递单号。后台能轻松查看!
(5) 后台商品可搜索子产品
(6) 博客列表排序改为按时间倒序
(7) 免运费功能,结账页显示还差XX免运费
(8) 系统环境持续升级
支持PHP8.0及以上 / MySQL8.0!
✦✦
04 | 修复功能一览
序号
修复功能点
1
修复 热卖功能
2
修复 产品缓存相关
3
修复 自提结账成功后页面问题
4
修复 注册成功页、秒杀、砍价等词条
5
修复 采集列表页全选无效以及重新发布问题
6
修复 手机端分类列表按钮UI
7
修复 登录、注册验证码问题
8
修复 手机端图片模块链接问题
9
修复 充值结账跳购物车问题
10
修复 商品导入/导出功能 无法导入分类问题
11
修复 图片resize返回路径错误
12
修复 秒杀问题以适配多商家
13
修复 后台客户导出按来源筛选无效的情况
14
修复 设置默认货币问题
15
修复 图片管理器 OSS 返回路径错误
更多产品更新动态
↓下方链接↓
https://www.opencart.cn/products_update
版权所有,转载需注明出处!
想了解电商独立站怎么做?想了解多商城系统建站?
想了解OpenCart独立站如何推广?对OpenCart有新的功能需求?
欢迎随时联系我们!
漏洞描述
owncast/owncast 是一个开源的实时视频和聊天服务平台。
owncast/owncast 0.0.13 之前的版本中由于 persistence.go 类对用户输入的 sql 语句没有正确转义,导致 /api/chat/users/setenabled API 端点容易受到 sql 注入漏洞的影响。具有 Moderator 权限的攻击者可通过向该端点发送包含恶意 userId 参数的 POST 请求进行基于时间的 SQL 盲注,获得 sqlite 数据库的管理权限,进而窃取 stream_key 访问 owncast 的管理仪表板。
影响范围
owncast/owncast@(-∞, 0.0.13)
修复方案
升级owncast/owncast到 0.0.13 或更高版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-60981
https://nvd.nist.gov/vuln/detail/CVE-2022-3751
https://github.com/owncast/owncast/commit/23b6e5868dc27a3fabbecf
https://huntr.dev/bounties/a04cff99-5d53-45e5-a882-771b0fad62c9/
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
前言
对于 ,相信熟悉 Go 语言的程序员基本都不陌生,一般线上的问题都是靠它可以快速定位。但是实际项目中,很多时候我们为了性能都不会开启它,但是出了问题又要靠它来分析。好在 go-zero 已经帮我们很好的集成进来了,我们只需要像开关一样去开启、关闭它即可,这样我们就可以配合运维监控,当出现 cpu、内存等异常情况时候,自动开始开启收集(比如大半夜你睡的正香的时候),那么第二天可以通过分析当时的采样还原现场,那我们看看 go-zero 是如何做的。
源码分析
我们可以看 go-zero 源码位置
服务启动的时候,go-zero 在 初始化了监听信号操作( 也是通过这里通知的,这里不展开讲了),可以看到在接收到 信号时候,如果是第一次就开始收集,第二次就停止收集,看到这块可能瞬间就明白了,我们只需要在服务器执行 就可以开始收集这个服务的 信息了,再执行一次就停止了收集,就可以将这些文件导出到本地,使用 分析。
一次线上实战
我们线上有一个 的服务监控告警,内存占用比较高,这时候我打开 看到服务内存累计占用的确异常,如下图:
这时候到线上找到这个服务的服务器,执行了 ,查询到了这个 服务的进程 是 21181,我们这时候就可以给这个 服务发送信号收集 信息:
第一次执行了这个命令后,在对应服务的 日志中可以看到 了 ,当我们再次执行 , 日志中可以看到 了 信息,这时候代表收集完成了。值得注意的是收集的信息都在 文件夹下,以这个服务名命名的如下:
这时候就可以下载对应的 去本地分析,可以使用 ,也可以配合 使用 查看,由于我这边通过命令行就快速定位了问题,就没用使用 。
我使用 然后进入命令行交互,使用 查看前面占用较高的资源。
前面基本是底层序列化等操作,发现主要问题集中在红色框中导致持续上涨的内存,因为业务同学在 中消费完了消息又向下游其他的mq服务使用 发送一个 消息,每次发送都调用一个 然后在 ,恰恰这个 服务又大量消息消费又特别频繁,导致内存不断上涨,最终解决方案将 在 中初始化一个 就可以了,没必要每次都要 ,世界又恢复清净了。
写在最后
想一下 go-zero 给了我们 开关,让我们很方便的实现分析问题,但是不是所有问题都是一直存在的,比如半夜突发内存、cpu 过高,早上起来服务正常了,这怎么排查?所以我们希望如果异常了,能保留问题现场,那我们是不是可以配合运维监控实现自动保存问题现场呢?比如内存、cpu 连续超过 指标3分钟的话,我们就调用这个开关收集,之后我们就可以根据这个文件来分析问题了,这样就达到自动化了。
项目地址
go-zero 微服务框架: https://github.com/zeromicro/go-zero
https://gitee.com/kevwan/go-zero
go-zero 微服务最佳实践项目:https://github.com/Mikaelemmmm/go-zero-looklook
欢迎使用 并 star 支持我们!
微信交流群
关注『微服务实践』公众号并 交流群 获取社区群二维码。</服务进程id>
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
Godot 团队近日发表博客介绍了他们对 4.0 和 Godot 4.x 未来的期望。
团队表示,Godot 4.0 只是 Godot 4 的开始,它当然不会是完美的,但已准备好用于生产环境。他们预计,用户会遇到破坏工作流的错误(尤其是在不太常见的硬件上),许多工作流会感觉不完善,并且性能未能完全达到设定的目标。但团队会快速并定期发布错误修复版本(就像对 Alpha 和 Beta 所做的那样)。因此,Godot 4.0.1、4.0.2 等会在名义上的“4.0”稳定版本发布后不久出现。
同时,为了减轻贡献者的压力并避免延迟发布。从 4.1 版开始,开发团队的目标是加快功能更新的发布周期(4.1、4.2 等,即“4.x”版本)。
目前 Godot 4.0 仍处于测试阶段,团队建议希望获得更稳定、无错误体验的用户继续使用 3.5 系列版本,当他们认为 4.0 已准备好用于生产环境时,就会发布 4.0,而不是等到它完美时再发布。因为它不会是完美的,也不一定要完美。但它将为未来的所有工作奠定基础,在众人的帮助下,它可能会更接近我们设想的《Godot 4》。
4.0 作为重大版本更新,其开发工作于 2020 年启动,在两年多的开发过程中,Godot 4.0 带来的新特性包括:支持 Vulkan API、改进图形渲染系统、改进 OpenGL、添加新的 Physics 特性、增强 GDScript 脚本、更好地支持音频、改进多人游戏模式,以及对 Godot 3.x 的大量其他改进。
Oracle Linux 9 系列发布了第一个版本更新,支持 64 位 Intel 和 AMD () 以及 64 位 Arm () 平台。与所有的 Oracle Linux 版本一样,此版本与相应 RHEL 版本 100% 应用二进制兼容。
对于 64 位英特尔和 AMD 架构,Oracle Linux 提供了两个内核选项,即 Unbreakable Enterprise Kernel (UEK) 和兼容红帽的内核 (RHCK)。在 Arm 平台上,Oracle Linux 只提供 UEK。
此版本使用的 UEK 版本是 Unbreakable Enterprise Kernel Release 7 (UEK R7)。UEK R7 基于上游 Linux Kernel 5.15,同时支持 Oracle Linux 9 和 Oracle Linux 8。
Oracle Linux 9.1 重新引入了 Application Stream 模块,包含错误和安全修复,以及功能更新。最重要的变化是增强了安全性,以及带来新的开发工具。
安全
-
OpenSSH 支持设置最小 RSA 密钥长度;此更新使用户能够为 OpenSSH 服务器和客户端设置最小 RSA 密钥长度。
-
默认情况下,加密策略强制执行 OpenSSH 2048 位 RSA 密钥长度最小值,且系统范围的加密策略强制 RSA 的最小密钥长度为 2048 位。如果 OpenSSH 连接失败并显示无效密钥长度错误消息,这意味需要使用更长的 RSA 密钥。
-
OpenSSL 选项支持 SHA-1 签名。
-
支持使用 keylime 包。keylime 是一种使用可信平台模块 (TPM) 技术对远程系统进行认证的工具。
开发工具
- 新 Application Stream 模块提供了以下更新:
- php: 8.1
- ruby: 3.1
- maven: 3.8
- nodejs: 18
- httpd 已更新到 2.4.53 版本并包含 httpd-core 包。它包含带有所有基本文件的 httpd 二进制文件。
详情查看 Oracle Linux 9 Update 1 Release Notes。
发布公告
Oracle Linux 是由 Oracle 支持的企业级 Linux 发行版,它从 RHEL 源代码包生成。Oracle Linux 的独有特性包括一份定制且严格测试过的名为 “Oracle Unbreakable Kernel” 的 Linux 内核,与 Oracle 的多数数据库应用在内的软硬件产品的紧密集成,以及 “零掉线打补丁” 技术 —— 该特性能让系统管理员在不重启的情况下更新内核。
IntelliJ IDEA 2022.3 正式发布,在新版本中,开发者可以通过设置切换到新 UI,即可预览新的 IDE 外观。此版本引入了一个新的 Settings Sync(设置同步)解决方案,用于同步和备份自定义用户设置。此外,新版本的 IDE 还具有以下多项其他改进和升级。
主要更新
通过设置使用新 IntelliJ IDEA UI
在 IntelliJ IDEA 2022.3 中,您可以切换到新 UI 并预览 IDE 完全重做的外观,新外观干净、现代且功能强大。 勾选 Settings/Preferences | Appearance & Behavior(设置/偏好设置 | 外观与行为)中的 New UI preview(新 UI 预览)框,在项目中尝试一下。
新的 Settings Sync(设置同步)解决方案
新的 Settings Sync(设置同步)插件现在可用于所有基于 IntelliJ 的 IDE(Rider 除外),包括免费版和付费版。 新的解决方案能够同步来自平台、捆绑插件和一些第三方插件的大部分可共享设置。 请注意,我们将停止支持旧的 IDE Settings Sync(IDE 设置同步)插件并取消捆绑 Settings Repository(设置仓库)。
处理 WSL 2 中的项目的新方式(Ultimate)
IntelliJ IDEA Ultimate 2022.3 带来了处理在 WSL 2 文件系统中运行的项目的替代方式。 IDE 后端将直接在 WSL 2 中启动,而不是在 Windows 上运行完整的 IDE。 然后,您可以像在 IntelliJ IDEA 中使用远程开发时连接到远程机器一样轻松连接到它。 处理 WSL 2 中的项目时,这种安排可以提供更好的 IDE 性能。
适用于 Spring Bean 自动装配和 OpenAPI 架构生成的新操作(Ultimate)
使用 IntelliJ IDEA Ultimate 2022.3,您现在可以在需要的地方轻松自动装配 Spring Bean。这项新操作适用于 Spring、Micronaut 和 Jakarta EE CDI。此外,我们还增强了使用 OpenAPI 规范记录 Web API 的用户体验,现在可以立即为 Spring 控制器或 JAX-RS 资源生成 OpenAPI 定义。
Redis 支持(Ultimate)
在 IntelliJ IDEA Ultimate 2022.3 中,我们实现了备受期待的对 Redis 的支持。 您现在可以连接到 Redis Single Instance,在数据查看器中探索键值,借助智能编码辅助编写和执行 Redis 查询等。
用户体验
将工具窗口停靠到浮动编辑器选项卡的选项
为了让您可以更轻松地安排工作空间并在多个显示器上与 IntelliJ IDEA 交互,我们实现了将工具窗口拖出主窗口并将其停靠到浮动编辑器选项卡的选项。
意图操作预览默认启用
在 IntelliJ IDEA 2022.3 中,意图操作的预览功能现在默认开启,让您可以立即查看应用 IDE 建议后代码将如何变化。 打开可用意图操作列表并将鼠标悬停在不同选项上时会显示预览。 您可以在意图操作列表打开时按 F1 禁用预览功能,或者在 Settings/Preferences | Editor | General | Appearance(设置/偏好设置 | 编辑器 | 常规 | 外观)中管理。
改进了 Search Everywhere(随处搜索)结果的用户体验
我们微调了 Search Everywhere(随处搜索)结果列表背后的算法,使其行为更可预测,使搜索的素的选择更加准确。 现在,开始输入查询时,IDE 会冻结出现的第一个搜索结果,并且不会在找到更多选项时对其重新排序。此外,机器学习排名现在对 Files(文件)选项卡默认启用,这样可以提高结果的准确性并缩短搜索会话。
Find Usages(查找用法)结果中的相似用法集群
Find Usages(查找用法)现在提供有关代码素如何在项目中使用的更深入信息。 借助集群算法,IDE 现在可以分析搜索结果,检测最常见的用法模式,并根据结构相似性将所有找到的用法分类。 这些用法集群显示在 Find Usages(查找使用)工具窗口的 Preview(预览)选项卡中。
改进了 Tips of the Day(每日小技巧)
我们对 Tips of the Day(每日小技巧)的外观和行为做出了多项更改,使其更实用且更易理解。 我们更新了对话框的设计,为每个小技巧添加了标题以指定描述的 IDE 区域,并实现了技巧评分功能以收集反馈。我们还微调了确定显示哪些提示的算法,让您可以看到与 IDE 体验和正在处理的项目最相关的提示。
改进了 Bookmarks(书签)
我们为 Bookmarks(书签)实现了多项 UI 改进。 首先,又可以从编辑器选项卡为文件添加书签了。只需右键选项卡调用上下文菜单,然后选择 Bookmarks(书签)。 此外,您可以将所有打开的选项卡中的所有文件添加到 Bookmarks(书签)。 为此,可以调用相同上下文菜单并选择 Bookmark Open Tabs(为打开的选项卡添加书签),也可以使用编辑器选项卡窗格右侧的三点图标调用此操作。 IDE 会将所有打开的选项卡放入一个新的书签列表中,您可以随意为其命名。
以偏好代码样式查看库代码
IntelliJ IDEA 2022.3 提供了以偏好样式阅读代码的功能,即使该样式与文件的当前格式不同。 您可以在 Reader(阅读器)模式下应用新的可视格式设置层,根据自定义格式方案调整代码外观,而无需重新格式化实际代码。
性能改进
我们进行了显著性能改进以优化 IDE 的启动体验:我们并行化了一些此前按顺序运行的进程并减少了 Eager 类加载。 我们还将操作更新移至后台线程以改进 UI 响应,并实现多线程 VFS 刷新来增强索引编制。
编辑器
改进了复制剪切粘贴行为
我们重做了粘贴操作 (⌘V) 的行为。 现在,如果在没有选择代码的情况下复制 (⌘C) 或剪切 (⌘X) 一行,粘贴操作会将剪贴板的内容添加到当前行上方,而不是像旧版本一样添加到文本光标处。 此外,Settings/Preferences | Advanced Settings(设置/偏好设置 | 高级设置)中新增了一个选项,可供在未选择任何内容的情况下调用复制操作后禁用复制行的选择。
针对 JavaScript 和 TypeScript 的 Code Vision 提示
我们针对 JavaScript 和 TypeScript 实现了 Code Vision 内嵌提示。 这些提示让您可以直接在编辑器中即时了解代码,显示 inheritors(继承者)、usages(用法)、code authors(代码作者)和 related problems(相关问题)等指标。
Java
新的 Java 检查和其他改进
我们实现了一系列新的 Java 检查和快速修复,保护您的代码免受潜在危害和错误。 新增了一项检查来帮助检测在每个分支中都有一条公共语句的 switch 表达式,并提供了一个快速修复来将语句向上移动到 switch 表达式中,从而缩短代码。 IDE 将报告冗余数组长度检查,以及 之后的冗余 调用。 另一项新检查可以报告仅使用一个素或字符时数组、列表或字符串的多余创建。
Java 19 支持
IntelliJ IDEA 2022.3 支持 2022 年 9 月发布的 Java 19 的新功能。 IDE 现在支持记录模式以及对 switch 表达式模式匹配的更改,提供了代码高亮显示、补全和导航。 现有检查和快速修复已相应更新以支持这些更改。
Kotlin
对 Kotlin 1.7.20 功能的支持
IntelliJ IDEA 2022.3 现在完全支持 Kotlin 1.7.20 中引入的功能,包括新的 运算符和数据对象声明。
针对 Kotlin 改进了 IDE 性能
我们优化了缓存和索引的使用,使代码分析更快、更稳定。 我们还改进了 .gradle.kts 文件中的代码补全算法,根据我们的基准测试,它的速度提高了 4-5 倍。
Scala
更出色的 Scala 3 支持
v2022.3 引入了大量升级以提供更好的 Scala 3 支持。IDE 现在支持形参解组和引用模式,并且在匹配类型和类型变量的支持方面做出了诸多改进。现在有针对类型变量的类型推断,类型变量会被正确解析以用于模式匹配目的。 特征构造函数中的命名实参已得到正确处理,您可以使用一项操作快速创建一个 Scala 3 枚举文件或仅为顶层定义创建一个空 Scala 文件。 我们还有许多 TASTy Reader 增强,提高了高亮显示的准确性并改进了编辑器性能。
新的 Can be private(可为 private)检查
有时可以将 public 类、方法或字段设为 private 或 protected。 然而,当代码较为复杂时就很难判断。 新的 Can be private(可为 private)检查现在可以帮助您确定,还会提出快速修复建议。 将可为 private 的成员实际标记为 private 后,您可以将接口与实现详细信息分离,从而更容易理解代码。 这也减少了自动补全中的噪声,使使用过程更容易、更快,同时减少认知负担。它还提高了编译器和 IDE 的性能。
从用法创建形参
如果在方法中有一个未解析的符号,新增的快速修复可以将这个符号添加到方法的形参列表。
版本控制系统
为 GitHub 和 Space 重新设计了 Review list(审查列表)
我们重做了 Review list(审查列表)UI,帮助减少认知负担并清晰提供有关请求的最重要信息。 在改进中,我们还确保在所有受支持的审查平台上保持一致的外观。
构建工具
针对 Groovy 项目中 build.gradle 文件操作的改进
IntelliJ IDEA 2022.3 为 Groovy 构建脚本中的 Gradle 版本目录提供了代码补全和导航。 我们还微调了 Groovy 的 build.gradle 文件中的代码高亮显示,并实现了一些新检查。 IDE 现在会高亮显示已弃用的配置方法并建议适用替换选项。 它还能够检测构建脚本中插件 DSL 的不正确用法,并提供了一组新检查来鼓励使用任务配置规避 API
使用新 IntelliJ IDEA 工作区模型 API 的 Maven 导入
在 IntelliJ IDEA 2022.3 中,我们使用新的 IntelliJ 工作区模型 API 引入了实验性 Maven 导入功能。 此更改有望在导入 Maven 项目时提高最高 10% 的速度。 选项现在在 Settings/Preferences | Build, Execution, Deployment | Build Tools | Maven | Importing(设置/偏好设置 | 构建、执行、部署 | 构建工具 | Maven | 导入)中默认启用。 请注意,并非所有功能在此阶段都可用,部分手动模块设置在重新导入时不会保留。
Maven2 支持插件
从 v2022.3 开始,我们将解绑对 Maven2 的支持,改为通过一个独立插件提供,您可以从 Settings/Preferences | Plugins(设置/偏好设置 | 插件)查找并安装或从 Marketplace 下载。
运行/调试
增强了 Java 调试器中的数据流分析辅助
我们改进了 Java 调试器中的数据流分析 (DFA) 功能。 DFA 辅助已经预测了某些表达式的未来值。 现在,当分析器可以预测代码的某个分支不会被执行时,它会灰显对应代码部分。
排除覆盖注解的新选项
IntelliJ IDEA 2022.3 引入了一个选项来控制项目中哪些注解应从覆盖统计信息中排除。 要将不想测试的方法通知 IDE,首先用任意注解标记,然后转到 Settings/Preferences | Build, Execution, Deployment | Coverage(设置/偏好设置 | 构建、执行、部署 | 覆盖)并将注解添加到 Exclude annotations(排除注解)列表。
Docker
在不安装 Docker Desktop 的情况下从 WSL 使用 Docker 可执行文件
从 v2022.3 起,IntelliJ IDEA 支持连接到 WSL 中运行的 Docker。 您可以在 Settings / Preferences | Build, Execution, Deployment | Docker(设置/偏好设置 | 构建、执行、部署 | Docker)中设置此类连接。
Pull Docker image(拉取 Docker 镜像)意图操作
新增的方式可供轻松拉取所需镜像,而无需从 Dockerfile、docker-compose.yml 或使用 Testcontainers 的测试中运行。 只需在高亮显示的镜像名称上调用上下文操作 (⌥⏎),然后选择 Pull Docker image(拉取 Docker 镜像)。
.dockerignore 文件类型支持
我们引入了对 .dockerignore 文件的全面支持,包括代码高亮显示和补全。 从 IDE 构建镜像时,这些文件会被纳入考量。
在 Dockerfile 文件中支持 heredoc 格式
Here 文档允许将后续 Dockerfile 行重定向到 或 命令的输入。 IntelliJ IDEA 现在支持此语法,您可以使用它在 Dockerfile 文件中生成配置文件或多行脚本。
来自 Docker 上下文的 Docker 连接
如果 Docker 配置文件中已经进行了设置,那么您现在可以使用 Docker Contexts(Docker 上下文)设置额外 Docker 连接。 为此,您可以在 Services(服务)视图中调用 Add Service(添加服务)上下文菜单并选择 Docker Connections From Docker Contexts(来自 Docker 上下文的 Docker 连接)。
已弃用的 Docker Machine 已从支持的连接列表中移除
由于 Docker Machine 已被 Docker 弃用,我们也已将其从 Settings/Preferences | Build, Execution, Deployment | Docker(设置/偏好设置 | 构建、执行、部署 | Docker)中的连接列表中移除。 如果您是活跃的 Docker Machine 用户,仍然可以通过 API URL 连接到它。 您可以获取 Docker 机器列表并输入相应 URL,也可以输入 certs 文件夹的路径。
教育功能
IDE 中的编程课程
现在,可以直接在 IDE 中学习 Java、Kotlin、Scala、Python、Go 和其他编程语言或者提高现有技能。 新功能还提供了创建个人教育课程的功能。 要访问此功能,请转到欢迎屏幕上的 Learn(学习)选项卡, Enable Access(启用访问)。 注意,对于 Java 和 Kotlin 以外的语言,您需要安装一个额外插件。
其他
- 现在,可以在带有 ARM64 处理器的 Windows 和 Linux 机器上运行 IntelliJ IDEA 2022.3。IDE 安装程序处于测试版阶段,网站和 JetBrains Toolbox App 均提供 Windows 版,但 Linux 版仅可从网站获得。
- 与 IntelliJ IDEA 捆绑的 Android 插件现在提供了 Android Studio Electric Eel Beta 2 的所有功能,包括对 Android Gradle 插件(AGP)7.4.0-beta02 的支持。
更多详情可查看:https://www.jetbrains.com/idea/whatsnew/
Chrome 108 正式发布,这个版本也是 Chrome 在 2022 年发布的最后一个稳定版,由于中间还有圣诞假期的缘故,下一次更新要到 2023 年的第二周才会到来。
新的 Viewport 尺寸单位
新的 viewport 单位让你有更多的控制权来创建自适应的 UI。这些单位以不同的方式测量 viewport 面积,因为它们考虑到了浏览器中可以展开或折叠的 UI 素,例如地址栏。
单位提供的 viewport 大小是假设这些用户代理界面是折叠的。另一方面, 单位提供的 viewport 尺寸是假设这些界面是展开的。
有了 单位,viewport 尺寸会根据浏览器界面素的显示与否而自动调整。这个值将是 单(最大)和 单(最小)范围内的任何值。
COLRv1 中现在支持可变字体
自 Chrome 98 开始,Chrome 就已支持 COLRv1 彩色矢量字体,但最初的版本只支持 COLRv1 表的静态功能。
但是 COLRv1 规范还包括 OpenType 变体,这意味着允许通过改变变轴的值来改变字体属性。如今 Chrome 108 已经支持这种变化。
这个版本还包括对 CSS 的 和 条件扩展。
有了这样的支持,开发者可以检测到字体功能何时可用,从而给用户带来最新最好的体验,也可以在支持不可用的情况下创建一个回退版本。
FileSystemSyncAccessHandle 方法现在是同步的
开发人员可以通过调用 来访问一种针对性能进行了高度优化的特殊文件,该方法在 对象上公开。这一调用会产生一个 。
其中 、 、 和 方法过去是异步的,但从Chrome 108 开始,它们是同步的。
这一变化会使 与基于 Wasm 的应用所期望的同步、类似 POSIX 的文件 API 相匹配,带来实质性的性能提升。
省电模式
几个月来,Google 一直致力于为 Chrome 和 ChromeOS 开发一些降低电池和内存消耗的功能,其中一些工具终于出现在浏览器的稳定版本中。省电模式默认处于禁用状态,用户可以将省电模式设置为在设备停止充电或电池电量低于 20% 时启用。更新到 108 后,用户可以访问 并将该标志设置为启用,就可以使用了。
更多详情可查看:https://developer.chrome.com/blog/new-in-chrome-108/
分层单体架构风格是分层思想在单体架构中的应用,其关注于技术视角的职责分层。同时,基于不同层变化速率的不同,在一定程度上控制变化在系统内的传播,有助于提升系统的稳定性。但这种技术视角而非业务视角的关注点隔离,导致了问题域与工程实现之间的Gap,这种割裂会导致系统认知复杂度的提升。
作者:倪新明
1 经典单体分层架构
1.1 四层单体架构风格
经典的四层单体分层架构如下图所示,应用在逻辑上划分为展现层、业务层、持久层及数据存储层,每层的职责如下:
展现层:负责给最终用户展现信息,并接受用户的输入触发系统的业务逻辑。用户可以是使用系统的人,也可以是其他软件系统。
业务层:关注系统业务逻辑的实现
持久层:负责数据的存取
数据存储层:底层的数据存储设施
这种分层单体架构可能是大多数开发人员最早接触、最为熟悉的应用架构风格,其特点是:
层间的依赖关系由上到下逐层向下直接依赖,每层都是关闭状态,请求的数据流向从上到下,必须严格通过每个分层进行流转,而不能进行穿透调用。
关注点隔离:通过分层将系统的关注点进行垂直分配,每层只关注自身层边界内的职责,层间职责相互独立不存在交叉。比如业务层负责处理系统的核心业务逻辑,而持久层则关注于对数据的存取。
除了关注点隔离这一维度,分层也在 “变化” 的维度进行隔离。每层的变化速率不同,由下级上逐层增加,展现层的变化速率最快,数据存储层变化速率最低。通过严格层依赖关系约束,尽量降低低层变化对上层的影响。这个特点的上下文是分层之间依赖于抽象,而非依赖于具体。当实现发生变化而接口契约不变时,变更范围框定在当前层。但,如果是接口契约的变更,则可能会直接影响到上游的依赖层。
这种分层架构风格具有明显的优势:
分层模型比较简单,理解和实现成本低
开放人员接受度和熟悉程度高,认知和学习成本低
1.2 五层单体架构风格
四层架构面临的问题是:
层间数据效率问题: 由于层间调用关系的依赖约束,层间的数据流转需要付出额外成本
业务层服务能力的复用性:业务层中处于对等地位的组件或模块之间存在共享服务的诉求
从复用性的角度考虑,如下所示的五层架构中,通过引入中间层解决复用问题。将共享服务从业务层沉淀到通用服务层,以提高复用性。其特点是:
引入通用服务层提供通用服务,提高复用性
通用服务层是开放层,允许调用链路穿透,业务层可以按需直接访问更下层的持久层
相比于四层架构,五层分层架构的主要优势是:通过中间层的引入一定程度解决系统的复用性问题。但从反向角度看,正是由于中间层的引入导致了如下问题:
引入中间层降低了数据传输效率,提高了开发实现成本
有造成系统混乱度提升的风险:由于通用服务层的开放性导致业务层可以穿透调用。但这种是否需要进行穿透的场景无法形成统一的判定原则,往往依赖于实现人员的个人经验进行权衡,同一个业务场景由不同的开发人员实现可能会有不同的判定结果(在四层架构中如果放开层间调用约束也会存在该问题)。随着业务需求迭代,系统的依赖关系一定会日趋增加,最终形成复杂的调用关系,也导致系统复杂性上升,增加团队成员的认知成本。
2 单体分层架构的共性问题探讨
当然,正是由于其极高的接受度,也造成了大家对分层的认知误区,认为分层是必然的“默认选项” ,从而忽略了分层的本质。分层到底是为了解决什么问题?
分层本质上是处理复杂性的一种方式:将复杂性在不同级别进行抽象,通过分层进行职责隔离,以此降低认知成本。同时,通过分层形成的“屏障”,控制变化在系统间的传播,提升系统稳定性。
不论是四层架构还是五层架构都是分层思想在单体应用架构风格下的实践,这种分层模式存在的固有问题主要体现在以下几个方面:
分层对系统复杂度和效率的影响
变化真的能完全隔离吗?
问题域与解决方案的隔离
2.1 分层对系统复杂度和效率的影响
如上文所述,分层架构中各层的变化速度不同。越往上变化越快,稳定性越低,越往下变化越慢,稳定性越高。比如,展现层的用户展示逻辑可能频繁变化,对应于不同的场景诉求展示数据及形式都可能不同。
如果划分层次越多,层间依赖关系越严格,则系统的调用链路和依赖关系会更加清晰。但,请求及响应的链路越长,层间数据转换有额外成本。即使引入各种数据转换工具,比如MapStruct,实现起来依然会感觉非常繁琐和重复。
如果划分层次越多,层间依赖关系宽松,允许跨层调用(如下所示的从展现层调用持久层只是一个示意),则能在一定程度降低数据频繁转换的成本。但:
其一:如何判定是否要跨层调用很难形成统一的严格判定标准,只能进行粗粒度划分。因此,在实现过程中会有不同的判定结果,系统的调用关系会随着代码规模增长而日趋复杂。当然,团队可以加强代码评审的粒度,每次评审基于是否穿透调用进行讨论、判断并达成一致。但实际经验是,由于人为因素,靠严格的代码评审并不能保证决策的一致性。
其二:如果允许跨层调用,则意味着 “模型” 的穿透,低层的模型会直接暴露在更上层,这与我们追求的组件内聚性和模型的封装性存在冲突
注:层间的依赖约束是一种架构决策,可以考虑通过自动化单测试机制进行保证,具体参考
《 基于ArchUnit守护系统架构 》
《 轻量级的架构决策记录机制 – ADR》
2.2 变化的隔离
我们对分层有一个普遍的、“先入为主” 的认知,分层能够隔离变化。首先会想到的例子,比如,如果底层的数据库发生了变更,又或者ORM框架发生了变更,那么,我们只需要修改DAO层的实现,而不需要更改上层的业务层代码。
你真的会替换数据库吗?你真的会替换ORM框架吗?有可能,但概率非常低,大部分系统并不会发生这种场景。
发生替换就真的能隔离吗?如果你的层间不是依赖于抽象,而是依赖于具体,那么隔离也无从谈起。
即使层间依赖于抽象,变化就真的隔离了吗?实现发生变化的直接结果就是依赖方需要引用新的实现,这种变化也同样会影响到上层。只不过是这种变化可能交由IOC容器了
但,这个是变化隔离的全部吗?
如果是展现层需要增加一个新的字段,而当前数据库模型中没有?
如果是数据库中需要增加一个新的字段,而展现层和业务逻辑层不关心?
如果是……
所以,引起系统变化的原因很多,场景各异,业务诉求亦不相同,分层对变化隔离程度也不相同:
分层可以控制变化在系统内的传播,由于变化场景的多样化,分层不能完全的隔离变化。
2.3 问题域与解决方案的割裂
重新思考下上文提到的分层单体架构的特点之一:关注点隔离,展现层、业务层、数据访问层、存储层等各层聚焦于自身的职责。这种关注点的本质是什么?
技术视角的隔离!!!
每层都是从技术视角将技术关注点进行隔离,而非业务领域视角。技术视角是研发友好的,作为开发人员,天然的可以理解和接受这种技术维度的统一语言:DAO层只负责处理数据相关逻辑,Controller层之服务处理Restful API相关,RPC层只处理与外部系统的跨进程调用等等。
而对于非常核心的业务概念,比如以订单为例,在单体分层架构下需要回答这样一个问题:“订单组件” 在哪里?
在经典的分层单体架构风格中,典型的实现如下图所示:
OrderConroller:Spring技术栈下的系统访问的Rest接口
OrderService/OrderServiceImpl:订单的核心业务逻辑实现服务,实现诸如下单、取消订单等逻辑
OrderDAO/OrdeDAOImpl:订单数据的存取
订单组件并不是以一个单一的、内聚的事物存在,其组成素OrderService以及其依赖的OrderDAO分散于不同的层,因此,这种模式下订单组件只是逻辑性、概念性的存在。作为业务域的核心抽象,订单组件没有真实的、直观的、内聚的反映在代码实现中。我们在工程代码库中寻找“订单组件”:
首先,在工程顶层最先看到的是技术视角的Module(Maven Module):web、service 、dao
然后,需要在各层导航才能一窥其全貌
在IDE的支持下,这种导航并不会很复杂。但问题的根本在于:认知成本的增加。
我们去了解系统,天然的是从业务域而非技术域出发,单体分层恰恰是从技术域而非业务域出发,这种不同导致业务域与实现间的割裂,增加了对系统的认知成本。
实现要反应抽象,组件化思维本质上一种模块化思维,通过内聚性和封装性,将问题空间进行拆分成子空间,分而治之。对外通过接口提供组件能力,屏蔽内部的复杂性。接口契约的大小粒度需要权衡,粒度越小,能力提供越约聚焦,理解和接入成本越低,但通用性越差。接口契约粒度越大,则通用性越强,但理解和接入复杂性越高。
将组件化思维应用于单体分层架构,引申出模块化单体架构风格。应用架构按照问题域进行模块化组织,而非基于技术关注点进行拆分。组件内部遵循内聚性原则,其内包含了实现组件能力所需要的各个素及交互关系。组件之间通过统一的、合适粒度的接口契约进行交互,不直接依赖于组件的内部能力或模型。同时,组织良好的模块化单体应用架构也是进行微服务拆分的重要保证。如果你无法在单体架构中进行优雅的模块化组织,又何谈合理的微服务拆分呢?
3 结语
单体分层架构风格是分层思想在单体架构中的应用,其关注于技术视角的职责分层。同时,基于不同层变化速率的不同,在一定程度上控制变化在系统内的传播,有助于提升系统的稳定性。但这种技术视角而非业务视角的关注点隔离,导致了问题域与工程实现之间的Gap,这种割裂会导致系统认知复杂度的提升。将组件化思维应用于单体分层架构,模块化单体技术视角的分层拉回至业务域视角的模块化,一定程度上降低业务与工程实现间的隔离。良好的模块化是单体走向微服务的重要基石,如果模块化设计较差的系统,不仅会增加微服务拆分的成本,更为重要的是,会增加形成分布式单体的概率和风险。
Go-IOC 是一款为 Go 语言开发的运行时依赖注入库。Go 语言的语言特性决定了实现一款类型安全的依赖注入容器并不太容易,因此 Go-IOC 大量使用了 Go 的反射机制。如果你的使用场景对性能要求并不是那个苛刻,那 Go-IOC 非常适合你。
并不是说对性能要求苛刻的环境中就不能使用了,你可以把 Go-IOC 作为一个对象依赖管理工具,在你的业务初始化时获取依赖的对象。
使用方式
要创建一个 Container 实例,使用 方法
此时就创建了一个空的容器。
你也可以使用 来创建容器,创建之后,可以自动的把已经存在的 对象添加到容器中,由容器托管。
对象绑定
在使用之前,我们需要先将我们要托管的对象告诉容器。Container 支持三种类型的对象管理
- 单例对象
- 原型对象(多例对象)
- 字符串值对象绑定
所有的对象绑定方法都会返回一个 返回值来说明是否绑定成功,应用在使用时一定要主动去检查这个 。
确定对象一定会绑定成功(一般不违反文档中描述的参数签名方式,都是一定会成功的)或者要求对象必须要绑定成功(通常我们都要求这样,不然怎么进行依赖管理呢),则可以使用 系列方法,比如 方法对应的时 ,当创建出错时,该方法会直接 。
绑定对象时,,, 方法对于同一类型,只能绑定一次,如果多次绑定同一类型对象的创建函数,会返回 错误。
有时候,希望对象创建函数可以多次重新绑定,这样就可以个应用更多的扩展性,可以随时替换掉对象的创建方法,比如测试时 对象的注入。这时候我们可以使用 系列方法:
使用 系列方法时,必须保证第一次绑定时使用的是 系列方法,否则无法重新绑定。
也就是说,可以这样绑定 -> , -> ,但是一旦出现 ,后续就无法对该对象重新绑定了。
单例对象
使用 系列的方法来将单例对象托管给容器,单例对象只会在第一次使用时自动完成创建,之后所有对该对象的访问都会自动将已经创建好的对象注入进来。
常用的方法是 方法,该方法会按照你提供的 函数或者对象来完成单例对象的注册。
参数 支持以下几种形式:
-
对象创建函数
比如
-
带错误返回值的对象创建函数
对象创建函数最多支持两个返回值,且要求第一个返回值为期望创建的对象,第二个返回值为 error 对象。
-
直接绑定对象
如果对象已经创建好了,想要让 Container 来管理,可以直接将对象传递 方法
当对象第一次被使用时,Container 会将对象创建函数的执行结果缓存起来,从而实现任何时候后访问都是获取到的同一个对象。
原型对象(多例对象)
原型对象(多例对象)是指的由 Container 托管对象的创建过程,但是每次使用依赖注入获取到的都是新创建的对象。
使用 系列的方法来将原型对象的创建托管给容器。常用的方法是 。
参数 可以接受的类型与 系列函数完全一致,唯一的区别是在对象使用时,单例对象每次都是返回的同一个对象,而原型对象则是每次都返回新创建的对象。
字符串值对象绑定
这种绑定方式是将某个对象绑定到 Container 中,但是与 系列方法不同的是,它要求必须指定一个字符串类型的 ,每次获取对象的时候,使用 系列函数获取绑定的对象时,直接传递这个字符串 Key 即可。
常用的绑定方法为 。
依赖注入
在使用绑定对象时,通常我们使用 和 系列方法。
Resolve
方法执行体 callback 内部能够进行依赖注入, 返回值,表明在注入对象时产生错误或者 callback 返回了 error。
比如,我们需要获取某个用户的信息和其角色信息,使用 Resolve 方法
Call
方法不仅完成对象的依赖注入,还会返回 的返回值,返回值为数组结构。
比如
Provider
有时我们希望为不同的功能模块绑定不同的对象实现,比如在 Web 服务器中,每个请求的 handler 函数需要访问与本次请求有关的 request/response 对象,请求结束之后,Container 中的 request/response 对象也就没有用了,不同的请求获取到的也不是同一个对象。我们可以使用 配合 方法实现该功能。
AutoWire 结构体属性注入
使用 方法可以为结构体的属性注入其绑定的对象,要使用该特性,我们需要在需要依赖注入的结构体对象上添加 标签。
结构体属性注入支持公开和私有字段的注入。如果对象是通过类型来注入的,使用 来标记属性;如果使用的是 绑定的字符串为key的对象,则使用 来标记属性。
由于 要修改对象,因此必须使用对象的指针,结构体类型必须使用 。
其它方法
HasBound/HasBoundValue
方法签名
用于判断指定的 Key 是否已经绑定过了。
Keys
方法签名
获取所有绑定到 Container 中的对象信息。
CanOverride
方法签名
判断指定的 Key 是否可以覆盖,重新绑定创建函数。
WithCondition
并不是 Container 实例的一个方法,而是一个工具函数,用于创建 接口。实现 接口后,在创建实例方法时会根据指定条件是否为 true 来判断当前实例方法是否有效。
WithCondition(init interface{}, onCondition interface{}) Conditional
参数 是传递给 和 方法的实例创建方法, 参数则是一个条件,在调用 及 方法时,会执行 函数,该函数支持两种形式
函数的 bool 返回值用于控制该实例方法是否生效。
Extend
并不是 Container 实例上的一个方法,而是一个独立的函数,用于从已有的 Container 生成一个新的 Container,新的 Container 继承已有 Container 所有的对象绑定。
容器继承之后,在依赖注入对象查找时,会优先从当前 Container 中查找,当找不到对象时,再从父对象查找。
在 Container 实例上个,有一个名为 的方法,该方法用于指定当前 Container 从 parent 继承。
示例项目
简单的示例可以参考项目的 example 目录。
以下项目中使用了 作为依赖注入管理库,感兴趣的可以参考一下。
- Glacier 一个应用管理框架,目前还没有写使用文档,该框架集成了 Container,用来管理框架的对象实例化。
- Adanos-Alert 使用 Glacier 开发的一款报警系统,它侧重点并不是监控,而是报警,可以对各种报警信息进行聚合,按照配置规则来实现多样化的报警,一般用于配合 来完成业务和错误日志的报警,配合, 等主流监控框架完成服务级的报警。目前还在开发中,但基本功能已经可用。
- Sync 使用 Glacier 开发一款跨主机文件同步工具,拥有友好的 web 配置界面,使用 GRPC 实现不同服务器之间文件的同步。
Elastic 是开源搜索和数据分析引擎 Elasticsearch 背后的母公司。今天 Elastic 的 CEO 宣布了裁员计划,表示将裁减公司大约 13% 的员工。
Elastic CEO 在发给全体员工的邮件中称,目前全球宏观经济环境正在迫使他们的客户收紧预算,并更仔细地审查投资。在市场的某些部分尤其如此,例如中小企业在不确定时期的消费意愿有限。为了渡过这个阶段,公司要将重心放在那些对未来最关键的业务领域,并找到更有效的方法来服务公司业务的某些部分。
Elastic 公司对被裁员工提供了如下方案:
- 遣散费:向所有被裁员工支付至少 14 周的补偿金,另外工作满一年就增加一周的补偿金。
- PTO:对于所有未使用的 PTO 时间(Pay Time Off,带薪休假)支付相应的薪水。
- 医疗保健:对于参与 Elastic 公司医疗保健计划的员工,支付 6 个月的现有医疗保健保费,或将根据工作地点支付等值现金。
- RSU 股票:被裁员工将会获得截至 12 月 8 日的 RSU 股票。
- 职业支持:为受影响的员工提供简历和求职支持。
- 移民支持:为有需要的人提供移民支持。
海外用户常用的社交平台如 WhatsApp、Telegram、Facebook Messenger 等都早已实现了端到端(E2E)加密的通信。反而另一大社交平台 Twitter 一直都没有使用端到端加密(Twitter 使用的是标准加密,使用了由服务提供商持有的密钥,这意味着任何有必要权限的人都可以读取用户的信息),目前用户在 Twitter 中发送私信进行一对一交流的时候,用户的聊天内容并没有足够的安全保障。
Twitter 的首席执行官 Elon Musk 最近就用一个 emoji 表情符号回应了逆向工程师 Jane Manchun Wong 的发现,暗示 Twitter 的加密的 DM 目前正在开发中,将会使用完全的端到端加密。
Jane Manchun Wong 进一步研究发现,Twitter 在 iOS 版应用中有对 Signal 开源协议的引用。这似乎表明,Twitter 计划使用主打信息安全的 Signal 应用程序相同的 E2E 加密技术。
该加密协议是开源的,也就意味着所有开发者都可以对代码进行审查,确保该协议足够安全可靠。至于 Twitter 何时会实现这个功能,目前官方还没有给出具体的时间表。
不过,曾经在 Twitter 任职的开发者 Brandon Carpenter 表示,这是他在 2018 年就写下的代码,并给出了当时删除 Twitter for iOS 中端到端加密原型的提交历史记录,之所以当时没有实现这个功能是因为该协议难以提供与标准协议相同的 DM 功能。
在上一篇文章《HTAP 的下一步?SoTP 初探(上):数据分析正在从“大”数据趋向“小”而“宽”数据》中,我们从 HTAP 的发展历史脉络出发,结合国际知名咨询机构Gartner 的调研报告,点出了 SoTP(Serving over TP)诞生的背景。今天这篇文章,我们着重来讲一讲,SoTP 的定义、解决的问题和典型应用场景。本文是在第七届中国开源年会上的演讲实录+编辑补充版,权当抛砖引玉,欢迎广大同行批评指正。
SoTP 的重要支撑
“小”数据和“宽”数据的崛起
开篇还是回顾一下,我们提出 SoTP 的重要背景:从“大”数据转向“小”数据和“宽”数据。
根据 Gartner 技术成熟度曲线的判断,小数据正处于“创新出发点”的阶段,可能还需要一段时间才可以进入成熟,不过,随着小数据市场渗透率不断提高,它对 AI 以及更广义的数据分析的影响是显而易见且非常深远的。小数据的优势在于,抛开了对大型单体数据的依赖,实现了对于大型、小型、结构化、非结构化数据源的分析与协同。
这个趋势不仅仅是被 Gartner 一家认可的, 国际权威学者吴恩达教授也在今年 2 月初提出了:AI 的下一个发展方向,是从大数据转向小数据。当然,我们提的 AI 也只是实时事务处理与数据分析的一个重要应用领域而已,并不是全部。不过,未来数据库、数据分析处理与 AI、ML 的结合却是必然的,就比如我们后续将在 StoneDB 架构中加入的 StoneDB Autopilot 功能。作为在人工智能和机器学习领域上有着全球级影响力的领军人物,吴恩达最近几年一直在倡导以数据为中心的人工智能。什么叫以数据为中心?那就是对数据的质要有更高的要求而不是一昧的追求量(优质的小数据集经过训练也能有很好的泛化能力,如果读者感兴趣,可以阅读吴恩达接受 IEEE Spectrum 的采访新闻),而“小”数据和“宽”数据恰恰就是高质量数据集的最佳载体,可以理解为,这是众多数据分析场景逐渐从依托“量”转向提升“质”的重大发展趋势。
大势所趋之下,作为实时数据分析场景的基础底座之一,HTAP 数据库扮演着的角色也越来越重要。如果说通过“小”数据和“宽”数据获得了更高质的数据,那么热数据则是对这个质的再一次提升。
热数据一般是指频繁被访问查询的在线数据,而在一个实时智能决策系统中,近期产生的热数据往往才会发挥最大的价值,但是,并非所有 HTAP 数据库都是专注于热数据场景下的“小”而“宽”数据的,对此,StoneDB 作为国内首个对标 Oracle MySQL HeatWave 的开源实时一体化 HTAP 数据库,率先提出了面向热数据、小数据和宽数据场景的 SoTP 型数据库理念。
SoTP 数据库的定义
2.1 Serving 的定义和分类
先说这个 Serving 场景,一些同学可能有些不熟悉,因为好像之前听到的都是 OLTP 场景(指在线事务处理,比如业务处理,交易系统等) 和 OLAP 场景(指在线分析处理,比如BI、Adhoc等),但其实还有一种场景,是指在线实时服务的,介于 OLTP 和 OLAP 之间,可能还偏向 OLTP 一些,那么这种场景我们就称之为 Serving(英语时态学得好的人,应该可以 Get 到,就是进行时的意思,也即可理解为“进行中的服务”)
Serving 可以和 OLTP 组合,也可以和 BigData 或者 Stream 组合,我们把 Serving 分成了三类:
Type1. Serving over TP(StoneDB)
-
特点:处理事务型热数据,提供实时分析、事务和分析处理一体化
-
典型代表:Oracle MySQL Heatwave,StoneDB
Type2. Serving for BigData
-
特点:处理非事务型冷、温数据;适用读多写少BI分析类
-
典型代表:ClickHouse
Type3. Serving for Stream
-
特点:处理非结构化数据,作业状态状态等数据管理
-
典型代表:RocksDB
为了方便大家理解,我们做了一张图,三种类型的 Serving 数据库如图所示:
2.2 SoTP 的定义和解决的问题
那么,SoTP (Serving over TP)的定义也就很清晰了,简单来说,我们把这种有能力对在 OLTP 数据库上的热数据、小数据、宽数据进行 Serving(在线实时服务) 操作的数据库,称之为 SoTP 数据库。具体来讲,比如以 SoTP 数据库 StoneDB 为例,一个 SoTP 产品至少要满足以下几点要求:
-
数据量:一个系统,数据量不超过 100 TB,通常介于 100GB~100TB 之间
-
数据类型:主要处理结构化数据,可处理 Text、JSON 等半结构化数据,不处理非结构化数据
-
NoETL:TP 到 Serving 的流转过程中,NOETL,直接基于 TP 数据完成实时分析
-
查询类型:复杂即时的查询,将事务型热数据,从行存变成可被快速读取的列存数据
-
高并发的混合负载:比 AP 查询的并发高 3 个数量级
-
成本控制:TCO 总成本下降 80%
简单举个例子。如下图,右边就 SoTP 据库 StoneDB,对外主要接受两个业务请求,分别是左边的 OLTP 和 Serving,其中,进行 Serving 请求的主要是是 OLTP 产生的热数据。那么这个 SoTP 处理数据的过程就是先把 OLTP 请求交给主引擎——TP 引擎承载(如 InnoDB),然后再把 Serving 请求交给次引擎——Serving 引擎承载(如 Tianmu)。
2.3 SoTP 的典型场景案例
2.3.1 场景一:Native Analytics Query
注意,我们这里重点提出了一个 Native,什么叫 Native,就是指数据源上的原生,我们如果对 OLTP 系统产生的数据进行查询分析,这里的数据应该是同源的热数据,而不是另外一份数据。
客户需要一个数据库,既能执行 OLTP,还能高效、实时地运行Analytics;否则还得需要另外一个数据库运行 Analytics,这引入了额外的复杂性和代价。
传统的 ETL 方案架构就是比较复杂的,比如 MySQL + ETL + Elastic:
这种方案就不能称为是 Native,体现在数据源的不一致、查询语句语法变更等等。但是,使用 SoTP 数据库 StoneDB,就有所不同了,我们是完全一体化架构,如下:
StoneDB 一体化架构
采用 StoneDB 这种一体化架构就可以达成降本增效的效果,下图就是我们在华东地区的一个 CRM 客户使用 StoneDB 的案例:
总结来说,这个厂商获得了以下成果:
高兼容:平行替代MySQL业务,零改动
低成本:节省了成本 52%
强性能:DTU 提升了 68%
易维护:技术难度降低 50%
2.3.2 场景二:Native Autopilot
Autopilot 自动化了实现大规模高查询性能的许多最重要和最具挑战性的方面,包括provisioning、数据加载、查询执行和故障处理。
如图,StoneDB 未来的 Autopilot 将有以下特性:
自动系统配置
-
自动资源占用监测,集群节点按需自动动态伸缩。
-
自动性能监控,对需要分析的表数据进行自适应采样来预测运行工作负载所需的节点数量。
数据加载
-
自动并行加载:自动调整数据表最佳并行度来优化加载时间和内存使用
-
自动数据放置:存储数据自动分区以实现最佳查询
-
自动编码:采用可变长度的字符串编码确保最佳查询性能
查询执行
-
根据历史查询计划执行情况和统计信息优化查询性能,提升查询效率。
故障处理
-
自动错误恢复:当数据库节点访问异常时,StoneDB将自动配置新的数据库节点并完成数据迁移,确保数据快速恢复。
这里也可以举个例子,比如现在我们的需求是减少用户使用成本:要提供自动化的集群配置、加载数据、查询处理和故障处理服务,使得用户可以更多关注业务开发,减少其繁重且易出错的运维操作。
在使用 Autopilot 之前:
1. 依据数据量和数据变化率,估算节点数量;
2. 与业务开发人员确定数据分布方案;
3. 业务运行中,不断优化SQL语句;调整数据分布策略;
4. 集群节点变化导致数据迁移,业务架构,中间件等相关策略需调整;
在使用 Autopilot 之后:
1. 搭建好StoneDB服务;
2. 系统依据运行情况,自动调整相关参数,使得StoneDB处于最佳运行状态;
3. 业务人员和DBA等得到解放,更加关注业务。
SoTP 与 OLTP、OLAP 的差异
我们总结了 SoTP 与 OLTP、OLAP 的差异,具体如下表:
SoTP 数据库——StoneDB
当然,可能有部分同学看到我们上述的定位,会想着说 SoTP 和 HTAP 有一些相同之处,这是当然,毕竟我们的说法是 HTAP 的下一步,SoTP 初探。实际上,SoTP 针对的是更加细分的 HTAP 赛道,我们的核心目标就是对最近产生的热数据、小数据和宽数据进行实时分析,更进一步的是,把数据分析能力与机器学习相结合,而且因为我们是基于 MySQL 生态做的一体化架构,也可以把我们称作是 MySQL 热数据分析加速器。总之,StoneDB 作为 SoTP 数据库的核心特性就是:能够将 Serving 需要的热数据实时分析做到极致。
我们努力的现在,就是为了让下一代热数据分析尽早走上国产数据库的历史舞台,让更多的用户体验到真正的商业智能,从而更好地利用数据协作共享、驱动运营和做出决策。以下便是我们的 StoneDB 2.0 架构图:
StoneDB 的 2.0 架构完全对标 Oracle MySQL MDS(HeatWave),HeatWave 有多强大?我们后面也会出一篇文章给大家分享一下。目前,我们的架构设计方案的RFC文档也完全公布在了 Github 上:
https://github.com/stoneatom/stonedb/issues/436
如果您想了解更多,也可以关注我们的 Github 仓库:
https://github.com/stoneatom/stonedb
以上,就是本次的分享,欢迎大家批评指正。如果您还有其他疑问,欢迎添加StoneDB小助手,加入StoneDB开源社区技术交流群,在群里您可以随时提问,我们会认真为您解答。
扫码添加小助手
加入StoneDB开源社区用户群
讨论交流,共同进步
2023 年十大战略技术趋势中哪一项最需要 HTAP ?
HTAP 的下一步?SoTP 初探
存算一体 VS 存算分离 ,IT发展下的技术迭代
没有HTAP,机器学习和人工智能都是不切实际的
面向场景,HTAP到底是刚需还是炒作?
StoneDB 团队成员与 MySQL 之父 Monty 会面,共话未来数据库形态
HTAP的关键技术有哪些?| StoneDB学术分享会
解读《Benchmarking Hybrid OLTP&OLAP Database Systems》| StoneDB学术分享会
深度干货!一篇Paper带您读懂HTAP | StoneDB学术分享会
文|田阳 (花名:烈)
MOSN Maintainer
专注云原生等技术领域
本文3042字 阅读 10 分钟
1. 背景
Service Mesh 被越来越多的公司认可并实践,在实际落地过程中也遇到了形形色色的问题,同时架构也在持续演进去解决这些问题:有的从初始的 DaemonSet mode 转变为 Sidecar mode,如 Linkerd ;有的从做 CNI 延伸到 Service Mesh 场景, 结合 eBPF 使用 DaemonSet mode,如 Cilium ;如今 Istio 也新增了 Ambient Mesh ,支持 DaemonSet mode 作为其主推模式。
不难看出一个演进趋势就是围绕着是否需要 Sidecar 而展开,那么 Service Mesh 的下一站将会是 Sidecarless 吗?本文将对目前的社区趋势做一个简要分析, 最后也将介绍蚂蚁在这方面的探索和实践。
2. 社区趋势
2.1 Cilium
Cilium[1] 是目前最火的云原生网络技术之一,基于革命性的内核技术 eBPF,提供、保护和观察容器工作负载之间的网络连接。
在 6 月份,Cilium 发布了 1.12 版本,其中发布了 Service Mesh 能力、Sidecarless 架构,它提供了两种模式:
通过图表我们可以发现:针对 L3/L4 的能力,Cilium 使用内核的 eBPF 直接支持;对于 L7 的部分能力,将使用 DaemonSet 部署的 Envoy 来支持。Cilium 认为大部分能力都不需要 L7 的参与,通过 eBPF 就能满足,所以 Cilium 也称自己为内核级服务网格。
针对于此 Cilium 也有一个解释,结合应用程序 TCPD 最终被合入 linux kernel 发展为 iptables 为例,认为 Mesh 也应该作为基础能力下沉到 linux kernel 作为网络的基础组件,就类似于 TCP,作为 Linux 的一部分透明地提供的服务。
在当需要 L7 代理能力的时候,会构建 DaemonSet Envoy 处理 L7 的能力。Envoy 也已经有了 Namespace 的初步概念,它们被称为监听器。监听器可以携带单独的配置并独立运行,从而可以支持多租户的配置隔离 (但目前还做不到资源和故障的隔离) 。
Cilium 认为 DaemonSet 相比 Sidecar 最明显的好处就是代理数大大减少,减少资源和管理成本。
可以看出 Cilium Service Mesh 的发展历程是由下而上,从内核层慢慢向业务层扩展自己的服务边界,由 eBPF 来支持服务网络也是有一定的立场因素。但 eBPF 并不是银弹,DaemonSet mode 也是有一些其他的问题,收益和损失都是相对的。
2.2 Linkerd
当然,Cilium 这个架构也不乏有挑战者,其中来头最大的就是 Linkerd[2] (Service Mesh 概念的提出者) 的创始人 William Morgan ,比较有意思的是 Linkerd 最开始的架构是 DaemonSet mode ,在后面的版本才换成 Sidecar mode ,对于此,作为逆行者的他应该最有发言权。
在 William Morgan 的最新文章[3] 中也客观提出了 eBPF 的一些局限性,为了保证 eBPF 的安全执行而不影响 kernel ,需要通过验证器验证是否有不正确的行为,这就导致 eBPF 的编写存在一定的潜规则,比如不能有无界循环;不能超过预设的大小等,代码的复杂性也就受到了一定限制。所以较复杂的逻辑用 eBPF 来实现也是有较高的成本的。
文章中也提到了 DaemonSet 的一些弊端:
– 资源管理不可评估:这取决于 K8s 调度多少 Pod 到该 Node;
– 隔离性:所有应用公用一个 Proxy ,相互影响稳定性;
– 爆炸半径变大:影响整个 Node 的 Pod 实例;
– 安全问题更复杂:比如 Proxy 保存有整个 Node 的秘钥。
简而言之,Sidecar 模式继续贯彻了容器级别的隔离保护 —— 内核可以在容器级别执行所有安全保护和公平的多租户调度。容器的隔离仍然可以完美的运行,而 DaemonSet 模式却破坏了这一切,重新引入了争抢式的多租户隔离问题。
当然他也认为 eBPF 可以更好的促进 Mesh 的发展,eBPF+Sidecar 的结合是 Mesh 的未来。
我们也比较认可他对于 eBPF 的看法, eBPF 就像是一把瑞士军刀,小巧精湛,作为胶水把各种网络数据面连接起来,提供基础网络能力,比如提供访问加速,透明劫持,网络可观察性等能力。但要开发复杂的业务能力,在实操之后,感觉还是有点力不从心。目前我们团队也正在使用 eBPF 开发 K8s Service 和透明拦截等基础网络能力。
William Morgan 的说法看着也不无道理,我们先不急着站队,再来看看 Istio 是怎么做的,看是否会有新的想法~
2.3 Istio
在 9 月份,Service Mesh 领域的当家花旦 Istio 毫无征兆的发布了 Ambient Mesh ,并作为自己后续的主推架构,简单来讲就是把数据面从 Sidecar 中剥离出来独立部署,Sidecarless 架构,以彻底解决 Mesh 基础设施和应用部署耦合的问题。
比较好奇 Istio 在没有经过社区讨论和落地案例的情况下,是怎样决策笃定这个新的架构方向的呢?
Istio 认为 Sidecar mode 存在如下三个问题:
– 侵入性
必须通过修改应用程序的 Kubernetes pod spec 来将 Sidecar 代理 “注入” 到应用程序中,并且需要将 Pod 中应用的流量重定向到 Sidecar 。因此安装或升级 Sidecar 需要重新启动应用 Pod ,这对工作负载来说可能是破坏性的。
– 资源利用不足
由于每个 Sidecar 代理只用于其 Pod 中相关的工作负载,因此必须针对每个 Pod 可能的最坏情况保守地配置 Sidecar 的 CPU 和内存资源。这导致了大量的资源预留,可能导致整个集群的资源利用不足。
– 流量中断
流量捕获和 HTTP 处理 通常由 Sidecar 完成,这些操作的计算成本很高,并且可能会破坏一些实现和 HTTP 协议不完全兼容的应用程序。
Envoy 的创始人也来凑了个热闹,他对 Sidecar 架构也是颇有微词。
我们在落地过程中也是遇到了类似的痛点,比如随着机房规模和应用规模的变大,应用的连接数继续膨胀导致 CPU 和 MEM 资源占用也在持续增加,但这一切都不是应用本身想去关心的。
那么让我们来解开 Ambient Mesh 架构真面目,是怎样来解决 Sidecar mode 的问题, 架构主要提出了分层:
从图中可以看出,跟 Cilium 有一些类似,这儿的两层数据面都是基于 Envoy 来构建的,Secure Overlay Layer 主要处理 L4 场景,DaemonSet 部署,L7 processing Layer 主要处理 L7 场景,以 gateway 形式通过 Pod 部署,一个应用部署一个 gateway。
图中的 ztunnel 就是 L4 (DaemonSet 部署) ,waypoint 就是 L7 (Pod 部署) ,L4 和 L7 都是可选的,可以根据业务场景灵活组合,比如没有 L7 的场景,直接就用 L4 即可。
注:图中的 ztunnel 就是L4 (DaemonSet 部署) ,waypoint 就是 L7 (Pod 部署) 。
无形之中,Ambient Mesh 架构对 William Morgan 评论中的问题也做了一定的解决和反驳:
– 资源评估
Istio 认为 L4 资源占用少,然后 L7 的资源占用是通过 Pod 部署,可以更好的弹性。
– 隔离性
每个应用都将有一个 L7 集群,相互不影响。
– 爆炸半径
L4 逻辑简单相对比较稳定,L7 独立部署,也只影响自身应用。
– 安全问题
Istio 认为 Envoy 作为被世界上最大的网络运营商使用的久经考验的成熟软件,它出现安全漏洞的可能性远低于与它一起运行的应用程序。DaemonSet 模式下,出现安全问题时的影响范围并不比任何其他依赖每节点密钥进行加密的 CNI 插件差。有限的 L4 攻击面和 Envoy 的安全特性,Istio 觉得这种风险是有限和可以接受的。
针对 William Morgan 提到的 DaemonSet 增加了安全风险,我们也持保留意见,就拿证书场景为例,在没有统一接入层 (南北向接入网关) 这个产品之前 (15 年前,还没有 K8s ) ,应用的 HTTPS 证书和私钥都是放在跟应用一起部署的 Tengine 上,就类似于 Sidecar 模式,但接入层诞生的一个原因恰恰就是为了集中管理证书和私钥来减少安全风险,通过证书和私钥的分离架构,私钥单独存放在更加安全的 key 集群,并且通过 QAT 硬件加速,HTTPS 性能也更加高效。
把 HTTPS 和 L7 服务治理能力从应用空间解耦出来下沉为基础设施,也让我们有更多的机会去做集中的优化和演进,同时也对应用更加透明,那个时代的以应用为中心。
统一接入层和目前 Service Mesh 的 DaemonSet mode 有着不少相似之处,DaemonSet mode 也可以认为是一个东西流量的 Node 接入层。
网络通信作为基础设施,和应用完全解耦后,可以更好的优化和演进,也能更加透明高效的为应用提供相关基础能力,比如网络连接治理,可信身份,链路加密,流量镜像,安全隔离,服务治理等,更好的以应用为中心。
从 Cilium 到 Linkerd,再到 Istio,几大社区相互切磋,归根结底还是大家的业务场景不一样,也或者是立场不一样。在安全性,稳定性,管理成本,资源占用上,总是会有一个侧重点,这是需要根据不同的业务场景去选择,脱离业务场景谈架构,还是比较空洞。
3. 下一站
没有最好的架构,只有最适合自己的架构,在大家的业务场景,你会选择 Sidecar ,还是 Sidecarless ,你认为的下一站是什么呢?
下周我们即将发布 《降本增效: 蚂蚁在 Sidecarless 的探索和实践》,一起来聊聊蚂蚁在这个方向的探索和演进,期待和大家的交流~
4. 引用
[1]Cilium :
https://istio.io/latest/blog/2022/introducing-ambient-mesh/
[2]Linkerd :
https://isovalent.com/blog/post/cilium-service-mesh/
[3]William Morgan 的最新文章:
https://buoyant.io/blog/ebpf-sidecars-and-the-future-of-the-service-mesh
MOSN Star 一下✨:
https://github.com/mosn/mosn
本周推荐阅读
蚂蚁集团 Service Mesh 进展回顾与展望
顺丰科技 Service Mesh:落地半年,最初目标已经实现,将在更多场景进行大规模探索
「网商双十一」基于 ServiceMesh 技术的业务链路隔离技术及实践
MOSN 反向通道详解
全球首创的开源数据编排软件开发商Alluxio,近日宣布2.9免费开源社区版和2.9企业版正式对外发布!
本文将为您快速盘点2.9的那些更新亮点:
2.9正式版本(GA)具备较强的稳定性、良好的支持性以及企业级特性。本文将介绍Alluxio的新架构以及该架构如何赋能世界头部企业在跨区域、跨计算引擎与存储系统的大数据分析和AI 应用场景下实现增长、增强敏捷性。
Alluxio 2.9 版本增加了跨环境集群同步功能,支持横向扩展的多租户架构;显著改进在Kubernetes上部署的工具集和指南,增强了Alluxio的可管理性;此外,新版本还通过优化S3 API 实现安全性和性能上的提升。
企业可以通过Alluxio打造跨计算和跨存储的多云数据平台。Alluxio可以与Spark、Presto、Trino、PyTorch 和 Tensorflow 等一起部署于任何云平台,如 AWS、GCP 和 Azure。同时,Alluxio还可以部署在私有云数据中心或公有云在 Kubernetes 上使用。
Alluxio社区版功能亮点
以下功能Alluxio 2.9社区版和企业版均支持
Master节点健康状态监测
Alluxio master 现在定期检查各类资源的综合使用情况,包括 CPU 和内存使用情况,以及通过几个影响性能的内部关键数据架构推断系统的整体状态。可以通过查看 master.system.status 指标获取Master节点健康状态:
- 闲置
- 正常运行
- 繁忙
- 过载
关于如何使用此功能,可“详细信息”查看文档,了解有关监测功能的更多内容。
Worker 节点上的分页式存储(试验功能)
新版本支持更细粒度的存储。以往Alluxio只支持64MB块存储,新版本支持1MB的分页级存储,数据能以更细的颗粒度缓存在Alluxio worker 节点上。
此功能是为了通过提高缓存的效率而增强性能,当应用首次访问底层存储时,可以减少读放大。
可查看文档,了解如何使用:
Alluxio企业版功能亮点
下列功能仅限于Alluxio企业版
新增跨环境集群同步功能
租户隔离可有效防止不同团队在访问共享数据湖存储时产生竞争。Alluxio通过新增的跨集群同步功能,提高了在Kubernetes上跨租户或跨环境部署多个Alluxio集群时的可扩展性。
多Alluxio集群的联合(federation)是通过数据同步实现的。不同的Alluxio实例之间知道各自对于数据的修改情况,实现数据的互通,从而自动保持数据同步。当部署卫星集群架构时,此功能尤其有用,数据生产者在更新数据湖时可与数据消费者实现隔离。
开始部署前,可通过查看文档
新增Kubernetes Operator,提升Alluxio的可管理性
在Kubernetes上运行Alluxio有助于将部署策略标准化,使得数据技术栈可移植到任何环境。新版本增加了Alluxio Operator,可简化多个Alluxio集群的部署和管理。
管理员如今可以通过CRD(自定义资源)轻松部署和管理Alluxio。使用Alluxio Operator可降低管理多个Alluxio实例的负担。
开始部署前,可查看文档,了解详情。
强化S3 API安全性
新版本进一步强化了S3 API功能,管理员可通过统一命名空间来集中管理身份验证和访问控制策略,实现无论是在本地还是跨云异构存储均能达到统一的安全保护。
新版本增加了对S3 API开放式身份验证协议的支持,确保在处理Alluxio的用户请求之前对其进行验证。这项新功能允许数据平台团队连接到身份管理系统(例如 PingFederate),并使用单点登录 (SSO)。
开始部署前,可查看文档,了解详情。
想要了解更多关于Alluxio的干货文章、热门活动、专家分享,可进入【Alluxio智库】:
引言
当前,数据量呈快速增长态势,给诸如 Presto 等查询引擎带来了挑战。
Presto 作为一种流行的交互式查询引擎,具有可扩展、高性能并可与 Hadoop 进行平滑集成的特性。随着数据量的增长,Presto 需要读取更大的数据块并将其加载到内存中,继而导致IO、内存占用增大以及 GC 时间变长等。
Apache Parquet 是一种可用于高效存储和检索数据的开源列式文件格式,提供高效的数据压缩和编码方案,性能更优,能批量处理复杂的数据。
我们先前已经采取了一些措施来加快 Presto 对 Parquet 数据的读取速度,但需要读取的数据量依旧很大。从 Java 版本的 Parquet(parquet-mr 1.11.0) 开始,Parquet 添加了一个名为 Page Index 的特性,通过在列块(column chunk)中过滤不必要的 Parquet 页(page)来加快查询速度。
本文就该特性、移植到 Presto 的状态以及基准测试结果进行了介绍。
统计信息
Parquet 文件数据包含有关文件中数据的最小/最大值的统计信息。对于一个给定 filter 的查询而言,统计信息的最小/最大值可以用作 filter 要查找的值的范围。如果要查找的值不在范围内,就可以跳过读取该数据块。这样一来提高了 IO、内存和 CPU等资源的利用率,从而加快了查询速度。
下述示例展示了如何将 filter 应用于包含统计信息的表,‘x > 100’的 filter 会查找(100, ∞) 范围内的值。表中的统计信息显示只有第二列(最小值为 1 和最大值为 209) 的数值范围 [1, 209],与 filter 的过滤范围重叠。因此,我们可以跳过读取剩余 3 列,从而将数据读取的时间减少3/4 。
Parquet Page Index
Parquet 包含列块和页的统计信息。列块的统计信息显示出该列块中数据的取值范围,而页统计信息显示的是页数据,粒度更细、更有效。下述示例展示了页统计信息与列统计信息相比,如何能更好地降低数据读取量。
在第一个示例中,有一个查询中包含了“x = 2000”的filter条件。为便于演示,我们仅在一个列块中显示三个页。图表中的三个页的统计信息构成了三个范围:[-100, 60]、[50, 234]和[800, 1000] 。列块的统计信息构成 [-100, 1000] 的范围。由于我们正在查找的值为2000 ,因此页统计信息和列块统计信息都显示无需读取该列中的数据。在这种情况下,页统计信息和列块统计信息一样,都有效地减少了数据读取量。
在第二个示例中,列块和页中的数据和统计信息与第一个示例相同。唯一不同的是filter “x = 55”。在这种情况下,由于该值在列块统计范围 [-100, 1000] 内,因此对于读取的判断为“yes”。同样地,第一个页统计范围 [50, 234] 和第二个页统计范围 [-100, 60] 对于读取的判断都为“yes”,但对于最后一个页而言,由于超出了 [800, 1000 ]的范围,因此读取判断为“no”。
在第三个示例中,列块和页中的数据和统计信息依旧与第一个示例相同,但filter更改为’x = 700’。该值在列块统计范围 [-100, 1000]内,因此对于读取的判断为“yes”,但对于所有页统计信息而言,由于所有的范围都不包含要查找的值“700”,因此读取的判断结果为“No”, 跳过整列数据,不予读取。
在所有上述示例中,我们在一个列块中只显示3个页,但实际上一个列块中通常有几十甚至几百个页。因此,在现实操作中能节省更多的成本。如果列数据是经过排序的,那么误报的可能性就会降低,从而使得页统计效果更好。
Presto的页统计
在1.11.0 版本之前,页统计信息都放在页头(page header)中。问题是要获取页统计信息必须读取每一个页。即便之后判定无需读取该页,但该页已经被读取。为了解决该问题,parquet-mr 1.11.0 将列块的所有页统计信息放在同一位置,方便reader可以一次性读取并判定应该读取哪个页。由于 Presto 部分重写了 parquet-mr 代码,我们需要将 Parquet 1.11.0 中的修改移植到 Presto 代码库中。代码修改(PR-17284) 已于 2022 年 2 月合并到 Presto master 分支中,并将在 0.273 版本中发布。
基准测试结果
我们基于需要频繁访问的生产数据表对 Parquet 列索引进行了基准测试。我们用原始生产环境的数据表的快照创建了一个测试表,它包含了若干数据分区,并且数据是经过排序的。之后,我们在测试环境中对表运行 Presto 查询。可以针对每个查询通过 Presto 会话属性设置打开和关闭 Page Index 功能,从而实现横向比较。
我们观察到,输入数据扫描存在巨大的优化空间。下图显示了 Parquet Page Index 启用(左)与禁用(右)时运行示例查询的统计信息。可以看出,他们在这一阶段生成了相同的数据,但是在未启用 Parquet 列索引(column index)时需要扫描 149.31MB/239K 行原始输入数据,而在启用 Parquet 列索引的情况下只需要扫描 63.31MB/75.4K 行原始输入数据。后者的输入读取量降低了57%。这是因为在使用 Parquet Page Index 时,operator 可以识别并跳过不符合过滤条件的页。
除了在原始输入读取量方面的提升外,我们还从测试中观察到内存使用量也有所降低。从下面的截图可以看出,在启用 Parquet Page Index(右)时,只需要使用 91.73MB的峰值内存,而在未启用 Parquet Page Index 时,则需要使用141.60 MB的峰值内存。实现此项提升在预期范围内:由于查询需要读取的原始输入数据更少,因此保存数据所需的内存也更小。
值得注意的是,我们测试用的Presto查询在经过排序的列上使用filter,例如:WHERE foo = bar,其中 foo 列是有序的,这也是 Parquet Page Index 降低读取量效果最显著的地方,如果不对 filter 依赖的列数据进行排序,则收益可能降低。
分享嘉宾:
Uber: Xinli Shang
Uber: Chen Liang
想要了解更多关于Alluxio的干货文章、热门活动、专家分享,可进入【Alluxio智库】:
算力在云端澎湃,云计算技术日新月异。
过去十年间,全球云计算市场快速扩张,市场规模爆发性增长。
中心化的云计算架构提供了集中、大规模的计算、网络和存储等资源,解决了泛互联网行业在前二十年快速发展所面临的业务迅速增长、流量急剧扩张和大规模计算需求等问题。
边缘计算是构筑在边缘基础设施之上,位于尽可能靠近事务和数据源头的网络边缘侧,并能够与中心云协作的云计算模式。
相较于集中式云计算,边缘计算可提供弹性扩展的云服务能力,具有快速响应、低延迟和轻量计算等特点。
产业发展,脉络一览
01 稳定增长,激发市场活力
政策环境不断完善,边缘计算发展,恰逢其时。
2021年,我国边缘计算市场规模达到436.4亿人民币,预计未来三年年均增速超过50%,至2024年边缘计算市场整体规模达1803.7亿,边缘计算市场增长空间广阔。
IDC《中国边缘云市场解读,2022》报告显示,2021年中国边缘云市场规模总计达50.4亿人民币,其中,边缘公有云服务细分市场占比超过50%,市场规模达25.6亿人民币,为整个边缘计算发展注入新活力。
02 欣欣向荣,共建边缘生态
边缘生态包括云厂商、电信运营商、软件/行业解决方案厂商、系统集成商等。
边缘计算产业全景图覆盖边缘硬件、物联网边缘、边缘云、边缘软件与工具、边缘应用和边缘安全等各环节要素,助力边缘业务落地。
其中,边缘云作为关键要素,承下对接物联网硬件等基础设施,向上通过计算服务支撑各行各业应用,起到了非常关键的作用。
03 形态丰富,部署模式呈多样化
随着边缘计算的深入发展,企业的部署模式呈现不同的落地形态:
| 云服务延伸:提供针对特定区域或是广域覆盖的边缘计算资源,包括边缘公有云,CDN边缘云等类型。
| 电信网络:利用运营商网络边缘节点,根据需求建设资源池规模、服务种类差异化网络边缘服务,提供类似MEC多接入服务的边缘计算服务。
| 深入用户现场:在靠近用户数据中心或业务现场的地方,实现按需部署,包括混合边缘云、现场边缘云等类型,支持用户在本地部署自己的边缘云服务,并达到数据合规的要求。
04 持续深化,应用部署加速落地
中国信通院《边缘计算市场和用户洞察报告(2022)》深入研究边缘计算在企业用户中的落地现状及未来规划,为产业未来发展提供实践参考和指引。以下数据源自其中,依次展开分析。
| 在边缘部署类型方面,企业客户采用私有化边缘云解决方案和边缘公有云服务的占比较高,分别为59.4%和52.8%,其次是IoT边缘计算和边缘软件解决方案,分别占比48.1%和32.5%。
边缘部署的类型占比
| 在技术应用方面,受访者企业中,边缘数据处理和分析、边缘虚拟化、边缘存储和边缘网络等技术应用较为广泛,占比均超过50%,同时,开发框架、AI、安全、中间价和容器等技术,在边缘的应用仍待进一步发展。
边缘计算的技术应用占比
| 在落地场景方面,数据采集、视频监控、物联感知、远程控制等是目前边缘计算落地应用相对比较广的场景,其中数据采集场景应用占比高达69.3%,其次是视频监控和物联感知,分别为57.1%和50.9%。
而远程医疗、视觉质检、云游戏、边缘渲染、低延时直播等场景应用在受访企业中占比不足20%,未来,仍有更多创新落地的空间。
边缘计算的落地场景占比
05 挑战VS机遇,规划引领发展方向
| 在效益提升方面,提升业务的敏捷部署,在边缘计算应用价值中至关重要,占比高达68.4%。
对于一些大型政企客户来说,相比于集中式的数据中心和云上部署,部署边缘云能够更好地实现业务敏捷部署,从而真正为业务带来新价值。
在企业调研中,降低计算时延、节约带宽成本、加强数据安全均成为企业部署边缘计算之后带来的显著成效,占比分别为63.7%,56.1%和49.5%,极大提升了业务效益和价值。
边缘部署的效益占比
| 在部署挑战方面,边缘系统管理复杂、维护系统可靠性和稳定性、成本等因素成为边缘云部署的主要挑战,在受访企业中占比分别为61.3%、60.8%和53.3%。
同时,部署边缘系统困难、无明显业务需求和具有安全风险,也为企业的边缘计算布局带来阻碍,亟待边缘计算技术的发展而解决。
边缘部署的挑战占比
| 在投入规划方面,企业加大对边缘部署的投入规模,边缘计算相关云服务、软件及解决方案、硬件设备等成为企业投入规划的TOP3,在受访企业中占比高达65.9%、60.3%和52.7%,边缘计算发展前景广阔。
边缘部署的投入规划占比
架构升级,极致演进
以下为边缘计算领域最受关注的五项技术架构,为用户在边缘计算模型的选型与开发提供参考。
01 分布式资源管理:协同统一管控
阿里云通过纳管分布广泛、资源异构、规模多样的边缘节点,实现全球范围内边缘云分布式资源统一视角管理使用、监控运维。
边缘管控需要适度自治能力。
根据阿里云与中国信通院最新联合发布的《边缘云技术演进与发展白皮书》,边缘云分布式管控系统是一对多的分级管控模型,各级管控平台需具备满足自身定位的管控能力。
边缘云分布式管控系统与中心管控系统协同完成管控逻辑,更加适配边缘计算场景。
02 分布式数据管理:释放要素价值
如何在边缘侧进行云边协同的数据管控,是保证业务流通的重要技术点。
边缘云分布式数据管理,通过构建数据采集、处理、汇聚、分析、存储、管理等全环节能力,实现业务生产、应用数据,经营、运营管理数据,第三方数据的统一汇聚和分析,发挥数据要素价值。
| 在终端侧,通过传感器、物联设备实现业务应用数据源全面感知采集;
| 在边缘侧,实现异构数据接入、实时处理、边缘存储、数据转发;
| 在中心云,构建统一数据汇聚集成、大规模存储、智能分析等协同体系,有效提升数据应用水平和能力。
03 分布式应用平台:构建敏捷弹性应用
分布式应用平台将云上的开发方式部署至边缘侧,通过跨边缘节点的应用统一开发、部署、调度、管理、运维等能力,加速构建云边协同下弹性敏捷的边缘原生应用。
| 应用部署:实现应用按需分布式部署;
| 多集群管理:通过集群安全连接,统一管理;
| 分布式应用管理:通过部署策略(地理亲和性、反亲和性等),调度策略(资源池、健康状态等),镜像加速(缓存、P2P等),数据迁移等,实现跨云边端集群的应用统一管理;
| 服务流量治理:通过云边、边边容器网络互通,服务智能路由(位置、时延、网络质量等),流量管理(流量切换、限流、降级、负载均衡等),实现服务统一治理。
04 分布式调度:实现体验、资源最优平衡
如何实现业务体验与资源利用的最优平衡?
边缘云分布式调度技术,从资源调度、流量调度以及应用调度等多个维度,统一全局调度管理,以云边端协同的方式满足业务调度需求,最大化提升业务体验,提高资源使用效率。
| 资源调度:构建全局资源监测和伸缩能力,实现资源监测、弹性伸缩;通过调度算法和策略,优化资源使用、时延、位置、成本等指标,实现资源智能化调度;
| 流量调度:结合业务特点,预先进行业务流量预测,对云边计算、网络带宽等进行拆分和规划(例如建立专用通道);针对流量接入、回源等方面需求,结合位置、成本等因素,实现流量动态接入和调节;
| 应用调度:通过感知业务特定需求(资源硬件、性能指标等),建立应用模型和资源模型,实现应用迁移、弹性扩展等。
05 安全统一能力:构筑立体化安全防护能力
在分布式的环境下,边缘安全面临全新挑战。
边缘安全行业标准
与集中式云资源相比,边缘节点部署环境复杂多样,并且单个边缘节点受限于资源和成本,安全部署能力较弱。
通过云边端协同安全,实现边缘侧设备的接入,数据的传输,网络的安全,以及和中心云进行统一的安全管控,构筑边缘侧的立体化安全防护能力。
场景拓展,应用创新
边缘计算应用场景不断拓展,云边协同的创新实践案例纷纷涌现。
目前,边缘计算已经在工业、制造、物流、能源、金融、视频、零售等行业应用落地,并取得显著成效,加速各行各业数字化转型。
多维发展,畅想未来
在技术架构方面,边缘原生理念兴起,通过资源管控、数据管理、调度、应用平台等边缘原生技术,推动整体架构升级和边缘应用落地。
在行业应用方面,边缘计算和各行各业进一步紧密融合,推动应用场景的不断拓展,助力企业提升业务价值和用户体验。
在生态融合方面,边缘侧的开源协同不断深化,通过与已有系统的融合,迎接边缘侧异构的新挑战,加速构建丰沛繁荣的边缘生态。
未来,边缘计算创新升级将会带动更多便捷服务和应用实践的落地,进一步推动边缘计算产业的繁荣兴旺发展。
画流程图一直是研发的一个难题,如何画得通俗易懂已经够让人头疼了,还要美观大方。用 d2 的语法描述下流程,d2 会自动帮你生成一张配色极佳的流程图。说到研发的选择,本周特推的 choiceof.dev 罗列了众多开发过程中会遇到的选项,你可以自测下你同主流研发的契合度。
本周周榜呢,有监控网络流量的 sniffnet,监控 API 流量的 kubeshark,还有以便不时之需的开发小抄 cheat.sh,记录日常事项的备忘录 memos 和音频转文字工具 buzz。
以下内容摘录自微博@HelloGitHub 的 GitHub Trending 及 Hacker News 热帖(简称 HN 热帖),选项标准: | | ,根据项目 release 时间分类,发布时间不超过 14 day 的项目会标注 ,无该标志则说明项目 release 超过半月。由于本文篇幅有限,还有部分项目未能在本文展示,望周知 🌝
- 本文目录
- 1. 本周特推
- 1.1 文本变图表:d2
- 1.2 艰难选择:choiceof.dev
- 2. GitHub Trending 周榜
- 2.1 轻松监控网络流量:sniffnet
- 2.2 音频转文本:buzz
- 2.3 高颜值备忘录:memos
- 2.4 研发小抄:cheat.sh
- 2.5 API 流量查看器:kubeshark
- 3. 往期回顾
- 1. 本周特推
1. 本周特推
1.1 文本变图表:d2
主语言:Go
本周刚开源并突破 5k star 关卡的“爆款”项目,只要用文本就可以生成对应的图表。比如下面这段语法讲得到一个流程图。
GitHub 地址→https://github.com/terrastruct/d2
1.2 艰难选择:choiceof.dev
主语言:TypeScript
开发人员日常面对着非常艰难的选择,可能就是技术选型,当然也可能是简单的如何提交代码。choiceof.dev 给出了形形色色同开发相关的选项,有复杂的也有简单的。比如,下图如何提交代码,强制提交的占了 64%。
GitHub 地址→https://github.com/bdebon/choiceof.dev
2. GitHub Trending 周榜
2.1 轻松监控网络流量:sniffnet
本周 star 增长数:900+,主语言:Rust
一个跨平台的网络流量监控工具,可快速、直观查看流量变化。
GitHub 地址→https://github.com/GyulyVGC/sniffnet
2.2 音频转文本:buzz
本周 star 增长数:550+,主语言:Python
转换音频为文本的工具,支持麦克风实时录入转文字,也支持导入已有音频文件。文本可以导出为 TXT、SRT、VTT 格式。
GitHub 地址→https://github.com/chidiwilliams/buzz
2.3 高颜值备忘录:memos
本周 star 增长数:1,850+,主语言:TypeScript
具备知识管理能力的备忘中心,可多人协作。特性:
- 支持自托管,秒拉起来一个 Docker 应用;
- 支持 Markdown 语法;
- 同组内成员协作;
- 自服务的 RESTful API;
GitHub 地址→https://github.com/usememos/memos
2.4 研发小抄:cheat.sh
本周 star 增长数:1,350+,主语言:Python
非必要不小抄,cheat.sh 具有理想小抄的一切特性:简洁、快速、全面、低调、可辅助学习。它能在 100ms 内搜刮完 Stack Overflow 等网站,并返回你所需要的答案。支持 curl / 浏览器 / 编辑器交互。
GitHub 地址→https://github.com/chubin/cheat.sh
2.5 API 流量查看器:kubeshark
本周 star 增长数:900+,主语言:Golang
作为 K8s 的 API 流量查看器,kubeshark 支持对 K8s 所有集群的 API 流量和负载进行监控。
GitHub 地址→https://github.com/kubeshark/kubeshark
3. 往期回顾
往期回顾:
- 视觉享受,兼顾人文观感和几何特征的字体「GitHub 热点速览 v.22.46」
- 一年一度!GitHub 开发者大会「GitHub 热点速递 v.22.45」
以上为 2022 年第 47 个工作周的 GitHub Trending 🎉如果你 Pick 其他好玩、实用的 GitHub 项目,记得来 HelloGitHub issue 区和我们分享下哟 🌝
更新日志
1. 用户增加区县字段、会员码
2. 展示型商品不校验库存
3. 系统更新必须先更新待更新的插件
4. 购物车汇总优化
5. 拖拽可视化新增[图文、图片魔方、自定义html]模块,商品支持左图右文样式
6. 后台管理操作栏优化、减少上下占据空间
7. 门店详情支持多规格直接加购
8. 分类页面支持多规格直接加购+购物车操作
9. 新增[主导航、logo及搜索栏、页脚]展示开关
10. 新增钱包付款码
11. 新增账号注销
12. 新增base64类库
13. 新增input、select清除操作
14. 小程序新增个人资料修改
15. 小程序新增手机号码修改
16. 小程序购物车分离优化
17. 微信小程序登录适配新规
18. 可视化数据展示新增缓存
19. web端首页轮播样式优化
20. 用户头像上传新增钩子
21. 分页统计优化避免sql浪费
22. 动态数据列表分页支持统计汇总
23. 底层框架升级到tp6.1
进销存效果图片(支持多商户使用)
门店收银台效果图片(O2O多门店)
小程序端效果图片(内置多种配色)
可视化 DIY 拖拽装修展示
PC 端展示
后台管理展示
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
我们很高兴地告诉大家,EMQX Enterprise 4.4.11 版本正式发布!
在此版本中,我们发布了 CRL 与 OCSP Stapling 为客户端提供更灵活的安全防护,新增了 Google Cloud Pub/Sub 集成帮助您通过 Google Cloud 各类服务发掘更多物联网数据价值,还加入了满足自动化运维需要的预定义 API 密钥功能。除此之外,我们还修复了多项 BUG。
CRL 与 OCSP Stapling
此前版本中,通过 EMQX 内置的 SSL/TLS 支持,您可以使用 X.509 证书实现客户端接入认证与通信安全加密,本次发布的版本在此基础上新增了 CRL 与 OCSP Stapling 功能。
持有数字证书的物联网设备,如果出现私钥泄漏、证书信息有误的情况,或者设备需要永久销毁时,需要吊销对应证书以确保不被非法利用,CRL 与 OCSP Stapling 就是解决这一问题的关键。
CRL(Certificate Revocation List,证书吊销列表) 是由 CA 机构维护的一个列表,列表中包含已经被吊销的证书序列号和吊销时间。EMQX 允许配置 CA 的请求端点并定时刷新获取 CRL,而客户端无需维护 CRL,在连接握手时通过 EMQX 即可完成证书有效性验证。
OCSP(Online Certificate Status Protocol,在线证书状态协议)是另外一个证书吊销方案,相比于 CRL, OCSP 提供了实时的证书验证能力。OCSP Stapling 是该项技术的最新改进,进一步解决了 OCSP 隐私问题和性能问题。
启用 OCSP Stapling 后,EMQX 将自行从 OCSP 服务器查询证书并缓存响应结果,当客户端向 EMQX 发起 SSL 握手请求时,EMQX 将证书的 OCSP 信息随证书链一同发送给客户端,由客户端对证书有效性进行验证。
通过 CRL 与 OCSP Stapling 功能,您可以控制每一张证书的有效性,及时吊销非法客户端证书,为您的物联网应用提供灵活且高级别的安全保障。
Google Cloud Pub/Sub 集成
Google Cloud Pub/Sub 是一种异步消息传递服务,旨在实现极高的可靠性和可扩缩性。
现在,您可以通过 EMQX 规则引擎的 GCP Pub/Sub 集成能力,快速建立与该服务的连接,这能够帮助您更快的基于 GCP 构建物联网应用:
-
使用 Google 的流式分析处理物联网数据:以 Pub/Sub 以及 Dataflow 和 BigQuery 为基础而构建整体解决方案,实时提取、处理和分析源源不断的 MQTT 数据,基于物联网数据发掘更多业务价值。
-
异步微服务集成:将 Pub/Sub 作为消息传递中间件,通过 pull 的方式与后台业务集成;也可以推送订阅到 Google Cloud 各类服务如 Cloud Functions、App Engine、Cloud Run 或者 Kubernetes Engine 或 Compute Engine 上的自定义环境中。
对于 Google IoT Core 用户,您无需做更多改变就能将 MQTT 传输层迁移至 EMQX,继续使用 Google Cloud 上的应用和服务。
通过文件初始化 API 密钥
本次发布提供了 API 密钥初始化能力,允许您在启动 EMQX 前通过特定文件设置密钥对。
预设的密钥可以帮助用户在 EMQX 启动时做一些工作:如运维人员编写运维脚本管理集群状态,开发者导入认证数据到内置数据库中、初始化自定义的配置参数。
EMQX Kubernetes Operator 也基于此特性来实现集群启动时的配置和管理操作。
# 指定 bootstrap 文件 # etc/plugins/emqx_management.conf management.bootstrap_user_file ="etc/bootstrap_apps_file.txt" # 使用 {appid}:{secret} 的格式初始化密钥对 # etc/bootstrap_apps_file.txt appid1:secret appid2:secret2
BUG 修复
以下是主要 BUG 修复,完整 BUG 修复列表请参考 EMQX 企业版 4.4.11 更新日志。
-
改进规则的 “最大执行速度” 的计数,只保留小数点之后 2 位 #9185。 避免在 dashboard 上展示类似这样的浮点数:。
-
修复在尝试连接 MongoDB 数据库过程中,如果认证失败会不停打印错误日志的问题 #9184。
-
限速 “Pause due to rate limit” 的日志级别从原先的 降级到 #9134。
-
修正了 API 的响应状态代码 #9210。 在修复之前,它总是返回 ,即使 EMQX 应用程序没有运行。 现在它在这种情况下返回 。
-
修复规则引擎的消息事件编码失败 #9226。 带消息的规则引擎事件,例如 和 , 如果消息事件是共享订阅产生的,在编码(到 JSON 格式)过程中会失败。 影响到的版本:, , 和 。
-
修复调用 ‘DELETE /alarms/deactivated’ 只在单个节点上生效的问题,现在将会删除所有节点上的非活跃警告 #9280。
-
在进行消息重发布或桥接消息到其他 MQTT Broker 时,检查 topic 合法性,确定其不带有主题通配符 #9291。
-
关闭管理端口(默认为8081)上对 HTTP API 的认证,Prometheus 对时序数据抓取不在需要配置认证 #9294。
-
修正了在 Kafka Consumer 中选择 偏移重置策略的选项。
-
修复了 SQL Server 资源中,无法在 字段里使用除 之外的端口的问题。
-
解决从 e4.4.5 以及更早的版本升级 EMQX 的时候,Kafka 资源的认证类型从 变成了 的错误。
结语
除了企业版 4.4.11 外,同期 EMQX 还发布了包括开源版在内的另外 3 个版本,请参考:
-
EMQX 企业版 4.3.17 更新日志
-
EMQX 开源版 4.3.22 更新日志
-
EMQX 开源版 4.4.11 更新日志
版权声明: 本文为 EMQ 原创,转载请注明出处。
原文链接:https://www.emqx.com/zh/blog/emqx-enterprise-v-4-4-11-released
前言
上海的天气降温让人猝不及防,但是我们的迭代速度却井然有序。
今天我们带来了LiteFlow v2.9.4版本。
我们每次的发布的issue有很大一部分依托于我们的使用者社区,社区人越来越多。我看到了使用者在使用过程中遇到的问题,也收集了很多使用过程中很有意思的建议。这些也正是我们每一次迭代的方向。谢谢那么多的小伙伴的支持和建议,LiteFlow一直会是一个以社区为驱动的开源框架。
LiteFlow是一个开源编排式规则引擎,能够让你的系统逻辑任意编排,使用脚本书写逻辑,所有的逻辑和规则均可热变更。设计系统和重构系统的神器。
如果你是第一次知道这个项目,可以去官网或相关的主页进行了解:
项目官网:
https://liteflow.yomahub.com
gitee托管仓库:
https://gitee.com/dromara/liteFlow
github托管仓库:
https://github.com/dromara/liteflow
v2.9.4介绍
新版本我们依旧依托于社区,一共完成了14个issue。
其中80%的issue来自于社区使用者。
2.9.4版本完全兼容2.9.3版本,可以无缝升级。
新的脚本引擎
鉴于之前社区有人反应LiteFlow提供的Javascript脚本引擎是基于jdk的,而JDK的Javascript引擎只支持到ES5规范,且不支持Java 17。
所以这次我们新增了一个Javascript引擎:。支持ES6规范,且支持Java 8~17。
当然老的引擎我们还是保留,如果是简单的js语法,你依旧可以用老的引擎。
关于这块详情请参考官网的章节。
提供规则验证接口
虽然LiteFlow在启动时会去编译所有的规则,如果有错也会详细报出,但是在更改脚本前,使用者可能不太确信自己的规则写的有没有问题。所以在社区内,有人提出了希望增加一个验证规则的接口。
那这次我们也提供了相应的接口。详情请参考官网的章节。
Zk和Etcd支持局部刷新机制
如果你使用zk或者Etcd,你在zk和etcd里更改了规则,会自动推送到相应的应用进行无感自动刷新。
但是之前的实现模式是全部刷新,即不管你改了哪个规则,所有的规则刷新一遍。虽然LiteFlow刷新速度非常快速,但是这种实现模式还是不够优雅。
这次我们实现了局部刷新,即你改变哪个即刷新哪个。
声明式组件的二次动态代理问题
在社区内,我们也收到了许多使用声明式组件特性小伙伴们的反馈,在声明式组件上使用类似事务标注等需要动态代理的特性时,LiteFlow的声明式组件会报错。
经过核验,我们发现LiteFlow之前漏考虑了二次动态代理的问题,这次我们修复了。
其他修复
在新版本中,我们修复其他issue也有很多,包括脚本对数据取值的bug,@ScriptBean标注所带来的一些小问题,脚本异常处理的优化等等。
完整更新列表
社区
LiteFlow的社区是一个异常活跃的开源社区,这里有许多的开源大佬,技术大牛,群内的小伙伴也很乐意帮你去回答问题。
如果你在使用和学习中有任何问题,可以通过以下官网或者以下方式进入社区群。
https://liteflow.yomahub.com/pages/73c2c3/
Dante Cloud 是一款企业级微服务架构和服务能力开发平台。首个全面拥抱 Spring Authorization Server 的版本,基于Spring Authorization Server 0.4.0、Spring Boot 2.7.6、Spring Cloud 2021.0.5、Spring Cloud Alibaba 2021.0.4.0、Nacos 2.1.2 等最新版本开发的多租户系统,遵循SpringBoot编程思想,高度模块化和可配置化。具备服务发现、配置、熔断、限流、降级、监控、多级缓存、分布式事务、工作流等功能
平台定位
- 构建成熟的、完善的、全面的,基于 OAuth2.1 的、前后端分离的微服务架构解决方案。
- 面向企业级应用和互联网应用设计开发,既兼顾传统项目的微服务化,又满足互联网应用开发建设、快速迭代的使用需求。
- 平台架构使用微服务领域及周边相关的各类新兴技术或主流技术进行建设,是帮助快速跨越架构技术选型、研究探索阶段的利器。
- 代码简洁规范、结构合理清晰,是新技术开发应用的典型的、综合性案例,助力开发人员对新兴技术的学习和掌握。
[1]、为什么更名为 Dante Cloud
Dante Cloud (但丁), 原项目名称 Eurynome Cloud,很多朋友都反映名字太长、读起来拗口、不容易记等问题。因此在加入 Dromara 开源社区之际,将名字进行了变更。
Dante,即但丁·阿利基耶里(公1265年-公1321年),13世纪末意大利诗人,现代意大利语的奠基者,欧洲文艺复兴时代的开拓人物之一,以长诗《神曲》(原名《喜剧》)而闻名,后来一位作家叫薄伽丘将其命名为神圣的喜剧。
他被认为是中古时期意大利文艺复兴中最伟大的诗人,也是西方最杰出的诗人之一,最伟大的作家之一。恩格斯评价说:“封建的中世纪的终结和现代资本主义纪的开端,是以一位大人物为标志的,这位人物就是意大利人但丁,他是中世纪的最后一位诗人,同时又是新时代的最初一位诗人”
更名为 Dante Cloud,寓意本项目会像恩格斯对但丁的评价一样,在行业变革的时期,可以成为一款承上启下,助力企业信息化建设变革的产品。
[2]、本次更新内容
- 主要更新
- Spring Boot 版本升级至 2.7.6
- 其它更新
- [修复] 解决使用 edge 浏览器并使用 feign,报错 Unexpected char 0x0a(PR by 狂练胸肌的李大懒)
- [修复] 修复前端唯一性字段在新建、编辑不同状态下校验不准确、状态不合理问题。解决导致编辑状态下唯一性字段数据未修改仍会校验失败问题。
- [修复] 优化微服务分布式 Session 共享配置,解决共享 Session 不一致问题。
- [新增] 数据初始化脚本补充 OIDC 客户端注册相关信息
- 依赖更新
- [升级] fastjson2 版本升级至 2.0.20
- [升级] dysmsapi 版本升级至 2.0.23
- [升级] aliyun-java-sdk-core 版本升级至 4.6.3
- [升级] tencentcloud-sdk-java-sms 版本升级至 3.1.641
- [升级] alipay-sdk-java 版本升级至 4.34.71.ALL
- [升级] aliyun-java-sdk-green 版本升级至 3.6.6
- [升级] postgresql 版本升级至 42.5.1
- [升级] jackson 版本升级至 2.14.1
[3]、Dante Cloud 2.7.X 特点
一、前端
- 未使用任何流行开源模版,使用全新技术栈,完全纯”手写”全新前端工程。
- 借鉴参考流行开源版本的使用和设计,新版前端界面风格和操作习惯尽量与当前流行方式统一。
- 充份使用 Typescript 语言特性,解决大量类型校验问题,尽可能规避 “any” 式的 Typescript 编程语言使用方式。
- 充份使用 Composition Api 和 Hooks 等 Vue3 框架新版特性进行代码编写。
- 充份利用 Component、Hooks 以及 Typescript 面向对象等特性,抽取通用组件和代码,尽可能降低工程重复代码。
- 对较多 Quasar 基础组件和应用功能组件进行封装,以方便代码的统一修改维护和开发使用。
- 对生产模式下,对基于 Vite3 的工程打包进行深度性能优化。
- 提供以 docker-compose 方式,对工程生产代码进行容器化打包和部署。
- 支持密码模式、授权码模式、手机短信模式、第三方社会化等多种登录模式。
二、后端
基于 深度定制和扩展:
-
基于 和 实现多租户系统架构, 支持 Database 和 Schema 两种模式。
-
基于 ,重新构建 基础数据存储代码,替代原有 JDBC 数据访问方式,破除 原有数据存储局限,扩展为更符合实际应用的方式和设计。
-
基于 ,在 OAuth 2.1 规范基础之上,增加自定义 (密码)认证模式,以兼容现有基于 OAuth 2 规范的、前后端分离的应用,支持 Refresh Token 的使用。
-
基于 ,在 OAuth 2.1 规范基础之上,增加自定义 (社会化登录)认证模式,支持手机短信验证码、微信小程序、基于JustAuth的第三方应用登录, 支持 Refresh Token 的使用。
-
扩展 默认的 模式,实现 模式支持 Refresh Token 的使用。
-
扩展 默认的 模式,实现真正的使用 Scope 权限对接口进行验证。 增加客户端 Scope 的权限配置功能,并与已有的用户权限体系解耦
-
支持 认证模式
-
支持 的标准的 JWT Token 加密校验方式外,新增基于自定义证书的 JWT Token 加密校验方式,可通过配置动态修改。
-
支持 Opaque Token (不透明令牌) 格式及校验方式,将低 JWT Token 被捕获解析的风险。可通过修改配置参数,设置默认Token 格式是采用 Opaque Token 格式还是 JWT Token 格式。
-
全面支持 OpenID Connect (OIDC) 协议, 系统使用时可根据使用需求,通过前端开关配置,快速切换 OIDC 模式和传统 OAuth2 模式
-
深度扩展 、、 几种模式,全面融合 IdToken、Opaque Token、JWT Token 与现有权限体系,同时提供 IdToken 和 自定义Token 扩展两种无须二次请求的用户信息传递方式,减少用户信息的频繁请求。
-
自定义 授权码模式登录认证页面和授权确认页面,授权码模式登录采用数据加密传输。支持多种验证码类型,暂不支持行为验证码。
- 基于 JetCache 的多级缓存支持,实现自定义 二级缓存,有效解决 Spring Cache 查询缓存更新问题。
- 全面整合 注解权限与 权限,通过后端动态配置,无须在代码中配置 权限注解以及权限方法,即可实现接口鉴权以及权限的动态修改。采用分布式鉴权方案,规避 Gateway 统一鉴权的压力以及重复鉴权问题
- 采用分布式服务独立鉴权方案, 的权限注解、权限方法以及 权限,通过后端动态配置后,实时动态分发至对应服务。
- 核心数据支持直连数据库获取和 远程调用两种模式。 直连数据库模式性能更优, 访问远程调用可扩展性更强。可通过配置动态修改采用策略方式。
- 基于自定义 Session,混合国密 SM2(非对称) 和 SM4(对称加密) 算法,实现秘钥动态生成加密传输。利用“一人一码机制”,实现密码模式登录数据进行动态加密传输。配合 验证,保护接口调用和前后端数据传输的合理性及安全性。
[4]、界面预览
Dromara 开源社区
一、社区愿景
让每一位开源爱好者,体会到开源的快乐。
二、社区官网
https://dromara.org 是 Dromara 开源社区官方网站。
三、成员项目
功能介绍 使用技术 特性注意事项 微服务权限管理系统 RuoYi-Cloud-Plus 重写 RuoYi-Cloud 全方位升级(不兼容原框架) 分布式集群分支 RuoYi-Vue-Plus 重写 RuoYi-Vue (不兼容原框架) 前端开发框架 Vue、Element UI 后端开发框架 SpringBoot 微服务开发框架 SpringCloud 微服务开发框架 SpringCloudAlibaba 容器框架 Undertow 基于 XNIO 的高性能容器 权限认证框架 Sa-Token、Jwt 强解耦、强扩展 关系数据库 MySQL 适配 8.X 最低 5.7 关系数据库(未完成) Oracle 适配 12c 关系数据库(未完成) PostgreSQL 适配 14 关系数据库(未完成) SQLServer 适配 2019 缓存数据库 Redis 适配 6.X 最低 5.X 分布式注册中心 Alibaba Nacos 采用2.X 基于GRPC通信高性能 分布式配置中心 Alibaba Nacos 采用2.X 基于GRPC通信高性能 服务网关 SpringCloud Gateway 响应式高性能网关 负载均衡 SpringCloud Loadbalancer 负载均衡处理 RPC远程调用 Apache Dubbo 原生态使用体验、高性能 分布式限流熔断 Alibaba Sentinel 无侵入、高扩展 分布式事务 Alibaba Seata 无侵入、高扩展 支持 四种模式 分布式消息队列 SpringCloud Stream 门面框架兼容各种MQ集成 分布式消息队列 Apache Kafka 高性能高速度 分布式消息队列 Apache RocketMQ 高可用功能多样 分布式消息队列 RabbitMQ 支持各种扩展插件功能多样性 分布式搜索引擎 ElasticSearch、Easy-Es 以 Mybatis-Plus 方式操作 ElasticSearch 分布式数据同步(未完成) Alibaba Canal 采集数据同步各种数据库 ES Redis Mysql 分布式链路追踪 Apache SkyWalking 链路追踪、网格分析、度量聚合、可视化 分布式日志中心 ELK ELK业界成熟解决方案 分布式锁 Lock4j 注解锁、工具锁 多种多样 分布式幂等 Redisson 拦截重复提交 分布式任务调度 Xxl-Job 高性能 高可靠 易扩展 分布式文件存储 Minio 本地存储 分布式云存储 七牛、阿里、腾讯 云存储 短信模块 阿里、腾讯 短信发送 分布式监控 Prometheus、Grafana 全方位性能监控 服务监控 SpringBoot-Admin 全方位服务监控 数据库框架 Mybatis-Plus 快速 CRUD 增加开发效率 数据库框架 P6spy 更强劲的 SQL 分析 多数据源框架 Dynamic-Datasource 支持主从与多种类数据库异构 序列化框架 Jackson 统一使用 jackson 高效可靠 Redis客户端 Redisson 支持单机、集群配置 校验框架 Validation 增强接口安全性、严谨性 支持国际化 Excel框架 Alibaba EasyExcel 性能优异 扩展性强 文档框架 SpringDoc、javadoc 无注解零入侵基于java注释 工具类框架 Hutool、Lombok 减少代码冗余 增加安全性 代码生成器 适配MP、Knife4j规范化代码 一键生成前后端代码 部署方式 Docker 容器编排 一键部署业务集群 国际化 SpringMessage Spring标准国际化方案
漏洞描述
Solarwinds Orion Platform是美国Solarwinds公司的一套网络故障和网络性能管理平台。
SolarWinds Platform < 2022.4 容易受到命令注入的影响。此漏洞允许完全控制SolarWinds数据库的远程攻击者执行任意操作系统命令。
影响范围
SolarWinds Platform@[0, 2022.4)
修复方案
将组件 SolarWinds Platform 升级至 2022.4 及以上版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-52648
https://nvd.nist.gov/vuln/detail/CVE-2022-36962
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
漏洞描述
QEMU 是一个通用的开源机器和用户空间模拟器和虚拟器,Error Record Serialization Table (ERST) 模块用于将错误记录存储在持久存储器中,便于引用和调试。
QEMU 7.1.0 及之前版本中 erst.c 类中的 read_erst_record() 和 write_erst_record() 函数中存在整数溢出和缓冲区溢出漏洞,由于 ERST 的缓冲区大小在创建 acpi-erst 设备时以前通过 size 参数固定,攻击者可通过控制客户机传输的错误记录大小(record_length)造成缓冲区溢出,从而使 QEMU 进程崩溃。
影响范围
qemu-project/qemu@(-∞, 7.1.0]
修复方案
qemu-project/qemu 暂未发布新版本,请关注官方公告:https://gitlab.com/qemu-project/qemu
参考链接
https://www.oscs1024.com/hd/MPS-2022-65681
https://nvd.nist.gov/vuln/detail/CVE-2022-4172
https://gitlab.com/qemu-project/qemu/-/issues/1268
https://gitlab.com/qemu-project/qemu/-/commit/defb7098
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
引言
尽管 redis 是一款非常优秀的 NoSQL 数据库,但更重要的是,作为使用者我们应该学会在不同的场景中如何更好的使用它,更大的发挥它的价值。主要可以从这四个方面进行优化:Redis键值设计、批处理优化、服务端优化、集群配置优化
1. Redis慢查询日志使用
Redis 提供了慢日志命令的统计功能,它记录了有哪些命令在执行时耗时比较久。
查看 Redis 慢日志之前,你需要设置慢日志的阈值。例如,设置慢日志的阈值为 5 毫秒,并且保留最近 500 条慢日志记录:
设置完成之后,所有执行的命令如果操作耗时超过了 5 毫秒,都会被 Redis 记录下来。
此时,你可以执行以下命令,就可以查询到最近记录的慢日志:
- slowlog len:查询慢查询日志长度
- slowlog get [n]:读取n条慢查询日志
- slowlog reset:清空慢查询列表
有可能会导致操作延迟的情况:
- 经常使用 O(N) 以上复杂度的命令,例如 SORT、SUNION、ZUNIONSTORE 聚合类命令,要花费更多的 CPU 资源
- 使用 O(N) 复杂度的命令,但 N 的值非常大,Redis 一次需要返回给客户端的数据过多,更多时间花费在数据协议的组装和网络传输过程中。
你可以使用以下方法优化你的业务:
- 尽量不使用 O(N) 以上复杂度过高的命令,对于数据的聚合操作,放在客户端做
- 执行 O(N) 命令,保证 N 尽量的小(推荐 N <= 300),每次获取尽量少的数据,让 Redis 可以及时处理返回
2. Redis键值设计
2.1 优雅的key结构
Redis的Key虽然可以自定义,但最好遵循下面的几个最佳实践约定:
- 遵循基本格式:[业务名称]:[数据名]:[id]
- 长度不超过44字节
- 不包含特殊字符
例如:我们的登录业务,保存用户信息,其key可以设计成如下格式:
这样设计的好处:
- 可读性强
- 避免key冲突
- 方便管理
- 更节省内存: key是string类型,底层编码包含int、embstr和raw三种。embstr在小于44字节使用,采用连续内存空间,内存占用更小。当字节数大于44字节时,会转为raw模式存储,在raw模式下,内存空间不是连续的,而是采用一个指针指向了另外一段内存空间,在这段空间里存储SDS内容,这样空间不连续,访问的时候性能也就会收到影响,还有可能产生内存碎片
2.2 拒绝BigKey
2.2.1 什么是BigKey
如果一个 key 写入的 value 非常大,那么 Redis 在分配内存时就会比较耗时。同样的,当删除这个 key 时,释放内存也会比较耗时,这种类型的 key 我们一般称之为 bigkey。
BigKey 通常以 Key 的大小和 Key 中成员的数量来综合判定,例如:
- Key 本身的数据量过大:一个 String 类型的 Key ,它的值为 5 MB
- Key 中的成员数过多:一个 ZSET 类型的 Key ,它的成员数量为 10,000 个
- Key 中成员的数据量过大:一个 Hash 类型的 Key ,它的成员数量虽然只有 1,000 个但这些成员的 Value(值)总大小为 100 MB
那么如何判断素的大小呢?redis 也给我们提供了命令
推荐值:
- 单个 key 的 value 小于 10KB
- 对于集合类型的 key,建议素数量小于 1000
2.2.2 BigKey 的危害
-
网络阻塞
对 BigKey 执行读请求时,少量的 QPS 就可能导致带宽使用率被占满,导致 Redis 实例,乃至所在物理机变慢
-
数据倾斜
BigKey 所在的 Redis 实例内存使用率远超其他实例,无法使数据分片的内存资源达到均衡
-
Redis 阻塞
对素较多的 hash、list、zset 等做运算会耗时较旧,使主线程被阻塞
-
CPU 压力
对 BigKey 的数据序列化和反序列化会导致 CPU 的使用率飙升,影响 Redis 实例和本机其它应用
2.2.3 如何发现BigKey
利用 redis-cli 提供的–bigkeys 参数,可以遍历分析所有 key,并返回 Key 的整体统计信息与每个数据类型的 Top1 的 big key
这个命令的原理,就是 Redis 在内部执行了 SCAN 命令,遍历整个实例中所有的 key,然后针对 key 的类型,分别执行 STRLEN、LLEN、HLEN、SCARD、ZCARD 命令,来获取 String 类型的长度、容器类型(List、Hash、Set、ZSet)的素个数。
这里需要提醒你的是,当执行这个命令时,要注意 2 个问题:
- 对线上实例进行 bigkey 扫描时,Redis 的 OPS 会突增,为了降低扫描过程中对 Redis 的影响,最好控制一下扫描的频率,指定 -i 参数即可,它表示扫描过程中每次扫描后休息的时间间隔,单位是秒
- 扫描结果中,对于容器类型(List、Hash、Set、ZSet)的 key,只能扫描出素最多的 key。但一个 key 的素多,不一定表示占用内存也多,你还需要根据业务情况,进一步评估内存占用情况
自己编程,利用 scan 扫描 Redis 中的所有 key,利用 strlen、hlen 等命令判断 key 的长度(此处不建议使用 MEMORY USAGE)
scan 命令调用完后每次会返回 2 个素,第一个是下一次迭代的光标,第一次光标会设置为 0,当最后一次 scan 返回的光标等于 0 时,表示整个 scan 遍历结束了,第二个返回的是 List,一个匹配的 key 的数组
第三方工具
- 利用第三方工具,如 Redis-Rdb-Tools 分析 RDB 快照文件,全面分析内存使用情况
- https://github.com/sripathikrishnan/redis-rdb-tools
网络监控
- 自定义工具,监控进出 Redis 的网络数据,超出预警值时主动告警
- 一般阿里云搭建的云服务器就有相关监控页面
2.2.4 BigKey 解决方案
这里有两点可以优化:
- 业务应用尽量避免写入 bigkey
- 如果你使用的 Redis 是 4.0 以上版本,用 UNLINK 命令替代 DEL,此命令可以把释放 key 内存的操作,放到后台线程中去执行,从而降低对 Redis 的影响
- 如果你使用的 Redis 是 6.0 以上版本,可以开启 lazy-free 机制(),在执行 DEL 命令时,释放内存也会放到后台线程中执行
bigkey 在很多场景下,都会产生性能问题。例如,bigkey 在分片集群模式下,对于数据的迁移也会有性能影响,以及我后面即将讲到的数据过期、数据淘汰、透明大页,都会受到 bigkey 的影响。因此,即使 reids6.0 以后,仍然不建议使用 BigKey
2.3 总结
- Key 的最佳实践
- 固定格式:[业务名]:[数据名]:[id]
- 足够简短:不超过 44 字节
- 不包含特殊字符
- Value 的最佳实践:
- 合理的拆分数据,拒绝 BigKey
- 选择合适数据结构
- Hash 结构的 entry 数量不要超过 1000
- 设置合理的超时时间
3. 批处理优化
3.1 Pipeline
3.1.1 客户端与服务端交互
单个命令的执行流程
N 条命令的执行流程
redis 处理指令是很快的,主要花费的时候在于网络传输。于是乎很容易想到将多条指令批量的传输给 redis
3.1.2 MSet
Redis 提供了很多 Mxxx 这样的命令,可以实现批量插入数据,例如:
- mset
- hmset
利用 mset 批量插入 10 万条数据
3.1.3 Pipeline
MSET 虽然可以批处理,但是却只能操作部分数据类型,因此如果有对复杂数据类型的批处理需要,建议使用 Pipeline
3.2 集群下的批处理
如 MSET 或 Pipeline 这样的批处理需要在一次请求中携带多条命令,而此时如果 Redis 是一个集群,那批处理命令的多个 key 必须落在一个插槽中,否则就会导致执行失败。大家可以想一想这样的要求其实很难实现,因为我们在批处理时,可能一次要插入很多条数据,这些数据很有可能不会都落在相同的节点上,这就会导致报错了
这个时候,我们可以找到 4 种解决方案
-
第一种方案:串行执行,所以这种方式没有什么意义,当然,执行起来就很简单了,缺点就是耗时过久。
-
第二种方案:串行 slot,简单来说,就是执行前,客户端先计算一下对应的 key 的 slot ,一样 slot 的 key 就放到一个组里边,不同的,就放到不同的组里边,然后对每个组执行 pipeline 的批处理,他就能串行执行各个组的命令,这种做法比第一种方法耗时要少,但是缺点呢,相对来说复杂一点,所以这种方案还需要优化一下
-
第三种方案:并行 slot,相较于第二种方案,在分组完成后串行执行,第三种方案,就变成了并行执行各个命令,所以他的耗时就非常短,但是实现呢,也更加复杂。
-
第四种:hash_tag,redis 计算 key 的 slot 的时候,其实是根据 key 的有效部分来计算的,通过这种方式就能一次处理所有的 key,这种方式耗时最短,实现也简单,但是如果通过操作 key 的有效部分,那么就会导致所有的 key 都落在一个节点上,产生数据倾斜的问题,所以我们推荐使用第三种方式。
3.2.1 串行化执行代码实践
3.2.2 Spring 集群环境下批处理代码
本文由教研团队发布。
如果本文对您有帮助,欢迎和;如果您有任何建议也可或,您的支持是我坚持创作的动力。
转载请注明出处!
大数据
架构向云原生演进是行业的
重要
趋势,
火山引擎
协助关键金融客户在大数据
云原生方向进行了深度实践,形成了整体解决方案,本文将分享火山引擎云原生大数据在金融行业的实践。
▌金融行业大数据需求
云原生相比 Hadoop 的优势
大数据
集群
通常
基于
Hadoop
系统构建,
传统大数据作业通常是以裸进程的形式运行在节点上,很容易受到节点上的其他进程或其他因素干扰,因此带来的
作业稳定性
问题
经
常困扰用户。
,
如果
一个
Flink
作业发生了延迟,找不到业务上的原因
,但是
观测到
节点的
CPU 使用率比较高。用户通常选择杀掉节点上的其他作业,使机器负载下降,这时作业很有可能恢复了正常。但是,最终也没有定位到延迟的具体原因,一段时间后很可能会再次出现相同的问题,而且每次杀掉其他作业的处理方式非常繁琐,并且代价
比较高
。
大数据
场景下,
云原生
系统
相比
Hadoop
系统,具备以下能力:
-
强制的容器化能力
:
可以屏蔽
大数据
作业的运行环境,提高运行时
隔离
能力;
-
可定制化的网络/存储
能力:
可以
支持
大数据
作业
使用复杂
的
容器化网络技术,以及
云原生
支持的任意存储
系统
;
-
便捷的运维能力
:
可以轻松地进行
节点
上下线,
集群
扩缩容,降低
基础设施
运维成本。
大数据
架构向云原生演进是全行业,特别是金融行业的重要趋势。
资源效率问题。
K8s
集群和
Hadoop
集群。
独立的 K8s 集群运行着在线服务,独立的 Hadoop 集群运行着
大数据
作业
,这两个集群
不仅
不能
彼此共享资源
,
而且
资源利用率都非常低
。
而
在线业务与离线计算的资源高低峰期往往是错开的,所以离线计算高峰时如何利用在线集群资源,在线业务高峰时如何利用离线集群资源,
成为
了降本增效的关键。
目标
是
在硬件资源不增加的情况下承载更多业务,整体提升集群资源利用率。
-
在线资源和大数据资源可以高效、灵活地相互转换
-
整个集群的利用率可充分地提升,降本增效
-
资源共池,统一的配额管控、机器运维、软件部署等,降低维护成本。
资源的高效利用是金融行业特别关注的能力和需求。
大数据迁移云原生的难点
-
一个运行在
Hadoop
系统上的传统
大数据
作业迁移到
云原生
系统,
具有一定的改造成本;而一个大数据集群通常存在数百个、数千个,甚至数万个、数十万个作业,全部迁移到云原生系统上,改造成本巨大,难以实现
;
-
传统的
大数据
引擎
,比如
Flink
、
Spark
,最初
不是针对
云原生
系统
设计,
其
AM-Task 作业形态难以
直接在
云原生
系统上
部署;
-
云原生
系统的原生调度器
不具备与
Hadoop YARN
队列
类似的多租户资源管控能力;
-
云原生
系统的
原生调度器不存在“作业”概念,不具备作业排队能力,不具备作业级调度策略;
-
云原生
系统的原生
调度器吞吐能力
差,不适用于任务量大且运行时间较短的
大数据
作业
,比如一个
只需要运行 1 分钟的
Spark
作业,
在
调度
阶段就花费
三分钟,不仅
使作业完成时间大幅增加,
还
造成了集群
资源浪费
;
云原生
系统上补齐上述
不足
,才可以更好地支撑金融行业
大数据
场景。
▌云原生大数据部署
火山引擎
支持
大数据
作业在
云原生
系统上的
两种
部署方式:
-
基于
Serverless YARN
的
Hadoop
方式
部署
-
基于
Arcee
Operator 的
云原生
方式
部署
基于云原生的 YARN 解决方案 —— Serverless YARN
是基于
云原生
的
YARN
解决方案,帮助
大数据
作业透明迁移到云原生系统。简单来说,在
K8s
系统
上模拟实现了 YARN
系统
,传统作业可以像
往常
一样提交
和运行,不需要进行任何改造
,完全感知不到 K8s 的存在。
保留了
YARN
Client、
YARN
API
,以及 YARN 原有的 AM 管理、Quota 管理、权限管理等功能。
流程如下图:
-
用户
在
计算引擎
的基础上进行开发
,调用 YarnClient
SDK
,提交作业到
Serverless YARN
的 Resource Manager 组件
;
-
RM 组件为作业创建 AM
Pod
(每个作业有一个 Master 实例,负责管控整个作业,
全
称为 Application
Master)
;
-
AM
Pod
经过
K8s
的
API
Server 和调度器调度到一个具体
的
节点
,然后由节点上的
Kubelet
负责启动和管控;
-
A
M
启动后定期向 RM 发送心跳,
心跳信息包括自身
运行状态
,以及
资源
申请
请求
;
-
AM 向 RM 申请更多资源,RM 将这些资源请求转换为
K8s
上的
Pod
,由 K8s 负责调度和启动;
-
作业的其他 Pod 启动,开始实际计算,受 AM 管控。
YARN
完全相同,唯一的区别在于
所有作业实例
都收敛到
K8s
上,通过
Kubelet
启动
容器并运行。
,
YARN
系统负责启动和管控作业实例的 Node
Mananger
组件具
有很多
Kubelet
不具备的
大数据
特有
功能
。
所以,
Serverless YARN
还
在每个节点上部署了大数据辅助
插件,以弥补 Kubelet 的功能不足
,
比如
:
-
提供
为作业
提前
下载 Jar 包的功能(在
大数据
体系中称为 Localization)
;
-
启动
计算引擎的
Shuffle
服务
;
-
为
大数据
作业提供
日志
服务
;
-
为
大数据
作业提供
监控
能力
,等
等。
Serverless YARN 集群上,
旧的
YARN
集群等到
没有
任何
作业
运行后,
可以
被操作
下线。
Serverless YARN
做了深度
的
性能优化,RM
切主时间
控制在
秒
级
以
内,
Pod
调度吞吐提高到
每秒 2000 个
以上
。
基于云原生的大数据统一 Operator —— Arcee Operator
Operator 是基于
云原生
的
大数据
统一 Operator,统一管控多种计算引擎
。
借鉴了
YARN
的
两级
管理模式
,
管理
大数据
作业的 Application Master,再由 AM 管理
计算
Worker。
大数据
作业状态,定制作业管理策略,确保计算引擎对计算作业运行有充分的掌握能力,有能力按需调整资源使用。
两级管理外
,
Arcee
Operator 还具备
以下
特性:
-
Arcee
定义了统一作业实例
:
Arcee Operator 利用
K8s
的自定义资源定义了统一作业实例,无论是
Spark
还是
Flink
,
或者使
其他类
YARN
的
计算引擎
,都
可以
使用统一的
CRD
描述作业
,包括作业配置、作业
规格
等信息
,而且可以收集
并展示作业的统一且
详细
的
运行状态,有利于业务的统一表达和处理;
-
Arcee
实现了作业异常处理
:Arcee Operator 可以
实时监控所有作业状态,
处理作业异常
,持续保障作业正常运行;
比如因为节点磁盘故障而导致 AM 运行异常,Arcee 检测到后在其他节点重新启动 AM,并接管之前启动的 Work
Pod
,使作业恢复正常运行;
-
Arcee
屏蔽了底层调度器
:Arcee Operator
封装
了
底层调度功能,降低
了
作业使用高级调度策略的门槛
,比如优先级调度、Gang 调度等
大数据
作业的强需求;并且可以从调度器上收集作业调度信息,然后对外展示,用户可以轻松知道“作业为什么没有进行调度”。
-
Spark
社区推荐
的
K8s
Native 方式,Spark
Pod
没有统一资源描述,很难进行管理和描述
;
-
Google
的
Spark
Operator 在
K8s
Native
方式的
基础上封装了
CRD
,提供
了
统一的资源描述
,
但是
它
是以旁路的方式实现的,
基本不存在
管控策略,
而且
不支持 Spark Client 模式。
Arcee
Operator
在适配
大数据
计算引擎的原生运行模式的同时,
提供了
:
-
统一的作业描述,以及详细、准确的状态信息;
-
丰富的作业异常处理策略;
-
快速接入高级调度功能的能力。
▌云原生大数据调度
的
云原生
大数据
系统存在三层
资源管理
:
-
全局的
多机房统一资源湖
——
ResLake
,负责全局统一的
资源管理
、调度、分发和
容灾
;
-
每个集群上,GRO Scheduler
负责集群内的 Quota 管控和
Pod
调度;
-
每个节点上,GRO Agent
负责单机调度和隔离增强。
基于云原生的高性能资源管理调度器 —— GRO
云原生
的高性能
资源管理
调度器,管控集群资源,并结合 GRO Agent 实现单机调度、隔离、和
混部
能力。
GRO Scheduler
系统
原生调度器的主要功能是
Pod
放置,
也就是
为 Pod 选择一个最优的节点
,
但是这完全不能满足
大数据
作业的需求。
YARN
等
大数据
调度器,在
Pod
放置的基础上,增加了 Quota 管控。
-
Quota 管控:调度器首先将集群资源分配给各个队列,然后将队列资源分配给该队列的各个作业,最后将作业资源分配给该作业的各 Pod。不是所有 Pod 都可以获得资源,只有获得资源的 Pod 才可以进入后续的 Pod 放置流程;
-
Pod
放置:和原生调度器一样,首先为 Pod 筛选符合条件的节点,然后对筛选出来的节点进行打分,最后将 Pod 绑定到分数最高的节点上。
队列
”的概念:一个集群包含多个节点,可以供多个租户同时使用集群资源。为了避免一个租户占用集群全部资源,而影响到其他租户,集群的运维人员或者资源的管理人员非常希望能够按照一定比例,或者按照指定数量将集群资源分配给不同租户。而云原生系统不支持这样的多租户资源管控能力。
为了更好地支持
大数据
场景资源分配,
GRO 使用
K8s 自定义资源
能力
新增
这两个概念
:
-
Queue
CRD
:
描述了一个“
队列
”,即 Quota(资源配额)的抽象;
-
PodGroup
CRD
:
描述了一个“作业”,标识多个
Pod
属于同一个集合,从而可以把多个 Pod 看作整体进行调度。
队列
有两个资源配额属性:
-
Min Quota,又称为保障资源量。调度器为该队列预留 Min Quota 的资源量,不允许其他队列占用,以保障该队列在需要使用时可以立刻获得资源;
-
M
ax
Quota,又称为资源使用上限。调度器限制该队列使用资源不超过 Max Quota 的资源量。
-
优先级调度:所有作业按照定义的优先级排序,调度器优先分配高优先级的作业;
-
Gang 调度:调度器一次性为作业的所有 Pod 分配资源,或者一个 Pod 也不分配,保证不出现一个作业的部分 Pod 启动,部分 Pod 排队等待的情况;一个作业只有部分 Pod 启动,有可能不能正常运行,这样不仅浪费了集群资源,还可能存在多个类似作业相互死锁,导致所有作业都不能正常运行;
-
DRF 调度:调度器公平分配资源给各个作业的同时,兼顾多维度资源的比例,尽可能提升资源利用率;比如队列剩余大量 CPU 和少量内存时,优先分配 CPU 需求多、内存需求少的作业,避免队列的内存完全耗尽,大量 CPU 剩余,无法被利用的问题。
Quota 管控策略
:
-
队列
间抢占:队列没有使用的 Quota 允许临时被其他队列占用,当队列有资源需求时,可以从其他队列将资源抢占回来;
-
队列
内抢占:队列没有剩余 Quota,高优作业提交后可以将正在运行的低优作业占用的资源抢占回来;
-
大作业资源预留:资源需求较大的作业很有可能因为节点资源碎片一直无法调度,调度器支持预留节点资源,保证大作业调度成功。
GRO Scheduler 统一管控云原生集群资源,同时调度在线服务和大数据作业。
-
在线服务高峰时,离线计算尽量停止运行,在线服务使用集群大部分资源;
-
在线服务低谷时,在线服务让出大部分资源,离线计算开始运行。
在离线资源可以高效且灵活地相互转换,整个
集群利用率得到极大地提升,实现降本增效
。
运维人员
只需要维护
云原生
集群,
降低维护开销
。
GRO Agent
SLA
保障机制,监控节点上在线服务的运行情况,结合业务指标、资源指标、基础指标等,在必要情况下,可以驱逐大数据 Pod,或者通知调度器重新迁移在线服务,以保障在线服务的稳定性。
闲置资源利用
-
GRO
Agent 监控所有
Pod
的资源使用情况,结合实时/历史资源变化曲线,实时计算出节点上可以被重复利用的闲置资源量(BestEffort 资源)
;
-
GRO Agent 上报 BE 资源量到 GRO Scheduler;
-
GRO
Scheduler 调度有预期的低优作业到节点上使用 BE 资源
;
-
GRO
Agent 通过单机隔离机制保障正常
Pod
的稳定性和性能
;
-
GRO
Agent 根据 BE 资源变化情况压缩
混部
Pod
资源或者驱逐混部 Pod
。
基于云原生的多机房统一资源湖 —— ResLake
是基于
云原生
的多机房统一资源湖,统一管理全局计算、存储、网络资源,并提供全局
容灾
能力。
提供了全局
虚拟队列
。每个虚拟队列对应不同机房或集群的多个队列。用户提交作业到虚拟队列,ResLake 考虑资源情况、存储亲和性等因素,自动分发到合适的机房、集群和队列。
ResLake
还提供了全局 Quota 管控。ResLake 在调度作业时,会考虑 Quota 约束、数据局部性、机房拓扑、自定义约束等条件。
还支持管理和调度存储资源:
-
针对周期性作业,ResLake 提交将存储资源搬迁到计算队列所在的机房;
-
针对临时查询,如果存在跨机房读取存储数据,ResLake 将存储资源缓存在目的机房一段时间。
达成“最优化资源利用率。最小化作业完成时间”的最终调度目的。
支持分发作业到具体的集群和
队列
:
-
支持一个作业全部分发到同一个队列;
-
支持一个作业的不同实例按照指定比例或者指定数量分发到不同队列,包括同集群、同机房的不同集群、不同机房的队列等。
ResLake
提供三种
容灾
能力:
-
迁移
容灾
:-
灾难发生后,自动重新提交作业到备用
队列
; -
备用集群资源不足时,自动杀死低优作业以腾出资源
;
-
-
多活
容灾
:
基于
多副本的
输入/输出,在备用
队列
启动副本作业
;
-
高可用
容灾
:
基于作业自身 HA 能力,作业子实例被分发到两个
队列
同时运行
。
▌云原生大数据助力金融
云原生
大数据
平台致力于金融行业云原生大
数据解决方案
:
-
Serverless YARN:基于云原生的 YARN 解决方案
-
Arcee
Operator:基于云原生的大数据统一 Operator
-
GRO:基于云原生的高性能资源管理调度器
-
ResLake:基于云原生的多机房统一资源湖
资源管理
能力和跨机房作业
容灾
能力,帮助
大数据
作业平滑迁移到
云原生
系统。
满足用户在硬件资源不增加的情况下承载更多业务,整体提升集群资源利用率。
开源圈的运营都分为哪几种?不用的运营需要哪些技能,每天都在负责什么工作呢?
在《中国开源社区 Landscape 社区畅聊》系列直播的第五期,我们邀请了 PG中文社区运营负责人王向阳(Benker)、 TiDB 开源社区运营黄漫绅( billmay | 表妹),让两位运营同学聊聊运营的日常工作,分享一些运营技巧,以及入门开源圈运营所需的一些技能,还有一些运营工作中有趣的故事…
直播期间可随时提问,嘉宾会抽取高质量问题进行解答,被选中的提问者可以获得礼品一份。
一、直播主题
- 主题:开源圈运营同学的日常
- 时间:12 月 6 日 20:00 ~ 21:00
- 平台:“OSC 开源社区” 视频号
- 主办方:COSCLC 社区 & TiDB 开源社区 & PG 中文社区
二、直播嘉宾
主持人:黄漫绅
TiDB 开源社区 社区运营
分享嘉宾:王向阳
象圈社区发起人,PG中文社区运营负责人
三、直播通知群
加入群聊,获取直播的一手通知、与其他开发者共同探讨技术(摸鱼吹牛)。
- 开发者运营&用户运营的日常是什么
- 开源社区运营需要具备哪些素养/技能?
- 开源社区运营技巧&注意事项
- 理想中的开源社区是什么样的?
- 运营中遇到的有趣的人和事
- 有趣的创业经历与故事
关于中国开源社区 Landscape 社区
COSCLC:中国开源社区 Landscape 社区,是以国内开源社区为单位的社区,旨在通过凝聚社区力量,推动国内开源生态发展。(COSCLC 具体章程等规划正在筹备中,近期公布。)
关于 《COSCLC 社区畅聊》系列直播
《COSCLC 社区畅聊》系列直播由中国开源社区 Landscape 社区(COSCLC) 推出,把目光聚焦于开源项目背后的开源社区和开源作者,让他们来畅聊一下:自己的开源项目因何而起、经历了怎样的发展,开源作者 / 社区在开源过程中的酸甜苦辣、开源项目的运营经验…
每个开源项目的背后都有不同的故事,让我们倾听这些来自社区,来自作者的声音。
什么是 KCL
KCL (Kusion Configuration Language) [https://github.com/KusionStack/KCLVM] 是一个开源的基于约束的记录及函数语言,主要用于配置编写和策略校验场景。KCL 期望通过成熟的编程语言技术和实践来改进对大量繁杂配置的编写,致力于构建围绕配置的更好的模块化、扩展性和稳定性,更简单的逻辑编写,以及更快的自动化集成和良好的生态延展性。
所谓配置就是当我们部署软件系统时,我们并不认为它们是固定不变的。不断发展的业务需求、基础架构要求和其他因素意味着系统不断变化。当我们需要快速更改系统行为,并且更改过程需要昂贵、冗长的重建和重新部署过程时,业务代码更改往往是不够的。而配置可以为我们提供了一种低开销的方式来改变系统功能,比如我们会经常为系统编写一些如下所示的 JSON 或 YAML 文件作为我们系统的配置。
-
JSON 配置
-
YAML 配置
我们可以根据需要选择在 JSON 和 YAML 文件中存储静态配置。此外,配置还可以存储在允许更灵活配置的高级语言中,通过代码编写、渲染并得到静态配置。KCL 就是这样一种配置语言,我们可以编写 KCL 代码来生成 JSON/YAML 等配置。这篇文章我们重点讲述使用 KCL 生成并管理 Kubernetes 资源,并通过一些简单的例子给大家一个简单的快速开始,更多的内容我们会在后续文章展开。
为什么使用 KCL
当我们管理 Kubernetes 资源清单时,我们常常会手写维护,或者使用 Helm 和 Kustomize 等工具来维护我们 YAML 配置或者配置模版,然后通过 kubectl 和 helm 命令行等工具将资源下发到集群。但是作为一个 “YAML 工程师” 每天维护 YAML 配置无疑是琐碎且无聊的,并且容易出错。
-
1. YAML 中的结构化数据是无类型的,缺乏验证方法,无法立即检查所有数据的有效性
-
2. YAML 编程能力欠佳,容易写出不正确的缩进,也没有逻辑判断、等常见代码组织方式,容易写出大量重复配置,难以维护
-
3. 用户很难理解 YAML 配置所有细节,比如上 Kubernetes 配置中的 和 字段,如果用户不理解调度逻辑,它可能被错误地省略掉或者多余的添加
因此,KCL 期望在 Kubernetes YAML 资源管理层面解决如下问题:
-
1. 用生产级高性能编程语言以编写代码的方式提升配置的灵活度,比如条件语句、循环、函数、包管理等特性提升配置重用的能力
-
2. 在代码层面提升配置语义验证的能力,比如字段可选 / 必选、类型、范围等配置检查能力
-
3. 提供配置分块编写、组合和抽象的能力,比如结构定义、结构继承、约束定义等能力
本篇文章是 KCL 可以做什么系列文章第一篇,重点讲述 KCL 快速入门,后续会持续更新和分享 KCL 的一系列特点和使用场景,大家敬请期待!
如何使用 KCL 生成并管理 Kubernetes 资源
前提条件
首先可以在 KCL 项目首页 https://github.com/KusionStack/KCLVM 根据指导下载并安装 KCL,然后准备一个 Kubernetes 环境
生成 Kubernetes 资源
我们可以编写如下 KCL 代码并命名为 main.k ,KCL 受 Python 启发,基础语法十分接近 Python, 比较容易学习和上手
上述 KCL 代码中我们分别声明了一个 Kubernets Deployment 资源的 、、 和 等变量,并分别赋值了相应的内容,特别地,我们将 字段分别重用在 和 字段。可以看出,相比于 YAML,KCL 定义的数据结构更加紧凑,而且可以通过定义局部变量实现配置重用。
我们可以执行如下命令行得到一个 Kubernetes YAML 文件
输出为:
当然我们可以将 KCL 工具与 kubectl 等工具结合使用,让我们执行如下命令并看看效果
可以从命令行的结果看出看出与我们使用直接使用 YAML 配置和 kubectl apply 的一个 Deployment 体验完全一致
通过 kubectl 检查部署状态
编写代码管理 Kubernetes 资源
对于 Kubernetes 资源发布时,我们常常会遇到配置参数需要动态指定的场景,比如不同的环境需要设置不同的 字段值生成不同环境的资源。对于这种场景,我们可以通过 KCL 的条件语句和 函数动态地接收外部参数。我们可以在上述例子的基础上根据不同的环境调整配置参数,比如对于如下代码,我们编写了一个条件语句并输入一个名为 的动态参数
使用 KCL 命令行 标记接收一个从外部设置的动态参数:
输出为:
上述代码片段中的 意思为:当动态参数 的值被设置为 时,image 字段值为 , 否则为 ,因此我们可以根据需要为 env 设置为不同的值获得不同内容的 Kubernetes 资源。
并且 KCL 支持将 option 函数动态参数维护在配置文件中,比如编写下面展示的 文件
使用如下命令行也可以得到同样的效果,简化 KCL 动态参数的输入过程
输出为:
下一期
本期内容大概简单介绍了用 KCL 编写配置的快速入门和使用 KCL 定义并管理 Kubernetes 资源。
目前阶段 Kustomize 和 Helm 已经慢慢演进成在 Kubernetes 配置定义和管理领域的事实意义上的标准,熟悉 Kubernetes 的小伙伴可能更喜欢显式配置编写方式编写。那么相较于 Kustomize 和 Helm,用 KCL 来写配置文件渲染,又有什么异同呢?考虑到有很多小伙伴已经在使用 Helm,Kustomize 这样的工具,下一期我将介绍用 KCL 的方式来写对应的配置代码,敬请期待!!
如果您喜欢这篇文章,一定记得收藏 + 关注!!更多精彩内容请访问:
KCL 仓库地址:https://github.com/KusionStack/KCLVM
Kusion 仓库地址:https://github.com/KusionStack/kusion
Konfig 仓库地址:https://github.com/KusionStack/Konfig
同时欢迎加入我们的社区进行交流:
https://github.com/KusionStack/community
漏洞描述
Cap’n Proto 是一个支持快速数据格式交换的 RPC 系统。
Cap’n Proto 受影响版本中由于 capnp/layout.c++ 和 capnp/layout.h 类处理列表的逻辑错误导致存在越界读取漏洞,攻击者可通过发送恶意消息,当用户使用指针类型列表执行处理恶意消息时触发漏洞。应用程序在执行特定的操作序列前提下,攻击者可利用此漏洞获取目标系统敏感信息,或远程执行恶意代码。
影响范围
capnproto@[0.9.0, 0.9.2)
capnproto@[0.8.0, 0.8.1)
capnproto@[0.10.0, 0.10.3)
capnproto@[0.7.0, 0.7.1)
修复方案
将组件 capnproto 升级至 0.7.1 及以上版本
将组件 capnproto 升级至 0.9.2 及以上版本
将组件 capnproto 升级至 0.8.1 及以上版本
将组件 capnproto 升级至 0.10.3 及以上版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-65542
https://nvd.nist.gov/vuln/detail/CVE-2022-46149
https://github.com/capnproto/capnproto/security/advisories/GHSA-ff-4vw4-f6hx
https://github.com/capnproto/capnproto/commit/25d34c67863fd960af34fc4f82a7ca3362ee74b9
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
漏洞描述
Linux kernel 是一种开源的类 Unix 操作系统内核,x86 KVM 是 Linux kernel 的一个子系统。
Linux kernel v6.1-rc6 的 x86 KVM 子系统在 guest 操作系统用户启用嵌套虚拟化(nested virtualisation)和 TDP MMU 时 direct_page_fault 方法中会产生竞争条件,攻击者可利用此漏洞造成拒绝服务(主机操作系统崩溃或主机操作系统内存损坏)。
影响范围
修复方案
参考链接
https://www.oscs1024.com/hd/MPS-2022-65207
https://nvd.nist.gov/vuln/detail/CVE-2022-45869
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=47b0c2e4c220f2251fd8dcfbbc715e15
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
漏洞描述
synthetic-monitoring-agent 是一个为 Grafana 提供探测功能并执行网络检查以监控远程目标的工具包。
synthetic-monitoring-agent 0.12.0之前的版本存在敏感信息泄露漏洞,原因是与 Synthetic Monitoring API 通信时的认证令牌会通过 debugg 端点暴露给攻击者,所有在本地网络中运行 synthetic-monitoring-agent 的用户都会受到影响。开发者可通过以下方式缓解漏洞:1、默认禁用调试端点。2、允许从环境中检索令牌。3、默认监听本地主机。
影响范围
github.com/grafana/synthetic-monitoring-agent/cmd/synthetic-monitoring-agent@(-∞, 0.12.0)
修复方案
将组件 github.com/grafana/synthetic-monitoring-agent/cmd/synthetic-monitoring-agent 升级至 0.12.0 及以上版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-65549
https://nvd.nist.gov/vuln/detail/CVE-2022-46156
https://github.com/grafana/synthetic-monitoring-agent/security/advisories/GHSA-9j4f-f249-q5w8
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
SRE
工程师
背景介绍
挑战分析和方案思考
从基础设施能力的使用者,转变为基础设施能力的构建者。云原生概念让我感受较深,很多企业各条业务线都选择上云并致力于构建云原生能力,随之业务应用架构也会应变来追求更高的迭代效率,以及更强的稳定性建设。
-
上线资源设备只能人工确认,资源设备没有统一的管理平台。
-
研发排查问题困难,对于服务进行诊断,每有一个资源设备都需要给研发单独分配 SSH 权限,管理成本巨高。
-
开发 debug 过程需要登录统一的内网主机使用 Kubectl 操作,权限不可控,风险大。
-
对于新上项目,面对不同的使用场景,需要创建多条 Jenkins Job,配置繁琐,维护负担重。
大部分操作都在一个平台完成,并且丰富的权限管控以及多集群接入等等功能能很好满足我们的需求。在完成调研后,我们选择 Zadig 作为我们下一阶段的 CI/CD 体系建设的重要组件。
落地和实践过程
的主机方式:
-
支持系统主机管理的同时支持了项目级别的主机管理,项目成员可以自己上下线资源设备
-
主机管理支持强大的探活机制(TCP/HTTP 协议),精准检测资源设备是否在线
-
服务可以查看到关联的主机资源,支持登录主机,方便开发登录资源设备诊断问题
-
完备的权限控制,极大降低了管理成本,实现安全风险可控
:
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
Mesa 22.3 已发布,此版本推出了多项新功能,例如:
- Mesa-DB,一种新的单文件缓存类型
- Radeon Vulkan (RADV) 驱动程序提供对 GFX11/RDNA3 的初始支持
- OpenGL 升级到 4.5 版本, 支持Freedreno/a6xx 驱动程序
- 使用 RADV_RRA_* 环境变量的 Radeon Raytracing Analyzer 集成
- Collabora 的 Panfrost 驱动程序着色器磁盘缓存和 Mali T620 支持
Mesa 22.3 还在 Radeon Vulkan (RADV) 驱动程序上添加了对 R8G8B8、B8G8R8、R16G16B16 和 64 位顶点缓冲区格式的支持,以及各种光线追踪优化和 VK_EXT_extended_dynamic_state2 功能。
其次,图形堆栈现在还支持各种新的 OpenGL 和 Vulkan 扩展。
Radeon Vulkan (RADV) 驱动程序支持:
- VK_EXT_attachment_feedback_loop_layout
- VK_KHR_global_priority
- VK_EXT_load_store_op_none
- VK_EXT_mutable_descriptor_type
- VK_EXT_extended_dynamic_state3 Vulkan
Intel Vulkan (ANV) 驱动支持:
- VK_EXT_extended_dynamic_state3
- VK_EXT_mesh_shader Vulkan
Gallium LLVMpipe 驱动支持 OpenGL 扩展:
- GL_ARB_shader_clock
Lavapipe 驱动支持:
- VK_KHR_shader_clock
- VK_EXT_attachment_feedback_loop_layout
- VK_EXT_extended_vulkandynamic_state3
Zink 驱动程序支持该 OpenGL 扩展:
- GL_KHR_blend_equation_advanced_coherent
V3DV 驱动程序支持:
- VK_EXT_image_robustness
- VK_EXT_pipeline_robustness Vulkan
更多细节解读可查看更新公告。
Spring Integration6.0.0 现已正式发布,且可以在 Maven Central 中找到。
此版本是一年多工作的结晶,完全基于 Spring Framework 6.0、Spring Data 2022.0、Spring for GraphQL 1.1、Spring WebServices 4.0 ,另一方面,Spring Integration 6.0 是最近发布的 Spring Boot 3.0 的一部分。
主要改进:
- Java17 基线
- 使用 GraalVM 和 Spring AOT 引擎支持本机图像
- 使用 EE9 基线,支持 Jakarta EE 10
- 支持使用 Micrometer 启用对计时器的观察和跟踪。有关详细信息,请参阅 Micrometer 观察。
- 添加了新的 MQTT,以支持跨不同通道适配器的可重用 MQTT 连接。有关更多信息,请参阅共享 MQTT 客户端支持。
- 添加了 GraphQL 支持。有关详细信息,请参阅GraphQL 支持。
- 引入了对 Apache Camel 路由的支持。有关详细信息,请参阅Apache Camel 支持。
- Hazelcast Spring Integration Extensions 项目已作为模块迁移。有关详细信息,请参阅 Hazelcast 支持。
- 引入了 Kotlin Coroutines 支持。有关详细信息,请参阅 Kotlin 协程。
更多一般改进可查看 6.0 版本功能改进页面。
更新公告:https://spring.io/blog/2022/11/29/spring-integration-6-0-goes-ga
经过将近两年的开发,Xfce 4.18 将于 12 月 15 日正式发布。此版本是 Xfce 4.16 稳定系列的后续版本,增加了许多新特性,例如使用的 GTK 框架升级到了 GTK 4、初步支持 Wayland,以及对核心应用的改进等。
- 针对文件管理器 Thunar 的更新
Thunar 是 Xfce 的默认文件管理器。在 Xfce 4.18 中它获得了大量新特性和扩展功能。
例如,现在可以在侧边栏启用图像预览。默认情况下,侧边栏左侧会显示所选图像的较大预览图。此外还提供了“独立预览”的选项,启用后会默认在右边的面板上预览所选图像。如下图所示:
此外,Thunar 新的可编辑工具栏允许用户根据需要添加和重新排列工具栏图标。
除了上述变化,文件夹属性对话框添加了新的高亮选项,用于为文件夹图标背景和前景选择任何自定义颜色。对于复杂的文件夹结构,能够快速导航。
其他变化:
- 引入新的书签菜单,可以将当前文件夹作为快捷方式添加到侧边栏
- 侧边栏增加“最近”选项
- 优化状态栏信息布局
- “前往”菜单提供“最近”和“搜索”的选项
- “编辑”菜单提供“撤销”和“重做”的选项
- 添加在启动时恢复选项卡的选项
- 添加执行 shell 脚本的选项
- ……
当然稳定性和性能方面也有所提升,还修复了不少错误。
- 针对桌面和面板的更新
新版本的面板设置有两个新的选项。第一个是面板的长度现在以像素设置,而不是百分比。其次是添加“保持面板在窗口前面”的选项,该功能将窗口对话放到面板后面。在这之前,应用程序的窗口只能位于面板的边缘。
此版本为时钟程序提供了新的字体选项,以及四种时钟布局:
- 只有日期
- 只有时间
- 日期和时间
- 时间和日期
- Wayland 和其他更新
除了上述 Xfce 4.18 的新特性外,窗口管理器和桌面还有许多额外的错误修复和性能改进。
Xfce 桌面核心和原生应用程序的 Wayland 迁移工作已经开始。不过离它完全准备好还有很长的路要走。在这个版本中,用户可能不会看到很多 Wayland 的更新。不过许多应用程序在 Wayland 下已经可以正常工作。点此查看更多关于迁移状态的信息。
最后,Xfce 4.18 pre2 今天刚发布,体验地址:Xfce 4.18pre2。
IPython 是一个综合环境,可以帮助程序员或开发人员等高级计算机用户测试或探索各种功能。尽管 Python 附带了一个强大的交互式解释器,使用户无需在目标计算机上创建额外的文件即可运行测试,但它在用户与软件交互方面存在一些限制。
IPython 的三个核心部分包括一个高度交互式的 Python shell,一个解耦的双进程通信模型和交互式并行计算的架构。
IPython 8.7 是 8.0 之后的第七个小版本,更新内容如下:
- 将最小提示工具包提升至 3.0.11
- IPython 现在已经带有 标记,未来将逐步增加更多类型
- 增加了对代码块格式的配置
更多详情可查看:https://github.com/ipython/ipython/releases/tag/8.7.0
ClamAV 是一个开源的(GPL)反病毒引擎,用于检测木马、病毒、恶意软件和其他恶意威胁。它为用户提供了许多实用程序,包括一个可扩展的多线程守护程序、一个命令行扫描器和一个自动更新数据库的高级工具。
ClamAV 由思科和开源社区共同开发,第一个版本的 ClamAV 于 2002 年发布,在首次发布近 20 年后,ClamAV 1.0 正式推出。
ClamAV 1.0.0 现已稳定,可通过 ClamAV.net 或 Docker Hub 下载。ClamAV 1.0.0 包括以下变化:
主要变化
- 支持解密用默认密码加密的基于 OLE2 的只读 XLS 文件。默认密码的使用现在将出现在数据 JSON 中。
- 彻底检查了全匹配功能的实现。较新的代码更可靠,更容易维护:
- 修复了全匹配模式下签名检测的几个已知问题:
- 启用嵌入式文件类型识别签名,当恶意软件签名也在同一层的扫描中匹配时,可进行匹配。
- 启用字节码签名,以便在发生匹配后以全匹配模式运行。
- 修正了各种全匹配的边缘案例问题。
- 增加了多个测试案例,以验证正确的全匹配行为
- 修复了全匹配模式下签名检测的几个已知问题:
- 在公共 API 中增加了一个新的回调,用于在每层档案提取的扫描过程中检查文件内容
- 在公共 API 中增加了一个新函数,用于解压 CVD 签名档案
- 使用外部 TomsFastMath 库构建的选项已被删除
- 将 Docker 文件和支持脚本从 ClamAV 主仓库移到了一个新仓库:https://github.com/Cisco-Talos/clamav-docker
- 由于 0.103 LTS 版本和 1.0 LTS 版本之间的 ABI 变化,增加了 libclamav 的 SONAME 主要版本。
其他改进
- 增加检查以限制 PDF 对象的提取递归
- 增加了对基于不可信任输入的内存分配的限制,并改变了超过限制时的警告信息,使其更有帮助
- 大幅改善了 libclamav-Rust 单测试的构建时间
- 对于 Windows:当以 “RelWithDebInfo” 或 “Debug” 模式构建时,调试符号(PDB)文件现在会与 DLL 和 LIB 库文件一起安装。
- 放宽了对重叠的 ZIP 文件条目的检查限制
- 增加了 FreshClam 中在 DNS 条目过期时发出警告的时间限制
- Docker:C 库的头文件现在包含在 Docker 镜像中
- 在使用 CMake 的 GUI 时显示 BYTECODE_RUNTIME 构建选项
- 增加了明确的最小和最大支持的 LLVM 版本,这样如果你试图用一个太老或太新的版本进行编译,编译就会失败,并且会打印出一个有用的消息,而不是简单地因为兼容性问题而编译失败
- 修正了 Clang 16 中可能变成错误的编译器警告
- 允许使用自定义 RPATH 进行构建,以便在开发环境中构建后将可执行文件移至最终安装目录。
更多详情可查看:https://blog.clamav.net/2022/11/clamav-100-lts-released.html
GoLand 2022.3 提供了性能增强以及针对泛型和 Go 工作区的新功能。新版本集成了 Go Playground,添加了改进 Go 文档注释的支持,为 HTTP 客户端和 Docker 引入了新功能,并提供了新 UI。
此外,GoLand 也迎来了 5 岁生日,官方邀请各位开发者们一起庆祝。现在在 GoLand 2022.3 或 GoLand 2022.2.5 中输入 “Happy B-day, GoLand!”,看看会有什么彩蛋。
性能改进
有助于改进索引编制的 更改
打开项目时,GoLand 会为文件编制索引并运行 命令,该命令会报告有关项目结构的信息。 索引编制会在 运行时暂停,在索引编制完成之前您无法访问代码洞察功能。
此前,GoLand 在某些情况下会运行两次 。 我们更改了 API,减少了 启动的数量。 我们希望这一改变能够显著提高具有许多模块的大型项目的性能。
打开时从缓存还原项目结构
现在,打开项目时, 报告的信息将被保存到磁盘缓存。 再次打开该项目时,项目结构相关数据将从内存加载并在索引编制开始时被纳入考量。
由此,索引编制可以不间断地继续,更快完成,并且代码洞察功能在打开项目后可以更快可用。
更快的 IDE 启动和项目打开
GoLand 还获得了许多其他性能改进,旨在减少启动应用程序以及在 JetBrains IDE 中打开项目所需的时间。
整体启动性能(包括编辑器还原)因此提高了约 30%。
泛型
泛型函数的测试生成
现在,您可以为具有泛型形参的函数生成测试。
大写类型形参的快速修复
现在有一项检测小写类型形参的检查,以及将其变成大写的快速修复。
Go 工作区
Go Workspace File(Go 工作区文件)操作
在 New(新建)上下文菜单中,您现在会找到 Go Workspace File(Go 工作区文件)操作。 选择时,根文件夹中将出现一个 文件。 现有 Go 模块将自动添加到 文件中。
使用 指令生成
如果有 指令,您现在可以从 生成 。 将文本光标置于 指令上,按 ⌥⏎ 查看所有可用意图操作,然后选择 Add … module to workspace…(将 … 模块添加到工作区)快速修复。
Go 文档注释
Go 1.19 在文档注释中添加了对链接、列表和新标题的支持。 GoLand 2022.3 也支持这些新功能。
对链接的支持
我们在 GoLand 中添加了对文档链接的引用。 它们可以前往引用的素,文本链接会前往文本链接定义。
文本和文档链接在 Quick Documentation(快速文档)弹出窗口和 Documentation(文档)工具窗口中都呈现为链接。
对新标题的支持
从 Go 1.19 开始,标题是以数字符号 () 开头后跟空格和标题文本的行。
新标题在 GoLand 的 Quick Documentation(快速文档)弹出窗口和 Documentation(文档)工具窗口中呈现为 HTML 标题。
对列表的支持
列表在 GoLand 的 Quick Documentation(快速文档)弹出窗口和 Documentation(文档)工具窗口中呈现为 HTML 列表。
集成式 Go Playground
我们在 GoLand 中集成了 Go Playground 功能。
您可以选择一段代码,选择 Open In(打开方式)选项,然后 Playground。 这将打开带有工具栏的 scratch 文件,工具栏中的选项与 Go Playground 相同。
您可以格式化和共享您的代码、更改 Go 版本、使用 Go Playground 服务器运行代码,或在本地运行。
新的快速修复
无效递归类型的快速修复
如果类型包含自身,您将收到“Invalid recursive type”(无效递归类型)错误。 为避免这种情况,您应该包含一个指向类型的指针,而不是类型本身。 我们现在提供了快速修复。
编辑器
Code Vision
我们已经开始实现 Code Vision 功能。 目前,启用版本控制集成后会显示代码作者。 代码作者姓名将打开 Annotate with Git blame(使用 Git 追溯注解)边栏,显示是谁引入了更改。
我们还引入了在所有函数和类型附近显示的用法,显示函数或类型在当前项目中被引用的次数。
常量定义的内嵌提示
GoLand 现在会显示常量定义块的内嵌提示。 这在 派生的常量块中特别实用,其中提示显示了与每个位置关联的 值。
Fill all fields(填充所有字段)忽略自动生成的 protobuf 字段
调用 Fill all fields(填充所有字段)意图操作时,IDE 会忽略以 开头的自动生成的协议缓冲区字段。 这些字段仅在第二次调用补全后显示。
其他 Go 相关功能
Go 环境变量在设置中显示
GoLand 现在会自动获取 Go 模块相关系统变量,并将其显示在 Environment variables(环境变量)对话框窗口中。 要打开此窗口,请转至 Preferences | Go | Go Modules(设置 | Go | Go 模块), Edit environment variables(编辑环境变量)图标。
软件包名称始终显示在 Quick documentation(快速文档)中
IDE 现在始终在顶层声明的 Quick documentation(快速文档)弹出窗口中显示软件包名称。 此前,只有在找到 或 文件时才会显示软件包头。
提高文件大小上限
我们已将文件大小上限从 2.5 MB 提高到 10 MB。 代码洞察功能(如导航和高亮显示)不适用于超过大小上限的文件。
虽然 2.5 MB 的上限对于大多数文件来说已经足够,但有些项目的文件更大,例如 AWS SDK 或 GCP。
Receiver names are different(接收器名称不同)检查忽略生成的代码
由于 Receiver names are different(接收器名称不同)检查与生成的代码无关,我们已为包含与以下正则表达式匹配的注释的文件将其禁用:
HTTP 客户端
为 JavaScript 处理程序预请求脚本和新 API
HTTP 客户端现在支持在请求之前执行脚本块。 您可以在执行请求之前生成数据,并使用变量将其放入最终请求。 可以使用快速修复创建用于初始化变量的样板代码。
HTTP 客户端现已支持 Crypto API。 您可以计算 HTTP 请求的 md5 或 sha1 哈希值。
对于简单的情况,IDE 现在具有一组新的随机变量。
Docker
在不安装 Docker Desktop 的情况下从 WSL 使用 Docker 可执行文件
GoLand 现在支持连接到在适用于 Linux 的 Windows 子系统 (WSL) 中运行的 Docker。 您可以在 Preferences | Build, Execution, Deployment | Docker(设置 | 构建、执行、部署 | Docker)中设置连接。
新意图操作:Pull Docker image(拉取 Docker 镜像)
现在,有一种无需从 或 运行即可拉取镜像的简单方式。 为此,在高亮显示的镜像名称上调用上下文操作 (⌥⏎),然后选择 Pull Docker image(拉取 Docker 镜像)。
文件类型支持
我们引入了对 文件的全面支持,包括代码高亮显示和补全。 从 IDE 构建镜像时,这些文件会被纳入考量。
在 Dockerfile 文件中支持 heredoc 格式
Here 文档允许将后续 行重定向到 或 命令的输入。 GoLand 现在支持此语法,您可以使用它在 文件中生成配置文件或多行脚本。
来自 Docker 上下文的 Docker 连接
如果 Docker 配置中已有这些设置,您现在可以使用 Docker 上下文设置额外的 Docker 连接。 为此,您可以在 Services(服务)视图中调用 Add Service(添加服务)上下文菜单并选择 Docker Connections From Docker Contexts(来自 Docker 上下文的 Docker 连接)。
远程开发(测试版)
IDE 后端现在可以直接在 WSL 2 中启动,并且您可以像在 GoLand 中使用远程开发时连接到远程机器一样连接到它。
用户界面
新 UI
如您所知,今年 5 月我们宣布了 JetBrains IDE 中新 UI 的封闭预览计划。
我们邀请您在 Preferences | Appearance & Behavior | New UI Preview(设置 | 外观与行为 | 新 UI 预览)中切换到新 UI。
意图操作预览默认启用
意图操作的预览功能现在默认开启,让您可以立即查看应用 IDE 建议后代码将如何变化。
在意图操作列表打开时,您可以按 F1 启用或禁用预览功能。
将工具窗口停靠到浮动编辑器选项卡
为了让您可以更轻松地安排工作空间并在多个显示器上与 GoLand 交互,我们实现了将工具窗口拖出主窗口并将其停靠到浮动编辑器选项卡的选项。
改进了 Tips of the Day(每日小技巧)
我们增强了 Tips of the Day(每日小技巧)功能,这是一种帮助您探索 GoLand 的学习工具。
每个提示现在都有一个标题。 我们还微调了确定显示哪些提示的算法,让您可以看到与 IDE 体验和正在处理的项目最相关的提示。
更新了 Bookmarks(书签)
现在,又可以从编辑器选项卡中为文件添加书签了。 只需右键选项卡调用上下文菜单并选择 Bookmarks(书签)。
您可以将当前打开的所有选项卡中的所有文件添加到 Bookmarks(书签)。 为此,可以调用相同上下文菜单并选择 Bookmark Open Tabs(为打开的选项卡添加书签),也可以使用编辑器选项卡窗格右侧的三点图标调用此操作。
新的 Settings Sync(设置同步)解决方案
我们为同步自定义用户设置引入了重做的解决方案。 长期以来,有两个并行存在且具有交叉功能的插件:IDE Settings Sync(IDE 设置同步)和 Settings Repository(设置仓库)。 为避免因拥有两个近似捆绑插件而造成困惑,我们将其功能集合并为一个解决方案,即新的 Settings Sync(设置同步)插件。
数据库
Redis 支持
期待已久的 Redis 支持的初步迭代现已实现。
快速筛选
现在,使用快速搜索时,您也可以筛选对象。 所有不匹配的对象都将被隐藏。
Web 开发
针对 JavaScript 和 TypeScript 的 Code Vision
此版本为 Web 开发引入了的新 Code Vision 功能。 它可以收集 JavaScript 和 TypeScript 代码中类型和类型成员的各种指标,并在声明附近显示此信息。
其他更新
在 YAML 中禁止检查的快速修复
在 YAML 文件(包括 Kubernetes 文件、OpenAPI 规范和 文件)中,新增的快速修复可以通过注释禁止检查。
还引入了一个选项,用于折叠组成 3 行或更多行的块并以 开头的多行注释。
适用于 Windows ARM64 的安装程序
GoLand 已经开始分发适用于 Windows ARM64 的安装程序,开发者可以从官方网站或通过 Toolbox App 下载。
更多详情可查看:https://blog.jetbrains.com/go/2022/12/01/goland-turns-5/
根据 Emacs 开发者邮件列表的消息,Emacs 29 的开发已基本完成,不再增加任何新功能,未来主要集中在修复 bug 上面。
Emacs 29 重要变化包括:
- Eglot 现在是 Emacs 核心的一部分
Emacs 包含多个 LSP 集成,例如 LSP Mode、Eglot 和 lsp-bridge。从 Emacs 29 开始,Eglot 已成为 Emacs 核心的一部分,不再需要安装。只需注册一个 LSP 服务器,自动补全、文档、错误检测和其他功能将立即可用。
- 解析器生成器工具 Tree-Sitter 成为核心的一部分
Tree-Sitter 用于将编程语言解析为具体的语法树。基于它不仅可以快速完成语法高亮显示,还可以对代码进行更深入的分析,并且实现语法操作等需求,因为语法树本身可作为可以操作的对象使用。
Tree-Sitter 现在是 Emacs 中的原生解决方案。Emacs 的 Tree-Sitter 支持如下的主要模式:
如果迫不及待地想测试 Tree-Sitter,现在已经有另一个适用于 Emacs 的软件包可供使用。请注意,这与集成到 Emacs 中的包不同。
- 使用 package.el 可以直接从 Git 安装软件包
现在可以使用 Emacs 的内置打包系统直接从 Git 安装软件包。可以使用 new 函数来完成 ,并且可以使用或来更新以这种方式安装的软件包。
- 原生支持 Wayland
以前 Emacs 在 GUI 模式下依赖于 Xorg,随着 Wayland 的日益流行,Emacs 现在原生支持 Wayland。请注意,Wayland 基本上是纯 GTK Emacs 的唯一用例。如果不使用 Wayland,Emacs 将显示一条警告消息,因为如果运行的是 Xorg,它很可能会导致问题。
- 原生支持 SQLite
现在可以使用对 SQLite 和 sqlite3 库的原生支持来构建 Emacs,它允许使用者在 Emacs 中探索 SQLite 数据库并与它们交互。
- csharp-mode
现在是 Emacs 的原生主要模式,并且基于。
- 支持 HaikuOS
- ……
点此查看更多新特性。
摘要:在本文中,我们将介绍用于测试的相关指标,如何进行大规模测试,以及我们如何实现大规模的集群接入。
本文分享自华为云社区《突破100倍集群规模!Karmada大规模测试报告发布》,作者:华为云云原生团队。
摘要
随着云原生技术在越来越多的企业和组织中的大规模落地,如何高效、可靠地管理大规模资源池以应对不断增长的业务挑战成为了当下云原生技术的关键挑战。在过去的很长一段时间内,不同厂商尝试通过定制Kubernetes原生组件的方式扩展单集群的规模,这在提高规模的同时也引入了复杂的单集群运维、不清晰的集群升级路径等问题。而多集群技术能在不侵入修改Kubernetes单集群的基础上横向扩展资源池的规模,在扩展资源池的同时降低了企业的运维管理等成本。
在Karmada的大规模落地进程中,Karmada的可扩展性和大规模逐渐成为社区用户的新关注点。因此,我们对Karmada开展了大规模环境下的测试工作,以获取Karmada管理多个Kubernetes集群的性能基线指标。对于以Karmada为代表的多集群系统而言,单集群的规模不是制约它的资源池规模的限制因素。因此,我们参考了Kubernetes的大规模集群的标准配置和用户的生产落地实践,测试了Karmada同时管理100个5k节点和2wPod的Kubernetes集群的用户场景。受限于测试环境和测试工具,本次测试并未追求测试到Karmada多集群系统的上限,而是希望能覆盖到在生产中大规模使用多集群技术的典型场景。根据测试结果分析,以Karmada为核心的集群联邦可以稳定支持100个大规模集群,管理超过50万个节点和200万个Pod,可以满足用户在大规模生产落地的需要。
在本文中,我们将介绍用于测试的相关指标,如何进行大规模测试,以及我们如何实现大规模的集群接入。
背景
随着云原生技术的不断发展和使用场景的不断丰富,多云、分布式云逐渐成为引领云计算发展的趋势。著名分析公司 Flexera 在 2021 的调查报告显示,超过 93%的企业正同时使用多个云厂商的服务,一方面受限于 Kubernetes 单集群的业务承载能力和故障恢复能力,单一的集群无法适应现有的企业业务,另一方面,在全球化的当下,企业出于避免被单家厂商垄断的目的,或是出于成本等因素考虑,更倾向于选择混合云或者多公有云的架构。与此同时,Karmada 社区的用户在落地的进程中也提出了多集群下大规模节点和应用管理的诉求。
Karmada 介绍
Karmada(Kubernetes Armada)是一个 Kubernetes 管理系统,它能够使你在无需修改应用的情况下跨集群和跨云运行你的云原生应用。通过使用 Kubernetes 原生 API 并在其上提供高级调度功能,Karmada 实现了真正开放的多云 Kubernetes。
Karmada 旨在为多云和混合云场景中的多集群应用管理提供完全的自动化。它具备集中式多云管理、高可用性、故障恢复和流量调度等关键特性。
Karmada 控制面包括以下组件:
- Karmada API Server
- Karmada Controller Manager
- Karmada Scheduler
ETCD 存储了 Karmada 的 API 对象, karmada-apiserver 提供了与所有其他组件通信的 REST 端口, 之后由 karmada-controller-manager 对你向 karmada-apiserver 提交的 API 对象进行对应的调和操作。
karmada-controller-manager 运行着各种控制器,这些控制器 watch 着 Karmada 的对象,然后发送请求至成员集群的 apiserver 来创建常规的 Kubernetes 资源。
多集群系统资源池规模的维度和阈值
一个多集群系统的资源池规模不单指集群数量,即Scalability!=#Num of Clusters, 实际上多集群资源池规模包含很多维度的测量,在不考虑其他维度的情况下只考虑集群数量是毫无意义的。
我们将一个多集群的资源池规模按优先级描述为以下所示的三个维度:
- Num of Clusters: 集群数量是衡量一个多集群系统资源池规模和承载能力最直接且最重要的维度,在其余维度不变的情况下系统能接入的集群数量越多,说明系统的资源池规模越大,承载能力越强。
- Num of Resources(API Objects): 对于一个多集群系统的控制面来说,存储并不是无限制的,而在控制面创建的资源对象的数量和总体大小受限于系统控制面的存储,也是制约多集群系统资源池规模的重要维度。这里的资源对象不仅指下发到成员集群的资源模板,而且还包括集群的调度策略、多集群服务等资源。
- Cluster Size: 集群规模是衡量一个多集群系统资源池规模不可忽视的维度。一方面,集群数量相等的情况下,单个集群的规模越大,整个多集群系统的资源池越大。另一方面,多集群系统的上层能力依赖系统对集群的资源画像,例如在多集群应用的调度过程中,集群资源是不可或缺的一个因素。综上所述,单集群的规模与整个多集群系统息息相关,但单集群的规模同样不是制约多集群系统的限制因素。用户可以通过优化原生的Kubernetes组件的方式来提升单集群的集群规模,达到扩大整个多集群系统的资源池的目的,但这不是衡量多集群系统性能的关注点。本次测试中,社区参考了kubernetes的大规模集群的标准配置以及测试工具的性能,制定了测试集群的规模,以贴切实际生产环境中的单集群配置。在集群的标准配置中,Node与Pod毫无疑问是其中最重要的两个资源,Node是计算、存储等资源的最小载体,而Pod数量则代表着一个集群的应用承载能力。事实上,单集群的资源对象也包括像service,configmap,secret这样的常见资源。这些变量的引入会使得测试过程变得更复杂,所以这次测试不会过多关注这些变量。
- Num of Nodes
- Num of Pods
对于多集群系统而言想要无限制地扩展各个维度而且又满足 SLIs/SLOs 各项指标显然是不可能实现的。各个维度不是完全独立的,某个维度被拉伸相应的其他维度就要被压缩,可以根据使用场景进行调整。以 Clusters 和 Nodes 两个维度举例,在 100 集群下将单集群的 5k 节点拉伸到 10k node 的场景或者在单集群规格不变的同时扩展集群数量到 200 集群,其他维度的规格势必会受到影响。如果各种场景都进行测试分析工作量是非常巨大的,在本次测试中,我们会重点选取典型场景配置进行测试分析。在满足 SLIs/SLOs 的基础上,实现单集群支持 5k 节点,20k pod规模的100数量的集群接入和管理。
SLIs/SLOs
可扩展性和性能是多集群联邦的重要特性。作为多集群联邦的用户,我们期望在以上两方面有服务质量的保证。在进行大规模性能测试之前,我们需要定义测量指标。在参考了 Kubernetes 社区的 SLI(Service Level Indicator)/SLO(Service Level Objectives)和多集群的典型应用,Karmada 社区定义了以下 SLI/SLO 来衡量多集群联邦的服务质量。
- API Call Latency
- Resource Distribution Latency
- Cluster Registration Latency
- Resource usage
Note:
- 上述指标不考虑控制面和成员集群的网络波动。同时,单集群内的 SLO 不会考虑在内。
- 资源使用量是一个对于多集群系统非常重要的指标,但是不同多集群系统提供的上层服务不同,所以对各个系统来说资源的要求也会不同。我们不对这个指标进行强制的限制。
- 集群注册时延是从集群注册到控制面到集群在联邦侧可用的时延。它在某种程度上取决于控制面如何收集成员集群的状态。
测试工具
ClusterLoader2
ClusterLoader2 是一款开源 Kubernetes 集群负载测试工具,该工具能够针对 Kubernetes 定义的 SLIs/SLOs 指标进行测试,检验集群是否符合各项服务质量标准。此外 ClusterLoader2 为集群问题定位和集群性能优化提供可视化数据。ClusterLoader2 最终会输出一份 Kubernetes 集群性能报告,展示一系列性能指标测试结果。然而,在 Karmada 性能测试的过程中,由于 ClusterLoader2 是一个为 Kubernetes 单集群定制的测试工具,且在多集群场景下它不能获取到所有集群的资源, 因此我们只用 ClusterLoader2 来分发被 Karmada 管理的资源。
Prometheus
Prometheus 是一个开源的用于监控和告警的工具, 它包含数据收集、数据报告、数据可视化等功能。在分析了 Clusterloader2 对各种监控指标的处理后,我们使用 Prometheus 根据具体的查询语句对控制面的指标进行监控。
Kind
Kind 是一个是用容器来运行 Kubernetes 本地集群的工具。为了测试 Karmada 的应用分发能力,我们需要一个真实的单集群控制面来管理被联邦控制面分发的应用。Kind 能够在节约资源的同时模拟一个真实的集群。
Fake-kubelet
Fake-kubelet 是一个能模拟节点且能维护虚拟节点上的 Pod 的工具。与 Kubemark 相比,fake-kubelet 只做维护节点和 Pod 的必要工作。它非常适合模拟大规模的节点和 Pod 来测试控制面的在大规模环境下的性能。
测试集群部署方案
Kubernetes 控制面部署在单 master 的节点上。etcd,kube-apiserver,kube-scheduler 和 kube-controller 以单实例的形式部署。Karmada 的控制面组件部署在这个 master 节点上。他们同样以单实例的形式部署。所有的 Kubernetes 组件和 Karmada 组件运行在高性能的节点上,且我们不对他们限制资源。我们通过 kind 来模拟单 master 节点的集群,通过 fake-kubelet 来模拟集群中的工作节点。
测试环境信息
控制面操作系统版本
Ubuntu 18.04.6 LTS (Bionic Beaver)
Kubernetes 版本
Kubernetes v1.23.10
Karmada 版本
Karmada v1.3.0-4-g1f13ad97
Karmada 控制面所在的节点配置
- CPU
- 内存
- 磁盘
组件参数配置
- karmada-apiserver
- karmada-aggregated-server
- karmada-scheduler
- karmada-controller-manager
- karmada-agent
- karmada-etcd
测试执行
在使用 Clusterloader2 进行性能测试之前,我们需要自己通过配置文件定义性能测试策略。我们使用的配置文件如下:
unfold me to see the yaml
Kubernetes 资源详细的配置如下表所示:
详细的测试方法和过程,可以参考
https://github.com/kubernetes/perf-tests/blob/master/clusterloader2/docs/GETTING_STARTED.md[1]
测试结果
APIResponsivenessPrometheus:
Cluster Registration Latency:
Note: Karmada 的 Pull 模式适合用于私有云的场景。与 Push 模式相比,成员集群会运行一个名为 karmada-agent 的组件。它会从控制面拉取用户提交的应用,并运行在成员集群中。在 Pull 模式集群注册的过程中,它会包含安装 karmada-agent 的时间。如果 karmada-agent 的镜像已经准备完毕的话,它很大程度上取决于单集群内 Pod 启动的时延。这里不过多讨论 Pull 模式的注册时延。
Resource Distribution Latency:
Push Mode
Etcd latency:
Resource Usage:
Pull Mode
Etcd latency:
Resource Usage:
成员集群中的 karmada-agent 消耗了 40m CPU(cores)和 266Mi Memory(bytes)。
结论与分析
在以上的测试结果中,API调用时延和资源分发时延均符合上述定义的SLIs/SLOs。在整个过程中,系统消耗的资源在一个可控制的范围。因此,Karmada能稳定支撑100个大规模集群,并且管理超过500,000个节点和2,000,000个的pods。在生产中,Karmada能有效支持数以百计的大规模的集群。接下来,我们会具体分析每个测试指标的数据。
关注点分离:资源模板和策略
Karmada 使用 Kubernetes 原生 API 来表达集群联邦资源模板,使用可复用的策略 API 来表达集群的调度策略。它不仅可以让 Karmada 能够轻松集成 Kubernetes 的生态, 同时也大大减少了控制面的资源数量。基于此,控制面的资源数量不取决于整个多集群系统集群的数量,而是取决于多集群应用的数量。
Karmada 的架构集成了 Kubernetes 架构的简洁性和扩展性。Karmada-apiserver 作为控制面的入口与 Kubernetes 的 kube-apiserver 类似。你可以使用单集群配置中所需的参数优化这些组件。
在整个资源分发过程中,API 调用时延在一个合理的范围。
集群注册与资源分发
在 Karmada 1.3 版本中,我们提供了基于 Bootstrap tokens 注册 Pull 模式集群的能力。这种方式不仅可以简化集群注册的流程,也增强了集群注册的安全性。现在无论是 Pull 模式还是 Push 模式,我们都可以使用 karmadactl 工具来完成集群注册。与 Push 模式相比,Pull 模式会在成员集群运行一个名为 karmada-agent 的组件。
集群注册时延包含了控制面收集成员集群状态所需的时间。在集群生命周期管理的过程中,Karmada 会收集成员集群的版本,支持的 API 列表以及集群是否健康的状态信息。此外,Karmada 会收集成员集群的资源使用量,并基于此对成员集群进行建模,这样调度器可以更好地为应用选择目标集群。在这种情况下,集群注册时延与集群的规模息息相关。上述指标展示了加入一个 5,000 节点的集群直至它可用所需的时延。你可以通过关闭集群资源建模[2]来使集群注册时延与集群的大小无关,在这种情况下,集群注册时延这个指标将小于 2s。
不论是 Push 模式还是 Pull 模式,Karmada 都以一个很快的速度来下发资源到成员集群中。唯一的区别在于 karmada-controller-manager 负责所有 Push 模式集群的资源分发,而 karmada-agent 只负责它所在那一个 Pull 模式集群。因此, 在高并发条件下发资源的过程中,Pull 在相同配置条件下会比 Push 模式更快。你也可以通过调整 karmada-controller-manager 的–concurrent-work-syncs的参数来调整同一时间段内并发 work 的数量来提升性能。
Push 模式和 Pull 模式的资源使用量对比
在 Karmada 1.3 版本中,我们做了许多工作来减少 Karmada 管理大型集群的资源使用量。现在我们很高兴宣布,相比于 1.2 版本,Karmada 1.3 在大规模场景下减少了 85% 的内存消耗和 32% 的 CPU 消耗。总的来说, Pull 模式在内存使用上有明显的优势,而在其他资源上相差的不大。
在 Push 模式中,控制面的资源消耗主要集中在 karmada-controller-manager,而 karmada-apiserver 的压力不大。
从 karmada-apiserver 的 qps 以及 karmada-etcd 的请求时延我们可以看出 karmada-apiserver 的请求量保持在一个较低的水平。在 Push 模式中,绝大多数的请求来自 karmada-controller-manager。你可以配置–kube-api-qps and –kube-api-burst这两个参数来控制请求数在一个确定的范围内。
在 Pull 模式中,控制面的资源消耗主要集中在 karmada-apiserver,而不是 karmada-controller-manager。
从 karmada-apiserver 的 qps 以及 karmada-etcd 的请求时延我们可以看出 karmada-apiserver 的请求量保持在一个较高的水平。在 Pull 模式中,每个成员集群的 karmada-agent 需要维持一个与 karmada-apiserver 通信的长连接。我们很容易得出:在下发应用至所有集群的过程中 karmada-apiserver 的请求总量是是 karmada-agent 中配置的 N 倍(N=#Num of clusters)。因此,在大规模 Pull 模式集群的场景下,我们建议增加 karmada-apiserver 的–max-requests-inflight以及–max-mutating-requests-inflight参数的值,和 karmada-etcd 的–quota-backend-bytes参数的值来提升控制面的吞吐量。
现在 Karmada 提供了集群资源模型[3]的能力来基于集群空闲资源做调度决策。在资源建模的过程中,它会收集所有集群的节点与 Pod 的信息。这在大规模场景下会有一定的内存消耗。如果你不使用这个能力,你可以关闭集群资源建模[4]来进一步减少资源消耗。
总结与展望
根据测试结果分析,Karmada可以稳定支持100个大规模集群,管理超过50万个节点和200万个Pod。
在使用场景方面,Push模式适用于管理公有云上的Kubernetes集群,而Pull模式相对于Push模式涵盖了私有云和边缘相关的场景。在性能和安全性方面,Pull模式的整体性能要优于Push模式。每个集群由集群中的karmada-agent组件管理,且完全隔离。但是,Pull模式在提升性能的同时,也需要相应提升karmada-apiserver和karmada-etcd的性能,以应对大流量、高并发场景下的挑战。具体方法请参考kubernetes对大规模集群的优化。一般来说,用户可以根据使用场景选择不同的部署模式,通过参数调优等手段来提升整个多集群系统的性能。
由于测试环境和测试工具的限制,本次测试尚未测试到Karmada多集群系统的上限,同时多集群系统的性能测试仍处于方兴未艾的阶段,下一步我们将继续优化多集群系统的测试工具,系统性地整理测试方法,以覆盖更大的规模和更多的场景。
参考资料
[1]https://github.com/kubernetes/perf-tests/blob/master/clusterloader2/docs/GETTING_STARTED.md: https://github.com/kubernetes/perf-tests/blob/master/clusterloader2/docs/GETTING_STARTED.md
[2]关闭集群资源建模: https://karmada.io/docs/next/userguide/scheduling/cluster-resources#disable-cluster-resource-modeling
[3]集群资源模型: https://karmada.io/docs/next/userguide/scheduling/cluster-resources
[4]关闭集群资源建模: https://karmada.io/docs/next/userguide/scheduling/cluster-resources#disable-cluster-resource-modeling
关注,第一时间了解华为云新鲜技术~
Maestral 是适用于 macOS 和 Linux 的轻量级开源 Dropbox 客户端。
系统要求
- macOS 10.13 或更高版本
- Linux
- Python 3.6 或更高版本
安装
Homebrew
如果你在系统上安装了 Homebrew,则可以使用以下方式安装:
$ brew install maestral
使用 PyPI 的 Python 包
请从 PyPI 下载并安装 Python 包:
$ python3 -m pip install --upgrade maestral
如果您打算使用图形用户界面,还需要在安装或升级期间指定 GUI 选项。 这将安装 前端、 和 :
$ python3 -m pip install ' maestral[gui] '
Docker 镜像
Docker 映像可用于 x86、arm/v7(32 位)和 arm64 平台:
英特尔工程师发布了最新的 “2022Q3”以及 “2022Q41 RC1” FFmpeg 补丁集,最新的补丁用于改进 FFmpeg 视频加速与英特尔图形,存放在英特尔的“cartwheel-ffmpeg” 仓库中。
“cartwheel-ffmpeg”仓库是英特尔开发者的暂存区,用于为 FFmpeg 贡献未合并的英特尔硬件补丁。换而言之,这是一个试验区,所有补丁都需要经过审查、适当的测试,最终才能合并到上游。
据外媒 Phoronix 介绍,最新的 2022Q3 系列 FFmpeg 补丁具有以下优化:
- 新增 Raptor Lake S 平台的 FFmpeg 支持
- ffmpeg-vaapi 添加了 av1 编码支持、
- ffmpeg-qsv vpp 缩放通过支持 EU、VDBOX 或 VEBOX 的 oneVPL 添加模型选择,用户可以使用“scale_mode”选项来选择硬件型号
- 对 H.265 QSV 编码的自适应 I/B 支持
- ffmpeg dnn:OpenVINO 完整的 GPU 检测和分类支持
- ffmpeg dnn:启用 Torch 库作为 FFmpeg DNN 后端之一
此外还有 2022Q41 RC1 系列补丁,但此系列目前尚无更改日志。
对于使用 Intel Arc Graphics 硬件的用户,Intel 的 FFmpeg cartwheel 可提供最新和最好的图像驱动支持。目前英特尔的大部分工程重点都放在 DG2/Alchemist 系列显卡的支持上。但在英特尔图形硬件上进行的测试结果显示: FFmpeg 补丁的优化范围可以追溯到带集成显卡的 Tigerlake / Icelake / JasperLake 架构上,甚至还有一些 Kabylake / Comet Lake 覆盖。
OpenStack 最新发布了一份 2022 年用户调查报告指出,OpenStack 部署在 2022 年达到了一个新的里程碑:现在拥有超过 4000 万个生产核心,与 2021 年相比增长了 60%,自 2020 年以来增长了 166%;且全球共有 300 多个公共云数据中心。
原因在于,对混合云环境和 Kubernetes 集成支持的依赖增加推动了指数增长。此项调查调基于 2021 年 8 月至 2022 年 8 月期间编目的 300 多个部署和 430 多个受访者的反馈。
“在权威人士质疑 OpenStack(世界第四大开源项目)是否已死之际,OpenInfra 基金会测得生产中的 OpenStack 内核数量达到前所未有的 4000 万个。核心服务(Nova、Neutron、Keystone、Glance 和 Ironic)的采用率仍然很高,但随着运营商发展其架构以适应新的工作负载,他们已转向 OpenStack 保护伞下的支持服务,包括 Octavia 和 Magnum。这些具体项目分别支持对混合云环境的依赖和与 Kubernetes 的集成,并作为生产就绪的 OpenStack 服务继续发展。”
各种规模的组织都在进行扩展以满足最终用户的需求。除了电信业外,OpenStack 已成为中国移动和 Verizon 等主要大型移动公司的中坚力量。日本即时通讯服务 LINE、按需云财务管理服务公司 Workday、沃尔玛实验室和雅虎以及许多其他小规模的公司也押注了 OpenStack。
另一方面,作为 OpenInfra 标准,Linux OpenStack Kubernetes Infrastructure (LOKI) 正在以越来越快的速度在生产中实现。Kubernetes 现在部署在超过 85% 的 OpenStack 部署中:73% 通过 vanilla Kubernetes,另外 12% 通过 OpenShift。OpenStack 容器编排服务 Magnum 也越来越受欢迎,现有 21% 的用户使用它运行生产工作负载 (去年仅为 16%)。
调查还指出,运行混合云环境和 OpenStack 部署的受访者也从 77% 上升到了 80%。为了实现工作负载在不同云环境之间的平稳过渡,越来越多的运营商转向 Octavia —— 一种开源的、运营商规模的负载平衡解决方案,旨在与 OpenStack 配合使用。如今已有几乎一半的生产部署都在生产中运行 Octavia,相较去年增加了 11%。
用户满意度上,OpenStack 表现稳定,NPS 为 41。用户称赞社区”能够培养和回馈的纯粹的技术人才”,并将”社区的鼓励和支持”以及项目的”社区驱动”性质列为其最大的优势。
但受访者也表示,升级仍然是头号痛点;基于此,社区决定将在下一个版本开始进行重大改变,以缓解 OpenStack 升级过程中的一些复杂问题。此外,社区还在致力于仪表板改进、项目文档改进和降低 OpenStack 的整体复杂性。
更多详情可查看完整报告。
在今年 8 月,黑客通过泄露的官方开发者账户入侵了 LastPass 的开发者环境,窃取了 LastPass 的源代码和专有技术。但那次泄漏事件仅发生在开发环境中,并没有牵涉到用户信息和用户保险库,因此用户的信息在那次事件中没有受到影响(了解此次事件)。
短短三个月,如今 LastPass 再次遭遇数据泄露,这一次用户数据没能幸免于难。
根据 LastPass 首席执行官 Karim Toubba 以及官方社交媒体披露的信息,黑客访问了 LastPass 使用的第三方云存储服务,并获得了能够访问客户信息特定素的权限。
LastPass 目前并没有公布黑客获取了哪些信息,以及有多少用户受到影响,不过 Karim Toubba 强调用户的密码并没有被泄露。
我们最近在第三方云存储服务中检测到了不寻常的活动,目前 LastPass 和它的附属公司 GoTo 都共享这个服务。由于 LastPass 的 Zero Knowledge 架构,用户的密码仍然被安全加密。
即只有用户知道他们的主密码,加密只发生在设备层面,而不是服务器端。
此次事件并非独立事件,因为此次事件与今年 8 月的数据泄露存在联系,Karim Toubba 在公告中表示,黑客利用了今年 8 月事件中获得的信息,才最终获得了对用户数据的访问。
目前 LastPass 正在展开调查以了解事件的影响范围,并确定具体有哪些用户信息被访问了,LastPass 产品和服务仍在正常运行。LastPass 将在基础设施中部署更强的安全措施和监控功能,以帮助检测和防止进一步的黑客活动。
报道称,自从 Covid-19 爆发以来,软件开发者的「职业倦怠」已经达到了一个临界点。Haystack Analytics 是一家专门研究工程师生产力的公司,其最近的一项研究发现,83% 的软件开发者感到“职业倦怠”。该公司解释导致此问题的主要原因是工作量大 (47%),流程效率低下 (31%),以及目标和指标不明确( 29%)。
职业倦怠(又称“工作倦怠”,“职业疲溃”;Job burnout),包含
衰竭(exhaustion,心理资源的损耗,缺乏激情和动力,精力耗竭)、
沮丧(负面情绪)和
怠慢(cynicism),三者将降低职业效率。更为精确地定义,“倦怠是一种由长期的过度的压力导致的情绪、精神和身体的疲劳状态”。情绪方面的倦怠是指情感资源的耗竭,继而怠慢由此发源;怠慢表现为对工作的冷漠和距离感,而降低的专业效能指对过去的/现在的期望的满足感的缺乏。
—— 摘自维基百科
近几年远程办公的流行使得企业在大多数情况下提升了生产率,有人甚至预计在未来两到三年内总生产力将提升 17%。92% 的企业预计在未来两到三年内会进一步节省开支。
不过,Haystack Analytics 调查得到的数据显示,在 Covid-19 大流行期间,企业为了保持或提升生产力而采取的方案和执行的措施对开发者并不友好。他们发现 83% 的软件开发者感到“职业倦怠”。而导致此问题的主要原因是工作量增加。除此之外,他们还列举了其他原因,例如流程效率低下 (31%) 和目标不明确 (29%)。该研究还显示,83% 的开发者会担心软件在其工作场所的可靠性,其中 20% 的开发者主要关注软件本身的可靠性。
Haystack Analytics 表示,软件开发者的职业倦怠情况比他们设计这项研究时预想的要严重得多。这引起了他们对在日常生活和关键国家基础设施中发挥重要作用的软件质量的严重担忧。
作者:谢奇璇
React 官方对 Server Comopnent 是这样介绍的: zero-bundle-size React Server Components。
这是一种实验性探索,但相信该探索是个未来 React 发展的方向,与 React Server Component 相关的周边生态正在积极的建设当中。
术语介绍
在 React Server Component (以下称 Server Component) 推出之后,我们可以简单的将 React 组件区分为以下三种:
Client Component 客户端渲染组件,拥有交互性。
Share Component 既可以在服务端渲染,又可以在客户端渲染。具体如何渲染取决于谁引入了它。当被服务端组件引入的时候会由服务端渲染当被客户端组件引入的时候会由客户端渲染。
React 官方暂定通过「文件名后缀」来区分这三种组件:
- 需要以 为后缀
- 需要以 为后缀
- 以 为后缀
混合渲染
简单来说 Server Component 是在服务端渲染的组件,而 Client Component 是在客户端渲染的组件。
与类似 SSR , React 在服务端将 Server Component 渲染好后传输给客户端,客户端接受到 HTML 和 JS Bundle 后进行组件的事件绑定。不同的是:Server Component 只进行服务端渲染,不会进行浏览器端的 hyration(注水),总的来说页面由 Client Component 和 Server Component 混合渲染。
这种渲染思路有点像 Islands 架构,但又有点不太一样。
如图:橙色为 Server Component, 蓝色为 Client Component 。
React 是进行混合渲染的?
React 官方提供了一个简单的 Demo , 通过 Demo,探索一下React sever component的运作原理。
渲染入口
浏览器请求到 HTML 后,请求入口文件 – main.js, 里面包含了 React Runtime 与 Client Root,Client Root 执行创建一个 Context,用来保存客户端状态,与此同时,客户端向服务端发出 请求。
看出这里没有渲染任何真实的 DOM, 真正的渲染会等 response 返回 Component 后才开始。
请求服务端组件
Client Root 代码执行后,浏览器会向服务端发送一个带有 data 数据的请求,服务端接收到请求,则进行服务端渲染。
服务端将从 Server Component Root 开始渲染,一颗混合组件树将在服务端渲染成一个巨大的 VNode。
如图,这一颗混合组件树会被渲染成这样一个对象,它带有 React 组件所有必要的信息。
不仅仅是这样一个对象, 由于 Client Comopnent 需要 Hydration, React 会将这部分必须要的信息也返回回去。React 最终会返回一个可解析的 Json 序列 Map。
- M: 代表 Client Comopnent 所需的 Chunk 信息
- J: 代表 Server Compnent 渲染出的类 react element格式的字符串
React Runtime 渲染
组件数据返回给浏览器后,React Runtime 开始工作,将返回的 VNode 渲染出真正的 HTML。与此同时,发出请求,请求 Client Component 所需的 JS Bundle。当浏览器请求到 Js Bundle 后,React 就可以进行选择性 Hydration(Selective Hydration)。需要注意的是, React 团队传输组件数据选择了流式传输,这也意味着 React Runtime 无需等待所有数据获取完后才开始处理数据。
启动流程
- 浏览器加载 React Runtime, Client Root 等 js 代码
- 执行 Client Root 代码,向服务端发出请求
- 服务端接收到请求,开始渲染组件树
- 服务端将渲染好的组件树以字符串的信息返回给浏览器
- React Runtime 开始渲染组件且向服务端请求 Client Component Js Bundle 进行选择性 Hydration(注水)
Client <-> Server 如何通信?
Client Component 与 Server Component 有着天然的环境隔离,他们是如何互相通信的呢?
Server Component -> Client Component
在服务端的渲染都是从 Server Root Component 开始的,Server Component 可以简单的通过 props 向 Client Component 传递数据。
但需要注意的是:这里传递的数据必须是可序列化的,也就是说你无法通过传递 Function 等数据。
Client Component -> Server Component
Client Component 组件通过 HTTP 向服务端组件传输信息。Server Component 通过 props 的信息接收数据,当 Server Component 拿到新的 props 时会进行重新渲染, 之后通过网络的手段发送给浏览器,通过 React Runtime 渲染在浏览器渲染出最新的 Server Component UI。这也是 Server Component 非常明显的劣势:渲染流程极度依赖网络。
Server Component 所带来的优势
RSC 推出的背景是 React 官方想要更好的用户体验,更低的维护成本,更高的性能。通常情况下这三者不能同时获得,但 React 团队觉得「小孩子才做选择,我全都要」。
根据官方提出 RFC: React Server Components,可以通过以下几点能够看出 React 团队是如何做到”全都要”的:
更小的 Bundle 体积
通常情况下,我们在前端开发上使用很多依赖包,但实际上这些依赖包的引入会增大代码体积,增加 bundle 加载时间,降低用户首屏加载的体验。
例如在页面上渲染 ,我们不得不引入相应的渲染库,以下面的 demo 为例,不知不觉我们引入了 240 kb 的 js 代码,而且往往这种大型第三方类库是没办法进行 tree-shaking。
可以想象,为了某一个计算任务,我们需要将大型 js 第三方库传输到用户浏览器上,浏览器再进行解析执行它来创造计算任务的 runtime, 最后才是计算。从用户的角度来讲:「我还没见到网页内容,你就占用了我较大带宽和 CPU 资源,是何居心」。然而这一切都是可以省去的,我们可以利用 SSR 让 React 在服务端先渲染,再将渲染后的 html 发送给用户。从这一方面看,Server Component 和 SSR 很类似,但不同的是 SSR 只能适用于首页渲染,Server Component 在用户交互的过程中也是服务端渲染,Server Component 传输的也不是 html 文本,而是 json。Server Component 在服务端渲染好之后会将一段类 React 组件 json 数据发送给浏览器,浏览器中的 React Runtime 接收到这段 json 数据 后,将它渲染成 HTML。
我们举一个更加极端的例子:若用户无交互性组件,所以组件都可以在服务端渲染,那么所有 UI 渲染都将走「浏览器接收”类 react element 文本格式”的数据,React Runtime 渲染」的形式进行渲染。 那么除了一些 Runtime, 我们无需其他 JS Bundle。而 Runtime 的体积是不会随着项目的增大而增大的,这种常数系数级体积也可以称为 “Zero-Bundle-Size”。因此官方这称为: “Zero-Bundle-Size Components”。
更好的使用服务端能力
为了获取数据,前端通常需要请求后端接口,这是因为浏览器是没办法直接访问数据库的。但既然我们都借助服务端的能力了,那我们当然可以直接访问数据库,React 在服务器上将数据渲染进组件。
通过自由整合后端能力,我们可以解决:「网络往返过多」和「数据冗余」问题。甚至我们可以根据业务场景自由地决定数据存储位置,是存储在内存中、还是存储在文件中或者存储在数据库。除了数据获取,还可以再开一些”脑洞”。
- 我们可以在 Server Component 的渲染过程中将一些高性能计算任务交付给其他语言,如 C++,Rust。这不是必须的,但你可以这么做。
- ……
简单粗暴一点的说:Nodejs 拥有什么样的能力,你的组件就能拥有什么能力。
更好的自动化 Code Split
在过去,我们可以通过 React 提供的 lazy + Suspense 进行代码分割。这种方案在某些场景(如 SSR)下无法使用,社区比较成熟的方案是使用第三方类库 。然而无论是使用哪一种,都会有以下两个问题:
- Code Split 需要用户进行手动分割,自行确认分割点。
- 与其说是 Code Split,其实更偏向懒加载。也就是说,只有加载到了代码切割点,我们才会去即时加载所切割好的代码。这里还是存在一个加载等待的问题,削减了code split给性能所带来的好处。
React核心团队所提出 Server Component 可以帮助我们解决上面的两个问题。
- React Server Component 将所有 Client Component 的导入视为潜在的分割点。也就是说,你只需要正常的按分模块思维去组织你的代码。React 会自动帮你分割
- 框架侧可以介入 Server Component 的渲染结果,因此上层框架可以根据当前请求的上下文来预测用户的下一个动作,从而去「预加载」对应的js代码。
避免高度抽象所带来的性能负担
React server component通过在服务器上的实时编译和渲染,将抽象层在服务器进行剥离,从而降低了抽象层在客户端运行时所带来的性能开销。
举个例子,如果一个组件为了可配置行,被多个 wrapper 包了很多层。但事实上,这些代码最终只是渲染为一个。如果把这个组件改造为 server component 的话,那么我们只需要往客户端返回一个字符串即可。下面例子,我们通过把这个组件改造为server component,那么,我们大大降低网络传输的资源大小和客户端运行时的性能开销:
参考自: https://juejin.cn/post/0#heading-5
我们可以通过在 Server Component ,将 HOC 组件进行渲染,可能渲染到最后只是一个 我们就无需将 bundle 传输过去,也无需让浏览器消耗性能去渲染。
Sever Component 可能存在的劣势
弱网情况下的交互体验
如上文所述: React Server Component 的逻辑, 他的渲染流程依靠网络。服务端渲染完毕后将类 React 组件字符串的数据传输给浏览器,浏览器中的 Runtime React 再进行渲染。显然,在弱网环境下,数据传输会很慢,渲染也会因为网速而推迟,极大的降低了用户的体验。Server Component 比较难能可贵的是,它跟其他技术并不是互斥的,而是可以结合到一块。例如:我们完全可以将 Server Component 的计算渲染放在边缘设备上进行计算,在一定程度上能给降低网络延迟带来的问题。
开发者的心智负担
在 React Server Component 推出之后,开发者在开发的过程中需要去思考: 「我这个组件是 Server Component 还是 Client Component」,在这一方面会给开发者增加额外的心智负担,笔者在写 Demo 时深有体会,思维上总是有点不习惯。Nextjs 前一段时间发布了 v13,目前已实现了 Server & Client Component 。参考 Next13 的方案,默认情况下开发者开发的组件都是 Server Component ,当你判断这个组件需要交互或者调用 DOM, BOM 相关 API 时,则标记组件为 Client Component。
「默认走 Server Component,若有交互需要则走 Client Component」 通过这种原则,相信在一定程度上能给减轻开发者的心智负担。
应用场景: 文档站
从上面我们可以知道 Server Component 在轻交互性的场景下能够发挥它的优势来,轻交互的场景一般我们能想到文档站。来看一个小 Demo, 通过这个 Demo 我们观察到几个现象:
- 极小的 Js bundle。
- 文件修改无需 Bundle。
当然像文档站等偏向静态的页面更适合 SSR, SSG,但就像前面所说的它并不与其他的技术互斥,我们可以将其进行结合,更况且他不仅仅能应用于这样的静态场景。
参考文档
- 【react】初探server component
- Introducing Zero-Bundle-Size React Server Components
- RFC: React Server Components
撰文 | 郑建华
更新|赵露阳、王迎港
深度学习框架一般通过自动微分(autograd)机制计算梯度并反向传播。本文尝试通过一个简单的例子,粗浅地观察一下OneFlow的autograd的实现机制。
1
自动微分基础
自动微分相关的资料比较多,个人感觉自动微分的原理介绍( https://sigusoft.com/s/BwQxmNoSBEnUlJ1luOwDag )这个系列及其引用的资料对相关背景知识的介绍比较完整清晰。
下面分几种情况对梯度传播的原理做一些直观解释。
1.1 stack网络的梯度传播
以x -> f -> g -> z这个stack网络为例,根据链式法则:
实际运行时,在梯度反向传播过程中:
-
z将∂z/∂g传给g。
-
如果节点g有权重w需要计算梯度,就计算∂z/∂w = ∂z/∂g * ∂g/∂w。
-
g需要计算∂g/∂f,再乘以z传过来的梯度,将结果传给f。g只需要给f传递链式乘积的结果,不需要传递各项明细。
-
在训练阶段的前向计算时,g需要保存∂g/∂f计算依赖的中间结果、以供反向计算时使用。
-
其它节点的传播情况依次类推。
1.2 简单graph的梯度传播
以下面这个简单的graph拓扑为例。
在继续之前,需要了解一下多复合函数微分的基本公式。
下图中,u和v都是关于x和y的函数,z是关于u和v的函数。
根据这个公式可以知道,z对x的梯度分别沿两条链路传播,z -> u -> x和z -> v -> x,节点x将两个梯度之和作为z对x的梯度。
1.3 复杂graph的梯度传播
再看一个拓扑稍微复杂点的例子:
上图可以视为x -> U -> L,其中U是e -> … -> h的子图。f -> g的子图可以视为V。
对于节点h来说,它需要把梯度传给g和k。 对节点e来说,它需要对f和k传来的梯度求和,才是∂L/∂e。 这样,L对x的梯度,仍可以按链路拆解,一条链路前后节点间的梯度是乘积关系,传入的多条链路梯度是加和关系。
这篇博客( https://blog.paperspace.com/pytorch-101-understanding-graphs-and-automatic-differentiation/) 中有一个几乎一样的拓扑图,给出了部分权重参数的梯度公式。
2
autograd中tensor相关的一些基本概念
2.1 叶子节点
OneFlow的autograd文档( https://docs.oneflow.org/en/master/basics/05_autograd.html )中介绍了leaf node和root node的概念。只有输出、没有输入的是leaf node,只有输入、没有输出的是root node。
个人理解,如果把weight、bias、data视为计算图的一部分,这些节点就是叶子节点(op不是叶子节点)。尤其是从反向计算图的视角( https://discuss.pytorch.org/t/what-is-the-purpose-of-is-leaf/87000/9 )看,这些节点的grad_fn是空,反向传播到这些节点就会停止。
is_leaf和requires_grad有比较密切的关系,但二者又是独立的。PyTorch是这样解释的:( https://pytorch.org/docs/stable/generated/torch.Tensor.is_leaf.html#torch.Tensor.is_leaf )
-
requires_grad=false的节点都是叶子节点。比如data。
-
requires_grad=true的节点如果是用户创建的,也是叶子节点。比如weight和bias。
-
在梯度的反向计算过程中,只有叶子节点的梯度才会被填充。对于非叶子节点,如果要填充梯度信息,需要显式设置retain_grad=true。
-
requires_grad=true才会计算、填充梯度。比如y = relu(x),y是op创建的、不是叶子节点。但如果x需要计算梯度,则y.requires_grad==true。但不需要为y填充梯度。
关于叶子节点这个概念,目前找到的主要是直观描述,还没看到严格、清晰的定义。也可能是因为用户一般不会直接使用is_leaf( https://discuss.pytorch.org/t/what-is-the-purpose-of-is-leaf/87000/9 ),这个概念只是在阅读代码的时候才会涉及到。
下面的资料可以供进一步参考:
-
What is the purpose of `is_leaf`? ( https://discuss.pytorch.org/t/what-is-the-purpose-of-is-leaf/87000 )
-
叶子节点和tensor的requires_grad参数( https://zhuanlan.zhihu.com/p/ )
2.2 tensor detach
Tensor的detach方法( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/tensor_impl.cpp#L155 )会创建一个新的tensor,新tensor的属性中
-
requires_grad = false
-
is_leaf = true
detach的意思是从grad的反向计算图中把tensor分离出来。新的tensor与原来的对象共享存储,但不参与反向图的拓扑构造。原有对象的requires_grad属性不变。
比如下面的代码,修改一个对象的数据,另一个对象的数据也会改变。
3
示例代码
本文通过如下代码来观察OneFlow的autograd机制。
y.backward方法有两种接口:
-
如果y是一个标量(比如loss),不需要传递任何参数。
-
如果y是一个向量,需要传入一个与y的shape一致的向量作为参数。
为什么会有这种区别呢?下面几篇参考资料中对这个问题做了比较详细的解释。简单的说:
-
如果函数的输出是向量,在反向传播的过程中会造成梯度tensor shape的维度膨胀,实现复杂、性能差。
-
如果函数的输出是标量,反向传播梯度tensor的shape与参数变量的shape一致,不会出现维度膨胀,更容易实现。
-
对于向量版本的backward,可以假想存在某个loss函数,backward的参数是loss传播到y这里的梯度。因为前后节点间的梯度是乘积关系,所以用ones替代这个假想的梯度,这样计算结果x.grad就是y对x的梯度。
后续将以y.backward(flow.Tensor([1, 1]))为例观察一下autograd的机制。其反向图只有x <- y这一步。
参考资料
-
自动求梯度 ( https://tangshusen.me/Dive-into-DL-PyTorch/#/chapter02_prerequisite/2.3_autograd?id=_233-梯度 )
-
PyTorch 的 backward 为什么有一个 grad_variables 参数?( https://zhuanlan.zhihu.com/p/ )
3.1 梯度结果的存储
Tensor的grad属性( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/api/python/framework/tensor.cpp#L611 ),在读取值时调用的是acc_grad()方法(acc应该是accumulate的缩写)。这样就知道梯度实际存储在哪里,读代码时可以重点关注相关部分。
调用流程如下:
注:图片中的MirroredTensor在最新源码中,已经更名为LocalTensor,其实是一样的。
4
autograd相关的类图关系
下图展示了autograd相关类的关系
在看autograd代码之前,可以参照这个类图,了解其中的结构和关系,有助于理解代码中各个部分的作用。
在eager模式下,用户通过op的组合逐步构建出前向计算图。在执行前向计算的过程中,引擎会为autograd需要的反向计算图记录必要的信息,在调用backward方法时执行这个反向计算图。
对照上面的类图
-
站在tensor的视角
-
-
前向op输出一个tensor y,即TensorIf <- ReluFunctor这部分。
-
从y可以找到反向计算图实际执行梯度计算的类,即TensorIf -> FunctionNode -> ReLU这个链路。
-
FunctionNode的backward_fn_包含了OpExprGradClosure。它只负责计算当前节点的梯度。
-
ReLU是执行梯度计算的类,它会调用ReluGradFunctor这个op来执行梯度计算。
-
-
站在反向图存储的视角
-
-
反向图相关的信息在FunctionNode中保存。
-
反向计算图的root是tensor(比如y或loss)的grad_fn_node_变量。
-
FunctionNode的next_functions_表示反向图的下游节点,当前节点把梯度结果传给这些下游节点。这些FunctionNode的连接就构成了反向图的拓扑结构。
-
tensor的梯度存储路径是TensorImpl.AutogradMeta.acc_grad_
-
AutogradMeta.current_grad_是反向图上游传递到当前节点的梯度合计。如果tensor t输入给op u和v,那么u和v反传的梯度会累加到current_grad_。current应该表示截至当前正在计算时的累加和。
-
FunctionNode虽然并不持有tensor实例,但它持有tensor的AutogradMeta成员变量指针。
-
基于上述relu的例子中的节点y
-
output_meta_data_即y.autograd_meta_
-
input_meta_data_即x.autograd_meta_
-
所以FunctionNode能获取到上下游的梯度数据并进行读写
-
AutoGradCaptureState可以存储一些梯度计算需要的状态信息,比如计算relu的梯度时需要用到它的前向输出结果y。
-
-
站在反向图执行的视角
-
-
GraphTask负责反向图的执行。
-
FunctionNode只保存必要的数据。
-
GraphTask基于这些数据,自己构造遍历需要的数据结构,遍历所有节点、执行梯度计算。
-
5
前向计算过程中为autograd所做的准备
反向图的执行过程是数据驱动的,数据的存储结构和内容决定了执行的具体动作。
以下讨论只针对eager模式。lazy模式下,反向图的构建是多轮优化passes的一部分( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter.cpp#L98 )。
之前在讨论Op、Kernel与解释器时已经了解Interpreter的作用。只是当时重点关注op的执行,忽略了grad相关的内容。
GetInterpreter( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter_util.cpp#L67 )返回的其实是一个AutogradInterpreter对象( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter_util.cpp#L42 ),在它的Apply方法中( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter.cpp#L86 ),调用内嵌Interpreter的同时,也会记录grad计算需要的信息。
AutogradInterpreter::Apply的主要流程如下:
Apply的第一步会先计算requires_grad。只要op的任一输入的requires_grad为true,op的输出的requires_grad也为true( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter.cpp#L151-L152 )(前提是输出的数据类型支持梯度)。y的requires_grad就是在这里决定的。
比如y = relu(x),如果数据类型支持梯度,y.requires_grad就等于x.requires_grad。
然后会调用内嵌的解释器internal_执行相关计算。在调用内嵌解释器期间,会临时禁止梯度模式,比如有些op可能会嵌套、多次调用解释器(ReluGradFunctor也会通过解释器执行),这些都不需要梯度逻辑。
需要说明的是,构造x时不会执行grad相关的逻辑,因为inputs的requires_grad都是false,x的requires_grad是在构造的最后才设置的( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/api/python/utils/tensor_utils.cpp#L187 )。
下面重点看一下几个核心函数的逻辑细节。
5.1 梯度闭包的构建
前面对类图的说明中已经提到,OpExprGradClosure只负责当前节点的梯度计算。
GetOrCreateOpGradClosure函数( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_expr.cpp#L146 )的核心代码如下:
NewObj会调用AutoRegistrationFactory( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/common/auto_registration_factory.h#L94 )获取预先注册的工厂、创建对象。之前在讨论Op指令在虚拟机中的执行时也看到过类似的注册机制。
这里op_type_name的值是relu,在代码中搜索”relu”,可以找到注册ReLU的宏( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/gradient_funcs/activation.cpp#L562 )。宏展开后的代码如下:
所以实际返回的对象是ReLU(h ttps://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/gradient_funcs/activation.cpp#L200 )。其Init函数是个空操作。
OpExprGradClosure只是简单的把ReLU存下来供backward执行时调用。 整个调用流程如下:
5.2 捕获梯度计算需要的数据
调用流程如下:
Capture函数( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter.cpp#L122 )的作用就是为后续的梯度计算保存必要的数据。
需要注意的是,OpExprGradFunction::CaptureIf( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_expr_grad_function.h#L93 )中保存的是detach的tensor。这些tensor与原来的tensor共享数据;可以读写梯度数据,但不会参与反向图的拓扑构造。这个函数把Interpreter传过来的op的detached outputs传给ReLU::Capture( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_expr_grad_function.h#L128 )(就是relu的前向输出y),ReLU::Capture就把output[0]存到ReLUCaptureState的saved_tensors_中( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/gradient_funcs/activation.cpp#L209 )。因为对于relu来说,根据y就可以计算梯度。
5.3 保存反向图结构信息
AutogradInterpreter::Apply中会构造一个lambada表达式backward_fn( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter.cpp#L103-L110 ),其核心逻辑只有一行grad_closure->Apply。
这个lambda的主要作用就是捕获grad_closure这个智能指针。lambda表达式最终会作为FunctionNode的backward_fn_变量。这样才有类图中FunctionNode到OpExprGradClosure这条线,才能从FunctionNode找到closue、执行节点的梯度计算。
GetThreadLocalAutogradEngine()->AddNode这个函数( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter.cpp#L113 )很关键,AddNode的主要任务(h ttps://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L478 )是为inputs和outputs创建FunctionNode、并保存反向图遍历需要的数据。其输入参数中的inputs/outputs,是前向计算的op的inputs/outputs。 对于relu来说,inputs就是x,outputs就是y。
在上述示例代码中,对于x,因为它是叶子节点、也需要梯度,在AddAccumulateFunctionNode会将grad_fn_node设置为一个空操作的函数( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L508 )。之所以是空操作,是因为叶子节点只需要存储梯度、不需要自己计算梯度;它所需要的梯度计算结果会由反向图的上游节点保存到x.autograd_meta_中。
之后会为y构造GraphFunctionNode并形成节点连接( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L491 )、并保存到grad_fn_node( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L495 )。需要注意的是,这里的backward_fn就是AutogradInterpreter::Apply中的lambda表达式( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter.cpp#L103-L109 )。
需要注意的是,AddBackwardFuncPtr中的inputs/outputs是针对op而言,GraphFunctionNode构造函数中同名变量的是针对FunctionNode而言,二者的含义和指向的对象是不一样的。
构造完成后,x和y的grad_fn_node_字段数据内容如下:
backward就是根据这些数据,从roots出发,完成反向图的遍历。
6
backward的入口
在《OneFlow源码阅读4:tensor类型体系与local tensor》(https://segmentfault.com/a/89895)中提到过,Tensor类在Python端经过一层包装,通过Python机制为Tensor类注册一些方法,backward就是包装的方法之一。
相关的源代码文件如下
-
python/oneflow/framework/tensor.py
-
python/oneflow/autograd/__init__.py
-
oneflow/python/oneflow/autograd/autograd.py
-
oneflow/api/python/autograd/autograd.cpp
C++的调用流程如下:
这里重复一下本文使用的示例代码:
上述示例代码执行时,Backward( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/api/python/autograd/autograd.cpp#L90 )的主要参数的值如下:
-
outputs: y, relu输出的tensor
-
out_grads: [1, 1]
CheckAndInitOutGrads( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/api/python/autograd/autograd.cpp#L49 )返回的是loss通过当前op、传到当前节点的梯度。其部分逻辑就是第3节讨论的
-
如果y是一个向量,backward必须传入一个与y的shape一致的向量(https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/api/python/autograd/autograd.cpp#L72-L81)。
-
如果y是一个标量,backward不要参数,框架会自动构造一个全1的tensor(https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/api/python/autograd/autograd.cpp#L70)。
7
反向计算中GraphAutogradEngine的调用流程
反向图计算的流程分析可以结合3类信息
-
流程代码
-
上述x和y的grad_fn_node_的值
-
类图以及类之间的关系
RunBackwardAndSaveGrads4LeafTensor( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L445 )函数的几个参数是:
-
outputs: relu的输出y
-
out_grads: 用户自己构造的ones [1, 1]
7.1 反向传递过来的梯度的累加
RunBackwardAndSaveGrads4LeafTensor( https://github.com/Oneflow-Inc/oneflow/blob/release/0.7.0/oneflow/core/autograd/autograd_engine.cpp#L447)函数中,PushPartialTensor(https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L450 )的作用就是将loss传过来的梯度累加到autograd_meta_.current_grad_.acc_tensor_。第4节中提到,TensorArg.acc_tensor_存储的就是loss传过来的梯度的合计。这就是roots(即y)接收到的梯度,要么是框架自动创建的ones,要么是用户提供的梯度(通常也是ones)。
这行代码的逻辑可以用如下伪码表示
7.2 反向图计算任务的构造与执行
FunctionNode只是记录了反向图的基础信息。RunBackwardAndSaveGrads4LeafTensor中会再构造一个GraphTask对象来表示一次反向计算任务。
-
GraphTask的构造函数( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L452 )主要是初始化反向图的roots_节点,并将图中各个节点的依赖计数dependencies_置为0。根据示例代码,roots_就是y(通常是loss)。
-
ComputeDependencies( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L321 )会对反向图进行深度优先遍历、统计图中各个节点的依赖计数。
-
GraphTask::Apply( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L405 )中实现了反向图的遍历逻辑(传入的save_grad_for_leaf参数是true)。当FunctionNode的依赖为0时,节点才会被放入执行队列( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L439 ),后续会对反向图执行按拓扑序遍历。FunctionNode::Apply执行时,它的依赖都执行完毕了。GraphTack::Apply这个函数中,涉及梯度计算逻辑主要包括两部分:
-
-
调用node->Apply执行单个节点的梯度计算( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L421 )
-
调用node->AccGrad4LeafTensor存储算好的梯度( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L430 )
-
7.3 节点的梯度计算
FunctionNode::Apply( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L187 )中,处理output_meta_data_的for循环( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L195-L205 )的核心逻辑可以用如下伪码表示:
从中可以看出来,output_grads的作用就是拷贝上游传过来的梯度数据(指针),作为backward_fn_的参数。
后面可以看到,backward_fn( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L206 )的核心逻辑是:
input_grads就是当前节点传给下游节点的梯度,调用backward_fn时会对它进行赋值。
处理input_meta_data的for循环的核心逻辑( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L214 )可以用如下伪码表示。实质就是将当前节点传给下游节点的梯度,累加到下游节点的current_grad上,从而实现梯度的传播。如果tensor输入给多个op,每个op的梯度会加起来。
7.3.1 梯度计算的执行:backward_fn
以下只考虑前述示例的root节点的执行。也就是y对应的FunctionNode。对于y来说,backward_fn就是AutogradInterpreter::Apply中定义的lambda表达式( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/framework/op_interpreter/op_interpreter.cpp#L103-L110 )。
对于relu来说,执行过程如下:
之前在5.1节已经确认,OpExprGradClosure::impl_就是ReLU( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/gradient_funcs/activation.cpp#L200 )。
如前所述,backward_fn的参数中,output_grads是上游传过来的梯度数据,backward_fn需要计算relu的梯度,二者的乘积赋值给in_grads。这些参数会一直传递到ReLU::Apply( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/gradient_funcs/activation.cpp#L213 )。
functional::ReluGrad( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/gradient_funcs/activation.cpp#L219 )的Functor名字是ReluGrad。对应的Functor是ReluGradFunctor( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/functional/impl/activation_functor.cpp#L61 )(命名空间是oneflow::one::functional::impl)。
ReluGradFunctor之后,是基于Primitive kernel实现的计算逻辑。ReluGradFunctor中对应op名字是”relu_grad”,这个relu_grad的注册被包在一个宏定义( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/user/kernels/activation_kernels.cpp#L331 )中,实际上会返回一个BinaryPrimitiveKernel,这是一种稍显特殊的基于Primitive的kernel,其具体为 下的一种 BroadcastElementwiseBinary 工厂( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/user/kernels/activation_kernels.cpp#L337-L339 ),其对应的cpu和cuda注册分别位于:
-
oneflow/core/ep/cpu/primitive/broadcast_elementwise_binary.cpp
-
oneflow/core/ep/cuda/primitive/broadcast_elementwise_binary.cu
最终实现位于 ( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/ep/common/primitive/binary_functor.h#L354 ):
至此,完成了梯度计算的逻辑。
7.4 梯度的存储
FunctionNode::Apply执行完毕后,GraphTask::Apply调用FunctionNode::AccGrad4LeafTensor( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L430 )为叶子节点拷贝梯度数据。
在上述例子中,因为y不是叶子节点,处理到y.grad_fn_node_时不会进行实质处理。对于x,会调用CopyOrAccGrad( https://github.com/Oneflow-Inc/oneflow/blob/48e511e40e0c96722c09bd061ce/oneflow/core/autograd/autograd_engine.cpp#L84 ),这个函数逻辑的伪码形式如下
autograd_meta.acc_grad_就是Python端读到的x的梯度。
参考资料
-
https://github.com/Oneflow-Inc/oneflow/tree/48e511e40e0c96722c09bd061ce
-
OneFlow学习笔记:Autograd解析
-
自动微分的原理介绍
-
自动求梯度 ( https://tangshusen.me/Dive-into-DL-PyTorch/#/chapter02_prerequisite/2.3_autograd?id=_233-梯度)
-
PyTorch 的 backward 为什么有一个 grad_variables 参数?( https://zhuanlan.zhihu.com/p/)
-
PyTorch 101, Part 1: Understanding Graphs, Automatic Differentiation and Autograd ( https://blog.paperspace.com/pytorch-101-understanding-graphs-and-automatic-differentiation/)
其他人都在看
-
Vision Transformer这两年
-
OneFlow源码解析:Global Tensor
-
更快的YOLOv5问世,附送全面中文解析教程
-
李白:你的模型权重很不错,可惜被我没收了
-
Stable Diffusion半秒出图;VLIW的前世今生
-
大模型狂潮背后:AI基础设施“老化”与改造工程
-
OneEmbedding:单卡 训练TB级推荐模型不是梦
欢迎Star、试用OneFlow最新版本:https://github.com/Oneflow-Inc/oneflow/
近年来,国际形势的风云变幻,对于科技领域,只有自己掌握核心关键技术,实现自主可控,才能摆脱越来越频繁的“卡脖子事件”,保证企业和国家信息安全。
俗话说“基础不牢,地动山摇“。大数据基础平台什么?是打地基的,是重中之重,地基扎得越深、打得越牢,上面的建筑才能越稳定。可以说,数字化转型的“万丈高楼”起于基础平台,具备自主可控的平台建设能力,是真正意义上一切的前提。
袋鼠云今年7月最新推出自研大数据基础平台EasyMR,该产品提供Hadoop、Hive、Spark、Trino、HBase、Kafka等组件的自动化安装、中心化管理与集群监控告警功能,完全兼容Apache开源生态,支持企业级安全管控,一键开启LDAP+Kerberos+Ranger认证权限体系,以及提供一站式运维管理平台。
结合袋鼠云在大数据领域多年的实践经验和沉淀积累,袋鼠云大数据基础平台EasyMR适配多种信创软硬件,可以更加自主化地帮助企业快速构建大数据平台,降低运维成本,极大提高集群管理效率。
一、EasyMR的系统架构
先来看看EasyMR的系统架构,由主体部分和监控告警组件共同构成:
EasyMR的主体部分由以下三部分构成:server端(matrix)、agent管控服务(easyagent-server)、agent管控客户端(sidecar):
matrix
matrix主要用于用户前端交互,将用户期望对大数据集群的对应运维操作通过web UI的方式呈献给用户,也可以通过这种方式将用户的运维指令下发到Hadoop集群中,比如安装HDFS Namenode、启动HDFS Namenode、停止HDFS Namenode等等,从而完成用户与Hadoop集群的交互。
matrix一般不部署在大数据服务节点上,是作为管控服务单独部署。
easyagent-server
作为matrix与easyagent-sidecar之间的中间服务,easyagent-server向上作为http服务端提供给业务层matrix一些restful接口,向下作为rpc服务端提供给底层easyagent-sidecar一些rpc接口供远程调用,从而将业务层与底层服务成功解耦。
并且支持高可用分布式部署,当集群压力增加时可以增加节点部署,缓解集群压力。与matrix一样,easyagent-server一般不部署在大数据服务节点上,是作为管控服务单独部署。
easyagent-sidecar
easyagent-sidecar是由golang语言开发,负责执行easyagent-server下发的指令,进行大数据基础服务的安装、部署、启动、停止、配置下发等操作。同时还负责进行集群内主机和服务监控信息以及心跳状态监控上报,当matrix检测到sidecar未及时上报心跳数据时在页面会显示主机状态异常。
虽然sidecar是与大数据集群最近的一个组件,但是它不保存任何跟集群相关的内容,只负责执行easyagent-server下发的命令以及自身主机与服务的心跳与健康检查上报。easyagent-sidecar部署在大数据服务节点上。
easyagent-server/easyagent-sidecar架构图
除了上述三种基础组件之外,EasyMR作为一个完备的大数据基础平台,对于集群的监控告警也引入了一些开源组件(prometheus、grafana),并根据需求对其进行了相应的二次开发,同时EasyMR还自研了专用告警通道发送组件(dt-alert):
prometheus
prometheus是由 SoundCloud 开源的监控告警解决方案,从 2012 年开始编写代码,2015 年在 GitHub 上开源,2016 年 Prometheus 成为继 Kubernetes 之后,CNCF (Cloud Native Computing Foundation)中的第二个项目成员,也是第二个正式毕业的项目,是新一代开源解决方案。
对于使用EasyMR接入过的主机以及使用EasyMR部署的大数据服务,我们会为其启动对应的prometheus exporter(如主机会使用node_exporter),prometheus会定期抓取主机与服务的监控数据并写入存储中,便于页面查询展示以及针对监控数据进行告警。
grafana
grafana是一个监控仪表系统,它是由 Grafana Labs 公司开源的系统监测 (System Monitoring) 工具。它可以极大地助力简化监控的复杂度,用户只需要提供需要监控的数据,它就可以帮助生成各种可视化仪表。同时它还有报警功能,可以在系统出现问题时做到及时通知。
EasyMR将开源版本的grafana进行了二次开发,做到无痕嵌入EasyMR UI中,大大丰富了监控图表的多样化展示。除此之外,对grafana的仪表盘配置告警规则后还可以对接自研的dt-alert组件进行告警发送。
DataNode监控大盘
dt-alert
dt-alert是袋鼠云自研的专用告警通道发送组件,原生支持邮件、短信、钉钉机器人、企业微信四种方式发送告警信息,同时也支持可扩展的自定义插件发送方式,用户可以根据我们设定的接口规范开发自定义插件发送告警信息到内部告警通道中。 添加告警通道
二、使用EasyMR部署Hadoop的操作原理
结合上述对EasyMR核心组件的描述,下文使用Hadoop集群的实例为大家说明,在使用EasyMR部署Hadoop时的底层操作原理:
Part.1
本地部署一套EasyMR服务,得到前端页面访问入口。
Part.2
通过前端页面进入主机接入页面进行主机接入操作,此时matrix会向easyagent-server发送请求在指定主机上安装easyagent-sidecar,easyagent-server会将安装脚本下发到对应主机,easyagent-sidecar安装完毕之后会通过回调的方式通知matrix,完成主机接入。
此外,EasyMR还会在主机上安装node_exporter,并将采集配置写入prometheus配置文件中,无需重启即可热加载配置进行主机监控数据采集。
Part.3
页面选中Hadoop产品包,根据提示进行前期配置触发部署操作,matrix也是通过easyagent-server向easyagent-sidecar发送下载安装包、解压安装、启动命令,启动完成之后easyagent-sidecar会定期对服务进行健康检查,并将结果通过easyagent-server上报到matrix。
与主机类似,EasyMR还会在主机上安装对应服务的prometheus exporter,并将采集配置写入prometheus配置文件中,无需重启即可热加载配置进行服务监控数据采集。
Part.4
进入仪表盘页面查看Hadoop服务的图表监控,此时查看的页面来自于iframe嵌入的grafana。
Part.5
对仪表盘进行监控告警配置并设置告警发送通道,那么当告警触发时(比如HDFS namenode full GC次数过大),grafana会调用dt-alert的接口将告警信息发送到用户指定的渠道。
三、EasyMR的能力优势
袋鼠云大数据基础平台EasyMR不仅拥有高效、完备的系统架构,还拥有更多的亮点优势,主要体现在以下三方面:
全面的国产化适配能力
外部环境渐趋复杂,我国正大力推进信创国产化的进程,逐步将CPU、操作系统、数据库等基础软硬件技术换成国内自主研发的技术,减少对国外产品的依赖。
EasyMR具备极强的国产化适配能力,可灵活部署在多种国产操作系统、CPU、服务器规格中,具体适配清单如下:
后续EasyMR也会继续适配其余国产化操作系统、CPU等基础组件,深耕信创国产化领域,为信创国产化献出自己的力量。
丰富的组件可扩展性
EasyMR本身提供了丰富的大数据组件,包括但不限于Hadoop、Hive、Spark、Flink、HBase、Kafka、Trino,可以满足用户不同需求场景下对大数据集群的一站式创建、管理、部署、运维与监控。
除此之外,EasyMR还拥有一套统一的产品包schema定义规范,将产品包完整的生命周期(安装、启动、配置、升级、卸载等)通过标准的schema定义表示。
当后续需要添加其余类型的大数据组件时,无需对EasyMR平台本身做出改造,只需根据规范定义新组件的产品包即可将其投入EasyMR平台使用。
支持高可用的可靠性平台
对于EasyMR系统架构中的多个核心组件,出于对平台稳定性方面的考虑,EasyMR做到了核心组件支持高可用且分布式可水平扩展。
• 当一台核心组件因为外界原因宕机后,EasyMR可以保证其余服务能够正常运行,包括但不限于服务安装、启动、停止、卸载等;
• 当需要接入大数据组件的节点数量增加时可以灵活扩展核心组件的数量以适配,同理,当需要接入大数据组件的节点数量减少时也可以灵活减少核心组件的数量以节省资源。
四、EasyMR使用场景
EasyMR作为一款自主研发、完全可控,致力于助力企业信息化智慧转型的“企业数据底座”,可以帮助客户轻松应对各类应用场景。
快速搭建Hadoop集群
在当前的大数据运维实践下,当用户需要使用Hadoop大数据分布式处理系统的时候,对用户自身来说前期需要准备硬件环境、部署启动Hadoop相关大数据组件。但是跟用户相关的内容是编写应用程序运行作业,对于不熟悉底层大数据集群的用户来说,这些前期准备工作非常冗长繁琐而且出了问题也无法得到及时的解决。
并且在传统模式下,运维手动部署一套Hadoop集群至少需要3天的,尤其当集群规模较大时,通过手动的方式更加耗费人力与物力,
但是使用EasyMR我们可以快速接入大数据节点并可以通过页面化的方式一键部署Hadoop集群,整个过程可以控制在半个小时内完成,极大提升了运维部署效率。
大数据集群开启安全
EasyMR通过集成第三方的安全管控服务Kerberos、LDAP和Ranger来分别对大数据集群做用户安全认证、访问用户管理以及用户数据权限管控。
对于使用EasyMR部署的大数据集群,用户可以通过一键开启的方式对大数据组件开启安全认证,大大节省了传统模式下的繁重的人工操作。
基于国产化操作系统部署大数据集群
关键技术国产化,是DT时代中国企业发展的必然选择。越来越多企业开始追求软硬件的国产替代和自主可控。
EasyMR目前已经适配多种国产操作系统与芯片架构,而且还将继续主动针对国产化软硬件去做适配,用户使用EasyMR可以快速部署对应架构下的大数据集群。
写在最后
作为全链路数字化技术与服务提供商,袋鼠云始终坚持自主研发和国产化路线,为攻克“卡脖子”难题,在技术创新上不遗余力。EasyMR基于最新的开源技术,为企业提供大数据基础设施底座,致力于Cloudera CDP等国外Hadoop商业版的国产化替代。
为了可信、可控、安全的数据未来,袋鼠云在路上。
对EasyMR感兴趣的用户可以添加【小袋鼠】进行咨询,进一步了解产品详情。 想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=szkyzg
添加【小袋鼠:dtstack001】入qun,免费获取大数据&开源干货
同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术qun」,交流最新开源技术信息,qun号码:,项目地址:https://github.com/DTStack
作者:Nicolas Fränkel 翻译:Sylvia https://blog.frankel.ch/poor-man-api/
在 API 日渐流行的年代,越来越多的非技术人员也希望能从 API 的使用中获利,而创建一套成熟的 API 方案需要时间成本和金钱两方面的资源加持。在这个过程中,你需要考虑模型、设计、REST 原则等,而不仅仅是编写一行代码。
如何打造一个具有高性价比且能持续迭代的产品,成为越来越多技术团队的目标。本文将展示如何在不编写任何代码的情况下,简单实现一个 API 实践。
方案初试
该解决方案主要使用的是 PostgreSQL 数据库,PostgreSQL 是一个开源 SQL 数据库。同时我们没有编写 REST API,而是使用了 PostgREST 组件。
PostgREST 是一个独立的 Web 服务器,它可以将 PostgreSQL 数据库直接转换为 RESTful API。如果你想了解 PostgREST 的使用方法,可以参考入门指南文档,内容非常全面且开箱即用。
接下来,我们将它应用到一个简单的示例中。
具体步骤
以下过程你可以在 GitHub 上找到完整源代码。 下方展示了一个通过 CRUD API 公开的 product 表。
由于我没有找到任何现成的 Docker 镜像,所以我单独创建了一份新的 Dockerfile。其中主要涉及依赖项的安装和参数化数据生成。
Dockerfile
之后,Docker 镜像在 文件夹中会包含一个名为 的可执行文件。这里可以通过 Docker Compose 来部署:
docker-compose.yml
接下来可以执行以下命令,查询前文提到的 表:
得到如下结果反馈:
方案优化
尽管上文提到的这套解决方案有效,但仍存在很大的改进空间。比如数据库用户不能更改数据、实际操作中每个人都可以访问相关数据等。这对于与产品相关的数据来说,可能不是一个大问题,但如果是医疗数据呢?
PostgREST 的官网使用文档中提到了这一点,并明确提出:建议用户使用反向代理。
提到反向代理,就不得不将目光转向到 API 网关行列。与 NGINX 不同,这里我选取了开源领域非常活跃的 API 网关产品 — Apache APISIX。APISIX 是一个动态、实时、高性能的 API 网关,提供了负载均衡、动态上游、灰度发布、精细化路由、限流限速、服务降级、服务熔断、身份认证、可观测性等数百项功能。
首先,我们可以在 Docker Compose 文件中补充 APISIX 相关信息,包括 APISIX 及其依赖的存储 etcd,而 etcd 主要用于存储 APISIX 的路由、插件等配置信息。
docker-compose.yml
然后将 APISIX 配置为 的代理进行调用。
现在再来查询端点,会得到与上文一致的返回结果。
添砖加瓦
虽然到目前为止,我们还没有添加任何实际项目,但准备工作已经全部就绪了。接下来就让我们为这个 API 添加一些其他功能,让其更安全有效,易于追踪。
DDoS 保护
API 作为一个连接属性的组件,必然要保证其过程中的传输安全。因此,在这里我们对 API 增加一些防护,让其免受 DDoS 攻击。APISIX 提供了非常多的官方插件,涉及鉴权、流量处理、监控等等。为了防止 DDoS,我们可以使用 APISIX 的 插件。
在 APISIX 中使用插件时,你可以在创建特定路由时在每个路由上设置某个插件。如果你想让某个插件在每个路由上都生效,则可以使用全局规则。如下方所示,我们希望在默认情况下可以保护每个路由,所以使用全局规则设定 插件。
现在,如果我们执行太多的请求,APISIX 将会保护上游。
增加鉴权
PostgREST 还在根端提供了一个 OpenAPI endpoint。因此,我们现在有两条路由: (控制 Open API 规范)和 (控制产品)。
假设我们现在需要制定一套限制访问的操作,即不允许未经授权的人访问数据。普通用户可以访问产品端信息,而管理员用户可以访问 Open API 规范和产品端信息。
APISIX 提供了几种身份验证方法,这些身份认证方式都可以通过插件进行实现。这里我们选取 APISIX 中最常用也是最简单的认证插件 key-auth,它依赖于 Consumer(消费者)抽象。 插件的使用中需要一个特定的 header,这样插件就可以根据值数据进行反向查找,并找到其对应的 Consumer。
以下代码展示了如何新建一个 Consumer:
同样的,我们需要对 Consumer 和 Key 进行相关操作。现在可以创建一个专用路由来配置它们,以便只有来自 的请求才能通过:
然后使用以下命令测试一下:
发现并没有起作用。这是因为我们没有通过 API 密钥的 header 进行身份验证。
添加 header 后再次进行测试:
发现仍然没有效果。这是因为这里 API key 为 ,我们前边仅为 也就是管理员设置了相关权限。所以如果更换为 ,就会如期返回 Open API 规范的相关信息。
配置监控
在软件系统中,总有一个被人们低估重要性的功能 —— 可观测性。在生产环境中部署了任何组件,都需要监控其运行状况。
如今,很多服务都提供了可观测性的功能,比如 Prometheus。得益于 Prometheus 的开源属性,它被广泛应用于实践中。因此,这里我们也选用 Prometheus 进行相关数据的监控。
为了通过图表等形式显示数据,我们也同时需要依赖于 Grafana。接下来,将这些组件添加到 Docker Compose 文件中。
docker-compose.yml
以上操作需注意:APISIX 的默认监控方案中自带 Grafana,因此只需从 APISIX 中获取相关配置 即可。同时将默认端口从 3000 更改为 3001 是为了避免与 PostgREST 服务发生冲突。
一旦监控基础设施到位,我们只需要指示 APISIX 以 Prometheus 期望的格式提供数据即可。可以通过配置插件和新的全局规则来实现这一目标:
config.yaml
此时发送几个查询请求,并打开 Grafana 仪表板,可看到类似数据。如果运行较多请求,则会出现更丰富的数据仪表。
总结
创建一个成熟的 RESTful API 是一项巨大的投资。你可以通过 PostgREST 将数据库暴露在 CRUD API 中来快速测试一个简单的 API。但是,这样的体系结构不适用于实际生产。要想使其更具实践性,就需要在 PostgREST 前设置一个 facade、一个反向代理,或者更好的 API 网关。
Apache APISIX 作为云原生 API 网关,提供了广泛的特性,从流量处理到认证授权和可观测性等。有了 APISIX,你就可以用较低的成本快速验证你的 API 需求。锦上添花的是,当你验证需求完成之后,还可以保留现有的 facade,并用自定义开发的 API 来替换 PostgREST。
作者:阿里云智能技术专家 周康,StarRocks Active Contributor 郑志铨(本文为作者在 StarRocks Summit Asia 2022 上的分享)
为了能够满足更多用户对于极速分析数据的需求,同时让 StarRocks 强大的分析能力应用在更加广泛的数据集上,阿里云EMR OLAP 团队与 StarRocks 社区在 2021 年就开始合作。
双方联手增强 StarRocks 的数据湖分析能力,使其不仅能够分析存储在 StarRocks 本地的数据,还能够以同样出色的表现分析存储在 Apache Hive(以下简称 Hive)、Apache Iceberg(以下简称 Iceberg)和 Apache Hudi(以下简称 Hudi)等开源数据湖或数据仓库的数据。
阿里云EMR StarRocks 正是 StarRocks 授权阿里云的一款开源 OLAP 产品,致力于构建极速统一分析体验,满足企业用户的多种数据分析场景。本文将主要阐释阿里云EMR StarRocks 在数据湖方向已经做过的工作、实际的效果体现,以及 StarRocks 在数据湖分析方向的规划。
#01
阿里云EMR StarRocks 整体架构
—
在存储层,有阿里云的对象存储 OSS 作为数据湖的统一存储,可以存储常见的 Parquet/ORC/CSV 等文件格式。
在湖管理与优化层,EMR 会通过数据湖构建(DLF),去进行整体数据湖的数据管理和一体化构建。同时在数据湖分析实践过程中,对象存储相对于传统的 Apache Hadoop(以下简称 Hadoop),HDFS 会存在一些性能问题。为了解决这个问题,在阿里云EMR,我们自研了 Jindo FS 系统,以便对数据湖存储层访问进行加速和优化。
同时针对常见的数据湖存储格式,包括 Parquet、ORC 的格式。比如像 Hudi、Iceberg,在索引统计版本信息、版本维护、小文件合并以及生命周期等方面,都做了优化和增强。有了存储以及针对数据库管理的优化等工作,就可以在这之上去构建分析层,也就是数据开发与治理层。
在数据开发与治理层,StarRocks 在阿里云EMR 分为两个角色,一部分是固定节点,一部分是弹性节点。有了 StarRocks 数据湖分析引擎之后,就可以去对接 EMR 上开源的 Apache Airflow(以下简称 Airflow)以及 Jupyter 等,也可以对接阿里云的 Dataworks,来做数据开发和调度。
1、StarRocks 在 Iceberg 的实现
StarRocks 主要包含 FE 和 BE 两个组件,两者之间再通过 RPC 进行通信,以实现查询的调度和分发、结果汇总等一系列工作。
为了支持 Iceberg 的数据湖分析,我们在 FE 侧以及 BE 侧都做了大量的改造。首先是 FE 侧,增加了外表类型 IcebergTable;在执行计划生成之后,通过修改 RPC 协议(Thrift 协议),把执行计划相关信息发送给 BE;在 BE 侧,再通过通过 HDFS scanner 来支持实际的数据扫描。
在做了上面这一系列的研发工作之后,我们基于 TPCH 和 Trino 做了性能对比测试。可以看到,StarRocks 相对于 Trino 性能表现非常突出。
那么为什么 StarRocks 相比 Trino 的性能要好这么多?
2、StarRocks 的性能分析
借助 StarRocks 已有的全面向量化执行引擎、全新的 CBO 优化器等,这些能力能够极大地提升我们在单表以及多表层面的性能表现。在这个基础之上,针对数据湖分析的场景,我们也增加了新的优化规则。
首先在优化规则的方面,举几个简单的例子,比如常见的谓词下推,通过支持谓词下推,能够把 col_a>x 等谓词条件下推到 scan 算子。这样实际在扫描数据时,就能够减少扫描的数据量。
如果没有做谓词下推(如上图左上角),通过整体扫描,会把数据先扫上来,然后再通过引擎本身上游的一些 Filter 算子去做数据的过滤。这会带来很大的 IO 开销。
为了进一步减少扫描数据量,我们也支持了分区裁剪,详见上图中间区域。在没有做优化之前,需要去扫描三个分区。通过分区裁剪的优化,在 FE 侧就可以把不需要的两个分区裁剪掉。只需要告诉 BE 扫剩余一个分区的数据。在 BE 我们也支持了 Global Runtime Filter,针对 Join 这种场景,能够有比较大的性能提升。借助于 StarRocks 优异的执行引擎,就能够在 CPU 密集型的数据湖分析场景下有很好的性能表现。但在一些实际场景落地过程中,基于 FE 侧的一些优化规则,或者是前面提到的全局 Runtime Filter 还不能够完全减少 IO开销。
如何降低 IO 开销非常关键。在大部分情况下,数据湖中需要分析的数据和计算节点,基本上不会在同一台物理机器上。那么在分析过程中,我们就面临着非常大的网络 IO 挑战,为此 StarRocks 社区针对 IO 方面做了非常多的优化,包括延迟物化、IO 合并、支持 Native Parquet/Orc Reader、针对对象存储的 SDK 优化等工作。
接下来,我通过两个例子展开介绍实际的优化细节是怎么实现的。
(1)IO 合并
在没有 IO 合并以前,若要读取一个 Parquet 文件相关的数据,首先需要基于 FE 侧发给 BE 的扫描数据路径去构建针对文件级别的 File Reader,在 FE 侧规划的时候,也能告知实际扫哪几列数据。在实际客户落地过程中遇到小文件导致 IO 耗时高的问题。
针对于 ColumnReader,假设一个 SQL 同时要读取三列,有可能有两列的数据量会比较小。这个时候可以对这两列 IO 合并。比如以前要通过两次的网络 IO,现在可以一次就把这两列的数据读取。针对于 Row Group ,也可以对小的 Row Group 做 IO 的合并,从而减少 IO 的次数。
对于文件本身,如果这个文件特别小,我们也支持一次把文件加载到内存中。实际在测试过程中,在这种小 IO 特别多的场景下,会有一个非常明显的提升。
(2)延迟物化
什么是延迟物化?延迟物化需要解决什么问题?
在没有延迟物化之前,回到 Parquet 的实现原理,比如要读取三列,就需要把这三列同时给读上来,然后再去运用一些谓词,再返回给上游算子。这里可以看到一个明显的问题,就是假设没有针对第三列的谓词,那其实第三列不需要把所有数据都读进来。
可以看上图左边部分,因为 SQL 针对于前两列 c0 和 c1 是有谓词的。这个时候会先把这两列数据读取到内存。然后基于这两列构建 Selection mask,这两个 Mask 叫标记数组。有了这两个标记数组之后,会把第三列定义为一个 Lazy column。
拿到了前两列的标记数组之后,基于这两个标记数组去构建一个新的过滤标记数组。然后再基于这个新的过滤标记数组读取 Lazy column。那在实际使用过程中,Lazy column 里边可能会有多列,这样能够极大地减少很多不必要的 IO 读取。因为有了前面的引擎赋能,包括全面向量化、CBO 优化器以及针对 IO 本身的优化数据湖分析,在测试和实际落地的过程中已经有一个很好的性能表现。
在实践过程中,另外一个问题就是数据访问。在数据湖场景之下,对文件的 List 操作可能会成为整个网络访问的瓶颈。为了解决这个问题,在 StarRocks 的 FE 侧设计了一套完整的细粒度智能缓存方案,能够缓存 Hive 的分区信息,以及文件信息。
在设计缓存中,缓存更新是一个比较大的挑战。基于事件驱动的模式,能够解决缓存更新的问题,在保证用户查询的性能基础之上,也能够有非常好的使用体验,而不需要手动更新缓存。同时,为了加速查询的规划和调度,也支持了统计信息的缓存。
3、StarRocks的生态分析
早期版本中,如果要支持新的数据源需要做很多冗余的开发,开发者需要对很多其他模块有深入的理解,用于使用的时候也需要去创建外表。如何解决这个问题呢?我们的解决思路是设计一套全新的 Connector 框架。
在以前的版本中,假设用户有一个库包含一两百张表,需要在 StarRocks 上去分析,那么他需要手动创建 100 多张的外表,然后通过 FE 管理数据,再让用户去使用。如果说用户做了一些 Schema change,外表可能又得重建,就极大增加了使用负担。
在 Connector 框架设计中我们引入了 Catalog 的概念,用户不在需要手动创建外表。比如说现在有 Hive Catalog、Iceberg Catalog,用户不需要去创建外表,只需要创建一个 Catalog,就能实时地获取到表的数据信息。我们已经对 Hive、Iceberg、Hudi 做了完整的支持。同时在 EMR 产品生态里也已经集成好了前面提到的数据管理的 DLF 以及 OSS、 Max Compute 等产品。
4、StarRocks的弹性分析
前面在做产品整体介绍的时候,提到了我们有一个比较关键的产品特性是弹性。弹性是怎么实现的呢?其实最核心的解决方案就是在 StarRocks 支持了 Compute Node(以下简称 CN)。下图左边部分就是一个固定的 StarRocks 集群,这些固定的 BE 节点都有实际的 SSD 存储。
绿色部分是 CN。CN 和 BE 共享同一套执行引擎代码,是一个无状态的节点。CN 可以部署在 K8S 上,数据可以存储在对象存储或 HDFS 上。通过 K8S HPA 的能力,在集群负载高的时候动态扩容 CN,在集群负载低的时候缩容。
经过上面的改造,EMR StarRocks 能够支持弹性伸缩,从而支持最大程度地降本。有了弹性之后,我们还需要解决另一个问题,那就是资源隔离。数据湖上的查询 workload 通常多种多样,有直接对接 BI 出报表的,也有分析师查询明细的 Ad-Hoc 等等。通常用户都希望通过软性的隔离,而不是物理隔离,来实现小租户资源的弹性隔离。例如在集群资源空闲的时候,允许查询充分利用集群资源,但是当集群资源紧张时,各个租户按照自己的资源限制使用资源。因此 StarRocks 还实现了基于 ResourceGroup 的资源隔离,这样用户可以从用户、查询和 IP 等层面,限制其对 CPU/MEM/IO 等资源的使用。
通过对性能优化、生态整合弹性等几方面的介绍,我们知道阿里云EMR StarRocks 在数据湖分析场景具体是怎么做的、做到了什么程度。归纳起来,阿里云EMR StarRocks 数据分析的核心就是“极速”、“统一”两个关键词。
极速:相对于 Trino 有数倍的性能提升,上图这一页的测试数据是针对于 Hudi。
统一:支持多种多样的数据源,包括上图没有提到的 JDBC 数据源。目前从 Trino 迁移到 StarRocks 已经有不少落地实践,基本可以实现无痛的迁移。
#03
阿里云EMR StarRocks数据湖规划
—
通过不断与用户交流探讨,我们认为,数据湖分析至少达到以下四点要求,才能成为一项大众化的数据分析技术:
1. Single Source of Truth 。只有一份数据,用户无需显示地进行数据流转。
2. 高性能。接近秒级别,甚至亚秒级的查询延时。
3. 弹性。分解存储和计算架构。
4. 经济高效。按需扩展和扩展。
当前阻碍数据湖分析达到上述四点要求的情况有以下三种:
1. 数据湖存储系统普遍存在 IO 性能差的问题,无法满足用户对于低延迟查询的要求。
2. 数据湖、数据仓界限分明。通常为了加速数据湖查询,我们还需要在其上去搭一层数据仓,破坏了 Single Source of Truth 的原则。
3. 复杂的数据栈结构使我们无法保证弹性、高性价比以及易用性。
经过多次思考、开放讨论以及仔细论证,我们提出了数据湖分析的新方式,希望通过数据湖分析的新方式攻克以上难题、达到理想的数据湖分析状态。
我们认为,数据湖分析的新方式等于缓存+物化视图。
由于数据湖存储系统包括 OSS 等,通常 IO 性能都比较差,导致数据湖分析的瓶颈通常落在 Scan 数据上。
为了能够进一步提升数据湖分析的性能,我们希望能够利用本地磁盘或内存缓存这些数据加速 IO 性能,使远端存储不再成为性能的瓶颈。引入缓存对于用户来说是透明的,用户无需额外的运维工作就能够享受到缓存加速的好处。
相比于远端存储,本地磁盘或内存的价格一般都比较昂贵。我们希望好钢用在刀刃上:只有用户分析所需要用到的列数据才会进入到缓存当中来,并且对于逐渐变冷的数据,我们会将其自动淘汰掉,从而提高缓存的空间利用率。
类似于 CPU 的缓存架构,我们也采用分级缓存的策略。第一级是内存,第二级是本地磁盘,对于缓存到内存的极热数据,所有的读取都能够直接引用缓存本身的内存,无需进行内存拷贝,在数据不断更新的场景下,新增数据通常会导致 Cache miss,从而导致查询延迟出现抖动。
目前我们已经做了一些 POC。POC 显示,在 SSB 多表性能测试的情况下,缓存的性能比不缓存快了三倍以上,并且已经基本接近 StarRocks 本地表。缓存帮助我们保证 Single Source of Truth 的同时达到高性能,由于缓存的特性,用户可以真正做到弹性伸缩、cost effective。对于延迟敏感的场景,提高缓存空间来降低查询延迟。对于延迟不敏感的场景,减少或不使用缓存,从而节约成本。
用户通常希望对数据进一步加工、预聚合或建模,使其进一步满足业务对数据分析的性能和质量要求,同时也能够节省重复计算的开销。然而不管是 Lambda 架构还是 Kappa 架构,用户都需要搭建复杂的数据栈,用于进一步加工数据湖上的数据。同时用户还需要分别维护数据和加工后的多份数据,处理数据之间的一致性问题。
为了满足用户对数据加工、建模的需求,进一步融合湖和仓,我们将为用户带来更加强大的物化视图能力解决上述问题。
首先,物化视图通过 SQL 定义,数据的加工和建模变得极其简单。其次,物化视图能够融合不同数据的数据,对外提供一个统一的视图,用户无需改写查询 SQL 即可做到查询自动路由透明加速。StarRocks 的视图支持实时增量更新,为用户提供更实时的分析能力。最后,物化视图作为 StarRocks 的原生能力,极大地降低了运维成本。通过物化视图,数据湖能够真正做到 Single Source of Truth,帮助用户更加简单地在数据湖上进行数据的加工建模,打破了湖和仓的次壁,简化整个数据栈的架构。
#04
总结和展望
—
StarRocks 数据湖分析的核心是:极速、统一、简单、易用。
通过 Connector、数据 Catalogs,数据源的接入变得极其简单。通过缓存,数据湖存储系统的 IO 性能将不再成为瓶颈。通过物化视图,湖、仓数据的流转更加自然,湖、仓视图一致,查询可以透明加速,数据栈的架构变得更加简约。最后借助云上和 K8S 的弹性能力,StarRocks 数据湖分析能够做到真正的弹性、cost effective。
关于 StarRocks
面世两年多来,StarRocks 一直专注打造世界顶级的新一代极速全场景 MPP 数据库,帮助企业建立“极速统一”的数据分析新范式,助力企业全面数字化经营。
当前已经帮助腾讯、携程、顺丰、Airbnb 、滴滴、京东、众安保险等超过 170 家大型用户构建了全新的数据分析能力,生产环境中稳定运行的 StarRocks 服务器数目达数千台。
2021 年 9 月,StarRocks 源代码开放,在 GitHub 上的星数已超 3600 个。StarRocks 的全球社区飞速成长,至今已有超百位贡献者,社群用户突破 7000 人,吸引几十家国内外行业头部企业参与共建。
摘要:为实现不同的功能,GaussDB(DWS)提供了不同的数据对象类型,包括索引、行存表、列存表及其辅助表等。这些数据对象在特定的条件下实现不同的功能,为数据库的快速高效提供了保证,本文对部分数据对象进行介绍。
本文分享自华为云社区《GaussDB(DWS)之数据对象及相互关系总结》,作者:我的橘子呢 。
为实现不同的功能,GaussDB(DWS)提供了不同的数据对象类型,包括索引、行存表、列存表及其辅助表等。这些数据对象在特定的条件下实现不同的功能,为数据库的快速高效提供了保证,本文对部分数据对象进行介绍。
1.索引(index)
索引是关系型数据库中对某一列或者多个列的值进行预排序的数据结构。如果数据库的记录非常多,通过建立索引可以获得非常快的查询速度,当对某一列建立索引之后,通过该列进行相关查询时数据库系统就不必扫描整个表,而是直接通过索引定位到符合条件的记录,在一定程度上能够大幅提升查询得速度。
假如需要执行如下的语句进行查询:
一般情况下数据库需要对每一行进行遍历查询,直到找到所有满足条件number=10的组信息。当数据库的记录很多,而满足where条件的记录又很少时,顺序扫描的性能就会很差。这时如果在表test_1的number属性上建立索引,用于快速定位需要匹配的组信息,数据库只需要根据索引的数据结构进行搜索,由于常用的索引结构有B-Tree、Hash、GiSt、GIN等,这些索引结构的查询都是快速高效的,因此可以在少数几步内完成查询,大大提高了查询效率。
对表test_1的number属性建立索引语句如下:
由于GaussDB里的所有索引都是“从属索引”,索引在物理文件上与原来的表文件分离,执行上述创建索引语句后,系统会生成relname为numberIndex的索引类型。表和索引都是数据库对象,在pg_class里会有该索引的记录,有与之相对应的oid,同时在pg_index表里会记录索引及其对应主表的信息。对应属性信息如图1所示。
图1 pg_index部分属性
2.toast表
toast(The Oversized-Atttibute Storage Techhnique)即超尺寸字段存储技巧,是数据库提供的一种存储大数据的机制。只有一些具有变长表现形式的数据类型才会支持toast,比如TEXT类型。由于在GaussDB(DWS)的行存储方式中,一条数据的所有列组合在一起称之为一个tuple,多个tuple组成一个page。page是数据在文件存储中的基本单位,其大小是固定的且只能在编译器指定,之后无法修改,默认发大小为8KB,当某行数据很大超过page的大小时,数据库系统就会启动toast,对数据进行压缩和切片。实际数据以行外存储的形式存储在另外一张表中,这张表就是toast表。
当一张表的任何一个属性是可以toast的,则这张表会有一张关联的toast表,在pg_class里表的reltoastrelid属性里记录了该toast表的oid,如果没有关联的toast表,reltoastrelid=0。那么如何判断一张表的属性是否是可以toast的呢?我们可以在表的Storage选项中查看对应属性的存储策略。有以下四种不同的存储策略:
- PLAIN:避免压缩或者行外存储;此外,它禁止为变长类型使用单字节的头。 这只对那些不能TOAST的数据类型的列才有可能。
- EXTENDED:允许压缩和行外存储。 这是大多数TOAST数据类型的缺省策略。首先会尝试对数据进行压缩, 如果行仍然太大,则进行行外存储。
- EXTERNAL:允许行外存储,但是不许压缩。 使用EXTERNAL,将使那些数据类型为text和bytea的字段上的子字符串操作更快 (代价是增加了存储空间),因为这些操作是经过优化的:如果行外数据没有压缩,那么它们只会获取需要的部分。
- MAIN:允许压缩,但不允许行外存储。 实际上,在这样的字段上仍然会进行行外存储, 但只是作为没有办法把数据行变得更小以使之足以放置在一个页面中的最后选择。
假如创建表语句如下:
创建了一张test_t表,该表有id和description两个属性,分别属于int和text类型,查看该表的属性对应的Storage策略:
图2 test_t表相关信息
我们可以看出description属性的Storage策略为EXTENDED,是可以toast的,系统会为test_t表创建一张关联的toast表。
图3 test_t表对应toast表
通过查询pg_class,可以的看到表test_t关联的toast表的oid为52579,进一步以此oid为条件在pg_class里就会得到toast表的相关信息。
图4 toast表相关信息
下图为test_t表和其对应的toast表之间的关系,以及toast表一些基本属性的介绍。
图5 test_t与其toast表关系图
3.cudesc表
GaussDB(DWS)除了提供行存储方式外,还支持列存储方式。列存储方式在数据压缩、列批量数据的运算、大数据统计分析等场景中有着显著的优势。CU(Compress Unit)压缩单是列存储的最小单位,每列默认60000行存储在一个CU中,CU生成后数据 固定不可更改。CUDesc本身是一张行存表,它用来辅助记录列存表的cu信息,该表的每一行描述一个CU,包括最大值最小值以及CU在文件中的偏移量和大小,连续多个行中各个不同的列的cu_id相同,可以认为就是把连续多个行截断拿出来,然后再根据不同的列,放到不同的cu中,这些CU所在的行数都是一致的,用一个cu_id表示,但是col_id不一样。同时还增加了一个col_id=-10的列,这个列为VCU,表示这些连续的行中,有哪些行已经是被删除了,用delete_map记录删除信息。如图6所示。
图6 cudesc表示意图
每张列存表都有一张对应的CUDesc表,CUDesc表的oid可以在pg_class中对应列存表组的relcudescrelid属性中查到,所有CUDesc表默认存储在namespace oid = 100,name为cstore的namespace下。
4.delta表
在列存储方式中,无论是向列存表中插入1条还是60000条数据,都只会生成一个CU,在多次插入少量数据时,不能有效的利用列存压缩能力,导致数据膨胀影响查询的性能和磁盘使用率。CU只支持追加写的方式,也就是说,后面对这个CU中的数据做更新或删除都不会真正更改这个CU,删除是将老数据在字典中标记为作废,更新操作是标记老数据删除后,再写入一条新记录到新CU,原来的CU不会有任何的修改。
从这里我们可以看出,在对列存表进行多次更新/删除,或每次只插入很少量的数据后,会导致列存表空间膨胀,大量空间无法有效利用,这是因为列存表在设计上就是为了大批量数据导入以及海量数据按列存储/查询。Delta表正是为了解决这两个问题。在启用delta表后,单条或者小批量数据导入时,数据将进入delta表中,避免小CU的产生,delta表的增删改查与行存表一致。开启delta表后,将显著提升列存表单条导入的性能。
delta表同样是一张行存表,为了辅助列存表而存在。在创建列存表时系统会为该列存表创建一张对应的delta表,delta表的oid可以在pg_class中对应列存表组的reldeltarelid属性中查到,所有delta表也默认存储在namespace oid = 100,name为cstore的namespace下。
创建一张列存表col_test,同时设置reloption属性enable_delta=true。在pg_class中查看该表对应的delta表oid。
图7 创建列存表并开启delta表
进一步根据该oid信息可以查到delta表的对应信息。
图8 查询delta表相关信息
可以指定reloption选项设置是否为该列存表开启delta表:
图9 开启/关闭delta表操作
5.分区表
分区表就是把逻辑上的一张表根据某种方案分成几张物理块进行存储。这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。分区表的定义不难理解,下面我们通过一个例子说明分区表的用法。
创建一张有id和name两个属性的分区表part_test,该表以id的大小进行分区,其中id<10的数据存储在分区location_1,10≤id<20的数据存储在分区location_2,所有id≥20的数据存储在分区location_3。
创建好part_test表后,我们所有的增删改查都是直接对part_test表操作的,对用户操作来说part_test表与普通表没有什么区别,但实际的存储方式却是严格按照分区的划分方式进行存储的,数据存储在各个分区上,part_test表作为一张逻辑表不保存数据。我们可以通过pg_partition这张系统表查询到一张分区表的分区信息。
图10 part_test表分区信息
分区表和分区的关系如图所示:
图11 分区表和分区关系图
6.各类表相关对象总结
关注,第一时间了解华为云新鲜技术~
Hexo 是一个快速、简单且功能强大的博客框架。使用 Markdown 解析文档,Hexo 能在几秒内生成带有自定义主题并集成各项功能的网站页面。
本文采用 Github Pages + Hexo 的方式,搭建个人博客。
零、准备工作
1. 使用个人 GitHub 创建仓库,并配置 GitHub Pages
注意: 此仓库用于存放个人博客页面,仓库名必须使用 格式。
仓库创建完成后,可以在仓库根路径下创建一个名为 的静态 HTML 文件来验证个人博客搭建是否成功。
在 仓库对应的 GitHub Pages 设置页面 (访问路径为) 可以找到个人博客的主页访问地址:https://<GitHub用户名>.github.io。
若能在浏览器中正常访问该地址,即代表个人 GitHub Pages 搭建成功。
2. 安装 Git 和 NodeJS
Hexo 基于 NodeJS 运行,因此在开始前,需要安装 和 工具。安装教程可参考如下步骤。
笔者的本地环境为 ,包管理工具使用 Scoop,NodeJS 通过 管理,下述安装步骤需要在 里执行。
一、安装 Hexo
此处只列出本次所需的关键步骤,更多说明详见官方文档:https://hexo.io/zh-cn/
1. 全局安装 工具
2. 创建一个项目 并初始化
3. 生成网页文件&本地启动
通过 生成的页面文件在项目 目录下;
使用 命令可以清理生成的页面文件。当配置未生效时,建议执行清理命令。
4. 本地访问
浏览器访问:http://localhost:4000/ 会看到一个比较简陋的页面。没关系,接下来介绍如何更换主题。
二、安装&配置主题
按照前两个小节所介绍的步骤,我们已经能够通过本地访问博客页面了,但 Hexo 默认的主题不太好看。
好在官方提供了数百种主题任君选择,可以根据个人喜好更换,具体可以(https://hexo.io/themes/)查看。
本文将主要介绍 Fluid 主题的安装与配置。
1. 安装 Fluid 主题
官方提供了两种安装方式,这里使用官方推荐的 方式。
在博客根路径下创建 文件,并将主题的 文件内容复制过去。
2. 指定主题
将如下修改应用到 Hexo 博客目录中的 :
3. 创建「关于页」
首次使用主题的「关于页」需要手动创建。
创建成功后修改 ,添加 layout 属性。修改后的文件示例如下:
需要注意的是, 必须存在,并且不能修改成其他值,否则不会显示头像等样式。
4. 更新 Fluid 主题
通过 npm 安装主题的情况,可在博客目录下执行命令:
5. 本地启动
执行如下命令重新生成页面,并启动 Hexo 服务。
再次通过浏览器访问 http://localhost:4000 , 便可以看到页面变得美观多了。
三、创建文章
修改 文件。这项配置是为了在生成文章的同时,生成一个同名的资源目录用于存放图片等资源文件。
创建文件名为 文章。
设置文章的标题及其他数据信息。
如上命令执行成功后,在 目录下生成了一个 Markdown 文件和一个同名的资源目录。
在 目录中放置一个图片文件 ,整体目录结构如下:
然后在文章的 Markdown 文件里,通过以下方式即可引用对应的图片。
图片的引用方式也不只一种,更多详细介绍可参考官方文档 (https://hexo.io/zh-cn/docs/asset-folders.html)。
文章创建并编辑好之后,就可以通过 命令启动服务,并在本地预览文章。
四、配置指南
如无特殊说明,如下配置文件一律默认为主题配置文件。
1. 页面 title 修改
修改 文件。
2. 博客标题
页面左上角的博客标题,默认使用站点配置中的 。此配置同时控制着网页在浏览器标签中的标题,如需单独区别设置,可在主题配置中进行设置。
3. 首页 – Slogan(打字机)
首页大图中的标题文字,可在主题配置中设定是否开启。这里支持配置固定的 或者从远程 实时获取,优先级 。
五、网页访问统计
目前 Fluid 支持多种统计网站,本文仅介绍 的配置。
使用 LeanCloud 之前,需要先注册账户并新建应用(需实名认证),可自行前往官网完成。
在 【控制台 -> 应用 -> 设置 -> 应用凭证】页面中找到对应的 AppID、AppKey、REST API 服务器地址等信息填入主题配置中。
如无特殊需要,记得配置 ,这样 LeanCloud 在 localhost 域名下访问不会增加数据。
1. 展示 PV 与 UV 统计
页脚可以展示 PV 与 UV 统计数据,目前支持两种数据来源: 与 。
2. 展示文章日期/字数/阅读时长/阅读数
3. 文章评论功能
评论功能需要在主题配置中开启并指定评论插件,这里使用基于 的 。
六、发布 GitHub Pages
1. 安装 。
2. 修改站点配置 。
3. 生成站点文件并推送至远程 GitHub 仓库。
登入 Github,在库设置(Repository Settings)中将默认分支设置为 配置中的分支名称。
只需稍等片刻,个人博客站点就会显示在 Github Pages 中。
七、参考资料
- Hexo Docs:https://hexo.io/zh-cn/docs/
- Hexo Fluid 用户手册:https://fluid-dev.github.io/hexo-fluid-docs/
了解更多敏捷开发、项目管理、行业动态等消息,关注我们 LigaAI@oschina 或LigaAI – 新一代智能研发协作平台,在线申请体验我们的产品。
随着CPU和存储的价格持续降低、网络资源愈加富余,用户行为习惯开始发生改变,数据量也急速上升,数据计算正式步入云原生时代。充分结合云计算、大规模并行处理技术的云原生数据库 PieCloudDB Database(以下简称PieCloudDB)应运而生。其突破式创新的eMPP(elastic Massive Parallel Processing)分布式技术,打破了传统数据库难以扩容、数据孤岛、缺乏弹性等瓶颈,实现了弹性伸缩、动态扩容、跨集群关联、跨云等众多优势,配合可视化的云原生平台为云时代用户带来更高性价比和更便捷的使用体验。
云原生时代的数据安全一直是用户最关注的话题之一。近日,国家发改委发布的《关于数字经济发展情况的报告》中提到要: “全面加强网络安全和数据安全保护,筑牢数字安全屏障“。 数据库系统存储着各类重要且敏感的数据,常常成为黑客的主要攻击目标。而数据的泄露往往会为企业的品牌声誉、业务运营、合法性等众多方面造成巨大的影响和损失。
作为OpenPie旗下的云原生分析型数据库,PieCloudDB开发团队早在设计初期就将数据安全作为重要的设计目标,让 PieCloudDB 通过一系列技术实现了Unbreakable(坚不可破),并做到了真正的「安全可靠」。这一系列技术秉持着三项基本原则:无惧宕机、不丢数据、不泄露数据,方能为数据安全保驾护航。
数据库服务器故障,出现宕机,会直接或者间接影响应用的可用性。如何通过设计减少系统不能正常提供服务的时间?高可用成为数据库系统设计中必须考虑的重要因素。
数据库内的数据分为数据和用户数据。 PieCloudDB 重新打造了云上的数据库内核,实现了数据-计算-存储分离的三层架构。数据和用户数据被分开存储在云上虚拟机中。PieCloudDB 通过实现计算节点的无状态,让计算节点不存储数据和用户数据,使得用户数据可以做到跨云的分布。
数据描述了数据库内的数据结构和建立方法。用户在进行查询操作时,会根据数据信息获取表格的基本信息,再定位用户数据获取所需数据,从而形成查询结果。数据作为现代数据库的”基石”,保证了数据库高效、安全、稳定运行。
数据库宕机是对业务影响最大的故障之一。宕机期间,数据库将处于不可用状态,业务将中断。更严重者,会出现硬盘损坏的情况,数据库上线后将需要进行数据重分布。硬盘损坏还常伴随数据的损坏,在数据同步期间将进一步拉长数据库不可用的时间,加重用户损失。
传统数据库虽为减少宕机期间的停机时间进行了一定的高可用设计,例如主从架构。但损坏/故障的服务器主机仍然需要消耗大量的运维资源。同时,对于新上线的服务器需要进行同步操作,性能会受影响,而且面临主从都宕机,以至于有服务不可用的风险。
对于云原生数据库 PieCloudDB 而言,由于其计算节点是无状态的,不存储数据信息,计算节点启动和停止非常容易,企业可以根据自身的需求启动足够的冗余计算节点。PieCloudDB 提供了自动监控托管,如果发生服务器异常,会自动重启重连,重新建立集群拓扑关系,并恢复使用,保证业务无间断。只有像 PieCloudDB 这样的云上的第三代数据库才能实现计算节点的无状态。企业无需担心数据库宕机,做到了真正的“Unbreakable”(坚不可破)。
由于 PieCloudDB 实现了存算分离,用户数据被存储到对象存储服务器中。对象存储价格低廉,相比本地自建存储系统具有巨大的价格优势。
对象存储采用分布式多副本、多机房存储机制,即存储系统会自动确保多个数据副本分布在不同服务器的不同物理磁盘上,且确保多个数据副本之间的数据强一致性,将由于人为或自然原因导致的数据丢失概率降低到最低,保证单个硬件设备的故障不会影响业务。
PieCloudDB 数据被分布式KV存储管理,具有完备的高可用方案。在PieCloudDB中,每份数据都将以多副本的形式分散到多个服务节点,并将在不久的未来实现多数据中心,以确保避免因为用户数据的丢失而造成的损失。此外,容灾方面会通过定期备份和实时热备来做到万无一失。
未来,PieCloudDB 还将实现时间回溯(Time Travel)功能。通过时间回溯,用户只需在设置时指定保留天数,就能够从任何时间点恢复数据。正是由于这些特性,PieCloudDB 将丢失数据的概率降到零,真正做到了” “Unbreakable”。
PieCloudDB 的安全技术贯穿数据库的各个方面,通过透明加密、可视化角色与权限管理、SQL标准和标准数据库接口的兼容等多种安全技术全方位保证数据安全,将数据泄露风险降至最低。
由于加密和解密的过程需要时间来完成,会对数据库的性能造成损失,因此由于历史原因,很多传统数据库的数据都以明文的形式存储,但数据明文存储会存在数据泄露风险。云数据库的数据部署在云上,需要更完备的数据加密功能来保证数据的安全。PieCloudDB 提供企业级透明数据加密,在不影响数据库性能的同时,让数据在存储时完成加密。PieCloudDB 通过实时加密(on-the-fly)、高强度算法、多级密钥、传输加密等技术保证企业的数据安全。
PieCloudDB 支持数据实时加密,即对数据文件执行实时I/O加密和解密,实现原生用户数据(包括表数据、辅助数据、磁盘缓存文件)的自动加解密,无需修改查询语句且性能损失小。
数据实时加密让数据在通过优化器、执行器的处理后,自动加密并存储到 PieCloudDB 存储层。需要进行读取时,将自动对(加密)数据进行解密,并推入数据缓冲区进行优化。整个过程做到内核原生、对用户和数据库透明无感知,无需业务改造。此外,PieCloudDB 通过原生支持现代CPU加密指令,在最小化性能损失的同时,保证了加密过程中的高安全性。
PieCloudDB 支持基于云端硬件加密特性,将加密对性能的影响降至最低。同时,PieCloudDB 计划接入云厂商/用户自带的 KMS(密钥管理系统),进一步提升数据库存储数据的安全性,满足用户对安全审计的不同要求。
PieCloudDB 采用现代主流的高级加密标准 AES-256 。 高級加密标准 AES-256是加密信息的方法之一,众多银行、证券等行业机构都在使用这种近乎严苛的高级加密标准。
PieCloudDB 做到了分组密码,分组密码将数据分为多个块,AES-256 使用256位块大小,提供了更高性能的加密过程,大大加强了加密的安全性。PieCloudDB 将在后续的研发中支持国密算法,进一步提升数据安全的保障。
PieCloudDB使用三层密钥结构,第一级密钥为主密钥,用来加解密第二级密钥,第二级密钥为各个数据表的表密钥,用来加解密第三层密钥,第三级密钥为各个数据文件的密钥,用来加解密对应的数据文件。 PieCloudDB 内每个租户数据完全隔离,拥有独立的密钥体系。三层密钥有效防范了数据泄露,确保了用户的数据安全。
在数据传输过程中,PieCloudDB 支持 SSL/TLS 加密,让数据不管是在传输中,做到端到端的完全加密,全链路添加 SSL/TLS安全协议。只需消耗极少计算资源就可以完成节点间数据传输通道的传输加密,有效消除全链路网络通信的窃听攻击、中间人攻击和身份伪装攻击带来的安全性威胁,保证了数据在节点传输过程中的安全与稳定。
PieCloudDB 为用户提供了智能可视化的云原生平台。通过可视化的操作为用户在角色与权限管理操作上降低了门槛,让数据库管理员能够轻松管理不同角色可见的数据,让数据库使用体验上了一个台阶。 PieCloudDB 基于 RBAC(Role-Based Access Control,基于角色的访问控制)模型设计权限,将用户通过角色与权限进行关联。在这种模型中,用户与角色之间,角色与权限之间,是一种多对多的关系。
PieCloudDB 对于权限管理的目标是实现可见即可管,可视化权限管理让数据库管理员得以更便捷地管控不同的角色对数据的可见和操作权限。PieCloudDB提供了租户下的角色管理模块,支持创建角色,建立基于系统角色的基本角色架构,对不同的角色完成用户的关联、角色的继承、权限的赋予等操作,通过可视化操作和图表结构帮助用户理解当前系统角色关系。
PieCloudDB 实现了多租户下的用户管理功能,支持创建用户、查找用户、修改用户信息、重置密码、赋予用户角色、删除用户等操作;可视化的管理界面让用户管理变得更加便捷。
PieCloudDB 为用户提供了集群操作管理和集群精细化管理模块,支持将创删集群等操作分配给不同角色来实现集群权限管理,拥有授权的用户可以按需对集群进行扩容或缩容、启停或删除等操作.。
此外,PieCloudDB 会在即将发布的新版本中,实现集群精细化管理,使用户可以按照每个集群为最小对象进行角色授权管理。
PieCloudDB 高度兼容SQL:2016标准,完全支持SQL:1992标准、大部分的SQL:1999和部分SQL:2003标准(主要支持其中的OLAP 特性),支持包括窗函数、汇总、数据立方体和各种其他表达功能。此外,PieCloudDB 完全支持和认证标准数据库接口(PostgreSQL、 SQL、ODBC、JDBC 等) 。此外, SQL:1999中定义的RBAC(Role-Based Access Control,基于角色的访问控制)模型设计权限,成为 PieCloudDB 权限管理的设计理念,为用户的数据安全保驾护航。
对SQL的全面支持使得 PieCloudDB 能够无缝集成业内常见的提取/转换/加载(ETL)和BI(商业智能)工具。企业只需安排少量的集成工作,就可以用现有的使用标准 SQL 结构和接口的工具,让应用在 PieCloudDB 上运行,避免企业受制于供应商。
在公有云场景,PieCloudDB 将和云厂商的KMS(密钥管理系统)集成,进一步增强安全等级。同时 PieCloudDB 将做到证书、密钥等管理白屏化,大大降低用户的误操作的可能性。
敏捷快速不是问题,Unbreakable(坚不可破)才是关键。PieCloudDB将在云原生时代继续保障用户的数据安全,筑造数据安全的“铜墙铁壁”,为企业数字化转型保驾护航!
更多参考:
- 2022拓数派「OpenPie」产品发布会 PART 4|「坚不可破的」PieCloudDB
- PieCloudDB|在云原生时代构筑数据安全防线
Curve 是云原生计算基金会 (CNCF) Sandbox 项目,是网易数帆发起开源的高性能、易运维、云原生的分布式存储系统。
为了让大家更容易使用以及了解 Curve,我们期望接下来通过系列应用实践文章,以专题的形式向大家展示 Curve。
本篇文章是Curve块存储应用实践的第一篇,该系列文章包括:
- Curve块存储应用实践一部曲之iSCSI
- Curve块存储应用实践二部曲之nbd
- Curve块存储应用实践三部曲之云主机
- Curve块存储应用实践四部曲之云原生数据库
- Curve块存储应用实践五部曲之性能调优
iSCSI 及 tgt 简介
tgt 是一个开源 iSCSI 服务器,详情请见 tgt githu[1]。我们在开发 Curve 块设备服务器时,想让更多的系统能够使用 Curve 块设备,而不仅仅是 Linux 系统,iSCSI 协议是一个广泛使用的块设备协议,我们想修改 tgt 以便让 Curve 提供 iSCSI 服务。
Curve 块存储
为tgt提供了访问 Curve 的驱动,详见部署网络高性能版本tgt[2] , 文档里有操作步骤,这样用户就可以在任何支持 iSCSI 的操作系统上使用 Curve 块设备存储,例如Windows。
Curve 在初步使用 tgt 时也遇到一些问题:
我们观察到原版 tgt 使用单一主线程 epoll 来处理 iSCSI 命令,还包括管理平面的 unix domian socket 也在这个主线程里。
在10 Gbit/s 网络上甚至更快的网络上,单线程(也即单cpu)处理 iSCSI 命令的速度已经跟不上需求了,一个线程对付多个target的情况下,多个iSCSI Initiator的请求速度稍微高一点,这个单线程的cpu使用率就100%忙碌。
所以本文的重点就是介绍tgt的性能优化。同时社区用户使用过程中还遇到了nebd服务的单点和性能问题,社区用户对此也进行了优化,详情可参考创云融达基于 Curve 的智慧税务场景实践。
Curve 对 tgt 的性能优化实践
1. 使用多个线程做 epoll
实现多个event loop线程,每个线程负责一定数量的socket connection上的iSCSI命令处理。这样就能发挥多cpu的处理能力。
2. 为每个 target 创建一个 epoll 线程
为了避免多个target共享一个epoll时依然可能出现超过单个cpu处理能力的问题,我们为每一个 target设置了一个epoll线程。target epoll的cpu使用由OS负责调度,这样在各target上可以 实现公平的cpu使用。当然如果网络速度再快,依然会出现单个epoll线程处理不过来一个iSCSI target上的请求,但是目前这个方案依然是我们能做的最好方案。
3. 管理平面
管理平面保持了与原始tgt的兼容性。从命令行使用方面来说,没有任何区别,没有任何修改。管理平面在程序的主线程上提供服务,主线程也是一个epoll loop线程,这与原始的tgt没有区别,它负责target, lun, login/logout,discover,session, connection等的管理。当Intiator连接到iSCSI 服务器时,总是先被管理平面线程所服务,如果该connection最后需要创建session去访问某个target,那么该connection会被迁移到对应的target的epoll线程上去。
4. 数据结构的锁
为每一个target提供一个mutex,当target epoll线程在运行时,这把锁是被该线程锁住的,这样该线程可以任意结束一个sesssion或connection,当线程进入epoll_wait时,这把锁是释放了的,epoll_wait返回时又会锁住这把锁。我们修改了相关代码,让这个epoll线程不用遍历target list,只存取它服务的target相关结构,这样我们不需要target列表锁。管理面也会增加、删除一个session或者connection时,也需要锁住这把target锁。所以管理面和target epoll线程使用这个mutex来互斥,这样就可以安全地访问对应target上的session和connection了。
5. connection 建立 session
当login_finish成功时,login_finish有时候会创建session(如果没有session存在)。login_finish在connection结构的字段migrate_to里设置目标iSCSItarget。
6. 什么时候做 connection 迁移
当调用返回到iscsi_tcp_event_handler时,因为login_finish设置了migrate_to目标target, iscsi_tcp_event_handler就锁住目标iscsi target结构,并把该connection的fd插入到目标target的evloop 里面,完成迁移。
7. 设置 pthread name
设置各target event loop的线程在top中的名为tgt/n, n为target id,这样容易用top之类的工具观察哪一个target占用的cpu高。
8. 举个例子
假如MGMT要删除一个target,下面的代码说明了流程:
性能优化结果
我们为tgt配置了3块盘,一块 Curve 块存储卷,两块本地盘
使用本机登录iscsi iscsiadm –mode node –portal 127.0.0.1:3260 –login
为fio设置存取这些 iSCSI 的块设备,使用:
测试结果如下:
下面是未经优化的fio成绩,IOPS 38.8K
下面是经过多线程优化的fio成绩,IOPS 60.9K
<原创作者:徐逸锋,Curve PMC>
参考[1]:
https://github.com/fujita/tgt
参考[2]:
https://github.com/opencurve/curveadm/wiki/curve-tgt-deployment#%E7%AC%AC-4-%E6%AD%A5%E5%90%AF%E5%8A%A8-tgtd-%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B
第一辆汽车诞生之初,时速只有 16 公里,甚至不如马车跑得快,很长一段时间,汽车尴尬地像一种“很酷的玩具”。人工智能作图的出现也是如此。
AI 作图一开始的 “风格化” 本身就为 “玩” 而生,大家普遍兴致勃勃地尝试头像生成、磨皮,但很快就失去兴趣。直到扩散模型的降临,才给 AI 作图带来质变,让人们看到了 “AI 转成生产力” 的曙光:画家、设计师不用绞尽脑汁思考色彩、构图,只要告诉 Diffusion 模型想要什么,就能言出法随般地生成高质量图片。
然而,与汽车一样,如果扩散模型生成图片时“马力不足”,那就没法摆脱玩具的标签,成为人类手中真正的生产工具。
起初,AI 作图需要几天,再缩减到几十分钟,再到几分钟,出图时间在不断加速,问题是,究竟快到什么程度,才会在专业的美术从业者甚至普通大众之间普及开来?
显然,现在还无法给出具体答案。即便如此,可以确定的是 AI 作图在技术和速度上的突破,很可能已经接近甚至超过阈值。
其中一大标志性事件是,近期 OneFlow 首度将 Stable Diffusion 模型加速至“一秒出图”时代,随后AI社区开启一场AI作图的竞速“内卷”。刚刚,OneFlow又刷新了SOTA记录。
-
OneFlow Stable Diffusion 使用地址:https://github.com/Oneflow-Inc/diffusers/wiki/How-to-Run-OneFlow-Stable-Diffusion
-
OneFlow 地址:
https://github.com/Oneflow-Inc/oneflow/
比快更快,OneFlow 一马当先
11月7日,OneFlow 宣布将 Stable Diffusion 模型作图速度实现了字面意义上的“一秒出图”,在各种硬件以及更多框架的对比中,OneFlow 都将 Stable Diffusion 的推理性能推向了一个全新的 SOTA。
下面的图表分别展示了此前在 A100(PCIe 40GB / SXM 80GB)硬件上,分别使用 PyTorch, TensorRT, AITemplate 和 OneFlow 四种深度学习框架或编译器,对 Stable Diffusion 进行推理时的性能表现。
Soumith Chintala 为此打
call。
性能优化无止境,OneFlow 也在不断迭代。两周之后,OneFlow 对Stable Diffusion 也做了进一步性能升级,并再度反超了 AITemplate 的结果 ,现在速度最快的还是 OneFlow。
可以看到,在 A100 显卡上,无论是 PCIe 40GB 的配置还是 SXM 80GB 的配置,OneFlow 基于此前性能结果继续提升 10% 以上,并且依然是当之无愧的性能之王。
生成图片展示
无缝兼容 PyTorch 生态,实现一键模型迁移
-
OneFlowStableDiffusionPipeline.from_pretrained 能够直接使用 PyTorch 权重。
-
OneFlow 本身的 API 也是和 PyTorch 对齐的,因此 import oneflow as torch 之后,torch.autocast、torch.float16 等表达式完全不需要修改。
上述特性使得 OneFlow 兼容了 PyTorch 的生态,这不仅在 OneFlow 对 Stable Diffusion 的迁移中发挥了作用,也大大加速了 OneFlow 用户迁移其它许多模型,比如在和 torchvision 对标的 flowvision 中,许多模型只需通过在 torchvision 模型文件中加入 import oneflow as torch 即可得到。
使用 OneFlow 运行 Stable Diffusion
https://github.com/Oneflow-Inc/diffusers/wiki/How-to-Run-OneFlow-Stable-Diffusion
后续工作
欢迎在GitHub上Star、试用:
- OneFlow Stable Diffusion 地址:https://github.com/Oneflow-Inc/diffusers/wiki/How-to-Run-OneFlow-Stable-Diffusion
- OneFlow 地址:
https://github.com/Oneflow-Inc/oneflow/
Vision Transformer这两年
-
OneFlow源码解析:Global Tensor
-
更快的YOLOv5问世,附送全面中文解析教程
-
李白:你的模型权重很不错,可惜被我没收了
-
Stable Diffusion半秒出图;VLIW的前世今生
-
大模型狂潮背后:AI基础设施“老化”与改造工程
-
OneEmbedding:单卡 训练TB级推荐模型不是梦
目录 1 前言 2 方案意义 3 架构设计 4 数据表设计 5 代码结构 6 项目演示 7 总结
1 前言 openGauss是一款全面友好开放的企业级开源关系型数据库。openGauss采用木兰宽松许可证v2发行,提供面向多核架构的极致性能、全链路的业务、数据安全、基于AI的调优和高效运维的能力。本文采用openGauss设计一个AI小demo。
2 方案意义
人工智能被广泛用于棋类对弈的主要原因是:
棋类对弈自古以来就被认为是人类智力活动的象征,若人工智能成功达到、甚至高于人类水平,则就代表AI的发展潜力,从而吸引更多研究者关注并投身其中; 棋类很适合作为新AI算法的标杆。棋类游戏规则简洁、输赢都在盘面,适合计算机求解。理论上只要在计算能力和算法上有新的突破,任何新的棋类游戏都有可能得到攻克。而在棋类游戏上的表现也可以直观体现出AI之间计算能力与算法的高低,是促进AI算法发展的有效途径。 就本五子棋智能对弈系统而言,其服务对象为同局域网下的多个终端,讲求联机互动、互相限制、互相博弈,打破了传统二人对弈五子棋规则中,“若无禁手,先手易胜;若为后手,十堵九输”的说法,是AI算法设计、网络通信、数据库等技术的综合应用。
3 架构设计
其中对弈数据库采用openGauss数据库
4 数据表设计 棋盘数据表的表头如图所示
为将二维棋盘状态存入数据库中,令棋盘按 轴方向展开为一维序列
玩家数据表的表头如图所示
走子数据表的表头如图所示
5 代码结构
如图所示,依据模块化程序设计的基本思想,将整个项目按照功能划分为若干个小程序模块,每个小程序模块完成一个确定的功能,自顶向下、逐步分解、分而治之,各模块相对独立、功能单一、结构清晰。同时,在这些模块之间建立必要的联系,通过模块的互相协作完成整个功能的程序设计
image.png
各模块具体设计如下:
main.py:启动文件。 config.py:变量管理文件。管理所有跨文件的全局变量。 settings.py:配置文件。开发环境配置、第三方扩展插件参数配置、数据库的链接路径及其他配置等。 apps:主体文件包。其初始化文件包括Flask类的实例创建以及工厂函数。该文件包下设三个子文件包,分别对应架构设计中的三张蓝图。 exts:扩展文件包。第三方扩展插件的例化,创建映射对象等。 项目采用高度模块化设计的优点有:控制了程序设计的复杂性;提高了代码的重用性;易于维护和功能扩充;有利于团队开发等。
6 项目演示
7 总结 基于openguass开发AI应用相当方便,也使我进一步掌握了数据库的常用技术,提高工程开发能力和面对未知问题的临场解决能力,对设计、创新、分析水平都有很大的帮助。
作者:杨皓冬 openGauss: 一款高性能、高安全、高可靠的企业级开源关系型数据库。
🍒如果您觉得博主的文章还不错或者有帮助的话,请关注一下博主,如果三连点赞评论收藏就更好啦!谢谢各位大佬给予的支持!
版本名称 版本说明 版本地址 GoFrame+Layui混编版 采用GoFrame、Layui等框架研发 https://gitee.com/easygoadmin/EasyGoAdmin_GoFrame_Layui Beego+Layui混编版 采用Beego、Layui等框架研发 https://gitee.com/easygoadmin/EasyGoAdmin_Beego_Layui Gin+Layui混编版 采用Gin、Layui等框架研发 https://gitee.com/easygoadmin/EasyGoAdmin_Gin_Layui Iris+Layui混编版 采用Iris、Layui等框架研发 https://gitee.com/easygoadmin/EasyGoAdmin_Iris_Layui Echo+Layui混编版 采用Echo、Layui等框架研发 https://gitee.com/easygoadmin/EasyGoAdmin_Echo_Layui Revel+Layui混编版 采用Revel、Layui等框架研发 https://gitee.com/easygoadmin/EasyGoAdmin_Revel_Layui GoFrame+EleVue前后端分离版 采用GoFrame、Vue、ElementUI等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_GoFrame_EleVue Beego+EleVue前后端分离版 采用Beego、Vue、ElementUI等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Beego_EleVue Gin+EleVue前后端分离版 采用Gin、Vue、ElementUI等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Gin_EleVue Iris+EleVue前后端分离版 采用Iris、Vue、ElementUI等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Iris_EleVue Echo+EleVue前后端分离版 采用Echo、Vue、ElementUI等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Echo_EleVue Revel+EleVue前后端分离版 采用Revel、Vue、ElementUI等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Revel_EleVue GoFrame+AntdVue前后端分离版 采用GoFrame、Vue、AntDesign等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_GoFrame_AntdVue Beego+AntdVue前后端分离版 采用Beego、Vue、AntDesign等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Beego_AntdVue Gin+AntdVue前后端分离版 采用Gin、Vue、AntDesign等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Gin_AntdVue Iris+AntdVue前后端分离版 采用Iris、Vue、AntDesign等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Iris_AntdVue Echo+AntdVue前后端分离版 采用Echo、Vue、AntDesign等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Echo_AntdVue Revel+AntdVue前后端分离版 采用Revel、Vue、AntDesign等框架研发前后端分离版本 https://gitee.com/easygoadmin/EasyGoAdmin_Revel_AntdVue
简介
Restful Fast Request 是一个类似于 Postman 的 IDEA 插件。它是一个强大的 restful api 工具包插件,可以根据已有的方法帮助您快速、自动生成 url 和 params。 Restful Fast Request = API 调试工具 + API 管理工具 + API 搜索工具。 它有一个漂亮的界面来完成请求、检查服务器响应、存储你的 api 请求和导出 api 请求。插件帮助你在 IDEA 界面内更快更高效得调试你的 API。
Fast Request 为简化API调试而生
倾听用户的声音,不断提升自我,本次Fast Request更新主要内容如下:
新功能、优化项、修复项
- 兼容IDEA2022.2.4
- 全局动画配置
- 多Cookie值错误
- 导航Navigate tab加载错误
全局动画配置
开发者可以在此关闭全局动画,如果关闭了,图标将不再动
2022.2.8部分
- 自动适配下载
- @RequestParam支持name解析
- 检查更新报错
下载文件适配
当response加了,send自动适配下载
更多详情
请 ————-> 这里
OpenAPI Log Cat(下简称APIcat)是一款基于OpenAPI定义文档对nginx/阿里云日志进行分析的开源工具,和原有网络日志分析工具多从底层或常见漏洞匹配的扫描逻辑不同,得益于OpenAPI定义文档的加入,对日志分析可以深入到应用逻辑层面。
APIcat 报告-防护-检测三部曲完成第二步。
APIcat本周在原有API日志分析报告的基础上,进行了防护层级的开发工作。
实时检测日志文件,实现对日志访问的实时分析
在报告逻辑中,APIcat主要实现了全文读取日志文件的功能,在防护逻辑中,主要依靠实时读取日志来进行分析,对所有日志中记录的所有访问行为,细分成了以下几个层次:
程序显示
说明
9999
UnknownError
未知错误(内部错误,日常不会出现)
10000
Legal
合法访问
10001
Illegal_StaticView
Openapi文件中没有定义过的静态文件
10002
Illegal_UnknownUrl
Openapi文件中没有定义过的非静态文件(危险级别较静态文件高)
10003
Illegal_Method
Openapi中定义过url,但是访问方法错误
10004
Illegal_EmptyArgs
Openapi中定义过该url和对应的访问方法,但未提交任何参数
10005
Illegal_UnexpectedArgs
Openapi中定义过该url和对应的方法,但访问提交的参数不符合定义中规定的参数范围
10006
Illegal_DiffusedArgs
Openapi中定义过该url和对应的方法,但访问提交的参数被判定为滥用
联动生成Nginx IP规则,实现恶意访问防护
APIcat实时获取日志进行分析之后,目前实现了对Nginx配置的自动更新,通过配置deny/allow规则实现对恶意访问者的拦截。
APIcat 的nginx过滤方式会自动维护一个包含所有ip deny列表的文件,如果需要启用,需要在nginx配置的http段或者server段增加以下配置:
include /etc/nginx/conf.d/iptables;
路径是watch子命令配置的nginx输出日志文件路径,上述样例为默认路径,可根据自身情况修改
支持多种配置规则,细化Nginx拦截策略
配置重启Nginx命令
完成配置文件更新之后,默认会调用使得nginx重新按配置初始化
如果是docker等其他情况,支持通过以下参数设置重启指令
指定重启命令的执行目录 指定重启命令的命令
例如如果是docker-compose执行的nginx命令
指向docker-compose.yaml文件的路径 设置为”‘docker-compose exec <PROXY> nginx -s reload'”,其中<PROXY>替换为你的nginx service name,请注意因为该命令基本都是复杂命令,请使用引号将传入参数括起来
最小启动间隔
日志的检测和输出是实时探测的结果,但是在通常情况下,配置和重新加载不能根据错误实时执行,因此,设计为每隔一段时间周期执行,默认为5分钟。
这个参数可以通过修改
配置设置级别
因为nginx只能配置放行(allow)或不放行(deny),所以需要配置一个我们需要的错误级别,只有高于这个级别的,我们才针对性的采取deny的设置。
这个设置通过–nginx-level我们可以设置,默认的配置为10002,也就是Illegal_UnknownUrl,具体的级别列表见上文
配置设置错误最低次数
我们还可以设置最低的错误次数,只有超过该次数的访问者才会被认为是恶意访问者,加入不放行规则,这个判定是按用户来的,比如一个用户访问了两个错误地址,则次数为2。
这个设置通过–nginx-count我们可以设置,默认的配置为2
了解更多有关OpenAPI的使用,可以访问百家饭OpenAPI站点
近日,北京探真科技有限公司(以下简称“探真科技”)签署openKylin社区CLA(Contributor License Agreement 贡献者许可协议),正式加入openKylin开源社区。
探真科技成立于2020年7月,专注于提供全栈内生的云原生安全解决方案。探真·领航云原生安全平台基于零摩擦、零信任和持续安全的理念,在云原生应用的整个生命周期之中,构建可信镜像安全体系、确保镜像安全。同时通过人工智能赋能实现运行时状态下的威胁检测响应:偏移防御、AI 免疫防御,云原生主动防御、智能微隔离,并将这些安全能力自动嵌入CI/CD流程,帮助客户实现DevSecOps。
在加入openKylin社区后,探真科技向社区提供自主研发产品——探真领航·云原生安全平台,并成立云原生安全 SIG,共同打造云原生环境下安全可信的桌面操作系统顶级社区。
探真领航·云原生安全平台,能够帮助企业在云原生环境下快速构建应用服务生命周期安全闭环,结合CI/CD流程实现安全能力的自动化嵌入于运行。探真领航·云原生安全平台实现了容器镜像威胁扫描、安全合规检查、基于AI算法的运行时入侵防御,资产风险自动发现与智能告警排序、容器自动加固、微隔离等功能,可以帮助企业快速安全拥抱云原生,打造云原生安全闭环。
社区会员持续招募中
目前,openKylin社区会员招募正在火热进行中,欢迎更多企业伙伴加入,携手共建,打造桌面操作系统顶级社区,推动国产操作系统产业生态健康发展。详情可查看:【https://www.openkylin.top/join/partnerlist-cn.html 】
openKylin(开放麒麟)社区旨在以“共创”为核心,在开源、自愿、平等、协作的基础上,通过开源、开放的方式与企业构建合作伙伴生态体系,共同打造桌面操作系统顶级社区,推动Linux开源技术及其软硬件生态繁荣发展。
社区首批理事成员单位包括麒麟软件、普华基础软件、中科方德、麒麟信安、凝思软件、一铭软件、中兴新支点、心科技、中国电科32所、技德系统、北京麟卓、先进操作系统创新中心等13家产业同仁和行业机构。
审核:openKylin
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
漏洞描述
Snap 是适用于桌面、云和物联网的应用程序包,可自动更新、易于安装、安全、跨平台且无依赖性。snapd 是管理和维护 Snap 已安装快照的后台服务的代码存储库。
Snapd 受影响版本 snap-confine 模块的 must_mkdir_and_open_with_perms 方法存在竞争条件漏洞,当用户创建私有快照时,非特权攻击者可以结合 multipathd 中的授权绕过和符号链接攻击漏洞(CVE-2022-41974、CVE-2022-41973)将 /tmp 目录绑定到文件系统中的任意目录,进而将普通用户权限提升至ROOT权限。
影响范围
snapcore/snapd@[2.54.3, 2.57.6)
修复方案
将组件 snapcore/snapd 升级至 2.57.6 及以上版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-58112
https://nvd.nist.gov/vuln/detail/CVE-2022-3328
https://www.qualys.com/2022/11/30/cve-2022-3328/advisory-snap.txt
https://github.com/snapcore/snapd/commit/21ebc51f00b8afaa2e83a372fd29d0f5e
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
OpenStack 最新发布了一份 2022 年用户调查报告指出,OpenStack 部署在 2022 年达到了一个新的里程碑:现在拥有超过 4000 万个生产核心,与 2021 年相比增长了 60%,自 2020 年以来增长了 166%;且全球共有 300 多个公共云数据中心。
原因在于,对混合云环境和 Kubernetes 集成支持的依赖增加推动了指数增长。此项调查调基于 2021 年 8 月至 2022 年 8 月期间编目的 300 多个部署和 430 多个受访者的反馈。
“在权威人士质疑 OpenStack(世界第四大开源项目)是否已死之际,OpenInfra 基金会测得生产中的 OpenStack 内核数量达到前所未有的 4000 万个。核心服务(Nova、Neutron、Keystone、Glance 和 Ironic)的采用率仍然很高,但随着运营商发展其架构以适应新的工作负载,他们已转向 OpenStack 保护伞下的支持服务,包括 Octavia 和 Magnum。这些具体项目分别支持对混合云环境的依赖和与 Kubernetes 的集成,并作为生产就绪的 OpenStack 服务继续发展。”
各种规模的组织都在进行扩展以满足最终用户的需求。除了电信业外,OpenStack 已成为中国移动和 Verizon 等主要大型移动公司的中坚力量。日本即时通讯服务 LINE、按需云财务管理服务公司 Workday、沃尔玛实验室和雅虎以及许多其他小规模的公司也押注了 OpenStack。
另一方面,作为 OpenInfra 标准,Linux OpenStack Kubernetes Infrastructure (LOKI) 正在以越来越快的速度在生产中实现。Kubernetes 现在部署在超过 85% 的 OpenStack 部署中:73% 通过 vanilla Kubernetes,另外 12% 通过 OpenShift。OpenStack 容器编排服务 Magnum 也越来越受欢迎,现有 21% 的用户使用它运行生产工作负载 (去年仅为 16%)。
调查还指出,运行混合云环境和 OpenStack 部署的受访者也从 77% 上升到了 80%。为了实现工作负载在不同云环境之间的平稳过渡,越来越多的运营商转向 Octavia —— 一种开源的、运营商规模的负载平衡解决方案,旨在与 OpenStack 配合使用。如今已有几乎一半的生产部署都在生产中运行 Octavia,相较去年增加了 11%。
用户满意度上,OpenStack 表现稳定,NPS 为 41。用户称赞社区”能够培养和回馈的纯粹的技术人才”,并将”社区的鼓励和支持”以及项目的”社区驱动”性质列为其最大的优势。
但受访者也表示,升级仍然是头号痛点;基于此,社区决定将在下一个版本开始进行重大改变,以缓解 OpenStack 升级过程中的一些复杂问题。此外,社区还在致力于仪表板改进、项目文档改进和降低 OpenStack 的整体复杂性。
更多详情可查看完整报告。
开源圈的运营都分为哪几种?不用的运营需要哪些技能,每天都在负责什么工作呢?
在《中国开源社区 Landscape 社区畅聊》系列直播的第五期,我们邀请了 PG中文社区运营负责人王向阳(Benker)、 TiDB 开源社区运营黄漫绅( billmay | 表妹),让两位运营同学聊聊运营的日常工作,分享一些运营技巧,以及入门开源圈运营所需的一些技能,还有一些运营工作中有趣的故事…
直播期间可随时提问,嘉宾会抽取高质量问题进行解答,被选中的提问者可以获得礼品一份。
一、直播主题
- 主题:开源圈运营同学的日常
- 时间:12 月 6 日 20:00 ~ 21:00
- 平台:“OSC 开源社区” 视频号
- 主办方:COSCLC 社区 & TiDB 开源社区 & PG 中文社区
二、直播嘉宾
主持人:黄漫绅
TiDB 开源社区 社区运营
分享嘉宾:王向阳
象圈社区发起人,PG中文社区运营负责人
三、直播通知群
加入群聊,获取直播的一手通知、与其他开发者共同探讨技术(摸鱼吹牛)。
- 开发者运营&用户运营的日常是什么
- 开源社区运营需要具备哪些素养/技能?
- 开源社区运营技巧&注意事项
- 理想中的开源社区是什么样的?
- 运营中遇到的有趣的人和事
- 有趣的创业经历与故事
关于中国开源社区 Landscape 社区
COSCLC:中国开源社区 Landscape 社区,是以国内开源社区为单位的社区,旨在通过凝聚社区力量,推动国内开源生态发展。(COSCLC 具体章程等规划正在筹备中,近期公布。)
关于 《COSCLC 社区畅聊》系列直播
《COSCLC 社区畅聊》系列直播由中国开源社区 Landscape 社区(COSCLC) 推出,把目光聚焦于开源项目背后的开源社区和开源作者,让他们来畅聊一下:自己的开源项目因何而起、经历了怎样的发展,开源作者 / 社区在开源过程中的酸甜苦辣、开源项目的运营经验…
每个开源项目的背后都有不同的故事,让我们倾听这些来自社区,来自作者的声音。
近日,Serverless 开发者平台 Serverless Devs 重磅发布基于 Serverless 架构的轻量级 CI/CD 框架——Serverless-cd。Serverless-cd 是一款运行在 Serverless 架构上的功能强大而灵活,安全,低成本的CI/CD开源框架。该框架基于 Serverless Devs 开发者工具打造,通过 Serverless-cd开发者可以快速构建企业内部应用管理PaaS平台。
开发者更想关注业务价值的创造
Serverless Devs 是CNCF 沙箱孵化项目,2020年由阿里云开源,它是一个开源开放的 Serverless 开发者平台,Serverless Devs 也是业内首个支持主流 Serverless 服务 / 框架的云原生全生命周期管理的平台,致力于为开发者打造 Serverless 应用开发一站式服务,帮助解决目前的工具链之困,让开发者一键体验多云产品,极速部署 Serverless 项目。
Serverless Devs 项目为应用的开发,调试,部署,运维,监控提供全生命周期的解决方案。在实际使用中,应用部署和交付对于开发者来说仍然是一个难题。开发者希望更专注于应用的开发和价值的创造——也就是关注代码编写和应用的构建,而非应用部署和交付。
在 Serverless-cd 项目发布之前,Serverless Devs 项目通过集成的方式,集成了主流的 CI/CD 工具:https://github.com/Serverless-Devs/cicd,如 Jenkins、Github、Gitlab 等,但使用这些传统的 CI/CD 工具一般会面临如下几个问题:
- 资源利用率低:需要提前准备构建机器,在没有构建任务时,机器资源浪费;
- 任务排队:如果资源准备不充足,在业务构建的高峰期间, 任务排队时间过长;
- 隔离性差:如果某个任务执行过程中消耗大量计算/存储资源,导致其他任务失败;
- 安全问题:
- 使用平台提供的CICD服务:代码和构建机器不在同一个网络环境,不得不开放公网访问,引起安全问题。
- ECS虚机部署:多个应用同时在一个实例构建,某个恶意应用可以访问其他的应用的代码
CI/CD 流水线的 2个特点
CI/CD 流水线有两个显著的特点:
- 事件驱动
无论是接收 Webhook 自动触发,还是调用 Open Api 手动触发,对于 CICD 系统来说都是被动接收指令进行消费
- 业务明显波峰波谷
触发 CI/CD 构建的高峰一般在上班的时间段中,下班后以及晚上构建任务比较少。同时有些任务执行非常耗时,有些任务又需要大量的CPU&内存资源,很难提前进行有效的容量预估。
- 机器资源准备过少:由于资源不足导致任务执行失败,或者多个任务进行资源抢占,一直无法执行。
- 机器资源准备过多:无法充分利用,造成资源闲置浪费。
基于Serverless架构的CI/CD优势
在 Serverless 架构下,CI/CD 可以具备以下优势
- 自动弹性
Serverless 平台会为每个构建任务分配一个全新的实例,保证每个任务之间互不影响。再也不用担心资源不足导致任务失败,也避免了由于资源不足导致任务一直排不上队的情况。
- 按价值付费
在业务波谷(晚上或者下班后)期,只有少量甚至没有任务执行,资源就出现了闲置和浪费。Serverless 的理念是帮助客户按实际产生的价值付费,只有实实在在的发生了构建行为,才会产生费用。
- 免运维
Serverless 弹性是按照请求进行水平扩容的,开发者无需关注底层资源调度和运维的工作,可以心无旁骛的实现业务开发和价值创造。
Serverless-cd 技术架构
Serverless-cd 是完全遵循 Serverless 架构最佳实践,在规范和生态层面参考 Github Action 的实现。下面是Serverless-cd 部署 Serverless Devs 应用的一段 YAML:
Serverless-cd 采用的是经典的 Master Worker 模型,采用事件驱动的架构,整体的架构如下图:
触发方式
触发器承担事件驱动中的生产者的角色,Serveless-cd暂时提供了三种触发方式:
- 通过Webhook自动触发:
开发者可以配置对应的触发条件:比如Push到Master分支,发起Merge Request。这是一种非常敏捷的开发和交付的方式
- 通过Open api触发:
Serverless cd平台的所有的能力都提供开放了Open api。以便开发者更好的构建企业内部的PaaS平台
- 通过CLI触发:
从技术的角度来看Serverless-Devs本质是一个CLI工作,提供了组件化的能力,所谓的组件化也就是通过热更新的机制,让开发者根据自己的需求进行拓展。Serverless-cd通过自定义组件,让开发者可以通过通过命令行直接操作。 当然我们也在计划接入更多的触发类型,比如 cloudevents 触发, 定时触发等
Serverless(FaaS) 平台
FaaS平台是整个平台的核心部分,承担事件驱动中的消费者角色,采用的是经典的 Master Worker 模型。
Master Worker 模型在 Serverless 架构的优势
传统的Master Woker部署,为了保证Master节点的高可用,需要部署三个节点搭配负载均衡以及健康检查,来保证Master节点高可用。在Serverless架构中,实例会根据请求自动弹性扩容,Master节点天然具备高可用能力,无论在可靠性,还是灵活性都有较大的优势
Master 函数作用
Master 函数本质是一个 HTTP 类型函数,作为整体流量的入口,同时也是整个系统的大脑,承担着非常重要职责。
- 安全保障
- 公网密钥校验 Master 暴露的 URL 地址是可以公网访问的,为了防范恶意请求,serverless-cd 系统在下发 URL 的同时也会下发签名规则。如果是恶意的请求,就无法通过校验,来保证系统的安全性
- VPC 绑定
也支持绑定VPC环境,代码仓库和serverless-cd 服务绑定在同一个VPC环境,通过Webhook触发。公网用户无法直接访问,从网络上保证了绝对的安全
- 过滤请求
我们每天在 Git Repository 会触发各种事件,比如新建 ISSUE,PUSH 代码,发起 Merge Request 等。这些动作都会通过 Webhook 触发,开发者可以配置规则过滤相关事件。下面是一个示例:代表在 GitHub 平台提交到Master 的代码才会触发
- 路由转发
Master 函数负责将请求分发给 Worker 函数,Worker 函数所有的行为都由 Master 函数控制
Worker函数作用
Worker 函数本质是一个事件(Event)函数,只和 Master 函数通信,唯一的职责是处理 Pipeline,可以长时间运行。
自定义 pipeline
serverless-cd 支持三种方式自定义 pipeline
shell 脚本
shell 脚本是最容易理解也是使用最广泛的
zx 脚本
google/zx 允许开发者通过javascript语法来编写您的Shell脚本
使用自定义应用(NPM Package)进行扩展
Serverless-cd也支持封装通用的NPM包进行扩展:比如钉钉通知,企业微信通知,OSS文件上传等通用能力,都可以通过自定义应用扩展。自定义应用本质是发布在NPM仓库的包。
快速体验
提前准备
serverless-cd 部署完全是基于云进行,依赖相关云产品也是Serverless化。
- 函数计算FC:整个系统的计算能力运行在FC上
- 日志服务SLS:分布式日志存储服务,更好的定位和发现问题
- 对象存储OSS:用于存储日志信息
- 表格存储Tablestore: 应用和任务的云数据信息存储
本地部署
- 下载安装 Serverless Devs: (版本必须大于2.1.7),详细操作引导请参考Serverless Devs 安装文档
- 配置密匙信息:, 详细操作引导请参考配置阿里云秘钥
- 初始化项目:
- 进入项目并部署:
Serverless-cd RoadMap
开源共建
Serverless-cd 是业界首个基于 Serverless 架构的 CI/CD 的探索,欢迎大家关注我们的开源地址:https://github.com/Serverless-Devs/serverless-cd 。Serverless-cd 刚刚开源,还有大量的细节和工作,期待与更多开发者一起共建 Serevrless 生态,让开发者可以心无旁骛的专注业务开发和价值创造。
更多内容关注 Serverless 微信公众号(ID:serverlessdevs),汇集 Serverless 技术最全内容,定期举办 Serverless 活动、直播,用户最佳实践。
可以看到,这个语句中只有两个查询表, 4 个谓词条件,特点是在子查询中使用了外表的字段,我们也管这种叫做相关子查询,而在驱动表里则使用了聚合。
这里科普一下,驱动表(Driving Table),也称外层表(Outer Table),顾名思义,驱动表是用来驱动查询的。驱动表仅仅用于 Nested-Loop Join 和 Hash Join,简单来说,就是用来最先获得数据,并以此表的数据为依据,逐步获得其他表的数据,直至最终查询到所有满足条件的数据的第一个表。
介绍完简单的语句之后,说下我们在这里的优化方案。
常见的子查询优化
子查询合并:如果两个查询块语义等价,则能够将其合并成一个子查询,这样多次 TableScan、TableJoin 都可以消减为单表的 Scan、Join。
子查询展开:又称为子查询上拉,把子查询的查询谓词和表提到上层中,变为 join 操作,这样子查询就不存在了,连接方法和连接顺序也可以随意调整了,如 Nested-Loop Join 可以换成 Hash Join 等等,我们的 Q4 也就是通过这种方式进行优化的。
针对 Q4 的优化方案
上一段也有说到,针对 Q4,我们需要是子查询展开优化。就是将子查询重写为同语义的 Semi-join(半连接), 然后执行 Semi-join 即可。
mysql 的子查询展开代码流程
resolve_subquery :对subqueryitem进行解析,收集能够unnesting为semi-join的所有subqueryblock,这里有很多的严格限制条件(mysql5.7有11个限制条件),基本来说就是只允许 SPJ 的 subquery 进行 unnesting,具体条件可详见函数中的代码及注释。可以做 unnesting,会把这个 subquery 的 item 对象,加入到外层 select_lex::sj_candidates 中后续使用,无法做 unnesting 的,则调用 select_transformer,尝试做 IN->EXIST 的转换。
convert_subquery_to_semijoin: 将真正可以展开的(内层有 table),建立 sj-nest 这个 TABLE_LIST 对象, 基本思路就是想将 inner table 放到外层的 Join list 中, 内层的谓词条件都放在外层对应的 ON/WHERE 条件上。sj-nest 是后续优化 Semi-join 的一个重要结构,会用子查询 SELECT_LEX 中的内容对其进行填充。
我们的优化方案
首先是 MySQL-5.7 只展开 in 子查询,无法展开 exists 子查询,而我们的 Q4 就是一个 exists 子查询;再者我们的 Tianmu 查询引擎目前没有执行 Semi-join 流程,所以即使是 in 子查询也无法在 tianmu 引擎中执行。所以我们的优化方案也就不言自明了,首先在 MySQL-5.7 增加针对 exists 子查询展开的这个 case,然后让我们的 tianmu 引擎能够执行 semi-join。
优化器改写
我们的 exists 语句改写参照 in 语句进行的,但是跟 in 语句稍有不同。首先 resolve_subquery 函数中,判断是 exists 则不进行转换,这里我们把他加回来;resolve_subquery只是进行的判断,是否能够转换,真正的转换操作是在 convert_subquery_to_semijoin 函数中进行的,在 convert_subquery_to_semijoin 中,我们把子查询所有用到的表上提到 sj_nest,把所有的谓词上提到 sj_cond, in 子查询因为 in 子查询是一个谓词,所以需要针对谓词进行单独处理,exists 则不需要,直接上提。但是这里我们还需要做一个操作,就是把子查询中用到的外表的表达式放到 sj_outer_exprs 中,所有用到内表的表达式放到 sj_inner_exprs 中,这个 mysql 的执行器或者 tianmu 执行器都会用到。我们可以使用 EXPLAIN 语句在查询、调试我们优化后的语句:
子查询被成功上提到外层查询中,接下来只要能够正确执行 Semi-join 就大功告成了。
Semi-join 的执行策略
MySQL 的 Semi-join 执行策略
Semi-join 的执行概括来看就是想办法把内层的查询进行去重。在写我们自己的 Semi-join 执行前,我们先学习一下 MySQL 中执行的方式,主要有 4 种,分别是:
-
DuplicateWeedout,使用临时表针对 join 序列中,join 内表产生的重复部分,做消除处理;内层子查询的表通过在外层表的 rowid 上建立唯一索引来对重复生成的 country 行数据做去重。
-
FirstMatch,比较好理解,在选中内部表的第 1 条与外表匹配的记录后,就跳过后续的匹配过程,从外层表的下一条记录重新开始,从而也达到了去重的目的。
-
LooseScan,把 inner-tables 中的第一个表,其数据基于索引进行分组,取每组第一条数据向后做匹配。
-
Materialize,这个是想法上最直观的,通过将 inner-table 去重,并固化成临时表,遍历 outer-table,然后在固化表上去寻找匹配。
Tianmu 的 Semi-join 执行策略选择
根据我们的执行引擎特点,最后决定使用实现 DuplicateWeedout 和 Materialize 两种执行策略。
因为 Tianmu 是列存,内部没有 row by row 的执行流程,所以放弃了 FirstMatch;而且只有主键,没有索引, LooseScan 其实主要使用索引,所以也放弃这一方案了。
DuplicateWeedout
DuplicateWeedout 方式其实相对比较容易实现,可以复用现有的 inner-join 执行流程,其实 semi-join 跟 inner-join 的主要区别就内表的去重,这个确实是我们的难点,因为 mysql 这里使用了,默认主键(rowid)来进行内表的去重,而我们的此概念,所以在这里我们又增加一个限制,就是给必须外表必须包含主键,才能子查询展开。另外一个难点是我们的 group by 处理,因为我们 group by 和 distinct 是同一个算子,而且做不到先去重后聚合这种操作,所以这里我们增加了一个临时表,专门用来去重,然后再分组聚合,这里又会遇到新的问题,因为 SPJ 和 非 SPJ 语句用到的 Field 是不同的, 例如我们需要将 count(*), min(xxx),avg(xxx) 等 Field 中聚合去掉,保留原始 Field, 然后等去重之后,再添加聚合属性。细节处理很多,大家可以直接看代码。
我们来看一个具体例子:
从例子中我们可以看到,T:-2 这个临时表是用来去重的,T:-4 这个临时表是用来聚合的,最后物化的结果集也是 T:-4 这个临时表。
Materialize
Materialize 方式是直接将内表进行物化,当然如果内表包含相关条件,则无法直接进行物化,这里需要把需要相关条件提出来,变成外表的 join 条件,注意这里执行器需要 join 的表换成我们为内表创建的临时表,而不是原来的物理表。这种执行方式不是有必须包含主键的限制,但是他有两个问题,首先是他走了两遍查询流程,比 DuplicateWeedout 要慢,然后就是相关条件的提取非常困难,目前还是无法在所有场景下都支持, 所以最后的代码中没有包含使用 Materialize 方式的代码,后续如果必须有主键这个限制很大,我们会考虑把 Materialize 的方式加回来,但是肯定是能使用 DuplicateWeedout, 优先使用 DuplicateWeedout。
总结
通过子查询优化这个,发现Tianmu引擎中部分语句性能慢的原因是优化器还不够完美,相比其他组件,我们目前的优化器可能没做那么精致,虽然我们的大部分语句性能都不错,但是遇到个别复杂语句时性能却不够给力。我们后续会 Tianmu 的 Join order 做优化,敬请期待。
以上就是本次分享,欢迎大家批评指正,我们会持续发布 StoneDB 的研发分享文章,希望能帮助到大家学习数据库和 StoneDB 的相关知识。
摘要:本文重点介绍几种通过优化Cache使用提高程序性能的方法。
本文分享自华为云社区《编译器优化那些事儿(7):Cache优化》,作者:毕昇小助手。
引言
软件开发人员往往期望计算机硬件拥有无限容量、零访问延迟、无限带宽以及便宜的内存,但是现实却是内存容量越大,相应的访问时间越长;内存访问速度越快,价格也更贵;带宽越大,价格越贵。为了解决大容量、高速度、低成本之间的矛盾,基于程序访问的局部性原理,将更常用数据放在小容量的高速存储器中,多种速度不同的存储器分层级联,协调工作。
图1 memory hierarchy for sever [1]
现代计算机的存储层次可以分几层。如图1所示,位于处理器内部的是寄存器;稍远一点的是一级Cache,一级Cache一般能够保存64k字节,访问它大约需要1ns,同时一级Cache通常划分为指令Cache(处理器从指令Cache中取要执行的指令)和数据Cache(处理器从数据Cache中存/取指令的操作数);然后是二级Cache,通常既保存指令又保存数据,容量大约256k,访问它大约需要3-10ns;然后是三级Cache,容量大约16-64MB,访问它大约需要10-20ns;再接着是主存、硬盘等。注意,CPU和Cache是以word传输的,Cache到主存以块(一般64byte)传输的。
前文提到了程序的局部性原理,一般指的是时间局部性(在一定时间内,程序可能会多次访问同一内存空间)和空间局部性(在一定时间内,程序可能会访问附近的内存空间),高速缓存(Cache)的效率取决于程序的空间和时间的局部性性质。比如一个程序重复地执行一个循环,在理想情况下,循环的第一个迭代将代码取至高速缓存中,后续的迭代直接从高速缓存中取数据,而不需要重新从主存装载。因此,为了使程序获得更好的性能,应尽可能让数据访问发生在高速缓存中。但是如果数据访问在高速缓存时发生了冲突,也可能会导致性能下降。
篇幅原因,本文重点讨论编译器在Cache优化中可以做哪些工作,如果读者对其他内存层次优化感兴趣,欢迎留言。下面将介绍几种通过优化Cache使用提高程序性能的方法。
对齐和布局
现代编译器可以通过调整代码和数据的布局方式,提高Cache命中率,进而提升程序性能。本节主要讨论数据和指令的对齐、代码布局对程序性能的影响,大部分处理器中Cache到主存是以Cache line(一般为64Byte,也有地方称Cache块,本文统一使用Cache line)传输的,CPU从内存加载数据是一次一个Cache line,CPU往内存写数据也是一次一个Cache line。假设处理器首次访问数据对象A,其大小刚好为64Byte,如果数据对象A首地址并没有进行对齐,即数据对象A占用两个不同Cache line的一部分,此时处理器访问该数据对象时需要两次内存访问,效率低。但是如果数据对象A进行了内存对齐,即刚好在一个Cache line中,那么处理器访问该数据时只需要一次内存访问,效率会高很多。编译器可以通过合理安排数据对象,避免不必要地将它们跨越在多个Cache line中,尽量使得同一对象集中在一个Cache中,进而有效地使用Cache来提高程序的性能。通过顺序分配对象,即如果下一个对象不能放入当前Cache line的剩余部分,则跳过这些剩余的部分,从下一个Cache line的开始处分配对象,或者将大小(size)相同的对象分配在同一个存储区,所有对象都对齐在size的倍数边界上等方式达到上述目的。
Cache line对齐可能会导致存储资源的浪费,如图2所示,但是执行速度可能会因此得到改善。对齐不仅仅可以作用于全局静态数据,也可以作用于堆上分配的数据。对于全局数据,编译器可以通过汇编语言的对齐指令命令来通知链接器。对于堆上分配的数据,将对象放置在Cache line的边界或者最小化对象跨Cache line的次数的工作不是由编译器来完成的,而是由runtime中的存储分配器来完成的[2]。
图2 因块对齐可能会浪费存储空间
前文提到了数据对象对齐,可以提高程序性能。指令Cache的对齐,也可以提高程序性能。同时,代码布局也会影响程序的性能,将频繁执行的基本块的首地址对齐在Cache line的大小倍数边界上能增加在指令Cache中同时容纳的基本块数目,将不频繁执行的指令和频繁指令的指令放到不同的Cache line中,通过优化代码布局来提升程序性能。
利用硬件辅助
Cache预取是将内存中的指令和数据提前存放至Cache中,达到加快处理器执行速度的目的。Cache预取可以通过硬件或者软件实现,硬件预取是通过处理器中专门的硬件单实现的,该单通过跟踪内存访问指令数据地址的变化规律来预测将会被访问到的内存地址,并提前从主存中读取这些数据到Cache;软件预取是在程序中显示地插入预取指令,以非阻塞的方式让处理器从内存中读取指定地址数据至Cache。由于硬件预取器通常无法正常动态关闭,因此大部分情况下软件预取和硬件预取是并存的,软件预取必须尽力配合硬件预取以取得更优的效果。本文假设硬件预取器被关闭后,讨论如何利用软件预取达到性能提升的效果。
预取指令prefech(x)只是一种提示,告知硬件开始将地址x中的数据从主存中读取到Cache中。它并不会引起处理停顿,但若硬件发现会产生异常,则会忽略这个预取操作。如果prefech(x)成功,则意味着下一次取x将命中Cache;不成功的预取操作可能会导致下次读取时发生Cache miss,但不会影响程序的正确性[2]。
数据预取是如何改成程序性能的呢?如下一段程序:
假设一个Cache line可以存放两个double素,当第一次访问a[0]时,由于a[0]不在Cache中,会发生一次Cache miss,需要从主存中将其加载至Cache中,由于一个Cache line可以存放两个double素,当访问a[1]时则不会发生Cache miss。依次类推,访问a[2]时会发生Cache miss,访问a[3]时不会发生Cache miss,我们很容易得到程序总共发生了50次Cache miss。
我们可以通过软件预取等相关优化,降低Cache miss次数,提高程序性能。首先介绍一个公式[3]:
上述公式中L是memory latency,S是执行一次循环迭代最短的时间。iterationAhead表示的是循环需要经过执行几次迭代,预取的数据才会到达Cache。假设我们的硬件架构计算出来的iterationAhead=6,那么原程序可以优化成如下程序:
由于我们的硬件架构需要循环执行6次后,预取的数据才会到达Cache。一个Cache line可以存放两个double素,为了避免浪费prefetch指令,所以prologue和steady state循环都展开了,即执行prefetch(&a[0])后会将a[0]、a[1]从主存加载至Cache中,下次执行预取时就无需再次将a[1]从主存加载至Cache了。prologue循环先执行数组a的前12个素的预取指令,等到执行steady state循环时,当i = 0时,a[0]和a[1]已经被加载至Cache中,就不会发生Cache miss了。依次类推,经过上述优化后,在不改变语义的基础上,通过使用预取指令,程序的Cache miss次数从50下降至0,程序的性能将会得到很大提升。
注意,预取并不能减少从主存储器取数据到高速缓存的延迟,只是通过预取与计算重叠而隐藏这种延迟。总之,当处理器有预取指令或者有能够用作预取的非阻塞的读取指令时,对于处理器不能动态重排指令或者动态重排缓冲区小于我们希望隐藏的具体Cache延迟,并且所考虑的数据大于Cache或者是不能够判断数据是否已在Cache中,预取是适用的。预取也不是万能,不当的预取可能会导致高速缓存冲突,程序性能降低。我们应该首先利用数据重用来减少延迟,然后才考虑预取。
除了软件预取外,ARMv8还提供了Non-temporal的Load/Store指令,可以提高Cache的利用率。对于一些数据,如果只是访问一次,无需占用Cache,可以使用这个指令进行访问,从而保护Cache中关键数据不被替换,比如memcpy大数据的场景下,使用该指令对于其关键业务而言,是有一定的收益的。
循环变换
重用Cache中的数据是最基本的高效使用Cache方法。对于多层嵌套循环,可以通过交换两个嵌套的循环(loop interchange)、逆转循环迭代执行的顺序(loop reversal)、将两个循环体合并成一个循环体(loop fusion)、循环拆分(loop distribution)、循环分块(loop tiling)、loop unroll and jam等循环变换操作。选择适当的循环变换方式,既能保持程序的语义,又能改善程序性能。我们做这些循环变换的主要目的是为了实现寄存器、数据高速缓存以及其他存储层次使用方面的优化。
篇幅受限,本节仅讨论循环分块(loop tiling)如何改善程序性能,若对loop interchange感兴趣,请查阅。下面这个简单的循环:
我们假设数组a、b都是超大数组,m、n相等且都很大,程序不会出现数组越界访问情况发生。那么如果b[j]在j层循环中跨度太大时,那么被下次i层循环重用时数据已经被清出高速缓存。即程序访问b[n-1]时,b[0]、b[1]已经被清出缓存,此时需要重新从主存中将数据加载至缓存中,程序性能会大幅下降。
我们如何通过降低Cache miss次数提升程序的性能呢?通过对循环做loop tiling可以符合我们的期望,即通过循环重排,使得数据分成一个一个tile,让每一个tile的数据都可以在Cache中被hint[4]。从内层循环开始tiling,假设tile的大小为t,t远小于m、n,t的取值使得b[t-1]被访问时b[0]依然在Cache中,将会大幅地减少Cache miss次数。假设n-1恰好被t整除,此时b数组的访问顺序如下所示:
经过loop tiling后循环变换成:
假设每个Cache line能够容纳X个数组素,loop tiling前a的Cache miss次数为m/X,b的Cache miss次数是m*n/X,总的Cache miss次数为m*(n+1)/x。loop tiling后a的Cache miss次数为(n/t)*(m/X),b的Cache miss次数为(t/X)*(n/t)=n/X,总的Cache miss次数为n*(m+t)/xt。此时,由于n与m相等,那么loop tiling后Cache miss大约可以降低t倍[4]。
前文讨论了loop tiling在小用例上如何提升程序性能,总之针对不同的循环场景,选择合适的循环交换方法,既能保证程序语义正确, 又能获得改善程序性能的机会。
小结
汝之蜜糖,彼之砒霜。针对不同的硬件,我们需要结合具体的硬件架构,利用性能分析工具,通过分析报告和程序,从系统层次和算法层次思考问题,往往会有意想不到的收获。本文简单地介绍了内存层次优化相关的几种方法,结合一些小例子深入浅出地讲解了一些内存层次优化相关的知识。纸上得来终觉浅,绝知此事要躬行,更多性能优化相关的知识需要我们从实践中慢慢摸索。
参考
-
John L. Hennessy, David A. Patterson. 计算机体系结构:量化研究方法(第6版). 贾洪峰,译
-
Andrew W.Apple, with Jens Palsberg. Modern Compiler Implenentation in C
-
http://www.cs.cmu.edu/afs/cs/academic/class/15745-s19/www/lectures/L20-Global-Scheduling.pdf
-
https://zhuanlan.zhihu.com/p/
关注,第一时间了解华为云新鲜技术~
白屏到高清彩屏,带电子屏的产品数量激增;二是人机界面更加酷炫流畅,交互功能趋向智能化。图形
用户界面(
GUI
)快速推进了嵌入式产品的智能化,大幅提升了用户体验,降低了用户使用门槛,普惠
更广泛的社会人群。
OneOS
,在各种各样带屏幕的
MCU
产品上大放光彩。比如:智能家居、工业
控制、汽车表盘、医疗设备、穿戴设备等,可谓是大有可为!如果说
MCU
上的
CPU
核是灵魂,那么屏幕
则是它美丽的容颜,让人一眼难忘。
1 组件信息
本轻量化图形组件基于 LVGL 移植,目前支持版本: LVGL7.9 及 LVGL8.2 。支持之初,我们考量了市面上常用的开源图形框架,最终在 QT for MCU , LVGL ,以及 GUIX 三者中选择了 LVGL ,也和其 LVGL开源项目的发起者 Kiss–Vámosi 建立了友好的合作。而后,我们增加了 Arm–2D 用以支撑硬件加速,以及更小资源的图形显示。
目前为止,本轻量化图形界面GUI组件达到如下的设计目标及功能:
- 强大的构建块,例如按钮、图表、列表、滑块、图像等
- 带有动画、抗锯齿、不透明度、平滑滚动的高级图形
- 支持各种输入设备,如触摸板、鼠标、键盘、编码器等
- 具有类似 CSS 样式的完全可定制的图形素
- 独立于硬件:与任何微控制器或显示器一起使用
- 即具有高级图形效果,也可进行单帧缓冲区操作
- 用C编写以获得最大的兼容性(C++ 兼容)
- 多语言支持 UTF-8 编码
- 多显示器支持,即同时使用多个TFT、单色显示器
- 可扩展:能够以很少的内存运行(64 kB Flash,16 kB RAM)
- 高性能:在Cortex-M4架构MCU芯片,GUI渲染帧率达到40FPS
2 开始体验
体验的第一步就是高效使用 menuconfig 对轻量级框架进行快速使用和配置。该章节对配置进行了较为详细的阐明。
touch 和 lcd 是 GUI 的输入输出设备,选中 Enable LVGL 即可使能 LVGL ,目前支持的版本为LVGL7.9 和 LVGL8.2 。
以上是适配支持的 LVGL 主要 menuconfig 配置。从上到下一一解释。
- LVGL basic menu 是 LVGL 最基本的配置,也是最重要的配置
- Widget usage 是对基础控件的支持与使能
- Extra Widgets 是对额外的高级控件的支持与使能
- Themes 是自带的一些主题
- Layouts 布局
- Text Settings 文本编码设置
- Font usage 字体选择
- LVGL FileSystem 文件系统支持
- LVGL Log 信息打印辅助开发
- LVGL Asserts 断言
- Third party Lib 第三方库
- Extra 其它功能
- Enable LVGL examples 一些简单的示例
- Enable LVGL Demo 一些复杂的示例
LVGL basic menu
- LVGL 的单绘制缓冲区的行数
- 默认显示刷新周期, LVGL 将在此期间重新绘制更改的区域
- 输入设备读取周期
- GUI 任务的优先级设置
- GUI 任务的栈大小设置
- GUI 任务的默认睡眠时间
- 使能 LVGL 双绘制缓冲区
- 显示 CPU 使用率和 FPS 计数显示
- 显示已用内存和内存碎片
- LVGL 最小化配置,一般用于硬件资源很小的情况
- 使能硬件加速
- 使能复杂绘图引擎
3 提高帧率
帧率FPS是图像领域中的定义,是指画面每秒传输帧数,通俗来讲就是指动画或视频的画面数。FPS是 测量用于保存、显示动态视频的信息数量。每秒钟帧数越多,所显示的动作就会越流畅。通常,要避免动作不流畅的最低是10。对于帧率,我们主要关注以下几个方面:
- 硬件本身性能
- OneOS-Lite系统影响
- LVGL本身
通常,要使得FPS更高,硬件选型是第一步
- 内核,处理能力越强,对FPS会有提升。
- 内存,尽量选择SRAM,对FPS提升很大,SDRAM相比于SRAM逊色不少。
- 传输方式SPI/LCD/DSI,使用SPI传输缓存数据至屏幕,显然不如LCD或者DSI。
- 具有专门处理图形图像的硬件,比如stm32的DMA2D。
- 更小的屏幕(分辨率)。
OneOS-Lite系统影响
LVGL本身是运行在OneOS之上的,因此,OneOS的配置会对帧率产生影响。硬件的支持也需要系统的管理。
- tick frequecy设置低一些,可能会提高帧率。想一想也是哈,tick frequecy影响的是时钟中断。设置低一些,时钟中断会来得没有那么频繁。
- 尽量使用SRAM。即使同样是SRAM,使用全局变量会比使用malloc分配,获得更高的帧率。想一 想也是哈,内存管理需要消耗时间。
- OneOS-Lite支持LTDC,DSI,DMA2D等。
- 不要让lvgl优先级太低,如果更高优先级的任务频繁执行,会影响图形显示性能。
- 尽量让存储帧缓冲器的存储器仅用于帧缓冲,如果用于存储帧缓冲器的存储器还用于其他应用,那可能会影响系统的图形性能。
- 使用更高的优化级别,能提高帧率。
VGL本身的配置也是影响其性能
- 不要打开性能监控 LV_USE_PERF_MONITOR && LV_USE_MEM_MONITOR
- 如果支持,建议开启相关硬件加速,比如: LV_USE_GPU_STM32_DMA2D
- 建议帧缓存区不要低于屏幕的1/4,建议双缓存
4 运行Demo
Benchmark 是LVGL性能测试的测试用例。其在矩形、边框、阴影、文本、图像混合、图像变换、混合模式等各种情况下进行性能测试。测试期间对象的大小和位置使用伪随机数设置,以使得性能测试可重复。我们现在来运行它!
使用menuconfifig配置Benchmark性能测试用例,并使用keil或者gcc编译,并烧写程序到stm32f469-st-disco板子上去。
FPS的代码测量原理如下:
- 构造scene_dsc_t结构体,并在其中保存各种场景下的帧率测试所需数据,包含:场景名、用于场景测试的回调函数、消耗渲染时间、刷新次数,以及权重。其中测试场景48个,叠加显示不透明度与完全不透明度方式,则测试总场景96个。
- 在显示驱动的回调函数 monitor_cb中,实现每一个测试场景的累积渲染时间和帧数。获取到此数据后,便可得到每秒钟帧数,即FPS=帧数/累积渲染时间。
- 在lv_demo_benchmark帧率测试入口函数中,调用scene_next_task_cb函数,并在其中调用每一个scene_dsc_t结构体中的场景测试回调函数,对每一个场景进行测试。
- 测试完每一个场景,即可得到每一个场景对应的帧率FPS,通过加权平均的方式,获取到平均帧率。
5 未来与期待
最后,轻量化图形组件仍然在持续地迭代开发中,并计划加入更多的功能,目前已计划的有:
- 增加高级语言JS的支持增加高级语言MicroPython的支持
- 增加字体转换库
- 增加图片转换库
🌷
。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
ShopWind 电商系统在 v3.4.x 版本加入了数据采集功能,支持淘宝、天猫、京东、1688、拼多多商品一键采集到平台的功能,你只需要输入商品详情页链接,就可以批量实现导入,导入的数据包括:商品标题,价格,库存,主图,规格(包括规格图),描述等字段。
一、使用采集功能前,您需要先配置数据采集组件秘钥,秘钥申请:https://www.99api.com/Login?log=5&referee=19843
二、进入商家后台 -》商品管理 -》采集商品
三、输入淘宝京东等商品详情页地址(支持批量),选择数据来源平台后提交
四、导入后如图 3 所示
$ https://www.xujun.org/bin/phalapi-buildcode Wecome to use https://www.xujun.org/bin/phalapi-buildcode command tool v0.0.1 Example: https://www.xujun.org/bin/phalapi-buildcode --a User/Reg Usage: Command [options] [arguments] --a 创建一个API层文件 --d 创建一个Domain层文件 --m 创建一个Model层文件
软件 版本 备注 OpenHarmony 3.2 Beta4 NA Public SDK Ohos_sdk_public 3.2.9.2 (API Version 9 Beta4) 面向应用开发者提供,不包含需要使用系统权限的系统接口。通过DevEco Studio默认获取的SDK为Public SDK。 Full SDK Ohos_sdk_full 3.2.9.2 (API Version 9 Beta4) 面向OEM厂商提供,包含了需要使用系统权限的系统接口。使用Full SDK时需要手动从镜像站点获取,并在DevEco Studio中替换,具体操作可参考替换指南。 HUAWEI DevEco Studio(可选) 3.1 Canary1 OpenHarmony应用开发推荐使用。 HUAWEI DevEco Device Tool(可选) 3.1 Beta1 OpenHarmony智能设备集成开发环境推荐使用。
漏洞描述
snakeYAML 是一个将 YAML 文件与 Java 对象相互转换的开源代码库。
snakeYAML 1.3.0 版本中的 Constructor() 类由于不限制在反序列化期间可以实例化的类型,在使用 Constructor() 类反序列化攻击者可控的 yaml 内容时会受到反序列化漏洞的影响,攻击者可利用此漏洞进行远程代码执行。用户在解析不受信任的内容时可使用 SnakeYaml 的 SafeConsturctor 类进行反序列化来缓解此漏洞。
影响范围
org.yaml:snakeyaml@[1.4, 1.33]
修复方案
官方暂未发布相关补丁,请关注官方公告:https://bitbucket.org/snakeyaml/snakeyaml/src/master/
参考链接
https://www.oscs1024.com/hd/MPS-2022-9425
https://nvd.nist.gov/vuln/detail/CVE-2022-1471
https://github.com/google/security-research/security/advisories/GHSA-mjmj-j48q-9wg2
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
CakePHP 是一个运用了诸如 ActiveRecord、Association Data Mapping、Front Controller 和 MVC(model–view–controller) 等著名设计模式的开源 Web 框架,它以 Ruby on Rails 的概念为模型,并在 MIT 许可下进行分发。
CakePHP 4.4.8 现已发布,这是 4.4 分支的维护版本,修复了几个社区报告的问题。
- 在如何处理代理标头方面,将 ServerRequest::scheme() 和 Uri::getScheme() 对齐
- 改进旧的 PaginatorInterface 别名的兼容性
- 修复了在没有名称或表的情况下创建表类,并调用 getAlias() 时的无限循环
- 改进 assertMailSentWith 与数组值的比较
- 修复了 sortDefault 和 directionDefault 不适用于多分页的问题
- 改进的类型提示和 API 文档
更新公告:https://github.com/cakephp/cakephp/releases/tag/4.4.8
OpenZFS 2.1.7 已发布,这是开源 ZFS 文件系统实现的最新版本,与现代 Linux 和 FreeBSD 系统兼容。
与 5.19 相比,OpenZFS 2.1.7 提供了数十个错误修复,同时将 Linux 内核支持扩展到 Linux 6.0 稳定版,意味着OpenZFS 2.1.7 支持从 Linux 3.10 到 Linux 6.0 版本的内核。
OpenZFS 2.1.7 的错误修复包括修复 Clang 编译问题、修复多个空指针取消引用、CI 更新,以及一些特定于 FreeBSD 的修复。
- zfs-2.1.7:将 ubuntu-20.04 用于 zloop 和 sanity 构建器
- 修复接收快照后设置 large_block 功能 #13699 #13782
- 修复 dbuf_prefetch_indirect_done() 中的 NULL 指针取消引用 # 14210
- Lua:修复 lua_strx2number() 中的错误位移位 #14204
- 修复 clang 13 编译错误 #13551
- 删除最终的 K&R 定义 #13447
- 模块:zfs:vdev_removal:删除未使用的 num_indirect #13304
- 测试:cmd:draid:删除未使用和未记录的 -v #13304
- linux: libspl: 区域: () -> (void) #12968
- 将 multipathd.target 更正为 .service #12709 #14171
- 修复 arc_p 激进增加 #14137 #14120
- FreeBSD:修复 zfs_ioctl_ozfs_to_legacy() 中的越界读取问题 #14135
更多详情可查看 release note。
近日在旧金山举行了一年一度的 OpenZFS 开发者峰会,会议主题包括介绍 OpenZFS 现状、亚马逊 AWS 如何大规模使用 OpenZFS,以及开发者目前正在解决的一些优化和改进等内容。延伸阅读:
- OpenZFS 开发工作重点:改进压缩、提升性能以及引入 uZFS 等
Redmine 4.2.9 和 5.0.4 已经发布。Redmine 是一个网页界面的项目管理与缺陷跟踪管理系统的自由及开放源代码软件工具。它集成了项目管理所需的各项功能:日历、燃尽图和甘特图以协助可视化表现项目与时间限制,问题跟踪和版本控制。此外,Redmine 也可以同时处理多个项目。
此次更新包含 4 个重要的安全修复,包括 Redmine 5.0 中引入的访问控制问题,允许未经身份验证的用户下载与 WikiContentVersion 关联的所有附件,因此官方强烈建议尽快升级。可以查看 Security_Advisories 以获取更多信息。
下载地址:https://www.redmine.org/projects/redmine/wiki/Download
主要更新内容有:
- 当活动页面上没有“Next”按钮时不必要地关闭 li 素
- wiki_syntax.css 中重复的垂直对齐属性
- 所有的系统测试在 4.2-stable 分支上失败,出现 “ArgumentError: unknown keyword: :desired_capabilities”
- 限制 puma < 6.0.0 以避免系统测试错误
- 当 Ruby 版本< 2.7 时,将 mocha 版本限制为 < 2.0.0,以避免测试错误
- 如果当前项目有子项目,项目字段的只读权限将被忽略
- 不允许查询未知的 display_type
- 序列化日期或时间对象的插件导致 Psych::DisallowedClass 异常
- 由于 blockquote 的引用,textile formattin 中存在持续的 XSS
- Redmine 包含一个跨站脚本漏洞
更多详情可查看 Changelog。
Android Studio 2022.1.1 (Electric Eel) 发布了首个 RC 版本。
下载地址:https://developer.android.com/studio/preview/index.html
Android Studio 2022.1.1 值得关注的变化:
- Live Edit
在 Android Studio Electric Eel 中,开发者可以使用 Live Edit 将代码的变化实时部署到模拟器或设备上,而不必等待构建或部署的完成,因此可以更快地创建应用程序。
- SDK insights
该工具支持从新的 Google Play SDK Index 中对依赖项进行分析。如果一个库的特定版本被其作者标记为过期,在查看该依赖定义时,会出现相应的 Lint 警告。方便开发者在开发过程中就发现依赖项问题,并进行更新。详情
- 可调整大小的模拟器
开发者现在可以使用一个可调整大小的模拟器在多种屏幕尺寸上测试应用程序。
在单个可调整大小的模拟器上进行测试,不仅可以快速测试不同界面的更改,还可以通过节省维护单独虚拟设备所需的计算资源和内存带来更流畅的开发体验。
- 蓝牙模拟器
开发者现在可以使用虚拟蓝牙发现并连接两个手机模拟器。使用虚拟蓝牙,开发者可以测试应用程序是否能够以可扩展的方式识别和访问蓝牙适配器。此功能在 Android Emulator 31.3.8 及更高版本的系统镜像 T (API 33) 上可用。官方计划在未来为创建示例虚拟外围设备(例如信标和心率监视器)和集成测试蓝牙功能添加更多支持。
- 对连接设备进行镜像 (Device Mirroring)
开发者现在可以在 Android Studio Electric Eel 的运行设备窗口中对设备进行镜像。通过将设备的显示内容直接流式传输到 Android Studio,从而直接在 IDE 执行常见操作,例如旋转屏幕、更改音量或锁定/解锁设备。
- 桌面 Android 虚拟设备 (Android Virtual Device, AVD) 现已可用
现在可以使用桌面 Android 虚拟设备 (AVD) 测试应用在 Chromebook 等桌面设备上的运行情况。用户通常在大屏幕设备上与应用程序进行不同的交互,桌面 AVD 使开发者能够看到应用程序在此环境中的行为方式。
- Compose Preview
从 Android Studio Electric Eel Beta 1 开始,开发者可以在预览更改时看到即时更新。
关于 Android Studio Electric Eel | 2022.1.1 的更多新特性介绍,查看 https://developer.android.com/studio/preview/features/#2022.1.1。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
Bitwarden 是一款开源的密码管理服务,使用者可在加密的保管库中储存敏感信息。Bitwarden 平台提供有多种客户端应用程式,包括 Web 版本、桌面应用,浏览器扩展、移动端应用和 CLI 版本等。
日前 Bitwarden 更新了 Desktop、Web 和 CLI 版本,带来了以下多项更新内容:
Desktop
- 更新了登录流程,将用户名和主密码分割成不同的页面
- 更新了选择和表单组的样式,以利于访问
- 在项目视图中添加文件夹
- 添加 Duckduckgo 的邮件转发服务
- 在保险库项目历史中显示创建日期
Web
- 更新了登录流程,将用户名和主密码分割成不同的页面
- 新的无密码登录选项,允许用户用已经认证的设备登录
- 对组织管理选项卡进行了重组,如新的账单和报告选项卡,以便更容易发现常见的 管理任务
- SCIM 触发的事件将从 SCIM 记录,而不是 Unknown
- 默认情况下,SCIM API 密钥将被模糊化
- 改进了网络保险库的加载时间和有数千保险库项目的账户的性能
- 在重新发送验证邮件时处理已经验证的邮件
- 添加 DuckDuckGo 的邮件转发服务
- 在保险库项目历史中显示创建日期
CLI
- 在保险库项目历史中显示创建日期
- 修复变量错字:EEFLongWordList -> EFFLongWordList
更多详情可查看:https://github.com/bitwarden/clients/releases
漏洞描述
snakeYAML 是一个将 YAML 文件与 Java 对象相互转换的开源代码库。
snakeYAML 受影响版本中的 Constructor 类由于没有对反序列化的类型进行限制,导致在处理恶意 yaml 内容时容易受到反序列化漏洞的影响。
缓解措施:使用 SnakeYaml 的 SafeConsturctor 类解析不受信任的内容
影响范围
org.yaml:snakeyaml@[1.4, 1.33]
修复方案
使用 SnakeYaml 的 SafeConsturctor 类解析不受信任的内容
参考链接
https://www.oscs1024.com/hd/MPS-2022-9425
https://nvd.nist.gov/vuln/detail/CVE-2022-1471
https://github.com/google/security-research/security/advisories/GHSA-mjmj-j48q-9wg2
Issue
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
前言
对于 ,相信熟悉 Go 语言的程序员基本都不陌生,一般线上的问题都是靠它可以快速定位。但是实际项目中,很多时候我们为了性能都不会开启它,但是出了问题又要靠它来分析。好在 go-zero 已经帮我们很好的集成进来了,我们只需要像开关一样去开启、关闭它即可,这样我们就可以配合运维监控,当出现 cpu、内存等异常情况时候,自动开始开启收集(比如大半夜你睡的正香的时候),那么第二天可以通过分析当时的采样还原现场,那我们看看 go-zero 是如何做的。
源码分析
我们可以看 go-zero 源码位置
服务启动的时候,go-zero 在 初始化了监听信号操作( 也是通过这里通知的,这里不展开讲了),可以看到在接收到 信号时候,如果是第一次就开始收集,第二次就停止收集,看到这块可能瞬间就明白了,我们只需要在服务器执行 就可以开始收集这个服务的 信息了,再执行一次就停止了收集,就可以将这些文件导出到本地,使用 分析。
一次线上实战
我们线上有一个 的服务监控告警,内存占用比较高,这时候我打开 看到服务内存累计占用的确异常,如下图:
这时候到线上找到这个服务的服务器,执行了 ,查询到了这个 服务的进程 是 21181,我们这时候就可以给这个 服务发送信号收集 信息:
第一次执行了这个命令后,在对应服务的 日志中可以看到 了 ,当我们再次执行 , 日志中可以看到 了 信息,这时候代表收集完成了。值得注意的是收集的信息都在 文件夹下,以这个服务名命名的如下:
这时候就可以下载对应的 去本地分析,可以使用 ,也可以配合 使用 查看,由于我这边通过命令行就快速定位了问题,就没用使用 。
我使用 然后进入命令行交互,使用 查看前面占用较高的资源。
前面基本是底层序列化等操作,发现主要问题集中在红色框中导致持续上涨的内存,因为业务同学在 中消费完了消息又向下游其他的mq服务使用 发送一个 消息,每次发送都调用一个 然后在 ,恰恰这个 服务又大量消息消费又特别频繁,导致内存不断上涨,最终解决方案将 在 中初始化一个 就可以了,没必要每次都要 ,世界又恢复清净了。
写在最后
想一下 go-zero 给了我们 开关,让我们很方便的实现分析问题,但是不是所有问题都是一直存在的,比如半夜突发内存、cpu 过高,早上起来服务正常了,这怎么排查?所以我们希望如果异常了,能保留问题现场,那我们是不是可以配合运维监控实现自动保存问题现场呢?比如内存、cpu 连续超过 指标3分钟的话,我们就调用这个开关收集,之后我们就可以根据这个文件来分析问题了,这样就达到自动化了。
项目地址
go-zero 微服务框架: https://github.com/zeromicro/go-zero
https://gitee.com/kevwan/go-zero
go-zero 微服务最佳实践项目:https://github.com/Mikaelemmmm/go-zero-looklook
欢迎使用 并 star 支持我们!
微信交流群
关注『微服务实践』公众号并 交流群 获取社区群二维码。</服务进程id>
rkyv 是一个用于 rust 的零拷贝反序列化框架。
它类似于其他零拷贝反序列化框架,例如 Cap’n Proto 和 FlatBuffers。然而,前者具有外部模式和严格限制的数据类型,而 rkyv 允许在代码中定义所有序列化类型,并且可以序列化其他类型无法序列化的各种类型。此外,rkyv 被设计为几乎没有开销,并且在大多数情况下将执行与本机类型完全相同的操作。
与 serde 一样,rkyv 使用 Rust 强大的特征系统来序列化数据而无需反射。尽管具有广泛的功能,但你也只需为使用的功能付费。如果你的数据检出,序列化过程可以像一样简单。与 serde 一样,这允许 rkyv 以类似于手写序列化程序的速度执行。
与 serde 不同,rkyv 生成的数据保证没有反序列化。如果你将数据写入磁盘,你只需将文件写入内存,投射一个指针,你的数据就可以使用了。这使其成为高性能和 IO 密集型应用程序的理想选择。
通过 Pin API 支持有限的数据突变,如果需要完整的突变功能,归档的值可以通过 Deserialize 真正反序列化。
rkyv 有一个 hashmap 实现,它是为零拷贝反序列化而构建的,所以你可以随意序列化你的 hashmaps。该实现使用压缩、散列和置换算法执行完美散列,以使用尽可能少的内存,同时仍然执行快速查找。
它还带有 B+ 树实现,该实现通过将数据拆分为易于分页的 4KB 段来实现最佳性能。这使得它非常适合为批量数据构建不可变的数据库和结构。
rkyv 还支持上下文序列化、反序列化和验证。它可以正确地序列化和反序列化共享指针,如和,并且可以扩展以支持自定义上下文类型。
最后,rkyv 使得序列化 trait 对象成为可能,并且无需反序列化就可以将它们用作 trait 对象。更多细节见 crate。
虽然 rkyv 是最终数据的一种很好的格式,但它缺乏完整的模式系统,并且不能很好地进行数据迁移和模式升级。如果你的用例需要这些功能,可能需要额外的库来在 rkyv 之上构建这些功能。可以使用与 rkyv 相同类型的其他序列化框架,如 serde,无冲突。
示例:
use rkyv::{Archive, Deserialize, Serialize}; // bytecheck can be used to validate your data if you want use bytecheck::CheckBytes; #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] // This will generate a PartialEq impl between our unarchived and archived types #[archive(compare(PartialEq))] // To use the safe API, you have to derive CheckBytes for the archived type #[archive_attr(derive(CheckBytes, Debug))] struct Test { int: u8, string: String, option: Option<Vec<i32>>, } let value = Test { int: 42, string: "hello world".to_string(), option: Some(vec![1, 2, 3, 4]), }; // Serializing is as easy as a single function call let bytes = rkyv::to_bytes::<_, 256>(&value).unwrap(); // Or you can customize your serialization for better performance // and compatibility with #![no_std] environments use rkyv::ser::{Serializer, serializers::AllocSerializer}; let mut serializer = AllocSerializer::<0>::default(); serializer.serialize_value(&value).unwrap(); let bytes = serializer.into_serializer().into_inner(); // You can use the safe API for fast zero-copy deserialization let archived = rkyv::check_archived_root::<Test>(&bytes[..]).unwrap(); assert_eq!(archived, &value); // Or you can use the unsafe API for maximum performance let archived = unsafe { rkyv::archived_root::<Test>(&bytes[..]) }; assert_eq!(archived, &value); // And you can always deserialize back to the original type let deserialized: Test = archived.deserialize(&mut rkyv::Infallible).unwrap(); assert_eq!(deserialized, value);
美国计算机历史博物馆 (Computer History Museum,CHM) 宣布公开发布并长期保存 Adobe 的 PostScript 源代码,作为其代码艺术系列的一部分。 “计算机历史博物馆很高兴首次公开发布突破性打印技术 PostScript 的源代码。我们感谢 Adobe, Inc. 的许可和支持,并感谢 John Warnock 对此次发布的支持。”
代码下载:https://info.computerhistory.org/aoc-postscript
PostScript 是 Adobe 于 1984 年推出的第一款产品,是桌面出版行业的重要组成部分;加速了 computing 对 printing 的转变,并推动了 Adobe 作为知名软件公司的成长。
起初,秉承着“任何计算机都可以通过一种通用语言与打印机和排字机连接,以最高保真度打印文字和图像”的愿景;在 Adobe 联合创始人 John Warnock 的带领下,Adobe 组建了一个程序员团队来创建这种用于高质量印刷的新编程语言,允许根据用户的喜好缩放、旋转和移动文本和图像。除了两位联合创始人之外,该团队还包括 Doug Brotz、Bill Paxton 和 Ed Taft。
PostScript 和 Adobe Type Library 的出现彻底改变了印刷和出版业,并从 1980 年代开启了桌面出版业的爆炸性增长。PostScript 成功的发展成为一个国际标准,Adobe 也公布了 PostScript 语言的细节,允许其他人创建与 PostScript 兼容的产品。现如今,大多数打印机都直接依赖 PostScript 技术,或者是从中衍生出来的技术:PDF (便携式文档格式)。
John Warnock 在 1990 年代倡导 PDF 的发展,将 PostScript 转变为一种更安全、更易于作为数字文件基础的技术,但保留了互操作性、保真度和质量的所有优势。几十年来,Adobe 极大地开发了 PDF,增强了其功能,并使其成为数字文档、打印以及在从笔记本电脑到智能手机和智能手表的屏幕上显示各种图形的重要标准。
团队成员 Doug Brotz 称,“PostScript 使印刷世界民主化”。PDF 如今也已成功的发展成为一个全球标准,每年创建的 PDF 数量以万亿计。
值得一提的是,计算机历史博物馆向公众发布的 PostScript 源代码版本是一个非常早期的版本,可追溯到 1984 年 2 月下旬,因此相对而言有很多内容没有包含其中。虽然此版本确实包含后来作为商业机密保存的“font hinting”程序的早期版本,但这些方法在随后的几个月里已被 Bill Paxton 完全重写、扩展和完善。
更多相关信息可查看博客文章。
在 2022 re:Invent 会议上, AWS 软件开发经理 Saikat Banerjee 锐评道:”我们发现 .NET 开源项目资金严重不足,仍可称之为第三方开源”。随即表示 AWS 过去非常重视 .net 生态,未来也将继续大力支持 .NET 的开源发展。
.NET 开源资金不足的说法令人吃惊,微软成立了 .NET 基金会,该基金会的介绍是“一个独立的非营利组织,旨在支持一个创新的、商业友好的开源生态系统 .NET 平台。” ,而 AWS 是该基金会仅有的 10 家企业赞助商之一。
另一方面,微软的 .NET 团队固然投入了大量精力,但在技术层面上,.NET 开源之后的跨平台进程包含大量外部贡献者的努力。比如 AWS 对 .NET 的开源工作非常上心,不仅给 .NET 基金会捐款支持、对社区中的出色的 .NET 项目进行现金和积分奖励,还积极参与 .NET 跨平台的代码开发工作,努力致力于 .NET 去 Windows /跨平台化。
根据 Banerjee 的说法,AWS 正试图“改进 WCF(Windows 通讯开发平台),不让它保留原有的局限性”。这项工作包括对 HTTP 绑定的联合身份支持,以及扩展 WFC 消息队列支持,支持除了 Microsoft 消息队列 (MSMQ) 以外的其他消息代理 ,例如 RabbitMQ 和 Amazon SQS。
另一个关键领域是 Active Directory (AD),在 Windows AD 中,组托管服务帐户 (gMSA) 通常用作应用程序服务的帐户。AWS 将该组件移植到了 Linux ,开发了一个名为 credentials fetcher 的组件,这是一个位于 Linux 实例上的守护进程,允许在 Linux 容器中使用 gMSA。
此外,使用 .NET 启动 Lambdas 时一直存在冷启动问题。函数运行时都需要加载 .NET 运行时,且 JIT编译器每次都会将 .NET 中间代码编译为本机代码,这也需要很长时间。.NET 7 版本中的解决方案是本机 AOT 编译, 而AWS 开发了适用于 .NET 的 Lambda tools ,可将本机 AOT 编译添加到 Lambda 函数中。
AWS 为啥对 .NET 跨平台工作这么上心?这就要追溯到 .NET Core 的前身 .NET Framework ,.NET Framework 出自 Windows 平台,导致调用 COM 或其他本机 Windows API 的 .NET Core 应用程序无法在 Linux 上运行。另一方面, .NET Framework 的某些部分(如 ASP.NET Web Forms 和 WCF 的大部分内容)不属于 .NET Core,使得大多数 .NET 应用程序更适合 Windows 或 Azure 云环境,移植到其他云上相当困难。
大厂当然不会为爱发电搞开源, .NET 是 AWS 应用程序开发中仅次于 Python 和 Java 的第三大受欢迎的平台,AWS 对.NET 开源工作的投资大多是为了让 .NET 摆脱对 Windows 的依赖,更易于使用其 Linux VM 和云原生技术, 以此摆脱 Windows 和 SQL Server 的许可,并获取更多云服务客户。当然,同样的优化当然也适用于微软的 Azure 和其他云环境,你好我好大家好,亦不失为一桩美事。
另,与其说 .NET 开源的“资金”不足,不如说“资源不足“。微软内部对 .NET 开源的意见恐怕并不统一,对开源业务倾斜的资源也一直在博弈。比如去年微软在即将发布的 .NET 6 中悄悄删除热重载的功能代码,宣称仅在 Visual Studio 中支持该功能,,强制用户改用昂贵的 Visual Studio 2022 。该举动随即引起微软内部 .NET 开发者和外部 .NET 社区的强烈反对和抨击,随后微软高层道歉,并在 .NET 6 中恢复了热重载功能。
SUSE 的工程主管 Marcus Meissner 在官网发布公告,宣告 openSUSE Leap 15.3 的生命周期即将结束,推荐用户尽快升级。
SUSE Linux Enterprise Server 15 SP3 将于 2022 年 12 月 31 日结束其常规维护和支持阶段。由于 openSUSE Leap 15.3 使用了 SLES 15 SP3 更新,因此 openSUSE Leap 15.3 的维护和安全支持也将在 2022 年 12 月 31 日结束。
因为该版本不再接受安全与维护更新,还在继续使用 EOL 版本的人未来将有潜在的可能性被暴露在漏洞中,所有用户需要尽快将系统升级到最新的次要版本 —— openSUSE Leap 15.4。
用户可以通过下载 iso 镜像或按照官网上提供的升级说明,从 15.3 升级到目前最新的 15.4。openSUSE Leap 15.4 已于今年 6 月发布,将获得安全补丁和更新直至 2023 年年底。根据路线图,后续版本 openSUSE Leap 15.5 预计将于 2023 年 6 月发布。
有兴趣从点状发布版本改为滚动版本的用户也可以借此机会从 Leap 转移到 Tumbleweed 上(俗称 “风滚草”),后者为官方软件库中的所有软件提供大量的日常和频繁的更新,并且始终处于 “最新版本”。Tumbleweed 版本可从这里下载。
无论是升级至 Leap 15.4 还是切换至 Tumbleweed,都最好对系统和文件提前进行备份,避免升级失败导致资料丢失。
GIMP (GNU Image Manipulation Program) 已经诞生 27 周年了。1995 年 11 月 21 日,GIMP 首次公开发布,当时它的全称为 General Image Manipulation Program,作为加州大学伯克利分校 eXperimental Computing Facility 的中长期发展项目发展。
1996 年,RMS 访问伯克利分校,GIMP 作者向他询问能否将 General 更改为 GNU。在 RMS 的许可下,GIMP 的全称改成了”GNU Image Manipulation Program”(GNU 图像处理程序),这也意味着 GIMP 成为了 GNU 计划的一部分。
GIMP 刚诞生时只是一个简单的图像编辑器,发展到现在,GIMP 拥有几乎所有图象处理所需的功能,号称 Linux 下的 Photoshop,可以说是公认的 Photoshop 的领先开源替代方案。
为了庆祝 GIMP 的 27 岁生日,Aryeom(自由开源电影 ZeMarmot 的导演)使用 GIMP 绘制了下面这张漂亮的插图:
因 GIMP 而诞生的 GTK 更是成为了不少 Linux 桌面环境项目的基础(例如 GNOME 和 Xfce),GTK (GIMP Toolkit) 是一套跨多种平台的图形工具包,最初为 GIMP 而写,GTK 后来发展成为 Linux 下开发图形界面应用的主流开发工具,演变成一个自成体系的项目,被成千上万的开发者使用。
GIMP 得到了比预期更多的热心贡献者的帮助,还吸引了来自好莱坞的开发者,他编写了后来成为新的图像处理引擎 GEGL 的雏形,现在也有许多软件项目在使用。
目前 GIMP 团队仍在积极开发 GIMP 3.0,但同时也表示在资金方面存在较大的需求。如果大家想反馈 GIMP,提供资助对他们而言是很好的方式,也是确保 GIMP 能够可持续发展的一部分。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
漏洞描述
authentik 是一个开源身份验证供应平台。
authentik 2022.11.2 和 2022.10.2 之前版本中存在身份验证不当漏洞,未经身份验证的攻击者可利用此漏洞在 authentik 中创建新帐户,如果存在允许通过电子邮件验证密码恢复的流程,攻击者可利用该流程覆盖管理员帐户的电子邮件地址并接管他们的帐户。用户可创建一个 策略,并将其设置为 “return request.user.is_authenticated”缓解此漏洞。
影响范围
goauthentik/authentik@[2022.10.0, 2022.10.2)
goauthentik/authentik@[2022.11.0, 2022.11.2)
修复方案
升级goauthentik/authentik到 2022.10.2 或 2022.11.2 或更高版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-65538
https://nvd.nist.gov/vuln/detail/CVE-2022-46145
https://github.com/goauthentik/authentik/security/advisories/GHSA-mjfw-54m5-fvjf
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
漏洞描述
GitHub Enterprise Server 是一个面向开源及私有软件项目的托管平台。
GitHub Enterprise Server 的受影响版本中存在权限管理不当漏洞,当攻击者被添加到具有写入权限的组织存储库中时,攻击者可利用此漏洞通过 API 创建或删除页面。
影响范围
GitHub Enterprise Server@[3.5.0, 3.5.7)
GitHub Enterprise Server@[3.6.0, 3.6.3)
GitHub Enterprise Server@[3.3.0, 3.3.15)
GitHub Enterprise Server@[3.2.0, 3.2.20)
GitHub Enterprise Server@[3.4.0, 3.4.10)
修复方案
升级GitHub Enterprise Server到 3.2.20 或 3.6.3 或 3.5.7 或 3.4.10 或 3.3.15 或更高版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-2164
https://nvd.nist.gov/vuln/detail/CVE-2022-23737
https://docs.github.com/en/enterprise-server@3.2/admin/release-notes#3.2.20
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
漏洞描述
Capsule 用于 Kubernetes 集群中实现 multi-tenant 和 policy-based 的微服务系统。
Capsule 0.1.3之前的版本中存在授权不当漏洞,当部署在 Tenant 命名空间中的 ServiceAccount 被授予自己的命名空间的 PATCH 功能时,该用户能够删除所有 OwnerReference,破坏 Capsule Operator 的协调并删除所有强制执行功能如 Pod 安全注释、网络策略、限制范围和资源配额项目。攻击者可以利用此漏洞启动特权 Kubernetes 容器并进行权限升级。
影响范围
clastix/capsule@(-∞, 0.1.3)
修复方案
升级clastix/capsule到 0.1.3 或更高版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-65560
https://nvd.nist.gov/vuln/detail/CVE-2022-46167
https://github.com/clastix/capsule/security/advisories/GHSA-x45c-cvp8-q4fm
https://github.com/clastix/capsule/commit/75525ac19254b0c5111e34d7985e2be7bc8b1ac1
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
漏洞描述
Chained Quiz 是一个 WordPress 的链式/条件逻辑测验插件。
Chained Quiz 1.3.2.3及之前版本中由于 chainedquiz_list 页面上的 date 参数没有进行有效清理从而存在反射型 XSS 漏洞,在诱骗用户单击恶意链接的前提下,未经身份验证的攻击者可利用此漏洞在执行的页面中注入任意 Web 脚本,窃取用户信息,或者在网站上添加新的管理员用户。
影响范围
Chained Quiz@(-∞, 1.3.2.4)
修复方案
将组件 Chained Quiz 升级至 1.3.2.4 及以上版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-65776
https://nvd.nist.gov/vuln/detail/CVE-2022-4215
https://gist.github.com/Xib3rR4dAr/417a11bcb9b8da28cfe5ba1c17c44d0e
https://plugins.trac.wordpress.org/changeset?sfp_email=&sfph_mail=&reponame=&old=%40chained-quiz&new=%40chained-quiz&sfp_email=&sfph_mail=
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
漏洞描述
Apache Tapestry 是一个基于 Java 的 Web 应用程序框架。
Apache Tapestry 3.x 版本(现已停止维护)存在 Java 反序列化漏洞,该漏洞与 CVE-2020-17531 漏洞相似,攻击者可通过传入包含恶意负载的 service parameter (sp)参数远程执行恶意代码,建议用户升级至 Apache Tapestry 5.x 版本。
影响范围
org.apache.tapestry:tapestry-project@[3.0, 5.0.1)
修复方案
升级org.apache.tapestry:tapestry-project到 5.0.1 或更高版本
参考链接
https://www.oscs1024.com/hd/MPS-2022-66596
https://nvd.nist.gov/vuln/detail/CVE-2022-46366
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
PyCharm 2022.3 日前正式发布,新版本带来了全新的 Settings Sync(设置同步)解决方案、管理 Conda 软件包的新方法针对 pandas DataFrames 的增强用户体验。
用户体验
新的 Settings Sync(设置同步)解决方案
新的 Settings Sync(设置同步)插件现在可用于 PyCharm。 新解决方案能够同步来自平台、捆绑插件和一些第三方插件的大部分可共享设置。 请注意,我们将停止支持旧的 IDE Settings Sync(IDE 设置同步)插件并取消捆绑 Settings Repository(设置仓库)。
管理 Conda 软件包的新方式
无需离开 Editor(编辑器)窗口即可搜索、安装和删除 Conda 软件包。 Python Packages(Python 软件包)工具窗口现在可与 Anaconda 软件包库配合使用,让您可以在编写代码期间直接自定义 Conda 解释器。
通过设置使用新 PyCharm UI
切换到新 UI,预览 PyCharm 完全重做的外观。 勾选 Settings/Preferences | Appearance & Behavior(设置/偏好设置 | 外观与行为)中的 New UI preview(新 UI 预览)框,在项目中尝试一下。
为 GitHub 和 Space 重新设计了 Review list(审查列表)
我们重做了 Review list(审查列表)UI,帮助减少认知负担并清晰提供有关请求的最重要信息。 在改进中,我们还确保在所有受支持的审查平台上保持一致的外观。
改进了 Tips of the Day(每日小技巧)
我们对 Tips of the Day(每日小技巧)的外观和行为做出了多项更改,使其更实用且更易理解。 我们更新了对话框的设计,实现了技巧评分功能以收集反馈。 我们还微调了确定显示哪些提示的算法,让您可以看到与 IDE 体验和正在处理的项目最相关的提示。
其他改进:
- 为了让您可以更轻松地在多个显示器上与 PyCharm 交互,我们实现了将工具窗口拖出主窗口并将其停靠到浮动编辑器选项卡的选项。
- 我们对 Bookmarks(书签)实现了一些 UI 改进:右键选项卡调用上下文菜单,然后选择 Bookmarks(书签)即可从编辑器选项卡中为文件添加书签。 您还可以将所有打开的选项卡中的所有文件添加到 Bookmarks(书签)。
- PyCharm 让您能够以偏好样式阅读代码,无需重新格式化实际代码。 您可以在 Reader(阅读器)模式下应用新的视觉格式设置层。
- 我们微调了 Search Everywhere(随处搜索)结果列表背后的算法。 IDE 将冻结第一个搜索结果,并且不会在找到更多选项时对其重新排序。 此外,ML 排名现在对 Files(文件)选项卡启用,可以提供更准确的查找结果。
编辑器
Quick Documentation(快速文档)中的 docstring 呈现改进
Quick Documentation(快速文档)弹出窗口现在会显示类 docstring 的 Attributes(特性)部分,帮助您快速查看类特性。 这也适用于继承的类特性和数据类的特性。
类实例现在更容易阅读:将鼠标悬停在 形参上,其描述就会从类 docstring 调用。
意图操作预览默认启用
当采取 IDE 的建议后,您可以立即查看代码将如何更改。 打开可用意图操作列表并将鼠标悬停在不同选项上时会显示预览。
Python 3.11: 类型的代码洞察 [PEP 673]
PyCharm 可以识别方法或特性注解的 类型,并为类实例建议正确的类型。
如果特定位置 的用法不正确,PyCharm 会发出警告。
其他改进:
- 在 YAML 文件(包括 Kubernetes 文件、OpenAPI 规范和 docker-compose.yml)中,新增的快速修复可以通过注释禁止检查。
针对 Python 控制台的 asyncio 支持
内置 Python 控制台现在支持在函数外使用 关键字快速运行协同程序。 PyCharm 2022.3 还为调试器添加了 asyncio 支持。 此功能虽然有助于调试异步代码,但目前还处于实验性阶段,可能并不完全稳定。 要启用它,请遵循这里介绍的步骤。
集成式开发者工具
安全性
软件包的漏洞检查器
PyCharm 将对照 Checkmarx SCA Database 和 National Vulnerability Database 检查软件包,检测项目中所用软件包的漏洞。 IDE 将在 package.json、requirements.txt、setup.py 文件中高亮显示被认为易受攻击的软件包。 要查看检查,请在 Preferences / Settings | Editor | Inspections | Security(偏好设置 / 设置 | 编辑器 | 检查 | 安全)中启用 Security Inspections(安全检查)。
安装程序
适用于 Windows 和 Linux ARM64 机器的安装程序(测试版)
现在,可以在带有 ARM64 处理器的 Windows 和 Linux 机器上运行 PyCharm。 IDE 安装程序目前处于测试版阶段。对于 Windows 用户,可以从网站和 JetBrains Toolbox App 获取安装程序。 Linux 用户只能从网站下载安装程序。
更多详情可查看:https://blog.jetbrains.com/pycharm/2022/12/2022-3/
NixOS 作为围绕独特的 Nix 软件包管理器构建的 Linux 发行版,推出了今年的最后一个版本。
NixOS 在这个版本中为 nixpkgs 增加了 16678 个新的软件包和 14680 个更新软件包,该版本还删除了 2812 个软件包,以保持软件包集的可维护性和安全性。除了软件包之外,NixOS 22.11 版本还带来了 91 个新模块,并删除了 20 个旧模块。在这个过程中,增加了 1322 个选项,删除了 487 个。
除了许多新的和升级的软件包外,这个版本还包括以下亮点:
亮点
- 使用 密码哈希 API 的软件现在使用 提供的实现,而不是 glibc 的实现,这使得支持更安全的算法成为可能。
- 对 libxcrypt 认为不强的算法的支持从这个版本开始被废弃,并将在 NixOS 23.05 中删除。
- 这包括系统登录密码。鉴于此,强烈建议所有用户更新他们的系统密码,因为如果在取消对密码哈希的支持时没有进行迁移,你将无法登录。
- 当使用 来配置用户密码时,运行 ,并使用提供的 yescrypt 哈希值作为新值。
- 另一方面,对于交互式配置的用户密码,只需用 为所有用户重新设置密码。
- 这个版本为这两种配置密码的方法引入了对使用已废弃的哈希算法的警告。为了确保你的迁移正确,请运行 。
- NixOS 文档现在是由 markdown 生成的,虽然 docbook 仍然是文档构建过程的一部分,但这是向全面迁移迈出的一大步。
- 现在包含在 和 频道中。这意味着当这些频道更新时, 和 都将可用。
- 的 ISO 现在可以在下载页面上找到。
- 现在可以作为 的替代使用了,并计划在 NixOS 23.05 中默认使用 。
- 新增了一个选项,即 ,可以用来启用 NVIDIA 开源内核驱动的使用。
值得注意的版本更新
- Nix 已从 v2.8.1 升级到 v2.11.0
- OpenSSL 从 1.1.1 更新至 OpenSSL 3。
- GNOME 已升级到版本 43
- KDE Plasma 已从 v5.24 升级到 v5.26
- Cinnamon 已经更新到 5.4,现在 Cinnamon 模块默认使用 Blueman 作为蓝牙管理器
- PHP 从 8.0 更新至 8.1
- Perl 已更新至 5.36
- Python 从 3.9 更新至 3.10
更多详情可查看:https://nixos.org/manual/nixos/stable/release-notes.html
PyTorch 团队在昨日举办的 2022 PyTorch Conference 大会上宣布了 PyTorch 2.0,提供了用于体验的早期版本,并表示稳定版将于 2023 年 3 月上旬发布。
团队介绍道,PyTorch 2.0 是他们向 PyTorch 下一代 2 系列迈出的第一步。在过去的几年里,从 PyTorch 1.0 到最新的 1.13,他们对 PyTorch 进行了创新和迭代,并将它迁移到新成立的 PyTorch 基金会,成为 Linux 基金会的一部分。
PyTorch 2.0 引入了 torch.compile,这是一种编译模式,可以在不更改模型代码的情况下加速模型。在 163 个涵盖视觉、NLP 和其他领域的开源模型中,该团队发现使用 2.0 可以将训练速度提高 38-76%。
其次,PyTorch 2.0 是 100% 向后兼容的:代码库一样,API 一样,写模型的方式也一样。团队之所以称它为 2.0,是因为它有一些标志性的新特性,包括:
-
TorchDynamo 可以从字节码分析生成 FX 图;
-
AOTAutograd 可以以 ahead-of-time 的方式生成反向图;
-
PrimTorch 引入了一个小型算子集,使后端更容易;
-
TorchInductor:一个由 OpenAI Triton 支持的 DL 编译器。
PyTorch 2.0 将延续 PyTorch 一贯的优势,包括 Python 集成、命令式风格、API 简单等等。此外,PyTorch 2.0 提供了相同的 eager-mode 开发和用户体验,同时从根本上改变和增强了 PyTorch 在编译器级别的运行方式。该版本能够为「Dynamic Shapes」和分布式运行提供更快的性能和更好的支持。
在官方博客中,PyTorch 团队介绍了他们对 2.0 系列的展望:
详情查看文档。
Module Version Issues Spring Cloud Task 3.0.0-RC3 (issues) Spring Cloud Bus 4.0.0-RC3 Spring Cloud Contract 4.0.0-RC3 (issues) Spring Cloud Circuitbreaker 3.0.0-RC3 Spring Cloud Function 4.0.0-RC3 Spring Cloud OpenFeign 4.0.0-RC3 (issues) Spring Cloud Zookeeper 4.0.0-RC3 Spring Cloud Commons 4.0.0-RC3 (issues) Spring Cloud Vault 4.0.0-RC3 (issues) Spring Cloud Kubernetes 3.0.0-RC3 (issues) Spring Cloud Stream 4.0.0-RC3 Spring Cloud Starter Build 2022.0.0-RC3 Spring Cloud Consul 4.0.0-RC3 Spring Cloud Config 4.0.0-RC3 (issues Spring Cloud Build 4.0.0-RC3 Spring Cloud Gateway 4.0.0-RC3 (issues) Spring Cloud Netflix 4.0.0-RC3
笔者是 RocketMQ 的忠实粉丝,在阅读源码的过程中,学习到了很多编程技巧。
这篇文章,笔者结合 RocketMQ 源码,分享并发编程三大神器的相关知识点。
1 CountDownLatch 实现网络同步请求
CountDownLatch 是一个同步工具类,用来协调多个线程之间的同步,它能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。
下图是 CountDownLatch 的核心方法:
我们可以认为它内置一个计数器,构造函数初始化计数值。每当线程执行 countDown 方法,计数器的值就会减一,当计数器的值为 0 时,表示所有的任务都执行完成,然后在 CountDownLatch 上等待的线程就可以恢复执行接下来的任务。
举例,数据库有100万条数据需要处理,单线程执行比较慢,我们可以将任务分为5个批次,线程池按照每个批次执行,当5个批次整体执行完成后,打印出任务执行的时间 。
温习完 CountDownLatch 的知识点,回到 RocketMQ 源码。
笔者在没有接触网络编程之前,一直很疑惑,<strong style=”font-size: inherit;line-height: inherit;color: rgb(255, 104, 39);”>网络同步请求是如何实现的?</strong>
同步请求指:客户端线程发起调用后,需要在指定的超时时间内,等到响应结果,才能完成本次调用。如果超时时间内没有得到结果,那么会抛出超时异常。
RocketMQ 的同步发送消息接口见下图:
追踪源码,真正发送请求的方法是通讯模块的同步请求方法 invokeSyncImpl 。
整体流程:
- 发送消息线程 Netty channel 对象调用 writeAndFlush 方法后 ,它的本质是通过 Netty 的读写线程将数据包发送到内核 , 这个过程本身就是异步的;
- ResponseFuture 类中内置一个 CountDownLatch 对象 ,responseFuture 对象调用 waitRepsone 方法,发送消息线程会阻塞 ;
- 客户端收到响应命令后, 执行 processResponseCommand 方法,核心逻辑是执行 ResponseFuture 的 putResponse 方法。
<img src=”https://oscimg.oschina.net/oscnet/up-3c7698bddf6aa00fc0d9ee38fb.png” style=”zoom:115%;” />
该方法的本质就是填充响应对象,并调用 countDownLatch 的 countDown 方法 , 这样发送消息线程就不再阻塞。
CountDownLatch 实现网络同步请求是非常实用的技巧,在很多开源中间件里,比如 Metaq ,Xmemcached 都有类似的实现。
2 ReadWriteLock 名字服务路由管理
读写锁是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,而写锁则是互斥锁。
它的规则是:<strong style=”font-size: inherit;line-height: inherit;color: rgb(255, 104, 39);”>读读不互斥,读写互斥,写写互斥</strong>,适用于读多写少的业务场景。
我们一般都使用 ReentrantReadWriteLock ,该类实现了 ReadWriteLock 。ReadWriteLock 接口也很简单,其内部主要提供了两个方法,分别返回读锁和写锁 。
读写锁的使用方式如下所示:
- 创建 ReentrantReadWriteLock 对象 , 当使用 ReadWriteLock 的时候,并不是直接使用,而是获得其内部的读锁和写锁,然后分别调用 lock / unlock 方法 ;
- 读取共享数据 ;
- 写入共享数据;
RocketMQ架构上主要分为四部分,如下图所示 :
-
Producer :消息发布的角色,Producer 通过 MQ 的负载均衡模块选择相应的 Broker 集群队列进行消息投递,投递的过程支持快速失败并且低延迟。
-
Consumer :消息消费的角色,支持以 push 推,pull 拉两种模式对消息进行消费。
-
BrokerServer :Broker主要负责消息的存储、投递和查询以及服务高可用保证。
-
NameServer :名字服务是一个非常简单的 Topic 路由注册中心,其角色类似 Dubbo 中的zookeeper,支持Broker的动态注册与发现。
NameServer 是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。Broker 启动之后会向所有 NameServer 定期(每 30s)发送心跳包(<strong style=”font-size: inherit;line-height: inherit;color: rgb(255, 104, 39);”>路由信息</strong>),NameServer 会定期扫描 Broker 存活列表,如果超过 120s 没有心跳则移除此 Broker 相关信息,代表下线。
那么 NameServer 如何保存路由信息呢?
路由信息通过几个 HashMap 来保存,当 Broker 向 Nameserver 发送心跳包(路由信息),Nameserver 需要对 HashMap 进行数据更新,但我们都知道 HashMap 并不是线程安全的,高并发场景下,容易出现 CPU 100% 问题,所以更新 HashMap 时需要加锁,RocketMQ 使用了 JDK 的读写锁 ReentrantReadWriteLock 。
- 更新路由信息,操作写锁
- 查询主题信息,操作读锁
读写锁适用于读多写少的场景,比如名字服务,配置服务等。
3 CompletableFuture 异步消息处理
RocketMQ 主从架构中,主节点与从节点之间数据同步/复制的方式有同步双写和异步复制两种模式。
异步复制是指消息在主节点落盘成功后就告诉客户端消息发送成功,无需等待消息从主节点复制到从节点,消息的复制由其他线程完成。
同步双写是指主节点将消息成功落盘后,需要等待从节点复制成功,再告诉客户端消息发送成功。
同步双写模式是阻塞的,笔者按照 RocketMQ 4.6.1 源码,整理出主节点处理一个发送消息的请求的时序图。
整体流程:
-
生产者将消息发送到 Broker , Broker 接收到消息后,发送消息处理器 SendMessageProcessor 的执行线程池 SendMessageExecutor 线程池来处理发送消息命令;
-
执行 ComitLog 的 putMessage 方法;
-
ComitLog 内部先执行 appendMessage 方法;
-
然后提交一个 GroupCommitRequest 到同步复制服务 HAService ,等待 HAService 通知 GroupCommitRequest 完成;
-
返回写入结果并响应客户端 。
我们可以看到:<strong style=”font-size: inherit;line-height: inherit;color: rgb(255, 104, 39);”>发送消息的执行线程需要等待消息复制从节点 , 并将消息返回给生产者才能开始处理下一个消息</strong>。
RocketMQ 4.6.1 源码中,执行线程池的线程数量是 1 ,假如线程处理主从同步速度慢了,系统在这一瞬间无法处理新的发送消息请求,造成 CPU 资源无法被充分利用 , 同时系统的吞吐量也会降低。
那么优化同步双写呢 ?
从 RocketMQ 4.7 开始,RocketMQ 引入了 CompletableFuture 实现了异步消息处理 。
- 发送消息的执行线程不再等待消息复制到从节点后再处理新的请求,而是提前生成 CompletableFuture 并返回 ;
- HAService 中的线程在复制成功后,调用 CompletableFuture 的 complete 方法,通知 remoting 模块响应客户端(线程池:PutMessageExecutor ) 。
我们分析下 RocketMQ 4.9.4 核心代码:
- Broker 接收到消息后,发送消息处理器 SendMessageProcessor 的执行线程池 SendMessageExecutor 线程池来处理发送消息命令;
- 调用 SendMessageProcessor 的 asyncProcessRequest 方法;
-
调用 Commitlog 的 aysncPutMessage 方法写入消息 ;
这段代码中,当 commitLog 执行完 appendMessage 后, 需要执行刷盘任务和同步复制两个任务。
但这两个任务并不是同步执行,而是异步的方式。
-
复制线程复制消息后,唤醒 future ;
-
组装响应命令 ,并将响应命令返回给客户端。
为了便于理解这一段消息发送处理过程的线程模型,笔者在 RocketMQ 源码中做了几处埋点,修改 Logback 的日志配置,发送一条普通的消息,观察服务端日志。
从日志中,我们可以观察到:
- 发送消息的执行线程(图中红色)在执行完创建刷盘 Future 和同步复制 future 之后,并没有等待这两个任务执行完成,而是在结束 asyncProcessRequest 方法后就可以处理发送消息请求了 ;
- 刷盘线程和复制线程执行完各自的任务后,唤醒 future,然后通过刷盘线程组装存储结果,最后通过 PutMessageExecutor 线程池(图中黄色)将响应命令返回给客户端。
笔者一直认为:异步是更细粒度的使用系统资源的一种方式,在异步消息处理的过程中,通过 CompletableFuture 这个神器,各个线程各司其职,优雅且高效的提升了 RocketMQ 的性能。
如果我的文章对你有所帮助,还请帮忙点赞、在看、转发一下,你的支持会激励我输出更高质量的文章,非常感谢!
Drawing 是 Linux 平台的图像编辑器,支持 PNG、JPEG 和 BMP 文件,支持简体中文和繁体中文。
Drawing 具备一个图像编辑器所具备的基本功能,它可以调整、裁剪或旋转图像,也可以应用简单的滤镜、插入文本等。用户还可以使用铅笔、直线、曲线工具、及其各种颜色和选项等工具在 Drawing 中直接绘画。
安装
用户可以从 flathub.org 中安装它(这个页面)。
大家好,我是 Kagol,Vue DevUI 开源组件库和 EditorX 富文本编辑器创建者,专注于前端组件库建设和开源社区运营。
假如你是团队的前端负责人,现在老板要拓展新业务,需要开发一个 Web 应用,让你来做技术选型,你之前用 Vue 比较多,对 Vue 比较熟悉,希望能在团队内部推行 Vue 技术栈,你会怎么跟老板说呢?以下是我做的一些调研,也许能对你有帮助。
声明:Vue 和 React 都是我很喜欢的前端框架,如有说得不对的地方,欢迎一起讨论交流。
一、Vue 在国内的使用量远高于 React / Angular
- 业界主流前端框架:React、Vue、Angular,从近3年的使用趋势上看,React 稳定在第一,Angular 逐年下降,Vue 持续增长。
- 从受欢迎程度上看,以 Svelte、Solid 为代表的新兴前端框架很受开发者喜爱,不过它们的使用量和生态繁荣程度还远低于三大框架。
- 虽然 React 在国外的份额高于 Vue,但 Vue 在国内的使用量大幅领先于 React,并且呈现出持续增长的趋势,这意味着在国内能更容易招聘到使用过 Vue、熟悉 Vue 的开发者。
图1: Vue 和 React 在全球的使用情况和受欢迎程度对比(来自 StateOfJS 数据)
图2: Vue 和 React 在中国的使用情况对比(来自 CSDN 调查报告)
参考:
- https://2021.stateofjs.com/en-US/libraries/front-end-frameworks/
- https://csdn.gitcode.host/Survey-Report-on-Developers-in-China/survey/
二、Vue 中文资料多,学习曲线平缓,上手快
- 国人开发,美观易读的官方中文文档,除了基本的使用指南和API文档之外,Vue 官网还提供了深色模式、互动教程、演练场和丰富的示例,降低了开发者的学习成本,提升了文档阅读体验。
- 在掘金、知乎、思否等国内技术社区,Vue 的关注者、文章数、讨论数都比 React 高,Vue 相关视频在B站的播放量和评论数总体上也比 React 高,Vue 中文书籍也比 React 的多,这意味着国内的 Vue 开发者拥有比 React 开发者更丰富的中文学习资料,并且在开发过程中遇到问题也能更容易找到解决方案。
- 从代码编写上,Vue 使用模板写法,从传统写法过渡的成本低,而 React 的 JSX 写法需要更多额外的学习成本。
图3: Vue 官方中文文档
图4: Vue 和 React 在国内各技术社区的关注者和内容数据对比
图5: Vue 和 React 在代码编写上的对比
参考:
- https://cn.vuejs.org/
- https://juejin.cn/live/xdc
三、Vue 是渐进式框架,更轻量,性能高
- Vue 是一个渐进式框架,它的设计非常注重灵活性和“可以被逐步集成”这个特点,可以根据你的需求场景,用不同的方式使用 Vue,并轻易地集成到你的现有项目中,不管你的项目是 HTML 网页、Web Components、SPA、桌面端、移动端、WebGL,甚至是命令行终端界面。
- Vue 的体积几乎只有 React 的一半(未压缩情况下),并且 Vue 3.0 的全局 API 和内置组件都支持摇树优化,这意味着用户只需要为他们实际使用到的功能“买单”,未使用的功能代码将不会出现在最终的打包产物中。
- 经过 Benchmark 工具的测试,包括创建数据行、替换所有行、部分更新、选择行、交换行、移除行、追加行在内的所有操作,Vue 都比 React 性能要好,特别是交换行操作,Vue 比 React 性能高出5倍以上。
图6: Vue 和 React 包体积对比
图7: Vue 和 React 性能测试数据
参考:
- https://krausest.github.io/js-framework-benchmark/2022/table_chrome_102.0.5005.61.html
四、Vue 官方支持的 Web 应用开发工具全面,可持续性好
- Vue 官方提供路由、状态管理、单测试、静态站点生成等常见 Web 应用开发工具,无需从众多第三方依赖库中做选择,并能获得更好的业务连续性支持;而 React 官方只提供了一个视图层工具,其他必要的 Web 应用开发配套工具都需要依赖于第三方库。
- 在 Awesome 资源大全中,awesome-vue 的资源数是 awesome-react 的6倍,这意味着 Vue 开发者不仅能获得更好的官方工具支持,而且能在社区找到更多配套的 Web 开发工具和学习资源。
图8: Vue 和 React 官方工具和生态对比
参考:
- https://github.com/vuejs/awesome-vue
- https://github.com/enaqx/awesome-react
再次声明:Vue 和 React 都是我很喜欢的前端框架,我们的 Vue DevUI 组件以及组件的单测试都是使用 TypeScript + JSX 语法写的,所以如有说得不对的地方,欢迎一起友好讨论交流。
Nate Graham 是 KDE 的主要开发者之一,前段时间他也入选了 KDE e.V. 董事会。跟以往一样,近日他又分享了一些与 KDE 相关的功能开发进度,让大家能够提前了解到 KDE 近期的开发任务,以及未来的路线规划。
而本次公开的 KDE 开发工作中,有一个功能特别值得关注 —— 那就是已完成 KWin 内置高级窗口分屏布局的初步工作,未来将允许用户创建自定义平铺布局。
KWin 是一个 X Window System 的窗口管理器和一个 Wayland 合成器。它作为 KDE Plasma 5 的一部分发布,它是该系统的默认窗口管理器。KWin 也可以单独使用或与其他桌面环境一起使用。
KWin 可由基于 ECMAScript 的脚本(如 QML、QtScript)来进行配置,能够让用户完全控制窗口,通过调整窗口的偏好设置,可以给用户带来更好的使用体验。其中包括的功能就有:
- 支持以特定的大小和位置启动应用程序
- 自定义标题栏按钮的位置
- 有多个显示器/桌面的情况下,支持在不同的桌面直接打开特定应用程序
- 可根据屏幕大小调整窗口装饰和字体等
- ……
从上图也能看出,目前 KWin 已经预设了多个平铺布局,用户可以快速调整多个窗口的布局方式,提升工作效率。
除了预设的方案,KWin 还提供了平铺配置选项,用户可以根据个人喜爱将水平平铺修改为垂直平铺(感觉将显示器竖直使用时更适合)。当然,通过直接拖动相邻的多个窗口之间的缝隙,手动调整它们的大小也是没有问题的。
这个功能仍然处于起步阶段,Nate Graham 希望它能随着时间的推移不断进步,同时,为它添加的新的 API 也能让那些想让 KWin 变成一个平铺窗口管理器的第三方平铺脚本受益。这个功能预计将在 Plasma 5.27 中发布。
除了会在 KWin 中内置高级窗口平铺系统,KDE 的改进还包括:
- 支持在 Dolphin 文件管理器和其他文件管理工具中使用原生 afc:// 协议浏览苹果 iOS 设备。
- Konsole 将采用 KHamburgerMenu
- Konsole 的标签栏现在默认位于窗口的顶部而不是底部
- 支持 Plasma 5.27 的 Global Shortcuts(全局快捷方式),允许 Flatpak 和其他沙盒应用程序使用 portal 系统,为设置/编辑全局快捷方式提供一个标准化的用户界面。
- 专注于移动 KDE 应用程序的 KDE Plasma Mobile Gear 现在将转移到正常的 “KDE Gear” 发布时间表,以统一它们。
Go 近日接受了名为「add support for wrapping multiple errors」的提案。
该项提案对错误处理进行了优化,与 Go 1.13 为错误处理提供的新功能有关:Error Wrapping。引入 Error Wrapping 后,Go 同时为包添加了 3 个工具函数,分别是、和。
对于「add support for wrapping multiple errors」提案,顾名思义就是一个错误可以包裹多个错误。
提出该提案的开发者表示,重用避免了与现有 Unwrap 方法产生歧义,从中返回一个长度为 0 的列表意味着错误没有包裹任何内容。调用方不得修改由返回的列表,返回的列表不得包含任何错误。
他还对和函数进行了更新,实现对 multiple errors 进行操作。
函数提供了 multierr 的简单实现:
目前该提案已被接受,作者表示将在 Go 1.20 中提供:
详情查看 https://github.com/golang/go/issues/53435。
-
更新内容
iot-modbus本次发布的V3.2.6版本支持设备上线、掉线、处理业务异常监听处理,请看下面的源码解读。
-
设备上线监听源码解读
主要是在MiiListenerHandler重写了channelActive方法
-
设备掉线监听源码解读
主要是在MiiListenerHandler重写了channelInactive方法。
-
处理业务异常监听源码解读
主要是增加了MiiExceptionHandler处理器,并在服务端MiiServer和客户端MiiClient初始化initChannel时添加进入。
-
连接监听器源码解读
主要通过spring的发布时间监听来处理,增加连接监听器ChannelConnectListener。
Acl 是一个跨平台网络通信库与服务器开发框架,支持 LINUX, WIN32, Solaris, FreeBSD, MacOS, AndroidOS, iOS,实现了常见的网络通信协议:HTTP/Websocket/SMTP/ICMP/MQTT/Redis/Memcached/Beanstalk/Handler Socket,实现了常见的编解码:XML/JSON/MIME/BASE64/UUCODE/QPCODE/RFC2047/RFC1035,另外,还封装了常见的数据库客户端 API,支持:Mysql, Postgresql, Sqlite。Acl 库不仅可以用在服务端开发高性能、高并发的服务器应用,而且还可以用在客户端(支持Win32, Android, iOS)开发网络通信模块。本次升级为年度大版本更新,主要包括如下重大更新:
1、feature:协程模块(lib_fiber)支持 Linux 中新增的 io_uring 引擎,在协程模式下统一了网络 IO 与文件 IO 过程,磁盘IO过程不会再阻塞协程调度器;
2、feature:协程模块(lib_fiber)中设计了新的可以用在协程之间、协程与线程之间同步的协程锁(fiber_mutex),相较于之前的 fiber_event 占用少量的文件句柄,同时具有更好的性能;
3、optimize:协程模块(lib_fiber)优化定时器模块,大幅降低调用gettimdofday API的次数,从而进一步提升协程调度器的性能;
4、optimize:协程模块(lib_fiber)优化网络IO超时模块,大幅提升大并发下网络模块的性能;
5、optimize:协程模块(lib_fiber)重新设计并实现了 DNS 协程模块,去掉对第三方 DNS 库的依赖;
6、feature:SSL 模块(lib_acl_cpp中)增加了针对 OpenSSL 的支持,从而使服务端开发 SSL 类服务应用的性能较之前(使用 MbedTLS)大幅提升;
7、optimize:Redis 模块(lib_acl_cpp中)中的 pipeline 接口进行优化,方便子类重载其中的消息管理模块,从而方便协程模式下使用 Redis pipeline 模式;
8、featue:acl_master 服务管理器与服务子进程之间更好地支持 SO_REUSEPORT 功能;
9、bugs fixed:包括一些已知问题的修复。
Acl 库下载:
gitee:https://gitee.com/acl-dev/acl
github: https://github.com/acl-dev/acl
漏洞描述
Apache Commons Net 是一个提供基本的互联网访问协议的客户端,支持的协议包括:Echo、Finger、FTP、NNTP、NTP、POP3(S)、SMTP(S)、Telnet、Whois 等。
Apache Commons Net 3.9.0之前版本中的 FTP 客户端默认信任来自 PASV (被动 FTP)响应的主机,当 Commons Net 的 FTP 客户端连接到攻击者可控的恶意主机时,攻击者可将 Commons Net 的 FTP 连接重定向到其它主机,进而获取 Commons Net FTP 客户端运行服务的敏感信息,补丁版本通过默认禁止来自 PASV 响应的主机(org.apache.commons.net.ftp.ipAddressFromPasvResponse = false)修复此漏洞。
影响范围
commons-net:commons-net@(-∞, 3.9.0)
修复方案
升级commons-net:commons-net到 3.9.0 或更高版本
参考链接
https://www.oscs1024.com/hd/MPS-2021-28440
https://nvd.nist.gov/vuln/detail/CVE-2021-37533
https://github.com/apache/commons-net/commit/b0bff89f70cfea70009e22fcc
https://issues.apache.org/jira/browse/NET-711.
https://github.com/advisories/GHSA-cgp8-4m63-fhh5
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
MyCms 是一款基于 Laravel 开发的开源免费的开源多语言商城 CMS 企业建站系统。
MyCms 基于 Apache2.0 开源协议发布,免费且可商业使用,欢迎持续关注我们。
V4.1 更新内容
新增:自媒体模块
新增:自媒体账号管理
新增:自媒体文章管理
新增:自媒体模板生成文章
新增:自媒体文章发布
新增:Neditor 编辑器
新增:编辑器切换开关
新增:接入秀米内容排版工具
新增:Neditor 编辑器远程抓取图片
新增:easywechat 开发包
优化:CURD快速生成
更新重点说明
1、新增 Neditor 编辑器
开启方法:系统模块 > 网站配置 > 富文本编辑器切换
2、对接秀米内容排版工具
3、新增自媒体模块
一、自媒体账号管理
二、自媒体文章管理
三、自媒体模板生成文章
通过模板生成文章,目前支持两种方式,一是通过 json 内容来进行生成,其次就是通过读取数据表来生成文章,以JSON 数据生成文章为例,简单说明一下使用方法。
四、自媒体文章预览发布
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
4MLinux 是一个轻量级的 Linux 发行版,适用于 32 位和 64 位架构。它被命名为 “4MLinux”,因为它有 4 个主要的操作系统组件。维护(它可以被用作救援的 Live CD)、多媒体(对几乎所有的多媒体格式都有内置的支持)、Miniserver(它包括一个 64 位的服务器),以及 Mystery(一个经典的 Linux 游戏集合)。当用该发行版安装程序时,该发行版会检索 Windows 版本,而不是 Linux 版本,因为它预装了 Wine(Windows 应用程序的兼容层),而且没有任何软件包管理器。
4MLinux 41.0 稳定版发布,更新内容如下:
新的功能:
- 开箱即用的新应用程序:
- FileZilla(FTP 客户端)
- XPaint 和 GNU Paint(简单的图像编辑工具)
- nvme(管理 NVM-Express 分区的命令行工具)
- 一系列小型 SDL 游戏。
- 作为可下载扩展的新应用程序:
- BlueGriffon(HTML 编辑器)
- ioquake3(Quake III 移植)
- The Legend of Edgar(平台游戏)
- BZFlag(坦克大战游戏)
- 4MLinux 中的默认视频播放器现在是 SMPlayer
- 默认音频播放器是Audacious
软件升级:
- LibreOffice 7.4.3
- GNOME Office(AbiWord 3.0.5、GIMP 2.10.32、Gnumeric 1.12.52)
- DropBox 151.4.4304
- Firefox 107.0
- Chromium 106.0.5249
- Thunderbird 102.5.0
- Audacious 4.2
- VLC 3.0.17.3
- SMPlayer 22.2.0
- Mesa 22.1.4
- Wine 7.18
- 4MLinux LAMP Server(Linux 6.0.9、Apache 2.4.54、MariaDB 10.6.11、PHP 5.6.40 和 PHP 7.4.33)。
- Perl 5.36.0
- Python 2.7.18 和 Python 3.10.6
- Ruby 3.1.2
更多详情可查看:https://4mlinux-releases.blogspot.com/2022/12/4mlinux-410-stable-released.html
最新版本的 Midori 浏览器正式发布,并开放下载。新版浏览器被命名为 Midori Next Generation,版本号为 10.0.2。
不知道还有多少人记得 Midori,它是一个轻量级的网络浏览器,最初使用 WebKitGTK 渲染引擎和 GTK UI 工具包。Midori 也曾是 Elementary OS 等 Linux 发行版中默认的网络浏览器。
由于这个项目已有 2 年多的时间没有更新了,各个 Linux 发行版也早已更换默认浏览器,Ubuntu 甚至从 Ubuntu 22.04 的系统资源库中将其彻底删除了。
就在几天前,Astian 基金会主动公开了最新的进展,表示 Midori 浏览器仍然活着,并会内置自家的开源搜索引擎。
只不过新版的 Midori 现在成为了基于 Chromium 的网络浏览器,并使用 Electron 构建,支持 Linux、macOS 和 Windows,以及 Android。
到目前为止,新的 Midori 浏览器的特点:
-
新的 Logo
-
集成 Adblock,开箱即可屏蔽广告
-
支持隐身模式
-
基于 Chromium,但没有 Google 服务和隐私跟踪,资源占用少
-
支持 Chrome 扩展
-
简单现代的用户界面
-
快速和高度可定制的用户界面
-
标签页分组
-
虽然承诺会使用自己的开源 AstianGo 搜索引擎,但到目前为止,浏览器还没内置 AstianGo(需要手动访问 https://astian.org/)。现在的默认搜索引擎为 DuckDuckGo,可选 Google、Bing 和 Ecosia。
下载链接:https://astian.org/midori-browser-desktop/download-midori-browser-desktop/
Genode OS 22.11 已正式发布。
Genode 操作系统框架是一个用于构建高度安全的专用操作系统的工具包。它可以从只有 4MB 内存的嵌入式系统扩展到高度动态的通用工作负载。
Genode 基于递归系统结构。每个程序都在专门的沙箱中运行,并且仅授予其特定用途所需的访问权限和资源。程序可以利用自己的资源创建和管理子沙箱,从而形成可以在每个级别应用策略的层次结构。该框架提供了让程序相互通信和交换资源的机制,但只能以严格定义的方式进行。由于这种严格的制度,与当代操作系统相比,安全关键功能的攻击面可以减少几个数量级。
该框架将 L4 的构建原则与 Unix 哲学保持一致。根据 Unix 哲学,Genode 是一组小型构建块的集合,从中可以组成复杂的系统。但与 Unix 不同的是,这些构建块不仅包括应用程序,还包括所有经典的操作系统功能,例如内核、设备驱动程序、文件系统和协议栈。
特性
CPU 架构:x86(32 和 64 位)、ARM(32 和 64 位)、RISC-V
内核:L4 家族的大多数成员(NOVA、 seL4、 Fiasco.OC、 OKL4 v2.1、 L4ka::Pistachio、 L4/Fiasco)、Linux 和自定义内核。
虚拟化:VirtualBox(基于 NOVA)、ARM 的自定义虚拟机监视器和 Unix 软件的自定义运行时
超过 100 个随时可用的组件
在从 Linux 移植最新的图形驱动程序代码,并更改其英特尔图形多路复用器设计后,他们现在通过 Genode OS 22.11 支持英特尔 Gen12 级图形。如果想在最新一代英特尔硬件上享受加速的图形效果,这对于 Genode 的 Sculpt OS 通用操作系统来说尤其是个好消息。
Genode OS 22.11 还在 PinePhone 支持、Arm 和 x86_64 的虚拟化改进、可配置的英特尔 HWP 模式、各种设备驱动改进、通过 HTTP 的启动加载以及其他补充方面带来了更多开发资源。
详情查看 Release Notes。
漏洞描述
Apache Commons Net 是一个提供基本的互联网访问协议的客户端,支持的协议包括:Echo、Finger、FTP、NNTP、NTP、POP3(S)、SMTP(S)、Telnet、Whois 等。
Apache Commons Net 3.9.0之前版本中的 FTP 客户端默认信任来自 PASV (被动 FTP)响应的主机,当 Commons Net 的 FTP 客户端连接到攻击者可控的恶意主机时,攻击者可将 Commons Net 的 FTP 连接重定向到其它主机,进而获取 Commons Net FTP 客户端服务通过 FTP 协议传输的文件信息,补丁版本通过默认禁止来自 PASV 响应的主机(org.apache.commons.net.ftp.ipAddressFromPasvResponse = false)修复此漏洞。
影响范围
commons-net:commons-net@(-∞, 3.9.0)
修复方案
升级commons-net:commons-net到 3.9.0 或更高版本
参考链接
https://www.oscs1024.com/hd/MPS-2021-28440
https://nvd.nist.gov/vuln/detail/CVE-2021-37533
https://github.com/apache/commons-net/commit/b0bff89f70cfea70009e22fcc
https://issues.apache.org/jira/browse/NET-711.
https://github.com/advisories/GHSA-cgp8-4m63-fhh5
情报订阅
OSCS(开源软件供应链安全社区)通过最快、最全的方式,发布开源项目最新的安全风险动态,包括开源组件安全漏洞、事件等信息。同时提供漏洞、投毒情报的免费订阅服务,社区用户可通过配置飞书、钉钉、企业微信机器人,及时获得一手情报信息推送:
https://www.oscs1024.com/cm/?src=osc
具体订阅方式详见:
https://www.oscs1024.com/docs/vuln-warning/intro/?src=osc
来自 Dedebiz 的消息:
2022年12月3日下午DedeCMS创始人林学先生(IT柏拉图)因罹患癌症逝世。
林学先生生于1979年10月10日,于2004年8月编写的DedeCMS至今仍有数十万企业、个人站长使用,在使用者中不免有一些互联网巨头,其中bilibili更是基于DedeCMS白手起家,而林学先生一直秉承着开源免费的理念,通过技术改变了中国,却从未因DedeCMS过上体面的生活。
在此我们缅怀林学先生为中国开源作出的贡献,其遗志必将传承下去,为社会创造更多价值。
从一个线上问题说起
最近在线上遇到了一些卡死
初步分析
观察了下主线程堆栈,用到的锁是读写锁随后又去翻了下持有着锁的子线程,有各种各样的情况,且基本都处于正常的执行状态,例如有的处于打开文件状态,有的处于状态,有的正在执行的方法…通过观察发现,出问题的线程都有标记。整体看起来持有锁的子线程仍然在执行,只是留给主线程的时间不够了。为什么这些子线程在持有锁的情况下,需要执行这么久,直到主线程的8s卡死?一种情况就是真的如此耗时,另一种则是出现了优先级反转。
解决办法
在这个案例里面,持有读写锁且优先级低的线程迟迟得不到调度(又或者得到调度的时候又被抢占了,或者得到调度的时候时间已然不够了),而具有高优先级的线程由于拿不到读写锁,一直被阻塞,所以互相死锁。之后引入了的概念,类似于线程的优先级,设置不同的的值后系统会分配不同的时间、网络资源和硬盘资源等,因此我们可以通过这个设置队列的优先级 。
方案一:去除对的优先级设置
在 Threading Programming Guide 文档中,苹果给出了提示:
Important: It is generally a good idea to leave the priorities of your threads at their default values. Increasing the priorities of some threads also increases the likelihood of starvation among lower-priority threads. If your application contains high-priority and low-priority threads that must interact with each other, the starvation of lower-priority threads may block other threads and create performance bottlenecks.
苹果的建议是不要随意修改线程的优先级,尤其是这些高低优先级线程之间存在临界资源竞争的情况。所以删除相关优先级设置代码即可解决问题。
方案二:临时修改线程优先级
在 pthread_rwlock_rdlock(3pthread) 发现了如下提示:
Realtime applications may encounter priority inversion when using read-write locks. The problem occurs when a high priority thread “locks” a read-write lock that is about to be “unlocked” by a low priority thread, but the low priority thread is preempted by a medium priority thread. This scenario leads to priority inversion; a high priority thread is blocked by lower priority threads for an unlimited period of time. During system design, realtime programmers must take into account the possibility of this kind of priority inversion. They can deal with it in a number of ways, such as by having critical sections that are guarded by read-write locks execute at a high priority, so that a thread cannot be preempted while executing in its critical section.
尽管针对的是实时系统,但是还是有一些启示和帮助。按照提示,对有问题的代码进行了修改:在线程通过拿到的时候,临时提升其优先级,在释放之后,恢复其原先的优先级。
值得注意的是,这里只能使用的,提供的是不可行的
Demo 验证
为了验证上述的手动调整线程优先级是否有一定的效果,这里通过进行本地实验:定义了个(目的是为了繁忙),优先级设置,且对其中可以被整除的的优先级调整为,在每个执行相同的耗时任务,然后对这被选中的个进行耗时统计。
统计信息如下图所示
可以看到
- 正常情况下,每个任务的平均耗时为:11.;
- 当被设置为低优先级时,其耗时大幅度提升为:94.;
- 当被设置为低优先级时,又在中手动恢复其原有的优先级,其耗时已经大幅度降低:15.0( 耗时比正常情况高,大家可以思考下为什么)
通过可以发现,通过手动调整其优先级,低优先级任务的整体耗时得到大幅度的降低,这样在持有锁的情况下,可以减少对主线程的阻塞时间。
上线效果
该问题的验证过程分为个阶段:
- 第一个阶段如第1个红框所示,从月号开始在版本上有较大幅度的下降,主要原因:堆栈中被等待的队列信息由变为了,队列的优先级从提升为,相当于实施了方案一,使用了默认优先级。
- 第二个阶段如第个红框所示,从月号在版本上开始验证。目前看起来效果暂时不明显,推测一个主要原因是:中是把优先级从提升为,而线上相当于把队列的优先级从默认的优先级提升为所以相对来说,线上的提升相对有限。
- 的层级优先级数是4;
- 的层级优先级数是31;
- 的层级优先级数是37;
深刻理解优先级反转
那么是否所有锁都需要像上文一样,手动提升持有锁的线程优先级?系统是否会自动调整线程的优先级?如果有这样的机制,是否可以覆盖所有的锁?要理解这些问题,需要深刻认识优先级反转。
什么是优先级反转?
优先级反转,是指某同步资源被较低优先级的进程/线程所拥有,较高优先级的进程/线程竞争该同步资源未获得该资源,而使得较高优先级进程/线程反而推迟被调度执行的现象。根据阻塞类型的不同,优先级反转又被分为和。这里借助 Introduction to RTOS – Solution to Part 11 (Priority Inversion) 的图进行示意。
Bounded priority inversion
如图所示,高优先级任务()被持有锁的低优先级任务()阻塞,由于阻塞的时间取决于低优先级任务在临界区的时间(持有锁的时间),所以被称为。只要一直持有锁,就会一直被阻塞,低优先级的任务运行在高优先级任务的前面,优先级被反转。
这里的任务也可以理解为线程
Unbounded priority inversion
在持有锁的情况下,如果有一个中间优先级的任务()打断了,前面的就会变为,因为只要抢占了的,就可能会阻塞任意多的时间(可能不止个)
优先级反转常规解决思路
目前解决有种方法:一种被称作优先权极限(),另一种被称作优先级继承()。
Priority ceiling protocol
在优先权极限方案中,系统把每一个临界资源与1个极限优先权相关联。当1个任务进入临界区时,系统便把这个极限优先权传递给这个任务,使得这个任务的优先权最高;当这个任务退出临界区后,系统立即把它的优先权恢复正常,从而保证系统不会出现优先权反转的情况。该极限优先权的值是由所有需要该临界资源的任务的最大优先级来决定的。
如图所示,锁的极限优先权是3。当持有锁的时候,它的优先级将会被提升到3,和一样的优先级。这样就可以阻止(优先级是2)的运行,直到和不再需要该锁。
Priority inheritance
在优先级继承方案中,大致原理是:高优先级任务在尝试获取锁的时候,如果该锁正好被低优先级任务持有,此时会临时把高优先级线程的优先级转移给拥有锁的低优先级线程,使低优先级线程能更快的执行并释放同步资源,释放同步资源后再恢复其原来的优先级。
和都会在释放锁的时候,恢复低优先级任务的优先级。同时要注意,以上种方法只能阻止,而无法阻止(必须等待执行完毕才能执行,这个反转是无法避免的)。
可以通过以下几种发生来避免或者转移:
- 减少临界区的执行时间,减少的反转耗时;
- 避免使用会阻塞高优先级任务的临界区资源;
- 专门使用一个队列来管理资源,避免使用锁。
优先级继承必须是可传递的。举个栗子:当阻塞在被持有的资源上,而又阻塞在持有的一个资源上。如果的优先级高于和的优先级,必须通过继承的优先级。否则,如果另外一个优先级高于和,小于的线程,将抢占,引发相对于的优先级反转。因此,线程所继承的优先级必须是直接或者间接阻塞的线程的最高优先级。
如何避免优先级反转?
QoS 传递
iOS 系统主要使用以下两种机制来在不同线程(或 )间传递 :
- 机制1:
- automatically propagates the QoS from the calling thread, though it will translate User Interactive to User Initiated to avoid assigning that priority to non-main threads.
- Captured at time of block submission, translate user interactive to user initiated. Used if destination queue does not have a QoS and does not lower the QoS (ex dispatch_async back to the main thread)
- 机制2:基于 XPC 的进程间通信()
系统的 QoS 传递规则比较复杂,主要参考以下信息:
- 当前线程的
- 如果是使用 () 方法生成的 ,则考虑生成 时所调用的参数
- 或 的目标 或线程的
调度程序会根据这些信息决定 以什么优先级运行。
- 如果没有其他线程同步地等待此 ,则 就按上面所说的优先级来运行。
如何触发优先级反转避免机制?
如果当前线程因等待某线程(线程1)上正在进行的操作(如 )而受阻,而系统知道 所在的目标线程(),系统会通过提高相关线程的优先级来解决优先级反转的问题。反之如果系统不知道 所在目标线程,则无法知道应该提高谁的优先级,也就无法解决反转问题;
记录了持有者信息()的系统 API 如下:
- 、、以及基于这二者实现的上层 API
- 的实现是基于 的
- 、、 等的实现是基于
- 、
使用以上这些 能够在发生优先级反转时使系统启用优先级反转避免机制。
基础API验证
接下来对前文提到的各种「基础系统」进行验证
测试验证环境:模拟器 iOS15.2
pthread mutex
的数据结构其中有一个字段,专门来记录持有该锁的线程。
代码来验证一下:线程优先级是否会被提升?
先在子线程上锁并休眠,然后主线程请求该锁
可以看到,低优先级子线程先持有锁,当时的优先级为,而该锁被主线程请求的时候,子线程的优先级被提升为
os_unfair_lock
用来替换,解决优先级反转问题。等待锁的线程会处于休眠状态,从用户态切换到内核态,而并非忙等。将线程保存到了锁的内部,锁的等待者会把自己的优先级让出来,从而避免优先级反转。验证一下:
结果和一致
pthread_rwlock_t
在 pthread_rwlock_init 有如下提示:
Caveats: Beware of priority inversion when using read-write locks. A high-priority thread may be blocked waiting on a read-write lock locked by a low-priority thread. The microkernel has no knowledge of read-write locks, and therefore can’t boost the low-priority thread to prevent the priority inversion.
大意是内核不感知读写锁,无法提升低优先级线程的优先级,从而无法避免优先级反转。通过查询定义发现:包含了字段,专门来记录持有写锁的线程,这不由令人好奇:为什么有信息却仍然无法避免优先级反转?
https://news.ycombinator.com/item?id= 链接中提到:
xnu supports priority inheritance through “turnstiles“, a kernel-internal mechanism which is used by default by a number of locking primitives (list at [1]), including normal pthread mutexes (though not read-write locks [2]), as well as the os_unfair_lock API (via the ulock syscalls). With pthread mutexes, you can actually explicitly request priority inheritance by calling pthread_mutexattr_setprotocol [3] with PTHREAD_PRIO_INHERIT; the Apple implementation supports it, but currently ignores the protocol setting and just gives all mutexes priority inheritance.
大意是:使用内核机制进行优先级继承,这种机制被应用在和上。
顺藤摸瓜,在方法中找到了的调用,其中的注释对读写锁解释的比较委婉,添加了
pthread mutexes and rwlocks both (at least sometimes) know their owner and can use turnstiles. Otherwise, we pass NULL as the tstore to the shims so they wait on the global waitq.
再去查看的定义,代码还是很诚实的,只有在才会启用进行优先级反转保护,而读写锁的类型为,这说明读写锁不会使用,所以无法避免优先级反转。
另外在也可以看到,读写锁的是
把锁更换为读写锁,验证一下前面的理论是否正确:
可以看到读写锁不会发生优先级提升
dispatch_sync
这个都比较熟悉了,这里直接验证:
是一个低优先级队列(),可以看到调用压入队列的任务,以及在这之前压入的任务,都被提升到较高的优先级(和主线程一致),而最后一个的任务则以优先级来执行。
dispatch_wait
是一个低优先级队列(),当在当前主线程使用进行等待时,输出如下,低优先级的任务被提升到优先级
而如果将注释掉之后,输出如下:
值得注意的是,是一个宏(的泛型),或者是一个入口函数,它可以接受,, 种类型的参数,但是这里的具体含义应该是指,只有会调整优先级,避免优先级反转。
神秘的信号量
之前对的认知非常浅薄,经常把二值信号量和互斥锁划等号。但是通过调研后发现: 没有 的概念,没有记录当前持有信号量的线程(),所以有高优先级的线程在等待锁时,内核无法知道该提高哪个线程的调试优先级()。如果锁持有者优先级比其他线程低,高优先级的等待线程将一直等待。Mutex vs Semaphore: What’s the Difference? 一文详细比对了和之间的区别。
Semaphores are for signaling (sames a condition variables, events) while mutexes are for mutual exclusion. Technically, you can also use semaphores for mutual exclusion (a mutex can be thought as a binary semaphore) but you really shouldn’t.Right, but libdispatch doesn’t have a mutex. It has semaphores and queues. So if you’re trying to use libdispatch and you don’t want the closure-based aspect of queues, you might be tempted to use a semaphore instead. Don’t do that, use os_unfair_lock or pthread_mutex (or a higher-level construct like NSLock) instead.
这些是一些警示,可以看到十分危险,使用需要特别小心。
这里通过苹果官方提供的demo进行解释:
- 假设在主线程执行这段代码,那么当前线程的优先级是;
- 由于从主线程进行了异步,异步任务队列的将会被提升为;
- 主线程被信号量阻塞,而负责释放该信号量的异步任务的优先级低于主线程的优先级,因此可能会发生优先级反转。
值得一提的是,专门针对这种情况进行了静态检测:
https://github.com/llvm-mirror/clang/blob/master/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp
如果想使用该功能,只需要打开设置即可:
另外, 跟 类似,在调用 方法时,无法预知谁会调用 ,所以系统也无法知道其 是谁,所以同样不会有优先级提升的问题。
信号量卡死现身说法
给笔者的印象非常深刻,之前写过一段这样的代码:使用信号量在主线程同步等待相机授权结果。
上线后长期占据卡死,当时百思不得其解,在深入了解到信号量无法避免优先级反转后,终于豁然开朗,一扫之前心中的阴霾。这类问题一般通过种方式来解决:
- 使用同步
- 异步回调,不要在当前线程等待
几个概念
turnstile
前文提到使用进行优先级继承,这里对机制进行简单的描述和理解。在内核中,存在着大量的同步对象(例如),为了解决优先级反转的问题,每个同步对象都必须对应一个分离的数据结构来维护大量的信息,例如阻塞在这个同步对象上的线程队列。可以想象一下,如果每个同步对象都要分配一个这样的数据结构,将造成极大的内存浪费。为了解决这个问题,采用了机制,一种空间利用率很高的解决方案。该方案的提出依据是同一个线程在同一时刻不能同时阻塞于多个同步对象上。这一事实允许所有同步对象只需要保留一个指向的指针,且在需要的时候去分配一个即可,而则包含了操作一个同步对象需要的所有信息,例如阻塞线程的队列、拥有这个同步对象的线程指针。是从池中动态分配的,这个池的大小会随着系统中已分配的线程数目增加而增加,所以总数将始终低于或等于线程数,这也决定了的数目是可控的。由阻塞在该同步对象上的第一个线程负责分配,当没有更多线程阻塞在该同步对象上,会被释放,回收到池中。的数据结构如下:
优先级数值
在验证环节有一些优先级数值,这里借助「Mac OS® X and iOS Internals 」解释一下:实验中涉及到的优先级数值都是相对于层而言的,且都是用户线程数值
- 用户线程的优先级是0~63;
- 的层级优先级数是4;
- 的层级优先级数是20;
- 的层级优先级数是31;
- 的层级优先级数是37;
- 的层级优先级是47;
- 内核线程的优先级是80~95;
- 实时系统线程的优先级是96~127;
- 64~79被保留给系统使用;
总结
本文主要阐述了优先级反转的一些概念和解决思路,并结合平台的几种锁进行了详细的调研。通过深入的理解,可以去规避一些不必要的优先级反转,从而进一步避免卡死异常。字节跳动 团队也针对线程的优先级做了监控处理,进而达到发现和预防优先级反转的目的。
加入我们
字节跳动 APM 中台致力于提升整个集团内全系产品的性能和稳定性表现,技术栈覆盖iOS/Android/Server/Web/Hybrid/PC/游戏/小程序等,工作内容包括但不限于性能稳定性监控,问题排查,深度优化,防劣化等。长期期望为业界输出更多更有建设性的问题发现和深度优化手段。
欢迎对字节APM团队职位感兴趣的同学投递简历到邮箱 xushuangqing@bytedance.com 。
参考文档
- WWDC18 What’ s New in LLVM – actorsfit
- https://developer.apple.com/videos/play/wwdc2015/718
- https://developer.apple.com/forums/thread/
- https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html
- https://developer.apple.com/library/archive/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html
- https://github.com/llvm-mirror/clang/blob/google/stable/lib/StaticAnalyzer/Checkers/ GCDAntipatternChecker.cpp
- Don’t use dispatch semaphores where mutexes (or dispatch queues) would suffice
- Concurrency Problems Written by Scott Grosch
- https://www.sigusoft.com/p/af64e05de503
- https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_rwlock_wrlock.html
- iOS中各种“锁”的理解及应用
- 不再安全的 OSSpinLock
- https://blog.actorsfit.com/a?ID=00001-499b1c8e-8a7f-4960-a1c1-c8e2f42c08c6
- https://objccn.io/issue-2-1/#Priority-Inversion
- Introduction to RTOS – Solution to Part 11 (Priority Inversion)
- https://threadreaderapp.com/thread/1229999590482444288.html#
- 深入理解iOS中的锁
- Threads can infect each other with their low priority
添加小助手回复【APM】可加入性能监控交流群,获取更多技术干货
ZomboDB 通过使用 Elasticsearch 作为索引类型,为 Postgres 带来了强大的文本搜索和分析功能。其全面的查询语言和 SQL 函数支持以新颖和创造性的方式来查询您的关系数据。
从技术角度来看,ZomboDB是一个100%用Rust和PGX编写的本地Postgres扩展。ZomboDB使用Postgres的索引访问方法API来直接管理和优化ZomboDB的专门索引。作为一个原生的Postgres索引类型,ZomboDB允许你用CREATE INDEX … USING zombodb在你现有的Postgres表中。在这一点上,ZomboDB接管并完全管理远程Elasticsearch索引,保证交易上正确的文本搜索查询结果。
ZomboDB完全兼容Postgres的所有查询计划类型和大多数SQL命令,如CREATE INDEX, COPY, INSERT, UPDATE, DELETE, SELECT, ALTER, DROP, REINDEX, (auto)VACUUM,等等。
无论你是使用 Elasticsearch 云提供商还是管理你自己的集群都没有关系——ZomboDB 通过其 RESTful API 与 Elasticsearch 通信,因此你可以采用任何一种方式。
ZomboDB 允许你直接从 Postgres 使用 Elasticsearch 的强大功能和可扩展性。你不必管理 Postgres 和 Elasticsearch 之间的事务、异步索引管道、复杂的重新索引过程或多个数据访问代码路径——ZomboDB 会为你完成这一切。
特性:
- MVCC 正确的文本搜索和聚合结果
- 通过标准 SQL 进行管理和查询
- 适用于当前的 Elasticsearch 版本(无需插件)
- 查询使用
- Elasticsearch 的查询字符串语法通过
- ZQL — ZomboDB 的自定义查询语言
- 原始 Elasticsearch QueryDSL JSON
- ZomboDB 的类型安全查询生成器 SQL 语法
- 以上的任意组合,甚至与标准 SQL 组合
- 评分和突出显示支持
- 支持所有 Elasticsearch 聚合
- 自动 Elasticsearch 映射生成
- 能够映射自定义域
- 每字段自定义映射
- 自动映射为动态嵌套对象
- 支持全套Elasticsearch 语言分析器
- 支持Elasticsearch的相似度模块
- Hot standby兼容
- 支持索引和搜索 PostGIS和类型
Fosshost 是一家总部位于英国的开源软件托管和云计算提供商,Fosshost 的服务已被 GNOME、KDE、Armbian、Debian、Rocky Linux、Ubuntu Unity 和 Xfce 等众多知名开源项目所使用。近日他们宣布服务器即将关闭,不再提供服务。
一开始,当你访问各种 fosshost.org 的链接时,都会返回 404 错误信息,后来 fosshost.org 在网站上更新了一份声明并写道:
此时此刻,Fosshost 非常抱歉地宣布,我们不再能够继续提供我们的服务。
在官网的声明中,其实并没有透露停止服务的具体原因,仅仅是写道:
由于 Fosshost 志愿者无法控制的情况,我们现在无法保证我们的服务器会一直在线,事实上,我们预计它们很快就会下线。 正因为如此,我们强烈建议所有 Fosshost 的用户立即备份他们的数据,并尽快迁移到其他地方。
在这个声明中,实际上是无法得知 Fosshost 关闭的真正原因。而在 HN 相关的帖子中,一位来自 Fosshost 的志愿者则是给出了更加明确的信息:
我们无力支付托管的费用,这就是为什么我们的服务器会因为无法联系上首席执行官 Thomas Markey 而下线,只有他能够访问银行账户,从而获得资金。
而且 CEO 失联的情况已经持续了半年时间,Fosshost 内部人员也因管理问题纷纷辞职,这位志愿者也是 Fosshost 的最后一位志愿者。
其实在今年 9 月,Fosshost 就因为可扩展性的问题暂停了其应用程序,给使用他们服务的开源项目造成了不便。在 11 月,维护者在试图操作一个芝加哥节点时也陷入了困境,因为首席执行官没有给其他任何人权限,该节点已无法访问、启动或恢复。
唯一的好消息是,前 Fosshost 志愿者和原架构师目前已经开始构建一个名为 Radix 的替代方案,并会提供免费的按需托管服务。
人工智能研究公司 OpenAI 上周正式推出 ChatGPT,这是一种基于对话的人工智能聊天机器人模型,它能够理解自然语言并以自然语言的方式做出回应。
ChatGPT 基于 GPT-3.5 模型微调而成,以语言服务模型 InstructGPT 为基础,通过人类回馈增强学习训练模型 RLHF,不过数据设置略有不同。它以对话方式进行交互,既能够做到回答问题,也能承认错误、质疑不正确的前提以及拒绝不恰当的请求,能以更贴近一般人的对话方式与使用者互动。
这几天许多用户都展示了与 ChatGPT 对话的有趣内容,它宛如化身为地球“最强懂哥”,各种问题轻松应答,让它解答防疫政策与经济发展的关系,给出的答案不仅条理清晰,还会引用例子支撑观点。让它帮忙写程序,不仅提供了可用的代码,更是把实现思路也一并写了出来。
更别说开发者如何应付老板这种小儿科的问题了:
下面介绍一些 ChatGPT 的“极客”玩法。
- 在 ChatGPT 中构建虚拟机
这名玩家把 ChatGPT 训练成了一台 Virtual Machine,可以运行各种 Linux 指令,甚至可以使用 curl 来让 ChatGPT 和自己做交互。
首先是让 ChatGPT “扮演” Linux 终端:
执行 ls 命令,以及新建文件和读取文件:
在这之后,这名用户推测 ChatGPT 似乎懂文件系统的工作原理、文件存储及检索方式。下面直接快进到用这个虚拟机运行 docker 文件——首先制作一个 docker 文件,然后运行它:
可以看到,ChatGPT 成功扮演了一个“虚拟机”的角色。
- 在 ChatGPT 中构建编程语言解释器
这名开发者使用 ChatGPT 为自己开发的编程语言构建了一个语言解释器:
并成功编写了解决作者问题的应用程序:
接着这名作者通过提供参数,让 ChatGPT 对自己编写的这段程序进行了验证,同样没问题:
- 在 ChatGPT 中实现新的编程语言
这名玩家在 ChatGPT 中实现了一门新的编程语言:GPTLang,并用这个语言写了一个排序算法。
首先告诉 ChatGPT 正在实现一门新的编程语言,能不能给一些 idea 或者建议,ChatGPT 给出了 GPTLang 的一些基本特性。
定义编译器命令为 `gptlc`,并且可以使用 `gptlc file.gpt` 来进行编译。 然后让 ChatGPT 给出一些常用的编译选项:
下图是最终的效果:让 ChatGPT 用 GPTLang 写了一个选择排序算法,并在命令行编译运行。
对于 ChatGPT 的这些“整活”案例,欢迎大家在评论区发表自己的看法。
作者:陈树煌,TCL 实业数据管理部副总监(本文为作者在 StarRocks Summit Asia 2022 上的分享)
作为伴随改革开放浪潮成长起来的中国领先电子企业,TCL 拥有 13 万员工,业务遍及 160 多个国家和地区,全球累计服务用户超 9.6 亿。如此庞大的企业体量和业务规模,构建统一的数据分析平台势在必行。
截止目前,TCL 已将 StarRocks 应用于新方舟实时大屏、集团 HR 服务、邮件告警等场景。新方舟实时大屏场景中,TCL 基于 StarRocks 构建了实时数仓,平均的响应速度在 200-500 毫秒内;集团 HR 服务场景中,TCL 把小时级数据从 ClickHouse 切换到 StarRocks 上进行多表关联的自助分析,查询性能提升了 3-5 倍;在邮件告警场景中,TCL 基于 StarRocks 构建了实时日志数据的数据分析及算法应用,实现了秒级预警功能,准确率达到 92.3%。
本文将围绕背景、OLAP 建设历程、StarRocks 典型应用场景、未来规划等几点展开介绍 TCL 选择并应用 StarRocks 的最佳实践。
#01
背景介绍
TCL 集团经过四十多年的发展,形成了两大集团和三大核心产业,其中 TCL 实业主要聚焦在智能终端业务,包括 TV、空调、冰箱等等。而 TCL 科技则向产业链的上游发展,聚焦在半导体显示、新能源与半导体材料等高科技产业。目前 TCL 有 13 万名员工,业务遍及 160 多个国家地区。
格创东智是 2018 年 TCL 战略孵化的工业互联网企业,背靠 TCL 这棵大树,对内负责 TCL 的数字化转型建设工作,对外则将在 TCL 内部实践成熟的方案转化成产品或服务对外输出。在去年刚获得工信部双跨平台的认证,累计为 20 多个行业提供产品和咨询服务。
TCL 即将迎来第 41 个生日,目前 TCL 正在进行第四次大的变革,全面地进行数字化转型,TCL 总部负责整体的统筹以及统一投资建设各个产业公共的设施以及技术平台,大数据平台是其中的共享平台之一。产业则根据自身的情况,自行规划转型的节奏。
TCL 实业目前正在进行业务模式、业务流程、规则等的梳理,输出了 13 个一级流程。最近几年会聚焦在研发领域的 IPD、供应链领域的 ISC、财务领域的 IFS 等重点的几个流程,梳理清楚每个业务的步骤以及上面所承载的数据将流程数据固化到新的自研的一套业务系统,用这套业务系统替换掉现有的业务系统。
在今年年中,我们在一家子公司投入了 300 多名业务人员、200 多名技术人员,同时上线了七套供应链系统。紧接着在八月份上线了国内的营销中台,目前正在进行的是国内的服务售后平台、研发平台,以及相关其他子公司的供应链系统的建设。
接下来的一两年是 TCL 实业建设的高峰期,对个人而言,这是积攒能力或者学习历练的好机会。放眼当今中国,很少有集团级的企业做这么大的投入,这对个人来说还是比较好的机遇,再此也欢迎感兴趣的朋友加入我们,助力 TCL 的数字化转型成功。
为什么 TCL 会投入这么多资源做标准的建设呢?做过数据分析平台的朋友应该比较清楚,数据分析的难点不在于技术,而是数据。就像厨师要做出美味的佳肴,关键不在于使用多先进、多精美的厨具,而是在于食材以及相应的方法。
TCL 实业是与多家原先独立经营的子公司整合而成,各个子公司的业务、数据、标准、流程都不一致,以研发运维为例,就存在了四套 PLM,在这上面所承载的对同一个电容,各个系统的编码是不一致的,而描述这个电容所使用的字段是不一样的。有些系统可能用 10 个字段去描述这个电容,有些系统用 50 个字段描述这个电容,从系统层面是没办法识别成同一个电容,这导致后续无法进行集中采购,通过规模去降低成本,同时也无法进行整个库存的分析,支撑后续的排查。有可能在 a 系统显示的是缺料,但在 b 系统其实材料已经积压。
所以实业目前想通过业务流程的标准化系统整合数据的治理,从数据产生就保证数据的干净、清洁,实现数据在全流程的贯通。一方面提升整个业务的运作效率,同时数据会汇聚到大数据平台,做进一步的数据分析,支撑量化的决策,驱动业务的改进。
为了支撑数据从产生到后期的消费、运营,全生命周期的管理,我们在建设整个数据管理体系,包括一些政策、规范、流程组织等一些 IT 系统。
#02
OLAP 建设历程
这是我们在建设的大数据及 AI 平台的应用架构,最上面是数据分析的平台,主要支撑的是自助 BI、大屏等等的一些分析。
TCL 经过几十年的发展,有一些数据分析平台,最简单的就是关系数据库,再加一些开源的组件,复杂点的是基于 Hive 平台其它 BI 做相应的建设。
为了保证业务的平滑迁移,在集团统一的平台建设的时候,我们也是基于整个 Hadoop 生态构建的 Hive 的数仓,将加工后的数据导入到关系型数据库或 Kudu 等数据库去做数据的分析。
2021 年随着财务数据的接入,海量分析的问题凸显,于是我们引入了 ClickHouse。随着业务发展、自助分析场景的应用越来越多,截至八月份,整个自助分析平台累计达到 6000 用户。多表关联的性能以及并发的问题也逐渐出现,同时,业务对数据的实效性也要求更高,在此背景下,我们引入了 StarRocks 解决相应的问题。
上图展现的是当前数据分析的相关组件,能看出组件还是比较多的,包括一些关系型的数据库、Kudu、ClickHouse 的组件。这导致运维的成本比较高,开发也要基于不同的场景选用不同的组件,增加了开发的难度。我们希望逐渐替换成 StarRocks,去降低运维成本以及开发的难度,提升开发的效率。
目前我们也在做 StarRocks 相应些场景的验证,基于前面的一些实践,我们总结了 ClickHouse 与 StarRocks 的一些优缺点,ClickHouse 目前来说还是单表的性能最优,StarRocks 的优点在于多表关联、写入的性能以及高并发,整体来说跟业界的指标是一致的,这里就不展开。
这是年初我们在做 POC 的时候做的多表上的写入和查询的对比,可以看出,随着数据量增加,StarRocks 的优势越来越明显。
#03
StarRocks 典型应用场景介绍
1、新方舟实时大屏
第一个场景是新方舟的实时大屏,我们基于 StarRocks 构建了实时数仓,去支撑实时数据的分析,体现的是 StarRocks 的时效性和高并发。
新方舟是我们今年刚上线的营销中台。基于营销,我们要做很多方面的数据的分析,这个场景要面临跨越营销、供应、制造等等多域的数据的集成分析,不同域的数据时效性,对分析的要求不一样。
新方舟的整体架构如上图所示。对于实时性要求比较高的分析,我们通过构建实时数仓去接入,而对于时效性要求比较低的,我们则通过离线数仓去接入。实时数仓和离线数仓加工后的数据全部导入到 StarRocks,以支持前端的数据应用,包括一些大屏的分析、自助分析等等。
这是当时做的 618 的销售看板,通过新方舟场景的验证,StarRocks 能很好的支撑实时数仓以及实时报表分析的需求。
整体的体验还是比较好的,平均的响应在 200 到 500 毫秒内。
2、集团 HR 服务
第二个场景是集团 HR 的服务,这里主要是验证 StarRocks 自助分析的过程中多表关联的查询性能。
集团 HR 是我们首个建设的数据资产,我们接入了各个产业的 E-HR 系统,进行数据的清洗,形成了整个数据的资产,支撑了几个人力的应用和数字化运营的分析。
这里面会有个指标极端的场景,TCL 每年会收到政府的一些临时的报数要求,为了应付这种场景,我们会做一个花名册,花名册里面有 200 多个字段,字段会分布在 30 多张表里面。
没有做整个数据分析平台之前,HR 是从 SAP 每月导出数据到 Excel 进行报数分析,整个导入的过程将近 30 分钟。上线整个数据分析平台之后,我们在数据平台里面会生成每个月的快照,支撑需要的自助分析,后来时效性提高到每天,今年提出更高的要求,要求小时级别的刷新。
这个场景主要面临的是多表关联的查询,刚开始,我们通过 ClickHouse 实现,包括每月的快照,每日的快照,用大宽表这种方式,整个体验还是比较好的。但到了小时级别,就需要做多表的关联,整个查询的时间比较长,大概 15 秒左右。
在今年我们引进了 StarRocks 之后,把小时级的数据切换到上面,查询的性能提升了 3-5 倍,查询只需要 3-5 秒,用户体验比较好。
3、邮件告警
第三个场景是邮件告警,主要验证的是 StarRocks 海量的读写、实时、高并发的能力。
整个 TCL 目前有 7 万多名用户,每天都面对着黑客攻击等威胁,为了避免相关的安全隐患给公司造成损失,我们目前在尝试通过一些 AI 等新技术去识别相应的风险。
这个场景主要面临的挑战是实时的要求比较高,海量数据的写入性能要求比较高,以及高并发的数据统计查询。
以前我们用 Kudu 加 Impala 实现,我们内部做了几个 StarRocks 和 Kudu 的性能对比,发现 StarRocks 的整体性能优于 Kudu,包括写入、查询和高并发。于是我们整个场景都切换成 StarRocks 去实现,整体的效果还是比较好的。目前我到外地出差,一下飞机打开邮件很快就能收到相应的提示。
#04
未来规划
1. 打通融合:StarRocks 是我们今年新上线的 MPP 数据库,跟我们自研的大数平台存在很多整合的工作,我们会继续往下开展。
2. 提升效能:整个实时数仓这块规划逐渐切换到 StarRocks,提升整个实时数仓效能。
3. 化繁为简:我们逐渐去收敛 OLAP 引擎到 StarRocks,降低运营以及开发的成本。
4. 极速统一:极速统一相关的开发。打造以 StarRocks 为主的 OLAP 数据分析平台,并基于此实现数据统一存储、统一分析、统一服务、赋能不同业务场景,加速数据价值产出。
5. 稳定运行:StarRocks 还算比较新的 MPP 产品,可靠性、稳定性有待进一步的观察,我们也在逐步完善 StarRocks 的监控。
关于 StarRocks
StarRocks 创立两年多来,一直专注打造世界顶级的新一代极速全场景 MPP 数据库,帮助企业建立“极速统一”的数据分析新范式,助力企业全面数字化经营。
当前已经帮助腾讯、携程、顺丰、Airbnb 、滴滴、京东、众安保险等超过 170 家大型用户构建了全新的数据分析能力,生产环境中稳定运行的 StarRocks 服务器数目达数千台。
2021 年 9 月,StarRocks 源代码开放,在 GitHub 上的星数已超过 3600 个。StarRocks 的全球社区飞速成长,至今已有超百位贡献者,社群用户突破 7000 人,吸引几十家国内外行业头部企业参与共建。
本期 News 快读有 GitHub 官方大动作一下子开源了两款字体,同样大动作的还有 OpenAI 发布的对话模型 ChatGPT,引燃了一波人机对话。
项目这块,也许会成为新的 Web 开发生产力工具的 leptos 和 Python UI 库 CustomTkinter,还有提升开发体验的 jsonhero-web 帮你读 JSON,以及本地跑 GitHub Actiona 的 act。最好玩的,当然是互帮互助的 Villain 一起给彼此的系统留个门。
最后,校招的小伙伴记得绕开这些坑,CampusShame 收录对应届生不友好的公司,当然也有部分对应届生不错的公司选择。
以下内容摘录自微博@HelloGitHub 的 GitHub Trending 及 Hacker News 热帖(简称 HN 热帖),选项标准: | | ,根据项目 release 时间分类,发布时间不超过 14 day 的项目会标注 ,无该标志则说明项目 release 超过半月。由于本文篇幅有限,还有部分项目未能在本文展示,望周知 🌝
- 本文目录
- News 快读
- 新品·GitHub 官方开源多款字体
- 爆款·ChatGPT 相关仓库
- 1. 本周特推
- 1.1 Web 应用构建:leptos
- 1.2 JSON 更好读:jsonhero-web
- 2. GitHub Trending 周榜
- 2.1 Python UI 库:CustomTkinter
- 2.2 本地跑 Action:act
- 2.3 事件驱动微服务:go-coffeeshop
- 2.4 系统开后门:Villain
- 2.5 校招避坑:CampusShame
- 3. 往期回顾
- News 快读
News 快读
新品·GitHub 官方开源多款字体
上周五,GitHub 官方发布了两款可变字体,分别名为:Mona Sans 和 Hubot Sans,你可以基于需求使用这两款字体。
这两款字体可以多种组合,做出漂亮的效果图(如下),更多介绍就得查看官方博客 https://github.blog/2022-12-02-introducing-mona-sans-and-hubot-sans/
爆款·ChatGPT 相关仓库
不知道本周你的朋友圈有没有被 ChatGPT 攻陷呢?一个可以帮你写代码、找 bug、写小说、写注释,各种工作都能搞定的文本机器人。比如,知乎的『电光幻影炼金术』提问过如何找男友的问题。
就这个神奇的聊天模型,也引发了 GitHub 的 ChatGPT 热潮,仅仅 2 天时间,便有 115 个相关的 repo。有兴趣的话,你可以了解下:
- ChatGPT 逆向工程,自己搞个聊天机器人 https://github.com/acheong08/ChatGPT
- 跑在你 macOS 状态栏的 ChatGPT https://github.com/vincelwt/chatgpt-mac
1. 本周特推
1.1 Web 应用构建:leptos
主语言:Rust
可用 Rust 快速构建 Web 应用。特性:
- 全栈:它可在浏览器中运行,也可以在服务器端渲染、运行,或是服务器渲染 HTML 时在浏览器中添加交互;
- 同构:你可以在客户端和服务端用相同形式调用函数,但它只在服务器上运行;
- Web:leptos 基于 Web 平台和 Web 标准之上,没有新的学习成本;
- 框架:提供构建现代 Web 应用所需的大部分内容:响应式系统、模版库、可在服务端和客户端跑的路有;
- 精细的响应:leptos 由响应式原语构造,当响应信号变化时,可以更新单个文本节点、单个类或是从 DOM 中删除一个素,不用动其他代码;
- 声明式;
示例代码:
GitHub 地址→https://github.com/gbj/leptos
1.2 JSON 更好读:jsonhero-web
主语言:TypeScript
API HERO 团队开源的 JSON HERO,旨在提供一个简洁、漂亮的 UI 给 JSON 使用者,让阅读和理解 JSON 更容易。部分特性:
- 多种查看方式,可树形、列视图、编辑器视图等方式看 JSON;
- 自动推断字符串内容,并提供有用预览;
- 创建可用于验证 JSON 的推断 JSON Schema;
- 可用键、值来检索 JSON 文件;
GitHub 地址→https://github.com/apihero-run/jsonhero-web
2. GitHub Trending 周榜
2.1 Python UI 库:CustomTkinter
本周 star 增长数:850+,主语言:Python
基于 Tkinter(Tk GUI 工具包的 Python 绑定包)的 Python UI 库,提供了新颖、现代、可定制的小部件。你可以单独使用这些部件,也可以组合使用。下图为 Windows 下的蓝黑主题。
GitHub 地址→https://github.com/TomSchimansky/CustomTkinter
2.2 本地跑 Action:act
本周 star 增长数:1,350+,主语言:Golang
在本地跑起你的 GitHub Actions。至于为什么选 act,项目给出了两个简单粗暴的理由:快速反馈,不需要每次测试都提交相关 变更;免去 Makefile 烦恼,本地任务器就能搞定。
GitHub 地址→https://github.com/nektos/act
2.3 事件驱动微服务:go-coffeeshop
本周 star 增长数:1,700+,主语言:Golang
Golang 实现的事件驱动微服务演示。部署用到了 Nomad、Consul、Vault 和 Terraform。
GitHub 地址→https://github.com/thangchung/go-coffeeshop
2.4 系统开后门:Villain
本周 star 增长数:1,350+,主语言:Python
一个给 Windows 和 Linux 系统生成后门和多会话处理的工具,允许用户连接兄弟服务器(运行 Villain 的其他机器)并共享后门会话。
GitHub 地址→https://github.com/t3l3machus/Villain
2.5 校招避坑:CampusShame
本周 star 增长数:700+
什么只允许公司做海王把应届生当鱼,不能学生自己当海王去养公司的鱼呢?CampusShame,校招污点与非污点公司名单,校招污点行为包括但不限于:毁意向书、毁两方协定、毁三方协定、试用期裁员、大量裁应届生。
GitHub 地址→https://github.com/forthespada/CampusShame
3. 往期回顾
往期回顾:
- 快速绘制流程图「GitHub 热点速览 v.22.47」
- 视觉享受,兼顾人文观感和几何特征的字体「GitHub 热点速览 v.22.46」
以上为 2022 年第 48 个工作周的 GitHub Trending 🎉如果你 Pick 其他好玩、实用的 GitHub 项目,记得来 HelloGitHub issue 区和我们分享下哟 🌝
V853芯片包含两个CPU。一个是主核心Arm A7 CPU,运行Tina Linux(全志自研Linux)系统,为芯片主系统;一个是RISC-V E907辅助CPU,运行Melis(全志自研RTOS)系统,主要功能是提供通用算力补充、辅助 Linux 实现快起和低功耗管理等功能。
- A7 – Linux系统
V853主核心 A7上运行的是Tina Linux系统。Tina Linux是全志针对AIoT类产品,基于Linux内核深度定制的嵌入式系统。
在 Tina Linux 中,提供 AMP 与 RPMsg 对接 E907
1.Linux remoteproc 管理控制 E907
2.RPMsg 与 E907 通讯
- E907 – RTOS系统
V853 辅助核心 E907 上运行的是全志自研 RTOS 系统 Melis。其独立于 A7 主核心中的 Linux 系统。可以独立运行。
在 E907 Melis 中,提供 OpenAMP 软件框架来与 A7 Linux 系统进行通信。
1.提供了处理器的生命周期管理(LCM,Life Cycle Management),与 Linux 的 remoteproc 兼容
2.提供了处理器间的消息传输机制,与 Linux 的 RPMsg 兼容
异构系统启动流程
首先,由芯片内部的 BORM 寻找启动介质,在 V853 开发板上便是 eMMC 储存器。找到启动介质后会运行其中的 BOOT0 代码。BOOT0 会在 A7 主核心中运行 Linux 系统,也会在 E907 核心中运行 RTOS 系统。启动的两个系统是独立运行的。
异构系统的通信
V853 的异构系统通讯在硬件上使用的是 MSGBOX,在软件层面上使用的是 AMP 与 RPMsg 通讯协议。其中 A7 上基于 Linux 标准的 RPMsg 驱动框架,E907基于 OpenAMP 异构通信框架。
V853 所带有的 A7 主核心与 E907 辅助核心是完全不同的两个核心,为了最大限度的发挥他们的性能,协同完成某一任务,所以在不同的核心上面运行的系统也各不相同。这些不同架构的核心以及他们上面所运行的软件组合在一起,就成了 AMP 系统 (Asymmetric Multiprocessing System, 异构多处理系统)。
由于两个核心存在的目的是协同处理,因此在异构多处理系统中往往会形成 Master – Remote 结构。主核心启动后再启动辅助核心。当两个核心上的系统都启动完成后,他们之间就通过 IPC(Inter Processor Communication)方式进行通信,而 RPMsg 就是 IPC 中的一种。
在AMP系统中,两个核心通过共享内存的方式进行通信。两个核心通过 AMP 中断来传递讯息。内存的管理由主核负责。
AMP 系统在每个通信方向上都有两个缓冲区,分别是 USED 和 AVAIL,这个缓冲区可以按照 RPMsg 中消息的格式分成一块一块链接形成一个环。
当主核需要和从核进行通信的时候可以分为四步:
- 主核先从USED中取得一块内存(Allocate)
- 将消息按照消息协议填充
- 将该内存链接到 AVAIL 缓冲区中(Send)
- 触发中断,通知辅助核有消息处理
反之,从核需要和主核通信的时候也类似:
- 主核先从AVAIL中取得一块内存(Allocate)
- 将消息按照消息协议填充
- 将该内存链接到 USED 缓冲区中(Send)
- 触发中断,通知主核有消息处理。
既然 RPMsg 是一种信息交换的协议,与TCP/IP类似,RPMsg 协议也有分层,主要分为三层,分别是传输层、MAC层和物理层。
其中 MAC层 的 VirtIO 是一种I/O 半虚拟化解决方案,是一套通用 I/O 设备虚拟化的程序,是对半虚拟化 Hypervisor 中的一组通用 I/O 设备的抽象。提供了一套上层应用与各 Hypervisor 虚拟化设备之间的通信框架和编程接口,减少跨平台所带来的兼容性问题,大大提高驱动程序开发效率。
RPMsg 总线上的消息都具有以下结构,包含消息头和数据两个固定的部分,该消息格式的定义位于drivers/rpmsg/virtio_rpmsg_bus.c中,具体定义如下:
异构系统的控制
在异构系统中,不止需要消息的传输,还需要相关控制。例如主核对辅助核心的开启,加载固件,关闭等等。这就需要用到 remoteproc 框架。
remoteproc 框架支持对不同平台,不同架构的处理器进行控制,可以监控辅助核心的运行情况。
对于 V853 来说,remoteproc 用于对 E907 进行生命周期管理,一般来说包含有加载固件、 检测远端处理器是否崩溃等功能。它在加载远端处理器的固件时,会根据固件中定义的 resource table 来申请资源,并创建 VirtIO 设备。
本文分享自微信公众号 – 全志在线
本文为全志在线开发者社区整理的 详解全志V853上的ARM A7和RISC-V E907之间的通信方式
文章目录
- 1.简介
- 2.接口介绍
-
- 开发流程
- 接口说明
- 3.使用
-
- 3.1环境准备
- 3.2下载并加载python驱动
- 3.3创建数据库连接用户
- 3.4示例
- 4.常见报错
1.简介
Psycopg是一种用于执行SQL语句的PythonAPI,可以为PostgreSQL、openGauss数据库提供统一访问接口,应用程序可基于它进行数据操作。Psycopg2是对libpq的封装,主要使用C语言实现,既高效又安全。它具有客户端游标和服务器端游标、异步通信和通知、支持“COPY TO/COPY FROM”功能。支持多种类型Python开箱即用,适配PostgreSQL数据类型;通过灵活的对象适配系统,可以扩展和定制适配。Psycopg2兼容Unicode和Python 3。
openGauss数据库提供了对Psycopg2特性的支持,并且支持Psycopg2通过SSL模式链接。
2.接口介绍
开发流程
接口说明
openGauss提供了如下接口供开发者使用:
- psycopg2.connect()
此方法创建新的数据库会话并返回新的connection对象(连接openGauss数据库实例的对象)。
conn=psycopg2.connect(dbname=“test”,user=“postgres”,password=“secret”,host=“127.0.0.1”,port=“5432”)
或者
conn = psycopg2.connect(“dbname=test user=postgres password=secret
host=127.0.0.1 port=5432”)
创建连接对象(SSl连接)
conn = psycopg2.connect(dbname=“postgres”, user=“user”, password=“password”, host=“localhost”, port=port, sslmode=“verify-ca”, sslcert=“client.crt”, sslkey=“client.key”, sslrootcert=“cacert.pem”)
注意: 如果sslcert, sslkey,sslrootcert没有填写,默认取当前用户.postgresql目录下对应的client.crt, client.key, root.crt
- connection.cursor()
此方法用于返回新的cursor对象(用于整个数据库使用Python编程的cursor)。
cursor(name=None, cursor_factory=None, scrollable=None,
withhold=False)
- cursor.execute(query,vars_list)
此方法执行被参数化的SQL语句(即占位符,而不是SQL文字)。psycopg2模块支持用%s标志的占位符。
curosr.execute(query,vars_list)
- curosr.executemany(query,vars_list)
此方法执行SQL命令所有参数序列或序列中的SQL映射。
curosr.executemany(query,vars_list)
- connection.commit()
此方法将当前挂起的事务提交到数据库。默认情况下,Psycopg在执行第一个命令之前打开一个事务:如果不调用commit(),任何数据操作的效果都将丢失。
connection.commit()
- connection.rollback()
此方法回滚当前挂起事务。执行关闭连接“close()”而不先提交更改“commit()”将导致执行隐式回滚。
connection.rollback()
- cursor.fetchone()
此方法提取查询结果集的下一行,并返回一个组。返回单个组,为结果集的第一条结果,当没有更多数据可用时,返回为“None”。
cursor.fetchone()
- cursor.fetchall()
此方法获取查询结果的所有(剩余)行,并将它们作为组列表返回。返回组列表,为结果集的所有结果。空行时则返回空列表。
cursor.fetchall()
- cursor.close()
此方法关闭当前连接的游标。
cursor.close()
- connection.close()
此方法关闭数据库连接。此方法关闭数据库连接,并不自动调用commit()。如果只是关闭数据库连接而不调用commit()方法,那么所有更改将会丢失。
connection.close()
3.使用
3.1环境准备
本篇使用环境信息:
- 华为云HECS 2核4G
- CentOS Linux release 7.6
- Python 3.6.8
- openGauss 3.1.0 极简版
3.2下载并加载python驱动
1、可以在openGauss官网下载后用FTP工具比如winscp等上传到服务器,也可以直接在服务器上用wget方式获取,根据操作系统版本下载对应的驱动。
root用户下新建存放目录,执行wget和解压命令。
解压后有两个文件夹 lib和psycopg2,分别放置对应的库文件。
2、在解压后的路径下执行拷贝命令,将驱动拷贝到python3下的site-packages目录
3、修改psycopg2/目录权限为755
4、对于非数据库用户,需要将解压后的lib目录,配置在LD_LIBRARY_PATH中。
3.3创建数据库连接用户
注意,由于psycopg2只能使用MD5方式连接,而openGauss默认安装时使用sha256加密,所以这里需要修改一下配置。
修改 data/single_node/postgresql.conf 中password_encryption_type = 1 ,表示支持md5和sha256。
修改pg_hba.conf 中加密算法
然后重启openGauss:gs_ctl restart -D /opt/software/openGauss/data/single_node
连接到openGauss创建用户和数据库。
如果在修改加密方式前之前已经创建过用户了,需要在配置文件修改及数据库重启完成后,重新建用户或者设置用户密码。
3.4示例
编写python文件
将如下测试语句拷贝进去,根据实际情况修改对应的openGauss数据库连接信息。
连接测试
报错了,psycopg2.OperationalError: SCRAM authentication requires libpq version 10 or above
解决办法:
根据提示升级版本
根据提示输入y,等提示Complete!
重新测试连接
注意,如果使用本地工具连接远端云服务器的数据库时,需要修改云服务器安全组,将openGauss的端口放开,否则会连接不上。
4.常见报错
执行python3 ogconn.py报错
1.提示如下错误
File “/opt/software/psycopg2/psycopg2/init.py”, line 122, in connect
conn = _connect(dsn, connection_factory=connection_factory, kwasync)
psycopg2.OperationalError: SCRAM authentication requires libpq version 10 or above
这个错是说libpq版本应该在10以上,需要升级下版本。
解决办法:
根据提示输入y,等提示Complete!
2.提示如下错误:
psycopg2.OperationalError: none of the server’s SASL authentication mechanisms are supported
这个就是加密方式的问题,参考文章中“创建数据库连接用户”部分解决。
欢迎大家测试、交流!
🍒如果您觉得博主的文章还不错或者有帮助的话,请关注一下博主,如果三连点赞评论收藏就更好啦!谢谢各位大佬给予的支持!
主要更新:
1. simple admin tools 升级至 v0.1.0
2. 新增基于Ent 的 CRUD 代码生成, 快速生成 RPC 服务
3. 新增基于 Proto 文件的 CRUD 代码生成,快速生成 api 网关逻辑代码
4. 新增代码生成文档
5. 优化api请求路径
6. 新增错误类型
7. 修复多个 bugs
即将支持
前端代码生成,尽请期待
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
UEditor是由百度开发的所见即所得的开源富文本编辑器,基于MIT开源协议,该富文本编辑器帮助不少网站开发者解决富文本编辑器的难点。
UEditorPlus 是有 ModStart 团队基于 UEditor 二次开发的富文本编辑器,主要做了样式的定制,更符合现代浏览器的审美。
在开发过程中解决了部分使用上的Bug,期待更多伙伴一期加入维护。
v2.7.0亮点介绍
附件优化,附件默认样式全部优化,附件图标替换为SVG格式,样式美观大方。
编辑器文档重新整理发布,方便二次开发和使用。
版本介绍
UEditorPlus v2.7.0 已经发布。
-
新增:开放UEditorPlus使用文档独立站
-
优化:优化OSX系统编辑器字体显示问题
-
优化:附件显示样式调整,图标替换为SVG
-
优化:源码模式下光标显示错位问题优化
-
修复:源码模式下内容编辑不生效问题修复
关于Bug反馈与维护
-
众所周知 UEditor 使用的人数多,目前已经累积了N个Bug,开源不易需要大家共同维护
-
对于在实际使用中遇到的问题,如果急需解决推荐使用 悬赏Issue ,这样让更多有能力的开发者有共同维护的动力
在线演示
-
https://open-demo.modstart.com/ueditor-plus/_examples/
在线文档
-
https://open-doc.modstart.com/ueditor-plus/
开源地址
-
国内:https://gitee.com/modstart-lib/ueditor-plus
-
国外:https://github.com/modstart-lib/ueditor-plus
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
4.12.5 – 正式版 更新详情:
build
- spring-boot > 2.7.6
- nacos.version > 2.1.2
- spring-boot-admin.version>2.7.7
- jasypt.version>3.0.4
- aliyun-java-sdk-core.version>4.6.2
- esdk-obs-java.version>3.22.3.1
- qiniu-java-sdk.version>7.12.0
- gson.version>2.8.9
- jsoup.version>1.15.3
- JustAuth.version>1.16.5
- okhttp3.version>4.10.0
feat
- 新增 员工、岗位、部门等业务 @Echo回显 的具体实现
- 演示环境拦截器启用IP白名单放行功能,方便特定IP的管理员操作数据,并拦截其他IP非法操作数据。
refactor
- spring.factories 文件替换为 org.springframework.boot.autoconfigure.AutoConfiguration.imports
- 特定的样式环境禁止取消应用授权和解绑用户
- 优化 okhttp3.OkHttpClient 配置
- 删除 HuaweiFileStrategyImpl 中无用代码
- 排除三方组件中低版本okhttp,固定使用okhttp 4.10.0
fix
- 升级后,原写法 `applicationContext.getBean(RequestMappingHandlerMapping.class)` 会报错,替换为 `(RequestMappingHandlerMapping) applicationContext.getBean(“requestMappingHandlerMapping”)`
本次更新主要是为后续升级SpringBoot3奠定基础。
更多功能,等你来体验:
- 《灯灯》官网: https://tangyh.top/
- 4.x 数据源模式体验地址: https://datasource.tangyh.top/
- 4.x 字段模式体验地址: https://column.tangyh.top/
- 4.x 非租户模式体验地址: https://none.tangyh.top/
- 3.x 体验地址 1: https://boot.tangyh.top/
- 3.x 体验地址 2: https://boot.tangyh.top/lamp-web/
《灯灯》中后台快速开发平台
如果你非要说 lamp 是 Linux+Apache+MySQL+PHP,那就算是吧,毕竟 PHP 是世界上最好的语言,我也希望此项目成为世界上最好的后台框架!😈😈😈
基于 jdk11/jdk8 ++ SpringCloudAlibaba+ 的微服务快速开发平台,专注于解决 SaaS 多租户体系问题, 具备 RBAC 功能、网关统一鉴权、Xss 防跨站攻击、自动代码生成、多种存储系统、分布式事务、分布式定时任务等多个模块,支持多业务系统并行开发, 支持多服务并行开发,可以作为后端服务的开发脚手架。代码简洁,注释齐全,架构清晰,非常适合学习和企业作为基础框架使用。
核心技术采用 Spring Cloud Alibaba、SpringBoot、Mybatis、Seata、Sentinel、RabbitMQ、FastDFS/MinIO、SkyWalking 等主要框架和中间件。 希望能努力打造一套从 – – – 的解决方案。
技术栈
- 开发方面:
- JSON 序列化:Jackson
- 消息队列:RabbitMQ
- 缓存:Redis
- 数据库: MySQL 5.7.9 或者 MySQL 8.0.19
- 定时器:采用 xxl-job 项目进行二次改造
- 前端 1 (后台管理):vue2 + element-ui
- 前端 2 (后台管理):vue3 + ant-design-vue + vite + TypeScript
- 持久层框架: Mybatis-plus
- 代码生成器:基于 Mybatis-plus-generator 自定义
- API 网关:Gateway
- 服务注册 & 发现和配置中心: Nacos
- 服务消费:OpenFeign
- 负载均衡:Ribbon
- 服务熔断:Sentinel
- 项目构建:Maven
- 分布式事务: seata
- 文件服务器:FastDFS 5.0.5 / 阿里云 OSS / 本地存储 / MinIO / 华为云 / 七牛云
- 监控方面:
- 监控: spring-boot-admin
- 链路调用跟踪: SkyWalking
- 分布式系统的流量防卫兵: Sentinel
- 部署方面:
- 服务器:CentOS
- Nginx
- Jenkins
- Docker
- Kubernetes
项目截图:
12月5日,DataEase开源数据可视化分析平台正式发布v1.17.0版本。
这一版本的功能升级包括:数据集方面,支持将数据集数据按指定条件导出为Excel文件,方便用户对权限范围内的数据进行二次处理。数据集字段支持日期解析格式设置,解决了日期过滤组件无效的问题;仪表板方面,Tab组件新增轮播功能,以满足多屏内容自动切换的需求;悬浮模式下组件支持精确位置设置和大小设置,用户可以制作更加精细的仪表板;视图方面,新增横向百分比柱状图。同时AntV图库的所有柱状图、面积图、仪表盘新增渐变色支持,对视图展示效果做了增强。
X-Pack增强功能方面,DataEase新增仪表板水印设置,用户可以为仪表板添加水印,保护自己的数据版权;数据集支持脱敏规则设置,用户可以通过制定多样的规则来保护用户的数据安全;定时报告新增对富文本支持,报告内容更加丰富多彩。
另外,我们还对其他一些常用的功能进行了功能优化和问题修复。
新增功能
■ 视图:AntV图库的柱状图、面积图、仪表盘等新增渐变色支持,展示效果更丰富
数据可视化工具除了清晰准确地表达数据内在意义以外,良好的展示效果对于用户的使用体验也很重要。在v1.17.0版本中,DataEase对AntV图库中的所有柱状图、面积图以及仪表盘均增加了渐变色的支持,丰富了这些图表类型的展示效果。
■ X-Pack增强包:定时报告新增富文本支持,报告内容更精彩
在DataEase v1.17.0之前的版本中,定时报告中的报告内容只能添加普通文本内容,不支持用户添加图片、链接等内容。
在v1.17.0版本中,DataEase将报告内容使用的普通文本编辑器替换为富文本编辑器,用户可以在报告内进行字体设置、文字排版、内容编号等操作,也可以添加诸如图片、超链接等素。
此外,DataEase对目前所支持的邮件、企业微信、钉钉、飞书、飞书国际版等所有报告分发渠道均进行了富文本的适配,用户无论通过哪个渠道发送报告,都可以获得内容丰富、形式多彩的报告。
■ X-Pack增强包:仪表板支持水印设置,数据分享更放心
随着企业数字化的推广与普及,企业用户日益重视保护数字产品的版权和完整性,并开始关注防复制或去向追踪的相关技术。
在v1.17.0版本中,DataEase加入了对水印设置的支持,用户可以将DataEase账号、昵称、IP和系统当前时间进行自由组合,形成水印内容。设置的水印将会影响所有仪表板展现的场景,包括仪表板预览、报告、PDF导出等。对数据安全具有较高要求的用户,还可以强制要求所有仪表板必须带有水印。
■ X-Pack增强包:数据集新增脱敏规则设置,数据展示更安全
在v1.17.0版本之前,DataEase为数据集数据提供了简单的脱敏处理功能,可以将指定字段的源数据用“*”号进行替代展示。但在某些情况下,用户希望一些类型的数据仅屏蔽关键部分的信息,而非完全屏蔽所有信息,例如屏蔽身份证号、手机号、人名等。用户仅需隐藏这些数据的中间部分,这样既可以看到省份、手机归属地等信息,又很好地把生日、具体号码、姓名等隐私信息进行了脱敏处理。
DataEase v1.17.0版本中新增数据脱敏规则支持,用户可以指定数据全脱敏、指定头尾位数脱敏、指定中间位数脱敏等脱敏规则,有效满足用户个性化的数据处理需求,让敏感数据在展示时更加安全。
除了上述新增功能外,DataEase v1.17.0版本还包含了很多其他的功能更新和优化,欢迎进入我们的官方文档及GitHub仓库的Release页面查看更加详细的更新日志。
功能优化
■ refactor(数据源):调整数据源类型选择页的样式(#3814);
■ refactor(仪表板):组件样式设置中,边框浏览背景颜色支持自适应;
■ refactor(仪表板):优化仪表板过滤组件中表格等组件的自适应缩放方式,防止组件在仪表板不同分辨率下出现组件大小不适配问题;
■ refactor(仪表板):优化置顶置底逻辑,以适配新画布(#3905);
■ refactor(视图):富文本视图允许修改标题;
■ refactor(视图):优化批量操作逻辑;
■ refactor(应用):优化应用模板界面,防止因误触导致关闭信息填写页面的问题(#3854);
■ refactor(插件):优化插件显示效果;
■ refactor:优化数据源类型的展示效果;
■ refactor:NPM(NodePackage Manager)缓存清理。
Bug修复
■ fix(数据源):修复添加API数据源时大小写无法作为区分不同字段名的依据的问题(#3424);
■ fix(数据集):修复关联数据集保存出错问题(#3426);
■ fix(数据集):修复API数据集存在空数据时导致定时任务同步报错的问题(#3668、#3792);
■ fix(数据集):修复MongoDB表名中带“-”号时创建数据集失败的问题(#3160);
■ fix(仪表板):修复开启辅助网格模式后矩阵和悬浮视图重叠的问题(#3717);
■ fix(仪表板):修复Tab下加入多个视图,公共链接打开后,饼图的图示内折叠切换按钮不可用的问题(#3761);
■ fix(视图):修复地图缩放功能异常(#3782);
■ fix(视图):修复PG数值类型长度不够的问题(#3632、#3745);
■ fix(应用):修复含有关联数据集的应用导入后关联数据集报错的问题(#3714);
■ fix:修复dectl脚本错误(#3683)。
Go 语言通用代码生成器仙童发布尝鲜版十一,兼容Java通用代码生成器的Excel模板
GO语言通用代码生成器:仙童尝鲜版十一。在尝鲜版十基础上有增强和修错,并支持数据库表与字段的中文注释和兼容所有java通用代码生成器的SGS2模板,直接生成go语言后端和Vue前端,并自动格式化java语言SGS2模板至go语言模板。支持三大变形功能群,支持四种数据库,支持Excel数据导出。支持复杂版面和图形报表。
尝鲜版十一最大特点是兼容Java通用代码生成器的Excel模板。您需要打开“使用Java兼容性”复选框,系统即可使用java通用代码生成器光,和平之翼代码生成器和无垠式代码生成器的SGS2模板(即Excel模板)生成go语言的代码生成物。唯一的不同是仙童的daoimpl,serviceimpl的包名不支持点号,您需要把文件夹设为单层即可。
仙童第一个稳定版,是尝鲜版十。功能基本完备,所有示例通过检测,并初步完整测试。
在尝鲜版九至尝鲜版十的研发中,克服了许多困难。终于得到了一个功能初步完整,没有已知缺陷,而且数据库和登录模块和 java 通用代码生成器光 2.3.0 文明 Beta8 版完全兼容的版本。这是仙童的新起点。大概至尝鲜版十二,仙童即可进入 Beta 版本阶段。
Go 语言通用代码生成器:仙童,已发布最新视频,演示了 SimpleAuth 弹性登录模块的使用。
视频请见:
https://www.bilibili.com/video/BV1a5411R7Zt/
https://www.bilibili.com/video/BV1pR4y1w7aB/
Go 语言通用代码生成器:仙童,已有重大功能增强,新增弹性登录模块 SimpleAuth。实现了弹性登录认证功能,现在功能已完整,前端支持动态菜单功能。
Go 语言通用代码生成器:仙童尝鲜版十拥有卓绝的变形能力。支持三大变形功能群即动态椰子树功能群,动词否定功能群和字段否定功能群。其 SimpleAuth 弹性登录模块是全自动的弹性登录模块,高度可配置。其三个模块的域对象都可以动态配置。系统自动完成编译检查,并生成符合要求的登录模块。
现在仙童已支持前端和后端复杂版面和图形报表功能。现已支持 Vue 和 ElementUI 的独立前端,一键生成双系统。现在支持 MariaDB,MySQL8,PostgreSQL 和 Oracle 四种数据库。多惊喜等着您去发现。
弹性登录模块 SimpleAuth 弹性模块包含了前端和后端功能,实现了登录认证功能。密码,角色权限功能都有自动数据增强。一键生成。已实现完整的角色和权限功能。
仙童的项目地址:https://gitee.com/jerryshensjf/Fairchild
二进制版本下载地址:https://gitee.com/jerryshensjf/Fairchild/attach_files
项目图片:
独立前端截图:
vue 前端复杂版面:树表
vue 前端图形报表
柱状图:
折线图:
代码生成物后端登录页面:
后端内页:
自从我们提供公共镜像库以来,不少同学询问是否支持手工上传镜像到镜像库。答案是:不支持。
今天给大家聊一聊为什么公共镜像库不应该支持手工上传,主要基于以下几个方面的考量:
Code First
建木作为一个完整实现GitOps理念的工具,开发团队在实现任何服务时所秉承和推广的当然也首选Code First的方式。
因此,我们提供的公共镜像库与GitHub和国内的Gitee都实现了集成,用户授权后可以直接选择代码库中的Dockerfile来进行镜像的构建,后续还会完成与更多代码托管平台的集成。
当然也支持根据分支、Tag等来设置自动构建计划的规则。
一旦使用了Code First的方式,用户就无需自己维护构建服务器或者在本地手工进行镜像构建。
镜像的变更与版本记录与镜像构建的过程一一对应,可追溯可审计,完美符合当前主流的工程理念。
便于生成软件物料清单(SBOM)
不提供手工上次镜像的功能的另一个理由是保证公共库镜像的安全性。最近的研究报告显示,恶意镜像已经成为软件供应链攻击中的攻击手段。而软件物料清单(SBOM)是应对软件供应链攻击的工具之一。
什么是SBOM
软件物料清单 (SBOM) 是一份正式记录,其中包含用于构建软件的各种组件的详细信息和供应链关系。BOM(物料清单)的说法来源于制造业的MES系统,简单说就是类似成分列表。当然BOM也可以包含层次结构,可以层层包含,列表中的组成部分可以继续拆分为子BOM。
在最新的OCI镜像标准中,已经有了推荐的SBOM的描述规范,但是如何生成SBOM并且进行可信的数字签名对于大部分用户仍然是个问题。
因此,建木Hub后续也将在镜像构建过程中增加相关的支持来降低针对公共镜像的软件供应链攻击风险。
上行带宽占用
众所周知,维护一个公共镜像库需要相当高的成本。因此建木Hub目前使用了CDN来优化镜像下载速度和降低镜像下载的流量成本,但是如果开放手工Push镜像功能,对于上行带宽和流量的成本暂时还没有好的优化方案。
总结
基于以上考量,建木Hub的公共镜像仓库不会开通手工上传镜像的功能。当然,随着产品的迭代完善,我们将会在私有镜像仓库中提供手工上传镜像的功能。如果大家确实需要,敬请期待。
最后,放上我们的服务地址。建木Hub 欢迎使用!
从 Android 12 开始,Google 就在 Android 系统中带来了 Rust 语言的支持,作为 C/C++ 的替代方案,他们的目标并不是把现有的 C/C++ 代码都转换成为 Rust,而是在新编写的代码中使用 Rust 语言开发。
通过将越来越多的 Rust 代码集成到其 Android 操作系统中,Google 在减少漏洞方面的努力最终是获得了回报。
Google 在公告中表示,”在过去几年/几个 Android 系统版本中,内存安全漏洞的数量大幅下降”。
具体而言,2019 年至 2022 年期间,每年的内存安全漏洞数量从最初的 223 个下降到如今的 85 个。内存安全漏洞现在在 Android 系统总漏洞的占比也只有 35%,四年前的占比则是 76%,而且 2022 年也是内存安全漏洞首次不再是 Android 系统漏洞最大占比的一年。
在此期间,进入 Android 系统的新内存不安全代码的数量也已经减少。
Rust 占了 Android 13 所有新的原生代码的 21%,在 AOSP 中已经有大约 150 万行 Rust 代码,涵盖各种功能和件,其中就包括超宽带(UWB)栈、DNS-over-HTTP3、Keystore2、Android 的虚拟化框架(AVF),以及各种其他组件及其开源依赖。
到目前为止,在整个 Android 12 和 13 系统中,Rust 代码中发现的内存安全漏洞为零,这是一个重要的发现,因为过去 Android 漏洞密度大于 1/kLOC,也就是说,每一千行代码至少会发现一个漏洞,基于 Rust 代码的行数来看,此举可能已经阻挡了成百上千个漏洞进入 Android 系统。
2022年11月30日,国内知名开源技术社区OSCHINA(开源中国)公布了“2022年度优秀开源技术团队”获奖名单。openKylin(开放麒麟)凭借在开源技术创新和开源社区运营方面的积极表现,荣获“2022年度优秀开源技术团队”奖项。
作为国内首个桌面操作系统根社区,openKylin社区自成立以来便积极推动开源生态建设。截至目前,已有131家企业加入社区,包括操作系统厂商、CPU厂商、GPU厂商、整机厂商、以及软件厂商等,并成立了56个SIG组开展各类技术研究和创新。
此番获奖不仅是openKylin社区的荣誉,也是全体社区成员的共同荣誉,是大家共同努力的结果,促使openKylin社区蓬勃发展。未来,openKylin社区也将保持初心,为构建良好开源生态发展持续努力。
openKylin(开放麒麟)社区旨在以“共创”为核心,在开源、自愿、平等、协作的基础上,通过开源、开放的方式与企业构建合作伙伴生态体系,共同打造桌面操作系统顶级社区,推动Linux开源技术及其软硬件生态繁荣发展。
社区首批理事成员单位包括麒麟软件、普华基础软件、中科方德、麒麟信安、凝思软件、一铭软件、中兴新支点、心科技、中国电科32所、技德系统、北京麟卓、先进操作系统创新中心等13家产业同仁和行业机构。
审核:openKylin
摘要:华为云Solution as Code重磅推出《基于MetaTown构建数字资产平台》解决方案。
本文分享自华为云社区《基于MetaTown构建数字资产平台》,作者: 阿米托福。
华为云Solution as Code重磅推出《基于MetaTown构建数字资产平台》解决方案,由华为云数字资产链支撑底层区块链技术,实现数字资产的铸造、发行、流转、确权等全生命周期管理。同时,推出一键部署的解决方案和快速体验版本,并开放源代码,帮助中小企业快速构建属于自己的数字资产平台。
基于MetaTown构建数字资产平台
一、NFT市场前景
目前,在国内,NFT在数字藏品与数字营销等场景率先大规模落地。2021年被称为“数字藏品”的年,数字藏品共创造了超816万总交易量和超65亿美的总交易额。截至到2022年5月,国内数字藏品平台超过450家,Top50家平台销售藏品500万份,销售额达到2亿。预测2023年度数字藏品国内云市场空间达到3亿。
二、NFT场景痛点需求
1. 唯一性
NFT需要利用区块链技术赋予其唯一性和不可篡改性。同时,还需要利用数字资产链平台,实现数字资产的确权、可信保存和安全交易。在国内NFT多使用联盟链,搭载区块链是否为自主研发,共识机制和验证节点是否具有权威度和信誉度已然成为中国数字资产交易平台的评价指标。
2. 实名认证
区块链信息服务提供者应当按照《中华人民共和国网络安全法》的规定,对区块链信息服务使用者进行基于组织机构代码、身份证件号码或者移动电话号码等方式的真实身份信息认证。用户不进行真实身份信息认证的,区块链信息服务提供者不得为其提供相关服务。
3. 高并发、弹性业务场景
在数字资产秒杀场景下,由于大量玩家涌入,业务高并发,常常会出现应用无法访问,无法支付等崩溃的情况。此外,数字资产大多情况都是限时发售,就会存在明显的浪涌现象,如何从容度过业务高峰又不至于造成资源浪费成为客户迫切需求。
4. 图片及多媒体存储
数字资产品类丰富,目前以数字图片,3D模型,视频等形式为主,大量发行时需要大量存储空间,且需支持加速访问。
三、基于MetaTown数字资产平台
该解决方案基于华为云开源项目MetaTown,可以帮助您在华为云上快速构建自己的数字资产管理平台。MetaTown 是利用华为云数字资产链DAC提供的底层区块链技术构建的数字资产管理平台,可以实现数字资产的铸造、发行、流转、确权等全生命周期管理。
基于MetaTown构建数字资产平台
能力一:数字资产链DAC
数字资产链(Digital Asset Chain,简称DAC)采用NFT技术,是华为云自研的数字资产链平台,基于华为云区块链引擎,通过时间戳、智能合约等技术创新,可实现数字资产的确权、可信保存、安全交易。支持多种形式的原创数字产品的版权保护,获得由中国版权保护中心分配的数字版权唯一标识符。版权交易流转过程清晰可循,具有公信力。同时,提供侵权监测、证据固证、版权鉴定等能力,快速解决版权纠纷。
能力二:人证核身
人证核身服务IVS通过身份证信息、人脸图片,与权威数据库进行比对,进而实现身份验证。该服务可以帮助客户快速核验区块链信息服务使用者的身份,满足法律法规要求。
能力三:分布式缓存
通过集成分布式缓存服务 Redis,支持藏品数据放入缓存,加快客户端访问速度,提高购买体验。
能力四:数字资产存储
数字资产链提供丰富的资产存储管理接口,支持图片、视频、音频、3D模型、文本等富媒体的一键存储,安全、高可靠、类型丰富。NFT数据存储到对象存储服务OBS,从OBS里面直接下载,提供单桶EB级存储能力,满足NFT数据存储诉求,拥有超高性能,支持千万级TPS,2.4Gb/s单流上传速度。
基于此, MetaTown数字资产平台具有三大优势:
(1)超高性能。华为云数字资产链 DAC支持五万次/秒并发链上数字资产创建,支持百亿级数字资产发行流转。
(2)支持一键部署。用户可以基于官方示例模板,一键部署各项云服务资源,快速构建 MetaTown数字资产平台。
(3)开源和定制化。解决方案已开源,用户可以免费用于商业用途,并且还可以在源码基础上进行定制化开发,以满足复杂多样的NFT业务场景。
四、MetaTown方案应用场景
基于MetaTown构建数字资产平台解决方案覆盖多行业,满足各种数字资产场景需求:
场景1:文旅行业
数字藏品是指使用区块链技术,对应特定的作品、艺术品生成的唯一数字凭证,在保护其数字版权的基础上,实现真实可信的数字化发行、购买、收藏和使用。将文物藏品、艺术品等通过实体数字化映射、数据上链等技术手段赋予了数字藏品额外价值,供消费者收藏,极大提升艺术品的变现能力。
场景2:数字营销
品牌零售业NFT数字营销,获取私域流量、直接形成销售转化、积累客户数据是品牌数字化营销的主要目标。数字藏品作为品牌理念载体,品牌价值与数字商品的结合体,即“品牌价值+数字带货”。不仅承载了品牌内容,还能与实体产品结合。数字藏品还是品牌传播介质,通过权益、徽章、门票、礼盒等形式进行展现,链接用户互动场景。
场景3:游戏
将游戏道具、资产或IP周边数字资产化,数字资产可流通、变现,从而扩大用户量、增加用户粘性。游戏IP孵化、游戏场景创新是目前游戏厂商面临巨大挑战,尤其游戏版号限制下,减少厂商试错机会,对游戏出品要求更高。预先通过数字资产发行流转等预测用户喜爱情况,有助于创新决策。
目前《基于 MetaTown 的数字资产平台 》已上线华为云官网。华为云云宝NFT也已发布在体验网址,快来体验吧!
关注,第一时间了解华为云新鲜技术~
本文基于 KubeSphere 可观测性与边缘计算负责人霍秉杰在北美 KubeCon 的 Co-located event Open Observability Day 闪电演讲的内容进行整理。
整理人:米开朗基杨、大飞哥
Fluent Operator 简介
2019 年 1 月 21 日,KubeSphere 社区为了满足以云原生的方式管理 Fluent Bit 的需求开发了 FluentBit Operator,并在 2020 年 2 月 17 日发布了 v0.1.0 版本。此后产品不断迭代,一直维护到 v0.8.0,实现了 Fluent Bit 配置的热加载,而无需重启整个 Fluent Bit 容器。2021 年 8 月,Kubesphere 团队将该项目捐献给 Fluent 社区,并从 v0.9.0 一直持续迭代到 v0.13.0。
2022 年 3 月,FluentBit Operator 正式更名为 Fluent Operator,因为我们增加了对 Fluentd 的支持,而且把 FluentBit CRDs 定义范围从命名空间扩大到集群级别,并于 2022 年 3 月 25 日发布了里程碑版本 v1.0.0。
整体架构预览
Fluent Operator 可以构建完整的云原生日志采集通道。FluentBit 小巧轻量,适合作为 Agent 收集日志;Fluentd 插件丰富功能强大,适合对日志进行集中处理,二者可以独立使用,也可以协作共存,使用方案非常灵活。
仅使用 Fluent Bit 收集日志
Fluent Operator 可以非常便捷地部署 FluentBit Daemonset 服务,运行于各计算节点。当然集群层级的 FluentBit CRD 也可以配置各种 Input,Filter,Parser,Output 等。Fluent Bit 支持将日志直接导出到 ElasticSearch,Kafka,Loki,S3 等众多目标服务,这些只需配置 CRD 即可。
仅使用 Fluentd 收集日志
Fluent Operator 可以非常便捷地将 Fluentd 部署为 Statefulset 服务,应用可以通过 HTTP,Syslog 等方式发送日志,同时 Fluentd 还支持级联模式,即 Fluentd 可以接收来自另一个 Fluentd 服务的日志。类比于 Fluent Bit,Fluentd 也支持集群级别的 CRD 配置,可以方便的配置 Input,Filter,Parser,Output 等。Fluentd 内置支持上百种插件,输入输出都非常丰富。
同时使用 Fluentd 和 Fluent Bit
Fluentd 和 Fluent Bit 在设计架构上极为相似,都有着丰富的社区插件支持,但二者侧重的使用场景有所差异。Fluent Bit 小巧精致,资源消耗少,更适合作为 Agent 来采集日志,而 Fluentd 相对前者功能更加丰富,作为数据中转站或数据治理服务更为贴切。所以绝大多数场景中,二者配合可以构建出灵活高效且扩展性极强的日志收集流水线。
v1.0 后的重要更新
至 Fluent Operator 发布 v1.0.0 至今,仍然在高速迭代。v1.1.0 版本新增了对 OpenSearch 输出的支持;v1.5.0 新增了对 Loki 输出的支持,同时还增加了对监控指标(Metrics)采集的支持,支持清单如下:
- Node Exporter 指标采集
- Prometheus Scrape 指标采集
- Fluent Bit 指标采集
- Prometheus 远程写入的输出信息采集
- OpenTelemetry 输出采集
正是基于对监控指标采集的支持,Fluent Operator 才可以完美构建云边统一的可观测性。
以上内容关注的是对云端资源的数据采集,下面我们来看看 Fluent Operator 在边缘计算场景下的支持情况。
我们使用的边缘计算框架是 KubeEdge,下面我给大家介绍下 KubeEdge 这个项目。
KubeEdge 介绍
KubeEdge 是 CNCF 孵化的面向边缘计算场景、专为边云协同设计的云原生边缘计算框架,除了 KubeEdge 之外还有很多其他的边缘计算框架,比如 K3s。K3s 会在边缘端创建完整的 K8s 集群,而 KubeEdge 只是在边缘端创建几个边缘节点(Edge Node),边缘节点通过加密隧道连接到云端的 K8s 集群,这是 KubeEdge 与 K3s 比较明显的差异。
KubeEdge 的边缘节点会运行一个与 Kubelet 类似的组件叫 Edged,比 Kubelet 更轻量化,用来管理边缘节点的容器。Edged 也会暴露 Prometheus 格式的监控指标,而且暴露方式和 Kubelet 保持一致,都是这种格式:。
统一可观测性方案架构
下面着重讲解如何使用 Fluent Bit 来实现云边统一的可观测性。
直接来看架构图,云端部署了一个 K8s 集群,边缘端运行了一系列边缘节点。云端通过 Prometheus Agent 从 Node Exporter、Kubelet 和 kube-state-metrics 等组件中收集监控指标,同时还部署了一个 Fluent Operator 用来同时管理和部署云端和边缘端的 Fluent Bit Daemonset 实例。
对于边缘节点来说,情况就不那么乐观了,因为边缘节点资源有限,无法部署以上这些组件来收集可观测性数据。因此我们对边缘端的监控指标收集方案进行了改良,将 Prometheus (Agent) 替换为 Fluent Bit,并移除了 Node Expoter,使用更轻量的 Fluent Bit Node Exporter Metrics 插件来替代,同时使用 Fluent Bit Prometheus Scrape Metrics 插件来收集边缘端 Edged 和工作负载的监控指标。
这个架构的优点是只需要在边缘端部署一个组件 Fluent Bit,而且可以同时收集边缘节点和边缘应用的日志和监控指标,对于资源紧张的边缘节点来说,这是一个非常完美的方案。
统一可观测性方案实践
最后给大家演示下如何在边缘端部署 Fluent Bit,并使用它来收集边缘节点的监控指标和日志数据。Fluent Bit 的部署方式通过自定义资源(CR)FluentBit 来声明,内容如下:
我们通过 Node Affinity 将 Fluent Bit 指定部署到边缘节点。为了能够替代 Node Exporter 组件的功能,还需要将 Node Exporter 用到的主机路径映射到容器中。
接下来需要通过自定义资源 创建一个 Fluent Bit Prometheus Scrape Metrics 插件来收集边缘端工作负载的监控指标:
并通过自定义资源 再创建一个 Fluent Bit Node Exporter Metrics 插件来收集边缘节点的监控指标(替代 Node Exporter):
最后还需要通过自定义资源 创建一个 Fluent Bit Prometheus Remote Write 插件,用来将边缘端收集到的监控指标写入到 K8s 集群的 Prometheus 长期存储中。
基于上述步骤,最终我们通过 Fluent Bit 实现了云边统一的可观测性。
总结
虽然 Fluent Bit 的初衷是收集日志,但最近也开始支持收集 Metrics 和 Tracing 数据,这一点很令人兴奋,这样就可以使用一个组件来同时收集所有的可观测性数据(Log、Metrics、Tracing)了。如今 Fluent Operator 也支持了这些功能,并通过自定义资源提供了简单直观的使用方式,想要使用哪些插件直接通过自定义资源声明即可,一目了然。
当然,Fluent Operator 这个项目还很年轻,也有很多需要改进的地方,欢迎大家参与到该项目中来,为其添砖加瓦。
本文由博客一文多发平台 OpenWrite 发布!
摘要:本案例是CenterNet-Hourglass论文复现的体验案例,此模型是对Objects as Points 中提出的CenterNet进行结果复现。
本文分享自华为云社区《CenterNet-Hourglass (物体检测/Pytorch)》,作者:HWCloudAI。
目标检测常采用Anchor的方法来获取物体可能存在的位置,再对该位置进行分类,这样的做法耗时、低效,同时需要后处理(比如NMS)。CenterNet将目标看成一个点,即目标bounding box的中心点,整个问题转变成了关键点估计问题,其他目标属性,比如尺寸、3D位置、方向和姿态等都以估计的中心点为基准进行参数回归。
本案例是CenterNet-Hourglass论文复现的体验案例,此模型是对Objects as Points 中提出的CenterNet进行结果复现(原论文Table 2 最后一行)。本模型是以Hourglass网络架构作为backbone,以ExtremNet 作为预训练模型,在COCO数据集上进行50epochs的训练后得到的。本项目是基于原论文的官方代码进行针对ModelArts平台的修改来实现ModelArts上的训练与部署。
具体算法介绍:https://marketplace.huaweicloud.com/markets/aihub/modelhub/detail/?id=380f95a6-1552-4128-ac96-f
注意事项:
1.本案例使用框架:PyTorch1.4.0
2.本案例使用硬件:GPU: 1*NVIDIA-V100NV32(32GB) | CPU: 8 核 64GB
3.运行代码方法: 本页面顶部菜单栏的三角形运行按钮或按Ctrl+Enter键 运行每个方块中的代码
4.JupyterLab的详细用法: 请参考《ModelAtrs JupyterLab使用指导》
5.碰到问题的解决办法: 请参考《ModelAtrs JupyterLab常见问题解决办法》
1.下载数据和代码
运行下面代码,进行数据和代码的下载和解压
本案例使用COCO数据集。
2.训练
2.1依赖库加载和安装
2.2训练函数
2.3开始训练
训练需要一点时间,请耐心等待
3.模型测试
3.1推理函数
3.2开始推理
可以自行修改预测的图像路径
关注,第一时间了解华为云新鲜技术~
sonic-cpp 是由字节跳动 STE 团队和服务框架团队共同研发的一款面向 C++ 语言的高效 JSON 库,极致地利用当前 CPU 硬件特性与向量化编程,大幅提高了序列化反序列化性能,解析性能为 rapidjson 的 2.5 倍。 sonic-cpp 在字节内部上线以来, 已为抖音、今日头条等核心业务,累计节省了数十万 CPU 核心。近日,我们正式对外开源 sonic-cpp,希望能够帮助更多开发者,欢迎大家star、fork。
Github:https://github.com/bytedance/sonic-cpp
为什么自研 JSON 解析库
在字节跳动,有大量的业务需要用到 JSON 解析和增删查改,占用的 CPU 核心数非常大,所对应的物理机器成本较高,在某些单体服务上JSON CPU 占比甚至超过 40%。因此,提升 JSON 库的性能对于字节跳动业务的成本优化至关重要。同时,JSON 解析库几经更新,目前业界广泛使用的 rapidjson 虽然在性能上有了很大的改进,但相较于近期一些新的库(如 yyjson 和 simdjson),在解析性能方面仍有一定的劣势。
图 1.1 yyjson、simdjson 和 rapidjson 解析性能对比
图片来源: https://github.com/ibireme/yyjson
yyjson 和 simdjson 虽然有更快的 JSON 解析速度,但是都有各自的缺点。simdjson 不支持修改解析后的 JSON 结构,在实际业务中无法落地。yyjson 为了追求解析性能,使用链表结构,导致查找数据时性能非常差。
图1.2 yyjson数据结构
图片来源自: https://github.com/ibireme/yyjson
基于上述原因,为了降低物理成本、优化性能,同时利用字节跳动已开源 Go JSON 解析库 sonic-go 的经验和部分思路,STE 团队和服务框架团队合作自研了一个适用于 C/C++ 服务的 JSON 解析库 sonic-cpp。
sonic-cpp 主要具备以下特性:
-
高效的解析性能,其性能为 rapidjson 的 2.5 倍
-
解决 yyjson 和 simdjson 各自的缺点,支持高效的增删改查
-
基本上支持 json 库常见的所有接口,方便用户迁移
-
在字节跳动商业化广告、搜索、推荐等诸多中台业务中已经大规模落地,并通过了工程化的考验
sonic-cpp 优化原理
sonic-cpp 在设计上整合了 rapidjson ,yyjson 和 simdjson 三者的优点,并在此基础上做进一步的优化。在实现的过程中,我们主要通过充分利用向量化(SIMD)指令、优化内存布局和按需解析等关键技术,使得序列化、反序列化和增删改查能达到极致的性能。
向量化优化(SIMD)
单指令流多数据流(Single Instruction Multiple Data,缩写:SIMD)是一种采用一个控制器来控制多个处理器,同时对一组数据中的每一个数据分别执行相同的操作,从而实现空间上的并行性技术。例如 X86 的 SSE 或者 AVX2 指令集,以及 ARM 的 NEON 指令集等。sonic-cpp 的核心优化之一,正是通过利用 SIMD 指令集来实现的。
序列化优化
从 DOM 内存表示序列化到文件的过程中,一个非常重要的过程是做字符串的转义,比如在引号前面添加转义符“ 。比如,把 序列化成 ,存放在文件。常见的实现是逐个字符扫描,添加转义,比如 cJson 的实现
sonic-cpp 则通过五条向量化指令,一次处理 32 个字符,极大地提高了性能。
序列化过程如下:
- 通过一条向量化 load 指令,一次读取 32 字节到向量寄存器 YMM1;
<!—->
-
YMM1 和另外 32 字节(全部为) 做比较,得到一个掩码(Mask),存放在向量寄存器 YMM2;
-
再通过一条 move mask 指令,把 YMM2 中的掩码规约到 GPR 寄存器 R1;
-
最后通过指令计算下 R1 中尾巴 0 的个数,就可以得到的位置
但如果没有 AVX512 的 load mask 指令集,在尾部最后一次读取 32 字节时,有可能发生内存越界,进而引起诸如 coredump 等问题。 sonic-cpp 的处理方式是利用 Linux 的内存分配以页为单位的机制,通过检查所要读取的内存是否跨页来解决。只要不跨页,我们认为就算越界也是安全的。如果跨页了,则按保守的方式处理,保证正确性,极大地提高了序列化的效率。具体实现见 sonic-cpp 实现。
反序列化优化
在 JSON 的反序列化过程中,同样有个非常重要的步骤是解析数值,它对解析的性能至关重要。比如把字符串”12.5″ 解析成浮点数 12.5。常见的实现基本上是逐个字符解析,见 Rapidjson 的实现 ParseNumber。
sonic-cpp 同样采用 SIMD 指令做浮点数的解析,实现方式如下图所示。
和序列化向量化类似,通过同样的向量指令得到小数点和结束符的位置,再把原始字符串通过向量减法指令,减去, 就得到真实数值。
当我们确定了小数点和结束符的位置,以及向量寄存器中存放的 16 个原始数值,通过乘加指令把他们拼成最终的 和指数 。
针对不同长度的浮点数做 benchmark 测试,可以看到解析性能提升明显。
但我们发现,在字符串长度相对比较小(少于 4 个)的情况下,向量化性能反而是劣化的,因为此时数据短,标量计算并不会有多大劣势,而向量化反而需要乘加这类的重计算指令。
通过分析字节跳动内部使用 JSON 的特征,我们发现有大量少于 4 位数的短整数,同时我们认为,浮点数位数比较长的一般是小数部分,所以我们对该方法做进一步改进,整数部分通过标量方法循环读取解析,而小数部分通过上述向量化方法加速处理,取得了非常好的效果。流程如下,具体实现见 sonic-cpp ParseNumber 实现
按需解析
在部分业务场景中,用户往往只需要 JSON 中的少数目标字段,此时,全量解析整个 JSON 是不必要的。为此,sonic-cpp 中实现了高性能的按需解析接口,能根据给定的 JsonPointer(目标字段的在 JSON 中的路径表示) 解析 JSON 中的目标字段。在按需解析时,由于JSON 较大,核心操作往往是如何跳过不必要的字段。如下。
传统实现
JSON 是一种半结构化数据,往往有嵌套 object 和 array。目前,实现按需解析主要有两种方法:递归下降法和两阶段处理。递归下降法,需要递归下降地“解析”整个 JSON,跳过所有不需要的 JSON 字段,该方法整体实现分支过多,性能较差;两阶段处理需要在阶段一标记整个 JSON token 结构的位置,例如等,在阶段二再根据 token 位置信息,线性地跳过不需要的 JSON 字段,如按需查找的字段在 JSON 中的位置靠前时,该方法性能较差。
sonic-cpp 实现
sonic-cpp 基于 SIMD 实现了高性能的单阶段的按需解析。在按需解析过程中,核心操作在于如何跳过不需要的 JSON object 或 array。sonic-cpp 充分利用了完整的 JSON object 中 左括号数量必定等于右括号数量这一特性,利用 SIMD 读取 64 字节的 JSON 字段,得到左右括号的 bitmap。进一步,计算 object 中左括号和右括号的数量,最后通过比较左右括号数量来确定 object 结束位置。具体操作如下:
经过全场景测试,sonic-cpp 的按需解析明显好于已有的实现。性能测试结果如下图。其中,rapidjson-sax 是基于 rapidjson 的 SAX 接口实现的,使用递归下降法实现的按需解析。simdjson 的按需解析则是基于两阶段处理的方式实现。Normal,Fronter,NotFoud 则分别表示,按需解析时,目标字段 在 JSON 中的位置居中,靠前或不存在。不过,使用 sonic-cpp 和 simdjson 的按需解析时,都需要保证输入的 JSON 是正确合法的。
按需解析扩展
sonic-cpp 利用 SIMD 前向扫描,实现了高效的按需解析。在字节跳动内部,这一技术还可以应用于两个 JSON 的合并操作。在合并 JSON 时,通常需要先解析两个 JSON,合并之后,再反序列化。但是,如果两个 JSON 中需要合并的字段较少,就可以使用按需解析思想,先将各个字段的值解析为 raw JSON 格式,然后再进行合并操作。这样,能极大地减少 JSON 合并过程中的解析和序列化开销。
DOM 设计优化
节点设计
在 sonic-cpp 中,表示一个 JSON value 的类被称作 node。node 采用常见的方法,将类型和 size 的信息合为一个,只使用 8 字节,减少内存的使用。对于每个 node,内存上只需要 16 字节,布局更紧凑,具体结构如下:
DOM树设计
sonic-cpp 的 DOM 数据结构采用类似于 rapidjson 的实现,可以对包括 array 或 object 在内的所有节点进行增删查改。
在 DOM 的设计上,sonic-cpp 把 object 和 array 的成员以数组方式组织,保证其在内存上的连续。数组方式让 sonic-cpp 随机访问 array 成员的效率更高。而对于 object,sonic-cpp 为其在 meta 数据中保存一个 map。map 里保存了 key 和 value 对应的 index。通过这个 map,查找的复杂度由 O(N) 降到 O(logN)。sonic-cpp 为这个 map 做了一定的优化处理:
-
按需创建: 只在调用接口时才会生成这个 map,而不是解析的时候创建。
-
使用 string_view 作为 key: 无需拷贝字符串,减少开销。
内存池
sonic-cpp 提供的内存分配器默认使用内存池进行内存分配。该分配器来自 rapidjson。使用内存池有以下几个好处:
-
避免频繁地 malloc。DOM 下的 node 只有 16 byte,使用内存池可以高效地为这些小的数据结构分配内存。
-
避免析构 DOM 上的每一个 node,只需要在析构 DOM 树的时候,统一释放分配器的内存即可。
Object 内建的 map 也使用了内存池分配内存,使得内存可以统一分配和释放。
性能测试
在支持高效的增删改查的基础上,性能和 simdjson、yyjson 可比。
不同 JSON 库性能对比
基准测试是在 https://github.com/miloyip/nativejson-benchmark 的基础上支持 sonic-cpp 和 yyjson,测试得到。
反序列化(Parse)性能基准测试结果
序列化(Stringify)性能基准测试结果:
不同场景性能对比
sonic-cpp 与 rapidjson,simdjson 和 yyjson 之间在不同场景的性能对比(HIB: Higher is better)。
生产环境中性能对比
在实际生产环境中,sonic-cpp 的性能优势也得到了非常好的验证,下面是字节跳动抖音某个服务使用 sonic-cpp 在高峰段 CPU 前后的对比。
展望
sonic-cpp 当前仅支持 amd64 架构,后续会逐步扩展到 ARM 等其它架构。同时,我们将积极地支持 JSON 相关 RFC 的特性,比如,支持社区的 JSON 合并相关的 RFC 7386,依据 RFC 8259 设计 JSON Path 来实现更便捷的 JSON 访问操作等。
欢迎开发者们加入进来贡献 PR,一起打造业界更好的 C/C++ JSON 库!
直播预告
为了帮助大家更好地理解 sonic-cpp,我们将于2022年12月15日19:30在《掘金公开课18期》,与大家直播分享 sonic-cpp 的技术原理、实践效果和未来规划。参与直播互动还有机会赢取周边礼品哦!礼品多多,欢迎大家关注并扫描下方二维码预约直播。
直播互动礼品图片
OpenAI 上周推出的 AI 对话模型 ChatGPT 这几天风靡全网,其回答各种问题的强大能力让许多人感慨它可替代 Google 等搜索引擎,甚至替代编程问答社区 Stack Overflow。
事实上,Stack Overflow 这几天也涌入了大量用 ChatGPT 生成的答案。不过 Stack Overflow 对 ChatGPT 生成的内容并不待见 —— 他们今天发布了一项临时规则:禁止使用 ChatGPT 生成的内容来回答 Stack Overflow 上的问题。
Stack Overflow 称,在使用 ChatGPT 生成的文本回复的问题中,其正确率非常低,而这些内容对整个网站以及寻求正确答案的用户来说是有害的。
Stack Overflow 认为,这里的主要问题是,由于使用 ChatGPT 的门槛非常低,很多人最近都在尝试使用 ChatGPT 回答 Stack Overflow 上的问题,但他们缺少专业知识,也不愿意在回复前验证 ChatGPT 生成的答案是否正确。因此现在 Stack Overflow 产生了许多无价值,甚至引起误导的回答。
针对这种情况,Stack Overflow 决定采取措施来减少使用 ChatGPT 生成的答案。在禁止 ChatGPT 的规则公布后,如果用户被发现仍在使用 ChatGPT 回答问题,他们可能会被禁止发帖。
延伸阅读
- 整活大师 ChatGPT:实现编程语言、构建虚拟机……
sonic-cpp 是由字节跳动 STE 团队和服务框架团队共同研发的一款面向 C++ 语言的高效 JSON 库,极致地利用当前 CPU 硬件特性与向量化编程,大幅提高了序列化反序列化性能,解析性能为 rapidjson 的 2.5 倍。 sonic-cpp 在字节内部上线以来, 已为抖音、今日头条等核心业务,累计节省了数十万 CPU 核心。近日,我们正式对外开源 sonic-cpp,希望能够帮助更多开发者,欢迎大家star、fork。
Github:https://github.com/bytedance/sonic-cpp
为什么自研 JSON 解析库
在字节跳动,有大量的业务需要用到 JSON 解析和增删查改,占用的 CPU 核心数非常大,所对应的物理机器成本较高,在某些单体服务上JSON CPU 占比甚至超过 40%。因此,提升 JSON 库的性能对于字节跳动业务的成本优化至关重要。同时,JSON 解析库几经更新,目前业界广泛使用的 rapidjson 虽然在性能上有了很大的改进,但相较于近期一些新的库(如 yyjson 和 simdjson),在解析性能方面仍有一定的劣势。
图 1.1 yyjson、simdjson 和 rapidjson 解析性能对比
图片来源: https://github.com/ibireme/yyjson
yyjson 和 simdjson 虽然有更快的 JSON 解析速度,但是都有各自的缺点。simdjson 不支持修改解析后的 JSON 结构,在实际业务中无法落地。yyjson 为了追求解析性能,使用链表结构,导致查找数据时性能非常差。
图1.2 yyjson数据结构
图片来源自: https://github.com/ibireme/yyjson
基于上述原因,为了降低物理成本、优化性能,同时利用字节跳动已开源 Go JSON 解析库 sonic-go 的经验和部分思路,STE 团队和服务框架团队合作自研了一个适用于 C/C++ 服务的 JSON 解析库 sonic-cpp。
sonic-cpp 主要具备以下特性:
-
高效的解析性能,其性能为 rapidjson 的 2.5 倍
-
解决 yyjson 和 simdjson 各自的缺点,支持高效的增删改查
-
基本上支持 json 库常见的所有接口,方便用户迁移
-
在字节跳动商业化广告、搜索、推荐等诸多中台业务中已经大规模落地,并通过了工程化的考验
sonic-cpp 优化原理
sonic-cpp 在设计上整合了 rapidjson ,yyjson 和 simdjson 三者的优点,并在此基础上做进一步的优化。在实现的过程中,我们主要通过充分利用向量化(SIMD)指令、优化内存布局和按需解析等关键技术,使得序列化、反序列化和增删改查能达到极致的性能。
向量化优化(SIMD)
单指令流多数据流(Single Instruction Multiple Data,缩写:SIMD)是一种采用一个控制器来控制多个处理器,同时对一组数据中的每一个数据分别执行相同的操作,从而实现空间上的并行性技术。例如 X86 的 SSE 或者 AVX2 指令集,以及 ARM 的 NEON 指令集等。sonic-cpp 的核心优化之一,正是通过利用 SIMD 指令集来实现的。
序列化优化
从 DOM 内存表示序列化到文件的过程中,一个非常重要的过程是做字符串的转义,比如在引号前面添加转义符“ 。比如,把 序列化成 ,存放在文件。常见的实现是逐个字符扫描,添加转义,比如 cJson 的实现
sonic-cpp 则通过五条向量化指令,一次处理 32 个字符,极大地提高了性能。
序列化过程如下:
- 通过一条向量化 load 指令,一次读取 32 字节到向量寄存器 YMM1;
<!—->
-
YMM1 和另外 32 字节(全部为) 做比较,得到一个掩码(Mask),存放在向量寄存器 YMM2;
-
再通过一条 move mask 指令,把 YMM2 中的掩码规约到 GPR 寄存器 R1;
-
最后通过指令计算下 R1 中尾巴 0 的个数,就可以得到的位置
但如果没有 AVX512 的 load mask 指令集,在尾部最后一次读取 32 字节时,有可能发生内存越界,进而引起诸如 coredump 等问题。 sonic-cpp 的处理方式是利用 Linux 的内存分配以页为单位的机制,通过检查所要读取的内存是否跨页来解决。只要不跨页,我们认为就算越界也是安全的。如果跨页了,则按保守的方式处理,保证正确性,极大地提高了序列化的效率。具体实现见 sonic-cpp 实现。
反序列化优化
在 JSON 的反序列化过程中,同样有个非常重要的步骤是解析数值,它对解析的性能至关重要。比如把字符串”12.5″ 解析成浮点数 12.5。常见的实现基本上是逐个字符解析,见 Rapidjson 的实现 ParseNumber。
sonic-cpp 同样采用 SIMD 指令做浮点数的解析,实现方式如下图所示。
和序列化向量化类似,通过同样的向量指令得到小数点和结束符的位置,再把原始字符串通过向量减法指令,减去, 就得到真实数值。
当我们确定了小数点和结束符的位置,以及向量寄存器中存放的 16 个原始数值,通过乘加指令把他们拼成最终的 和指数 。
针对不同长度的浮点数做 benchmark 测试,可以看到解析性能提升明显。
但我们发现,在字符串长度相对比较小(少于 4 个)的情况下,向量化性能反而是劣化的,因为此时数据短,标量计算并不会有多大劣势,而向量化反而需要乘加这类的重计算指令。
通过分析字节跳动内部使用 JSON 的特征,我们发现有大量少于 4 位数的短整数,同时我们认为,浮点数位数比较长的一般是小数部分,所以我们对该方法做进一步改进,整数部分通过标量方法循环读取解析,而小数部分通过上述向量化方法加速处理,取得了非常好的效果。流程如下,具体实现见 sonic-cpp ParseNumber 实现
按需解析
在部分业务场景中,用户往往只需要 JSON 中的少数目标字段,此时,全量解析整个 JSON 是不必要的。为此,sonic-cpp 中实现了高性能的按需解析接口,能根据给定的 JsonPointer(目标字段的在 JSON 中的路径表示) 解析 JSON 中的目标字段。在按需解析时,由于JSON 较大,核心操作往往是如何跳过不必要的字段。如下。
传统实现
JSON 是一种半结构化数据,往往有嵌套 object 和 array。目前,实现按需解析主要有两种方法:递归下降法和两阶段处理。递归下降法,需要递归下降地“解析”整个 JSON,跳过所有不需要的 JSON 字段,该方法整体实现分支过多,性能较差;两阶段处理需要在阶段一标记整个 JSON token 结构的位置,例如等,在阶段二再根据 token 位置信息,线性地跳过不需要的 JSON 字段,如按需查找的字段在 JSON 中的位置靠前时,该方法性能较差。
sonic-cpp 实现
sonic-cpp 基于 SIMD 实现了高性能的单阶段的按需解析。在按需解析过程中,核心操作在于如何跳过不需要的 JSON object 或 array。sonic-cpp 充分利用了完整的 JSON object 中 左括号数量必定等于右括号数量这一特性,利用 SIMD 读取 64 字节的 JSON 字段,得到左右括号的 bitmap。进一步,计算 object 中左括号和右括号的数量,最后通过比较左右括号数量来确定 object 结束位置。具体操作如下:
经过全场景测试,sonic-cpp 的按需解析明显好于已有的实现。性能测试结果如下图。其中,rapidjson-sax 是基于 rapidjson 的 SAX 接口实现的,使用递归下降法实现的按需解析。simdjson 的按需解析则是基于两阶段处理的方式实现。Normal,Fronter,NotFoud 则分别表示,按需解析时,目标字段 在 JSON 中的位置居中,靠前或不存在。不过,使用 sonic-cpp 和 simdjson 的按需解析时,都需要保证输入的 JSON 是正确合法的。
按需解析扩展
sonic-cpp 利用 SIMD 前向扫描,实现了高效的按需解析。在字节跳动内部,这一技术还可以应用于两个 JSON 的合并操作。在合并 JSON 时,通常需要先解析两个 JSON,合并之后,再反序列化。但是,如果两个 JSON 中需要合并的字段较少,就可以使用按需解析思想,先将各个字段的值解析为 raw JSON 格式,然后再进行合并操作。这样,能极大地减少 JSON 合并过程中的解析和序列化开销。
DOM 设计优化
节点设计
在 sonic-cpp 中,表示一个 JSON value 的类被称作 node。node 采用常见的方法,将类型和 size 的信息合为一个,只使用 8 字节,减少内存的使用。对于每个 node,内存上只需要 16 字节,布局更紧凑,具体结构如下:
DOM树设计
sonic-cpp 的 DOM 数据结构采用类似于 rapidjson 的实现,可以对包括 array 或 object 在内的所有节点进行增删查改。
在 DOM 的设计上,sonic-cpp 把 object 和 array 的成员以数组方式组织,保证其在内存上的连续。数组方式让 sonic-cpp 随机访问 array 成员的效率更高。而对于 object,sonic-cpp 为其在 meta 数据中保存一个 map。map 里保存了 key 和 value 对应的 index。通过这个 map,查找的复杂度由 O(N) 降到 O(logN)。sonic-cpp 为这个 map 做了一定的优化处理:
-
按需创建: 只在调用接口时才会生成这个 map,而不是解析的时候创建。
-
使用 string_view 作为 key: 无需拷贝字符串,减少开销。
内存池
sonic-cpp 提供的内存分配器默认使用内存池进行内存分配。该分配器来自 rapidjson。使用内存池有以下几个好处:
-
避免频繁地 malloc。DOM 下的 node 只有 16 byte,使用内存池可以高效地为这些小的数据结构分配内存。
-
避免析构 DOM 上的每一个 node,只需要在析构 DOM 树的时候,统一释放分配器的内存即可。
Object 内建的 map 也使用了内存池分配内存,使得内存可以统一分配和释放。
性能测试
在支持高效的增删改查的基础上,性能和 simdjson、yyjson 可比。
不同 JSON 库性能对比
基准测试是在 https://github.com/miloyip/nativejson-benchmark 的基础上支持 sonic-cpp 和 yyjson,测试得到。
反序列化(Parse)性能基准测试结果
序列化(Stringify)性能基准测试结果:
不同场景性能对比
sonic-cpp 与 rapidjson,simdjson 和 yyjson 之间在不同场景的性能对比(HIB: Higher is better)。
生产环境中性能对比
在实际生产环境中,sonic-cpp 的性能优势也得到了非常好的验证,下面是字节跳动抖音某个服务使用 sonic-cpp 在高峰段 CPU 前后的对比。
展望
sonic-cpp 当前仅支持 amd64 架构,后续会逐步扩展到 ARM 等其它架构。同时,我们将积极地支持 JSON 相关 RFC 的特性,比如,支持社区的 JSON 合并相关的 RFC 7386,依据 RFC 8259 设计 JSON Path 来实现更便捷的 JSON 访问操作等。
欢迎开发者们加入进来贡献 PR,一起打造业界更好的 C/C++ JSON 库!
直播预告
为了帮助大家更好地理解 sonic-cpp,我们将于2022年12月15日19:30在《掘金公开课18期》,与大家直播分享 sonic-cpp 的技术原理、实践效果和未来规划。参与直播互动还有机会赢取周边礼品哦!礼品多多,欢迎大家关注并扫描下方二维码预约直播。
直播互动礼品图片
DBeaver 22.3.0 已发布。
DBeaver 是免费的多平台数据库工具,适用于开发人员、数据库管理员、分析师和所有需要使用数据库的人,并且支持所有流行的数据库:MySQL、PostgreSQL、SQLite、Oracle、DB2、SQL Server、Sybase、MS Access、Teradata、Firebird、Apache Hive、Phoenix、Presto 等。
更新内容
- 数据编辑器
- 优化数据导出按钮 UI
- 将获取所有数据和大小的控件重新添加到状态栏
- 将套索工具 (Lasso tool) 添加到空间查看器 (spatial viewer)
- 修复空间查看器初始化中的错误
- 修复在 macOS 和 Linux 系统中,使用外部编辑器打开 BLOB 内容时出现的错误
- 修复基于浏览器的图像查看器控件(空图像句柄或无效图像句柄)
- SQL 编辑器
- 改进对大 SQL 文件的支持(自动禁用语法验证)
- 重新设计表格自动完成工具提示 UI
- 修复非关联脚本打开错误
- 通用
- 修复默认 SSL 信任库的选择问题(目前支持配置)
- 改进连接编辑/创建对话框的性能
- 数据库服务器版本现在显示在连接的工具提示中
- 重新设计对象删除对话框
- 数据库创建按钮已从不支持它的数据库的连接对话框中删除
- 打包驱动程序的安全补丁(添加 zip 存档的额外验证)
- SSH: 修复 SSHJ 隧道失效的问题
- Tasks: 修复在缺失(删除)表的情况下操作任务的问题
- Clickhouse: 修复标识符的引用问题 (for non ASCII characters)
- Intersystems Cache: 再次添加社区驱动程序
- MySQL:
- 修复 procedures 的超链接导航问题
- 修复复杂标识符的引用问题
- Netezza: 改进数据列的读取
- PostgreSQL:
- 修复角色的 create/edit 命令
- 改进 PostgreSQL 15 支持(支持新的数据类型类别)
下载地址 | 发布说明
Brave 是基于 Chromium 的一款免费开源网络浏览器,主打隐私保护,其默认设置就会自动阻止在线广告和网站跟踪。Brave Software(Brave 浏览器所属公司)于 2015 年由 Brendan Eich 和 Brian Bondy 联合创立,其中前者是 JavaScript 的创造者,同时也是 Mozilla 联合创始人。
Brave 1.46 发布,更新内容如下:
- 将 Chromium 升级到 108.0.5359.94
- 增加了通过管理策略禁用 Brave Wallet 的功能
- 为 Brave Rewards 增加了国家选择要求
- 增加了对新标签页下多个自定义背景图片的支持
- 在 Windows 上的首次运行对话框和 brave://settings/getStarted 中增加了 “钉在任务栏” 选项
- 在 macOS 上的首次运行对话框和 brave://settings/getStarted 中增加了 “保留在 Dock” 选项
- 为 Brave News 增加了西班牙、墨西哥和巴西的内容支持
- 在 brave://settings/content 下增加了 Brave Shields 设置
- 增加了对侧边栏的右侧显示支持
- [安全] 禁用了隐私窗口中的块状素选择器
- 为 Brave Wallet 启用了 ENS L2 解析
- 为使用 Tor 的隐私窗口启用了 HTTPS-Only 模式
- 启用了默认的浏览器信息栏提示
- 改进了非英语字符的字体外观
- 更新了 DNSLink 重定向的 “Ask” IPFS 解析方法
- 更新了 Brave News 的自定义 UI
- 更新了 Brave News 来源建议
- 更新了跳转功能,只适用于跨网站导航
- 更新了广告屏蔽组件以使用纯文本列表
- 重新启用了 brave://settings/appearance 下的 “侧面板” 显示设置
- 用 Poppins 替换了 Muli 字体
- 修正了对没有 DNS 记录的 URL 重定向的 x-ipfs-path 处理
- 修正了在 brave://settings/shields/filters 下启用 “RU Adlist” 时在 https://d3ward.github.io/toolz/adblock 的崩溃
- 修正了 HTTPSE 重定向优先于 adblock 重定向的问题
- 修正了应用某些主题时工具栏上不正确的按钮颜色
- 修复了拖放完成后,拖放指示器没有从侧边栏消失的问题
更多详情可查看:https://brave.com/latest/
Spring Shell 2.1.4 和 3.0.0-M3 已发布。
Spring Shell 是基于 Spring 的交互式 Shell,可让开发者使用简单的基于 Spring 的编程模型来开发命令。
Spring Shell 3.0.0-M3 是建立在 Spring Boot 3.0.0 GA 版本之上的第一个里程碑。
Spring Shell 2.1.4 版本主要变化:
修复
此 GA 包含一些显着变化:
- 基于 Spring Boot 2.7.6 构建
- 向后移植了一些错误修复
问题
#577 backport 没有连字符的 ShellOption 没有注册
#573 backport 如果没有值,方法执行应该不会出错
#571 升级 spring-boot 2.7.6
#570 backport 处理选项值中的空格
详情查看 release note 。
3.0.0-M3 版本主要变化:
修复
这个里程碑使用并包含一些显着的变化:
- 常见错误修复
- 新测试模块
问题
#576 在 linux 上使用 musl 构建示例
#575 ShellOption 未在没有连字符的情况下注册
#574 升级 spring-boot 3.0.0
#572 方法执行不应在没有值的情况下出错
#568 升级 spring-boot 3.0.0-RC2
#567 处理选项中的空格值
#565 自动配置类应该使用@autoConfiguration
#558 文档更新
#552 在本地修复 e2e flow.test.ts
#516 JLine 终端应该是可配置的
#489 提供测试框架
详情查看 3.0.0 M3 release note 。
pgAdmin 是 PostgreSQL 领先的开源图形化管理工具。pgAdmin 4 旨在满足新手和有经验的 Postgres 用户的需求,提供强大的图形界面,简化了数据库对象的创建、维护和使用。
这个版本的 pgAdmin 4 包括错误修复和新功能,主要更新内容如下:
安全
请注意这个版本包括一个安全更新,以确保在使用服务器模式下运行的 pgAdmin 时,只有授权和认证的用户可以验证二进制路径。在服务器模式下运行 pgAdmin 的用户应该尽快升级到这个版本。
这个问题不影响在桌面模式下运行的用户。
Bugs/Housekeeping:
- 确保只有授权和认证的用户可以验证二进制路径(CVE-2022-4223)
- 将 BigAnimal 的 API 版本更新为 V2
- 删除所有 Backbone 和 Underscore 的痕迹
- 修正了一个问题,即在模式差异工具中为外键显示了错误的模式。
- 确保桌面模式下的查询历史日期格式与 pgadmin 服务器的地区设置的格式一致。
- 修正了一个问题,即如果 CSV 引号字符长度超过 1,CSV 文件将无法下载。
- 确保 DATA_DIR 依赖的文件夹/文件如果没有在配置文件中单独指定,会自动在指定的 DATA_DIR 内创建。
- 修复了在编辑结果网格中的数据时,编辑器的位置是错误的问题。
- 确保查询工具对注册有 PostgreSQL 服务的服务器成功启动
更多详情可查看:https://www.postgresql.org/about/news/pgadmin-4-v617-released-2553/
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
Armbian Linux 是一款适用于 ARM 开发板的、基于 Debian 的 Linux 发行版,具有强大的图形化配置工具和安装程序,简单易上手。Armbian 每三个月提供一次稳定版本,由最近的 LTS 内核驱动,喜欢滚动发布的用户可以检查 EDGE 版本,这些版本使用来自 sid、hirsute 或 impish userland 的最新每日内核构建。
Armbian 22.11 版本已发布发布,此版本的重大更改包括:引入了对 Banana Pi M5、ODROID-M1 和 Rock Pi 4C+ 单板计算机的支持、RISC-V 64 UEFI 构建支持,以及改进了对 ROCK Pi S (基于瑞芯微 RK3308 的单板计算机)的支持。
此版本还添加了针对软件部署优化的极小映像,通过默认冻结内核升级来提高稳定性,实现了对 Linux 内核 5.19或更高版本的 Plymouth 启动启动支持,并为 ARMhf 和 AArch64 服务器和桌面添加了对 gpiod 库的支持(用于访问 GPIO 引脚/线)。
其他值得注意的变化,Armbian 22.11 为 nand-sata-install 添加了 UEFI 安装支持,在 Rock Pi 4 单板计算机上启用了正确的 ES8316 音频,添加了 ZFS 存储库,为 postinst 脚本中的所有用户添加了 SKEL 分发,以及将 Intel 声音固件添加到桌面图像。
在软件方面,此版本为 Terminator 终端模拟器应用程序添加了初始配置,重新启用了 Mozilla Thunderbird 电子邮件客户端,并在基于 Debian Sid 的图像上添加了 Codium IDE。
Armbian 22.11 中还修复了许多错误,以进一步改进对现有开发板的支持,包括 Raspberry Pi、ODROID-XU4、PINE H64、NanoPi NEO3 、JetHub D1 和 ROCK Pi S。
有关此版本的所有更改,可查看完整的变更日志。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
摘要:本文重点介绍几种通过优化Cache使用提高程序性能的方法。
本文分享自华为云社区《编译器优化那些事儿(7):Cache优化》,作者:毕昇小助手。
引言
软件开发人员往往期望计算机硬件拥有无限容量、零访问延迟、无限带宽以及便宜的内存,但是现实却是内存容量越大,相应的访问时间越长;内存访问速度越快,价格也更贵;带宽越大,价格越贵。为了解决大容量、高速度、低成本之间的矛盾,基于程序访问的局部性原理,将更常用数据放在小容量的高速存储器中,多种速度不同的存储器分层级联,协调工作。
图1 memory hierarchy for sever [1]
现代计算机的存储层次可以分几层。如图1所示,位于处理器内部的是寄存器;稍远一点的是一级Cache,一级Cache一般能够保存64k字节,访问它大约需要1ns,同时一级Cache通常划分为指令Cache(处理器从指令Cache中取要执行的指令)和数据Cache(处理器从数据Cache中存/取指令的操作数);然后是二级Cache,通常既保存指令又保存数据,容量大约256k,访问它大约需要3-10ns;然后是三级Cache,容量大约16-64MB,访问它大约需要10-20ns;再接着是主存、硬盘等。注意,CPU和Cache是以word传输的,Cache到主存以块(一般64byte)传输的。
前文提到了程序的局部性原理,一般指的是时间局部性(在一定时间内,程序可能会多次访问同一内存空间)和空间局部性(在一定时间内,程序可能会访问附近的内存空间),高速缓存(Cache)的效率取决于程序的空间和时间的局部性性质。比如一个程序重复地执行一个循环,在理想情况下,循环的第一个迭代将代码取至高速缓存中,后续的迭代直接从高速缓存中取数据,而不需要重新从主存装载。因此,为了使程序获得更好的性能,应尽可能让数据访问发生在高速缓存中。但是如果数据访问在高速缓存时发生了冲突,也可能会导致性能下降。
篇幅原因,本文重点讨论编译器在Cache优化中可以做哪些工作,如果读者对其他内存层次优化感兴趣,欢迎留言。下面将介绍几种通过优化Cache使用提高程序性能的方法。
对齐和布局
现代编译器可以通过调整代码和数据的布局方式,提高Cache命中率,进而提升程序性能。本节主要讨论数据和指令的对齐、代码布局对程序性能的影响,大部分处理器中Cache到主存是以Cache line(一般为64Byte,也有地方称Cache块,本文统一使用Cache line)传输的,CPU从内存加载数据是一次一个Cache line,CPU往内存写数据也是一次一个Cache line。假设处理器首次访问数据对象A,其大小刚好为64Byte,如果数据对象A首地址并没有进行对齐,即数据对象A占用两个不同Cache line的一部分,此时处理器访问该数据对象时需要两次内存访问,效率低。但是如果数据对象A进行了内存对齐,即刚好在一个Cache line中,那么处理器访问该数据时只需要一次内存访问,效率会高很多。编译器可以通过合理安排数据对象,避免不必要地将它们跨越在多个Cache line中,尽量使得同一对象集中在一个Cache中,进而有效地使用Cache来提高程序的性能。通过顺序分配对象,即如果下一个对象不能放入当前Cache line的剩余部分,则跳过这些剩余的部分,从下一个Cache line的开始处分配对象,或者将大小(size)相同的对象分配在同一个存储区,所有对象都对齐在size的倍数边界上等方式达到上述目的。
Cache line对齐可能会导致存储资源的浪费,如图2所示,但是执行速度可能会因此得到改善。对齐不仅仅可以作用于全局静态数据,也可以作用于堆上分配的数据。对于全局数据,编译器可以通过汇编语言的对齐指令命令来通知链接器。对于堆上分配的数据,将对象放置在Cache line的边界或者最小化对象跨Cache line的次数的工作不是由编译器来完成的,而是由runtime中的存储分配器来完成的[2]。
图2 因块对齐可能会浪费存储空间
前文提到了数据对象对齐,可以提高程序性能。指令Cache的对齐,也可以提高程序性能。同时,代码布局也会影响程序的性能,将频繁执行的基本块的首地址对齐在Cache line的大小倍数边界上能增加在指令Cache中同时容纳的基本块数目,将不频繁执行的指令和频繁指令的指令放到不同的Cache line中,通过优化代码布局来提升程序性能。
利用硬件辅助
Cache预取是将内存中的指令和数据提前存放至Cache中,达到加快处理器执行速度的目的。Cache预取可以通过硬件或者软件实现,硬件预取是通过处理器中专门的硬件单实现的,该单通过跟踪内存访问指令数据地址的变化规律来预测将会被访问到的内存地址,并提前从主存中读取这些数据到Cache;软件预取是在程序中显示地插入预取指令,以非阻塞的方式让处理器从内存中读取指定地址数据至Cache。由于硬件预取器通常无法正常动态关闭,因此大部分情况下软件预取和硬件预取是并存的,软件预取必须尽力配合硬件预取以取得更优的效果。本文假设硬件预取器被关闭后,讨论如何利用软件预取达到性能提升的效果。
预取指令prefech(x)只是一种提示,告知硬件开始将地址x中的数据从主存中读取到Cache中。它并不会引起处理停顿,但若硬件发现会产生异常,则会忽略这个预取操作。如果prefech(x)成功,则意味着下一次取x将命中Cache;不成功的预取操作可能会导致下次读取时发生Cache miss,但不会影响程序的正确性[2]。
数据预取是如何改成程序性能的呢?如下一段程序:
假设一个Cache line可以存放两个double素,当第一次访问a[0]时,由于a[0]不在Cache中,会发生一次Cache miss,需要从主存中将其加载至Cache中,由于一个Cache line可以存放两个double素,当访问a[1]时则不会发生Cache miss。依次类推,访问a[2]时会发生Cache miss,访问a[3]时不会发生Cache miss,我们很容易得到程序总共发生了50次Cache miss。
我们可以通过软件预取等相关优化,降低Cache miss次数,提高程序性能。首先介绍一个公式[3]:
上述公式中L是memory latency,S是执行一次循环迭代最短的时间。iterationAhead表示的是循环需要经过执行几次迭代,预取的数据才会到达Cache。假设我们的硬件架构计算出来的iterationAhead=6,那么原程序可以优化成如下程序:
由于我们的硬件架构需要循环执行6次后,预取的数据才会到达Cache。一个Cache line可以存放两个double素,为了避免浪费prefetch指令,所以prologue和steady state循环都展开了,即执行prefetch(&a[0])后会将a[0]、a[1]从主存加载至Cache中,下次执行预取时就无需再次将a[1]从主存加载至Cache了。prologue循环先执行数组a的前12个素的预取指令,等到执行steady state循环时,当i = 0时,a[0]和a[1]已经被加载至Cache中,就不会发生Cache miss了。依次类推,经过上述优化后,在不改变语义的基础上,通过使用预取指令,程序的Cache miss次数从50下降至0,程序的性能将会得到很大提升。
注意,预取并不能减少从主存储器取数据到高速缓存的延迟,只是通过预取与计算重叠而隐藏这种延迟。总之,当处理器有预取指令或者有能够用作预取的非阻塞的读取指令时,对于处理器不能动态重排指令或者动态重排缓冲区小于我们希望隐藏的具体Cache延迟,并且所考虑的数据大于Cache或者是不能够判断数据是否已在Cache中,预取是适用的。预取也不是万能,不当的预取可能会导致高速缓存冲突,程序性能降低。我们应该首先利用数据重用来减少延迟,然后才考虑预取。
除了软件预取外,ARMv8还提供了Non-temporal的Load/Store指令,可以提高Cache的利用率。对于一些数据,如果只是访问一次,无需占用Cache,可以使用这个指令进行访问,从而保护Cache中关键数据不被替换,比如memcpy大数据的场景下,使用该指令对于其关键业务而言,是有一定的收益的。
循环变换
重用Cache中的数据是最基本的高效使用Cache方法。对于多层嵌套循环,可以通过交换两个嵌套的循环(loop interchange)、逆转循环迭代执行的顺序(loop reversal)、将两个循环体合并成一个循环体(loop fusion)、循环拆分(loop distribution)、循环分块(loop tiling)、loop unroll and jam等循环变换操作。选择适当的循环变换方式,既能保持程序的语义,又能改善程序性能。我们做这些循环变换的主要目的是为了实现寄存器、数据高速缓存以及其他存储层次使用方面的优化。
篇幅受限,本节仅讨论循环分块(loop tiling)如何改善程序性能,若对loop interchange感兴趣,请查阅。下面这个简单的循环:
我们假设数组a、b都是超大数组,m、n相等且都很大,程序不会出现数组越界访问情况发生。那么如果b[j]在j层循环中跨度太大时,那么被下次i层循环重用时数据已经被清出高速缓存。即程序访问b[n-1]时,b[0]、b[1]已经被清出缓存,此时需要重新从主存中将数据加载至缓存中,程序性能会大幅下降。
我们如何通过降低Cache miss次数提升程序的性能呢?通过对循环做loop tiling可以符合我们的期望,即通过循环重排,使得数据分成一个一个tile,让每一个tile的数据都可以在Cache中被hint[4]。从内层循环开始tiling,假设tile的大小为t,t远小于m、n,t的取值使得b[t-1]被访问时b[0]依然在Cache中,将会大幅地减少Cache miss次数。假设n-1恰好被t整除,此时b数组的访问顺序如下所示:
经过loop tiling后循环变换成:
假设每个Cache line能够容纳X个数组素,loop tiling前a的Cache miss次数为m/X,b的Cache miss次数是m*n/X,总的Cache miss次数为m*(n+1)/x。loop tiling后a的Cache miss次数为(n/t)*(m/X),b的Cache miss次数为(t/X)*(n/t)=n/X,总的Cache miss次数为n*(m+t)/xt。此时,由于n与m相等,那么loop tiling后Cache miss大约可以降低t倍[4]。
前文讨论了loop tiling在小用例上如何提升程序性能,总之针对不同的循环场景,选择合适的循环交换方法,既能保证程序语义正确, 又能获得改善程序性能的机会。
小结
汝之蜜糖,彼之砒霜。针对不同的硬件,我们需要结合具体的硬件架构,利用性能分析工具,通过分析报告和程序,从系统层次和算法层次思考问题,往往会有意想不到的收获。本文简单地介绍了内存层次优化相关的几种方法,结合一些小例子深入浅出地讲解了一些内存层次优化相关的知识。纸上得来终觉浅,绝知此事要躬行,更多性能优化相关的知识需要我们从实践中慢慢摸索。
参考
-
John L. Hennessy, David A. Patterson. 计算机体系结构:量化研究方法(第6版). 贾洪峰,译
-
Andrew W.Apple, with Jens Palsberg. Modern Compiler Implenentation in C
-
http://www.cs.cmu.edu/afs/cs/academic/class/15745-s19/www/lectures/L20-Global-Scheduling.pdf
-
https://zhuanlan.zhihu.com/p/
关注,第一时间了解华为云新鲜技术~
AutoCut 是一款通过字幕来剪切视频的工具。
AutoCut 对你的视频自动生成字幕,然后你选择需要保留的句子,AutoCut 将对你视频中对应的片段裁切并保存。你无需使用视频编辑软件,只需要编辑文本文件即可完成剪切。
使用例子
假如你录制的视频放在这个文件夹里。那么运行
autocut -d 2022-11-04
提示:如果你使用 OBS 录屏,可以在中将空格改成,即。那么视频文件将放在日期命名的文件夹里。
AutoCut 将持续对这个文件夹里视频进行字幕抽取和剪切。例如,你刚完成一个视频录制,保存在。AutoCut 将生成。你在里面选择需要保留的句子后,AutoCut 将剪切出,并生成来预览结果。
你可以使用任何的 Markdown 编辑器。例如我常用 VS Code 和 Typora。下图是通过 Typora 来对编辑。
全部完成后在里选择需要拼接的视频后,AutoCut 将输出和对应的字幕文件。
当你看一张图片时,你会先注意图片的哪些部分,或者说图片中的哪些区域会首先吸引你的注意力,机器学习能不能提前知道用户的注意力会集中在什么地方?
基于这个想法,Google 训练了一个机器学习模型可以做出这样的预测,并将该模型应用于 JPEG XL 图像编码格式。当应用该模型之后,浏览器会首先加载用户会第一时间注意的图像部分,从用户的视角来看,图像加载速度会有明显提升,可以显著改善用户体验。
当然,这个模型不仅可以适用于 JPEG XL 图像的编码,只要是需要根据用户注意力来调整内容加载优先级的项目都可以使用这个模型(比如在 VR 中,可以结合摄像头和模型来调整 VR 画面的清晰度,优先加载用户目光所及的画面)。
如果各位的网龄足够大,是可以回想一下网速还不够快的年代,当时想要浏览一张图片,图片通常是一行一行逐渐出现,有很大的割裂感,图像不加载个 60%-70%,你根本看不出图像描绘的具体是什么东西。现在网速已经越来越快,图片通常能够一瞬间就加载完成,用户大多数情况下察觉不到图片的加载,但是该模型在一些欠发达地区仍然具有重要的意义。
根据这个模型的原理,当加载一张图像时,首先会在一开始显示整个图像的低分辨率版本(如上图,刚开始加载),当你的目光开始注视图像时,机器学习就会预测你目光会注视的区域,并加速将该区域的加载,使其变得足够清晰(如下图,加载 30%)。
然后,当你的目光在图片上游走时,机器学习已经猜到你的眼睛接下来会看哪里,图像的这些地方就会逐渐加载清晰(如下图,加载 50%)。
图片后续依然是基于注意力逐步加载图像(如下图,加载 80%)。
最后就是那些用户的目光可能完全不会特别关注的边缘区域,就完成了 100% 加载。
如果这套机器学习模型预测得足够准确,用户可能完全不会注意到图像是一部分一部分慢慢加载出来的,甚至会有一种图片一开始就是完整加载出来的错觉。
目前 Google 也放出了该技术的演示,用户可以自己试试看。要想获得最佳体验,前提是需要使用基于 Chromium 的浏览器,并启用其实验性的 JPEG-XL 图像渲染器(进入 ,搜索 并启用它)。
Google 放出的这个演示使用了 JPEG-XL 图像格式,但在 10 月份的时候他们就表示过将在后续的 Chrome 版本中删除这个格式(难道团队没有沟通?)。目前还不清楚 Google 未来会在什么领域使用这个机器学习模型。
该模型的 GitHub 地址:https://github.com/google/attention-center
TIOBE 公布了 2022 年 12 月的编程语言排行榜。
TIOBE 将于下个月揭晓其 2022 年度编程语言,目前共有 3 个候选者:Python、C 和 C++。TIOBE CEO Paul Jansen 指出,虽然 Python 和 C 已多次斩获该头衔,而 C++ 仅在 2003 年获得过一次;但在本月 TIOBE 指数中, C++ 已经实现了历史上首次超越 Java,Java 现已跌至榜单第 4 位。这是自 2001 年 TIOBE 指数开始以来,Java 首次未进入前 3 名。除此之外,Kotlin 和 Julia 也越来越接近 Top 20。
TIOBE 12 月 TOP 20 编程语言
除了 C++ 取代 Java 跃至第 3 位外,Top 10 中还有 SQL 继续上升一位至榜单第 8,Assembly language 被挤到第 9;其他语言排名不变。
Top 11-20 区间中的语言排行则反复波动。少儿编程语言 Scratch 短暂的从第 23 名上升至榜单第 17 后,又在本月跌出 Top 20 到了第 21 位。与此同时,Perl 又重回 Top 20 榜单,从上月的第 23 位攀升至现在的第 18 位;Go 和 R 语言也互换了位置。
具体而言排名出现上升的有:R(12→11)、Matlab(15→14)、Swift(18→15)、Ruby(19→17)。下降的有:Go(11→12)、Delphi/Object Pascal(14→16)、Objective-C(16→19)。Classic Visual Basic 和 Rust 分别保持第 13 和 20 的位置不变。
TOP 10 编程语言 TIOBE 指数走势(2002-2022)
第 21-50 名编程语言排行
第 51-100 名如下,由于它们之间的数值差异较小,仅以文本形式列出(按字母排序):
ABC, ActionScript, Alice, Apex, APL, AutoLISP, Awk, B4X, C shell, CL (OS/400), CLIPS, Clojure, Common Lisp, Crystal, Elixir, Emacs Lisp, Forth, Hack, Icon, Io, J#, JScript, Korn shell, Ladder Logic, LPC, Modula-2, MQL5, MUMPS, NATURAL, Occam, OpenCL, OpenEdge ABL, PL/I, Q, Racket, Raku, Ring, RPG, S, Smalltalk, Solidity, SPARK, Stata, Tcl, VBScript, Verilog, VHDL, WebAssembly, X++, Xojo
TIOBE 编程社区指数(The TIOBE Programming Community index)是一个衡量编程语言受欢迎程度的指标,该指数每月更新一次。评判的依据来自世界范围内的工程师、课程和第三方供应商,包括流行的搜索引擎,如 Google、必应、雅虎、维基百科、亚马逊、YouTube 和百度都被用于指数计算。值得注意的是,TIOBE 指数并不代表编程语言的好坏或编写代码的多少。
该指数可以用来检查你的编程技能是否还能跟上时代的步伐,或者在开始建立一个新的软件系统时,基于指数对采用何种编程语言做出决策。
TIOBE 指数的定义方式,以及详细榜单信息均可查看官网。
1992年12月3日,世界上第一条 SMS 消息成功发送,如今已经过去 30 周年。在这个关键节点,谷歌再度发文赞美 RCS 短信标准,并批评苹果迟迟不采用该标。
RCS 全称 Rich Communication Suite – 富媒体通信标准,属于高级消息传递标准的一部分。它由 GSM(Global System for Mobile Communications) 协会发起,目标是取代当前的 SMS 消息传递标准。
目前 RCS 已获得了全球主流移动网络运营商(包括国内三大运营商)、 500 多家 Android 设备制造商(小米、HTC、索尼、LG、华为、OPPO 、三星和中兴等)的支持。
在博文中,Google 集团产品经理 Neena Budhiraja 列举了 RCS 标准对比 SMS 的三大好处:
- RCS 支持端到端加密,该加密功能已经扩展到群聊,而 SMS 则不支持。
- RCS 功能更丰富,除了文本消息,RCS 还默认支持高达 10MB 的高品质图片消息、群聊、位置共享,甚至视频通话。此外,RCS 服务还支持已读回执(已读功能)和打字指示符( “对方正在输入” 功能)等复杂功能,还可以通过 WiFi 发短信。
- 市场上主要的移动运营商和设备制造商都采用 RCS 作为标准 ,无论用户处于哪个地区、使用什么型号的手机,其短信体验都相同。
目前苹果是主流手机厂商里唯一一位“ RCS 标准反对者“,使用 iPhone 向 Android 手机发送消息时,Apple 继续依赖 SMS 。谷歌博客文末也是呼吁苹果尽快采用 RCS 标准,顺便嘲讽了一把苹果“短信技术停留在 1990 年代”,实在是“拖大家后腿”。
除此之外,谷歌还提到了“绿蓝气泡”问题,该问题源于苹果 iMessage 即时通信应用程序存在的一些差异:Apple 用户在 iMessage 中默认使用蓝色文本气泡 ,而由于苹果公司未采用 RCS 标准,iPhone 对 Andriod 设备使用 SMS 而不是通过网络数据发送消息,因此,Android 用户在 iMessage 中的消息会用绿色气泡显示,“蓝 / 绿气泡” 之差让使用 Android 手机的青少年在社交活动中饱受歧视 —— “永远不要与绿色短信者约会”。
讲师:袁鹏,一页科技架构师
摘要: 君润人力采用多套 Apache APISIX 集群来满足自研服务平台的功能需求。
君润人力成立于 2019 年,是一家以科技驱动的人力资源解决方案服务商,依托行业领先的科技水平和服务能力,专注于为客户提供一站式人力资源服务。自研数十家人力资源服务平台,深度链接 B 端企业和 C 端用户,构建数字化人力资源服务生态。
本文从君润人力业务快速扩张的背景入手,重点介绍开源 API 网关 Apache APISIX 对其自研平台系统架构的多样化应用场景支持,共有四大线上实战案例,希望对仍在网关选型过程中的企业或用户有所帮助。
君润人力自研系统架构概述
君润人力在搭建自研服务平台架构时,首要原则就是“开放、开源、拥抱云原生”。平台基于 Kubernetes 微服务架构构建云端系统,整体架构参考下图。
右侧是君润自研服务平台,DevOps 流程依托 Git webhook、coding、Kubernetes 集群实现全自动化与无感发布,业务系统基于 PaaS 平台进行迭代开发,确保研发规范,并达成技术栈的统一。上侧是监控手段,系统集成了 sky-agent 和 arthas,满足了线上服务观测多维度的需求。与此同时,采用腾讯日志云与 Kubernetes 结合的方式将服务日志存储在云上,实现 Kubernetes 集群内无文件化服务,避免磁盘容量堆积从而影响到 Kubernetes 集群单个节点的健康。
左侧是业务系统中最重要的环节 —— 流量管理。所有流量会通过 WAF(WAF,Web 应用防火墙,负责网络安全)进入三层网络里面的第一层 CLB,主要负责流量转发;第二层就是云原生网关 APISIX,它承担了业务系统的内部服务治理;第三层则是业务系统的 Gateway 应用内部的网关,负责单系统鉴权和路由。
其中第一层的 CLB 和第二层的 APISIX 尤其重要,它是所有系统的入口,一旦出现问题,那么所有系统将无法被访问。CLB 采用的是腾讯云服务,稳定性、扩展性与抗并发性能都比较高,业务架构需要解决的是第二层云原生网关 APISIX,保证它的高可用。
APISIX-Service 被部署在 Kubernetes 集群内部,Kubernetes 集群采用的是腾讯云提供的服务,为了保证出现问题后能够快速恢复,系统外置了 etcd 集群,使数据得以保留,这是 APISIX 集群高可用的体现。
那么,如何来保证 APISIX 的高并发和高性能?这里系统利用了 Kubernetes 的机制,当 APISIX 进行路由转发时,通过 Kubernetes 的服务名 + 服务端口使它在同一个网段内跳转;因为网关服务部署在 Kubernetes 内部,依托于 Kubernetes 的特性,可以进行滚动升级,进而达到 APISIX 网关升级的无感发布。
通过该架构图不难发现,第二层是所有流量的入口,选择一个满足业务扩张需求的云原生网关,对系统架构来说至关重要,下面谈谈在网关技术选型时的主要思考。
技术网关选型痛点
- 数量庞大的业务系统。 目前人力资源这个领域有 15+ 服务平台,生态业务多样化,面临的问题也比较多,服务请求需要频繁变更,导致需要操作和配置的路由也非常多。原来系统是基于 CLB 进行流量转发,久而久之,运维人员需要配置和操作的地方非常多,耗费了大量的人力与时间。
- 频繁的高并发大流量。 举个例子,客户集中在同一天发薪或提现大额资金。在用户数量达到大几十万时,集中进行的某些行为,如打卡、签约、领取任务或工资等,此时系统并发流量非常大,短期翻倍的情况比比皆是。
- 个性化需求的扩张压力。 APISIX 是基于 OpenResty、Nginx 和 Lua 开发的,但如果用 Lua 来开发插件,会有一定的研发投入和维护成本。 对于插件的支持,APISIX 已经提前做好了准备。APISIX 的官网提供了自定义插件 来支持 Java 开发,技术栈问题迎刃而解。此外 APISIX 的生态非常好,作为国产网关产品,社区极其活跃,业内实践还特别多,在云原生网关这层来说,业内也是顶级存在。
我们的团队非常开放,做完技术选型后,快速实践落地。从上线部署到服务分批次接入,耗时不到 1 个月时间。目前 99% 的服务通过 APISIX 访问,上线一年多至今零事故,稳定性非常好。下面这张图里,大家能看到 APISIX 的一些特性,红字部分是我们最看重的几点。
APISIX 四大实践场景
下面我们来逐一介绍 APISIX 的四个实践场景。
路由策略
Apache APISIX 基于 Radixtree 和 etcd 提供路由极速匹配与配置快速同步的能力。路由和插件的设计实现都满足了极速性能和超低延迟的需求。比如以下两个场景中,都表现出了不错的性能:
- 高峰期的 API 紧急停用。 业务系统处在高峰期时,用户导出百万数量级的报表数据,会使 MySQL 数据库直接宕机,此时重启服务也无法解决,用户继续导出操作会持续故障,这个问题以前我们得发版才能解决;而现在只需要运维人员简单配置一番,就可以做到 API 紧急停用,通过路由优先级策略和失效策略(依托 Serverless 插件),配合使 API 接口在分钟级下线,从而保证服务的稳定。
- 业务系统较多。 其中 SaaS 系统需要支持客户自定义域名访问,我们采用了泛域名匹配,做到一次配置,全局通用。 下图是君润人力 2022 年度路由增长趋势图。可以看到,不论前端还是后端路由,在引入 APISIX 之后,都实现了三倍或以上的数量增长。
安全控制
我们基于 APISIX 做了双层网关架构,在 APISIX 上隔离出一个逻辑网关,用户访问 CLB 进来 APISIX 再转发到业务系统。如果用户使用的这个功能需要用到 PaaS,就会通过 PaaS 服务网关进行访问,此时的 PaaS 服务网关就是一个逻辑网关。
我们在 Kubernetes 内部封闭了一个区域,即 PaaS 平台,里面包含大量的基础服务。利用 APISIX 网关的特性:熔断、安全、身份识别,使上层业务系统访问 PaaS 服务都需要通过 PaaS 网关。
流量管理
由于业务系统数量较多, 核心服务(SSO、PaaS 服务和发薪服务)可用性要求高, 这些服务的流量管控需要依赖 APISIX 提供的流量管理灰度策略。
为此,系统内部采用了两种方式进行。一是基于标签灰度。核心服务上到生产环境之前,测试人员先在灰度环境验证。我们会将测试用户流量转发到灰度服务,进行生产环境验证,验证通过后再基于权重切入流量,观察一段时间,没问题后再把全部流量切换到新版本;二是生产环境内。相同的服务并存多个版本,不同的业务系统访问不同的版本时,基于标签进行路由转发。
日志管理
从下图的架构模式可以看出,APISIX 和 Pod 服务都基于 Kubernetes 架构,所有后端路由都被绑定在同一服务上,在 APISIX 服务上配置的 Kafka 插件用来采集日志数据,同时配置了 Skywalking 监控程序性能。根据 RequestId 和 TraceId 在 Skywalking 和日志云,可以观测到整个调用链路,并查看每个环节的日志记录和 API 请求耗时。
从目前观测到的数据来看,系统每天都有上千万次的 API 请求,平均每天产生的日志数据达到 30G ,日志总量达到 TB 级。
使用 APISIX 的经验与展望
在使用 APISIX 的过程中,我们总结了一些经验之谈,在这里分享给对 APISIX 感兴趣的朋友们。
构建基础镜像需要拉取国外资源。 APISIX 需要部署在 Kubernetes 内部,内部会进行一定的二次开发和源码编译,这时需要到 GitHub 上拉取资源,目前官方提供的 Docker 镜像有一部分需要拉取国外资源,在进行本地开发和线上部署时,环境调试相对麻烦。
调试环境部署有要求。 自定义插件 ,需要基于 runner.sock 进行 RPC 通讯,现有案例较少,调试起来有一定困难,它需要和 APISIX-Service 在同一个镜像内。
每天产生大量的日志记录到本地。 刚刚发布生产时,我们发现就算只开启 error 级别日志,每天的增长数量都非常大,导致 Kubernetes 集群中一个节点磁盘告警。后面打包镜像时将日志由文件记录改变为输出至控制台,收集至云日志服务 CLS 存储记录分析,实现本地无文件化存储。
当然,以上都属于前期准备工作上的必经之路,在正式投入使用后,APISIX 给我们带来的收益远远大于期望,总体有以下三点:
- 对业务发展起到了强有力的支撑。 使用 APISIX 后,系统功能更加丰富,性能更加强劲。APISIX 对 API 服务提供了多种可观测性和安全防护手段,可以支持我们每天千万次流量的访问。
- 助力研发交付效率。 比如原来配置 DNS 解析需要 10 分钟才能生效,而现在通过泛域名配置,几秒钟就能生效;因为原先需要在 CLB 和 Nginx 两个地方手动修改配置,而我们有 10 多个系统、100 多个服务,需要配置的点很多,应用了 APISIX 的泛域名配置后,现在只需要在控制面板上修改,极大地减少 DevOps 工作量。
- 大幅降低成本。 LB (负载均衡)成本的变化。LB 服务数量由 200+ 缩减到了 10+,大大降低了系统维护成本。 后期我们还会有一系列需要借助 APISIX 云原生网关达成的功能开发包括但不限于:集成 Sentinel 使服务具备热插拔动态限流功能、开发多维度流量控制、风控识别功能升级、分层治理和全链路日志分析等等。届时将采用多套 APISIX 集群来满足自研服务平台的功能需求。
总结下来,使用 APISIX 云原生网关给君润人力服务平台带来了非常大的帮助,使我们能轻松应对多样化的复杂场景,打造趋于完美的数字化人力资源服务生态。
本文由博客一文多发平台 OpenWrite 发布!
概述
在某些情况下,Metrics 监控的 2 大顶流:
- Zabbix: 用于非容器的虚拟机环境
- Prometheus: 用于容器的云原生环境
是共存的。但是在这种情况下,统一监控展示就不太方便,本文介绍利用 Grafana 对接 Zabbix, 来作为统一监控展示端。Let’s go!
在这里,主要是用到了 alexanderzobnin/grafana-zabbix 开源项目。
Grafana-Zabbix 功能亮点
Grafana-Zabbix 是 Grafana 的一个插件,允许可视化来自 Zabbix 的监控数据,并创建用于分析指标和实时监控的仪表板。 该项目的主要目标是扩展 Zabbix 的监控数据可视化功能,并提供快速、强大的方法来创建仪表板。
Grafana 与 Grafana-Zabbix 插件相结合,可以创建很棒的仪表板。 Grafana-Zabbix 有如下的功能亮点:
- 丰富的绘图功能;
- 使用 Regex 选择多个指标;
- 使用模板 (template) 变量 (variableds) 创建交互式和可重用的仪表板;
- 在带有注释 (Annotations) 的图形上显示事件
- 使用指标处理函数(平均值 Avg、中值 Median、最小值 Min、最大值 Max、乘 Multiply、汇总 Summarize、时移 Time shift、别名 Alias)转换和调整数据
- 在同一仪表板或面板中混合来自多个数据源的指标
- 在 Grafana 中创建告警
- 使用 Problems 面板显示 triggers
- 在官方库中发现和共享仪表板
快速演示
接下来我们进行一个快速演示,所有资源都安装在 K8s 中。
- (前提)安装 K3s
- 安装 Grafana
- 安装 Zabbix
- 在 Grafana 上安装 Grafana-Zabbix 插件并启用
- 在 Grafana 上配置 DB 数据源和 Zabbix 数据源
- 在 Grafana 上导入 Zabbix 仪表板并查看监控效果
- (可选)在 Grafana 上基于 Zabbix 指标配置告警
安装 K3s
安装完成后执行以下命令查看运行状态:
安装 Grafana
使用 Helm 安装:
这里为了后续使用方便加了 2 个参数:
- 数据持久化,重启不丢失
- 方便通过 NodePort 直接访问 Grafana UI
安装 Zabbix
为了图省事,也直接将 Zabbix 安装在 K3s 中。
但是🐾注意,往往在生产使用场景中,Zabbix 是安装在虚拟机环境上的,并用 Zabbix Proxy 和 Zabbix Agent 监控 Prometheus 覆盖不到的区域(典型如:非容器化的物理机、虚机;网络设备;数据库等)
直接在 Helm Chart 官方市场 – Artifact Hub 里找一个安装:
这个 aekondratiev/zabbix-server helm chart 会安装以下组件:
- zabbix-server
- 和 zabbix-server 一起,以 sidecar 形式运行的 zabbix-agent
- zabbix-web
- postgresql
在 Grafana 上配置 DB 数据源和 Zabbix 数据源
Grafana-Zabbix 的数据库直连功能
这里提一下,Grafana-Zabbix 插件可以使用 MySQL、Postgres 或 InfluxDB 数据源直接从 Zabbix 数据库查询历史和趋势数据。 为了执行查询,插件仅需要对、、 和 表的读访问权限。 为了使连接更安全并防止不必要数据泄漏,强烈建议只授予对表的读访问权限。 但是如果您想使用这个数据源来查询其他数据,您可以向整个 zabbix 数据库授予 SELECT 权限。 此外,所有查询都由 Grafana 服务器调用,因此您可以将连接限制为仅与 Grafana 主机连接。 下面是 MySQL 示例:
配置 DB 数据源
在 Grafana 的创建 Data Source 选项中,选择 数据源类型并提供数据库主机地址和端口(默认值为 )。 填写数据库名称(通常为 )并指定凭据。如下图所示:
之所以启用数据库直连, 是因为如果海量的 zabbix 历史和趋势数据都通过 zabbix 的 API 查询,性能会有一定问题。
在 Grafana 上安装 Grafana-Zabbix 插件并启用
进入 Grafana 容器中,并使用 安装:
🐾Warning:
通过 安装插件后需要重启生效,所以一定需要配置 , 否则重启后数据丢失,插件还是没装上。
安装后,就可以启用插件了。
通过 Grafana 的 Nodeport (如:http://192.168.1.5:30000) 访问并登录 Grafana(📝密码在 K8s Secret 中), 进入 Grafana 侧面板的 plugins 界面,选择 选项卡,然后选择 ,打开 选项卡并启用插件。如下图:
配置 Zabbix 数据源
启用插件后,就可以添加 Zabbix data source 了。
要添加新的 Zabbix 数据源,单击 并从下拉列表中选择 。如下图:
关键的配置项有以下几个:(其他一般不需要动)
- HTTP
- URL: Zabbix API url, 一般就是 , 如上图 1 中的:http://zabbix-web.zabbix/api_jsonrpc.php
- Zabbix API details
- Username 和 Password: 登录 Zabbix API 的账号密码。记得要用足够的权限。
- Trends: 如果是 Zabbix 3.x 及以上就 enable. 当显示长时间段(超过几天)时这个选项强烈建议使用,因为几天的项目历史包含海量的数据点。使用趋势将提高 Grafana 的性能。
- Direct DB Connection
- 启用并选择上面创建好的 Zabbix DB Data Source.
在 Grafana 上导入 Zabbix 仪表板并查看监控效果
之后,导入自带的几个 Zabbix 的仪表板:
接下来就能看到效果啦:
如上图,Grafana 支持灵活的表达式配置 zabbix 仪表板:
- Query Mode
- Group
- Host
- item tag
- Item: 聚合的表达式
- Functions
完全不用担心 Zabbix 上某些复杂的仪表板无法在 Grafana 上复现。
下面是官方的一些 demo:
在 Grafana 上基于 Zabbix 指标配置告警
侧边栏 , 就可以创建基于 Zabbix 的告警,也可以直接在仪表板上编辑 panel 的 alert 进行配置,配置后效果如下:
以上就是本次全部的演示全过程,感兴趣的可以自己尝试复现一下。
🎉🎉🎉
总结
在本文中,我们介绍了利用 Grafana + 插件:Grafana-Zabbix 实现了以下效果:
- Grafana 负责展示甚至告警
- Zabbix 作为 Grafana 的其中一个数据源。
更近一步,我们的环境上,可能不止有 Zabbix 和 Prometheus 2 个数据源,甚至还会有:
- Metrics
- AWS CloudWatch
- …
- Logging
- Tracing
在这种情况下,将所有的这些监控都视作 Grafana 的数据源,实现监控数据的统一展示和联动:
联动:
- 在 Slack 上收到 Grafana 发出的告警
- 链接或仪表板跳转到 Grafana 对应 Dashboard
- 在 Grafana 上查看相关 Metrics
- 在 Grafana 上跳转到 Metrics 异常时间点的日志
- 在 Grafana 上跳转到 Logs 异常的 Trace
- 发现并在 IDE 上 coding 解决问题
只能说,Grafana 为我们描绘了一个相当美妙的场景,未来可期。👍️👍️👍️
本文由东风微鸣技术博客 EWhisper.cn 编写!
目前针对 DNS 监控的 Grafana Dashboard 并不多,使用率较高的 Grafana CoreDNS 只适用于 K8s 环境,对于云服务器、物理硬件模式下的 DNS 监控也并不通用;同时,对于应用研发人员想定位 DNS 查询异常或者时延问题时,CoreDNS 的 Dashboard 仅提供 DNS 服务端视角,无法从应用视角出发来分析问题,只能依赖自身代码增加了 DNS 日志。
明确这些问题后,我们基于 DeepFlow 构建了对一个高效、可配置、无侵入、面向应用的 DNS 监控面板,可监控 DNS 服务的网络异常、吞吐、时延,以及访问日志,以快速定位性能瓶颈和排查故障原因。部署了 DeepFlow 之后,deepflow-agent 会自动采集所在节点上的可观测数据,我们基于这些数据构建了一个 Dashboard,内容包括:
- Overview
- Delay
- Error
- Request
- Log Analysis
前往我们的在线 Demo 也可快速体验 Dashboard。
同时,欢迎大家预约 “原力释放 云原生可观测性分享会” 直播。
直播活动由云原生社区主办,云杉网络发起,并联合OPPO联合举办,本期聚焦 “浅谈可观测性生态的优化和丰富” 主题。将分享OPPO自研时序数据库在业务高基数、持久化存储、乱序写入、多租户隔离等场景下的思考及实战演进,以及 DeepFlow 对 Grafana 插件做详细解析,讲解如何从零开始开发一个 Grafana 的 Datasource。
- 直播时间:12 月 8 日 (周四) 20:00~21:00
- 直播平台:云原生社区视频号&B 站、云杉网络视频号、开源江湖、GrafanaFans
- 活动链接:https://www.slidestalk.com/m/1336
- 扫描海报二维码预约直播
0x0: Dashboard 介绍
接下来,详细介绍下 Dashboard 的使用
进入 Dashboard 后,可通过变量来控制需要分析的 DNS 服务端,下面详细说下变量的使用方式:
- ①:DNS 服务端部署在 K8s 环境中,例如 CoreDNS,使用 // 变量
- cluster:选择 DNS 服务端所部署的 K8s 集群
- dns_service:选择 DNS 服务端对应的 K8s 服务名
- dns_wildcard:通过通配符的形式筛选 dns_service
- ②:DNS 服务端部署在云服务器环境中,使用 变量
- 特别说明:此时需要将 / 设置为
- ③:使用外部的 DNS 服务端,例如使用运营商提供的,则在 变量输入对应的 IP 即可
- 特别说明:此时需要将 // 设置为
- ④:DeepFlow 可在多个位置采集数据,可通过 来控制需要查看的数据统计位置,位置点的详细说明,可参考文档
模板变量说明
设置好变量后,接下来就可以利用 Dashboard 来分析 DNS 了,通过 Overview 可快速了解 、、、,得到大概总览情况后,可以结合 、、 模块中的曲线快速分析问题发生的时间点,然后利用 分组,可快速得到触发问题发生的客户端服务
Overview
Error
Delay + Request
接下来可以利用 模块来详细分析发生问题的客户端服务的 DNS 请求,分析之前,需要先设置 和 变量
- ⑤ client_for_Log_Analysis:输入在前面模块得到的客户端服务
- ⑥ status_for_Log_Analysis:确定需要分析的 DNS 请求的状态
- ⑦ domain_for_Log_Analysis:输入需要分析的 DNS 请求的域名
模板变量说明
通过 模块,可快速得到存在问题的 TOP N 、、、 以及客户端服务访问 DNS 的整个时延分布
Log_Analysis
接下来,让我们结合实际案例,来体验一下 DNS Dashboard 给我们带来的高效分析能力。
0x1: 案例1 – 无效内部域名解析
现象:
我们的集群里的应用规模不大,理论上 DNS 请求不会太多,但我们打开 DNS Dashboard 后,发现有大量 DNS 查询请求,且有访问异常:
Client Request Log Error
其中有较多 DNS 客户端异常,响应码为 0x3,错误描述是:Non-Existent Domain,意味着应用访问了不存在的域名。(更多的异常定义可见 DeepFlow-数据库字段定义)
我们通过异常排序,查看访问无效 Top10 域名,发现大量 DNS 请求后缀包含了 ,而这是 k8s 自动填充的搜索域:
Client Request Domain TopN Error
原因分析:
我们结合 k8s 的 DNS 原理来分析问题原因。首先,一个典型的 k8s Pod 中 resolv.conf 文件的内容如下:
1 2 3
search default.svc.cluster.local svc.cluster.local cluster.local nameserver 10.96.0.10 options ndots:5
这里有三个配置, 是域名检索的搜索域, 是集群内的 DNS 服务地址, 是自定义选项,其中 ndots=5,意味着当一个域名中包含的数量小于 5 时,会优先解析为内部域名,并按照 search 的顺序依次添加搜索域后缀来检索,如果它依然无法被解析,才会把这个域名当作外部域名来解析。
那为什么 k8s 的 ndots 默认配置是 5 呢?Issue#33554 也做出了解释,简单来说:
- 同命名空间下,形如 的域名要被优先解析为内部域名,所以 ndots>=1,并在搜索域 $namespace.svc.$zone 下搜索。
- 跨命名空间下,形如 的域名要被优先解析为内部域名,所以 ndots>=2,并在搜索域 svc.$zone 下搜索。
- 访问非 Service Name 时,形如 的域名要被优先解析为内部域名,所以 ndots>=3,并在搜索域 $zone 下搜索。
- 对于 StatefulSet 类型的应用,由于需要支持形如 的域名内部解析,所以 ndots>=4。
- 对于形如 的 SRV Record 要被优先解析为内部域名,所以 ndots>=5。
综上,k8s 的 resolv.conf 中 ndots 默认值是 5 。但这符合我们的使用场景吗?我们要访问的域名是一个小于 5 的外部域名,但它被解析为内部域名,并尝试通过 $url.default.svc.cluster.local / $url.svc.cluster.local / $url.cluster.local 的顺序来解析,最后才去访问 $url 本身,所以产生了大量的异常记录。
修复建议:
要解决这个问题,有几个可选的方案:
- k8s 文档中 Pod DNS 配置一节,只需要修改 Pod 的 DNS 策略,定义 ndots=2,这样就可以优先将域名解析为外部域名,弊端在于这样反而会使得内部域名的解析变慢。
- 把访问的外部域名修改为 FQDN,比如我们要访问的是 ,修改为 ,这样可以直接访问域名,不会依次检索搜索域。
- CoreDNS 使用 autopath 插件,减少搜索次数,但这依赖于 API Watch 机制,会使得 CoreDNS 增加内存消耗。
- 使用 Node LocalDNS,增加 DNS 解析性能,减少 CoreDNS 压力,但同样的,它需要使用内存来做 DNS 缓存查询,增加了内存消耗。
经过权衡,方案(2)对集群的侵入性和修改难度是最低的,效果也比较理想,所以我们采用方案(2)达成了目标。
0x2: 案例2 – 对已失效服务的依赖
现象:
同样通过 DNS Request Log 分析,我们发现还有大量的 Non-Existent Domain 异常,且它不是访问外部域名:
Client Request Domain TopN
原因分析:
集群里没有 zipkin 的 Service,按照上述的 k8s 的 DNS 原理分析,在访问域名的时候同样会尝试按搜索域顺序依次访问,造成了不小的 CoreDNS 压力,这说明应用的配置有错误,尝试访问无效的服务,导致冗余的开销。
修复建议:
检查代码或配置中是否还在访问失效的服务,去掉配置后恢复正常。
0x3: 后续规划
我们目前在制作一批 Dashboard,包括:Nginx、MySQL/PostgreSQL、HTTP、Dubbo/gRPC、Kafka/MQTT、TCP/UDP/IP 等,希望能带来社区高度自动化、高精度的可观测性体验,期待有社区的小伙伴能加入一起。
0x4: 什么是 DeepFlow
DeepFlow 是一款开源的高度自动化的可观测性平台,是为云原生应用开发者建设可观测性能力而量身打造的全栈、全链路、高性能数据引擎。DeepFlow 使用 eBPF、WASM、OpenTelemetry 等新技术,创新的实现了 AutoTracing、AutoMetrics、AutoTagging、SmartEncoding 等核心机制,帮助开发者提升埋点插码的自动化水平,降低可观测性平台的运维复杂度。利用 DeepFlow 的可编程能力和开放接口,开发者可以快速将其融入到自己的可观测性技术栈中。
GitHub 地址:https://github.com/deepflowys/deepflow
访问 DeepFlow Demo,体验高度自动化的可观测性新时代。
作者:李浩
责编:宇亭
当我们选择一款 HTAP 数据库时,总是先被其相关文档里所描述的优异性能所吸引。卓越的性能是我们选择一款产品的出发点,因为我们希望该款产品能够解决我们业务中的痛点。而大家使用 HTAP 产品的出发点就是希望该款数据库能够解决我们在事务处理过程中的实时分析痛点。不过,性能优势只能算作我们选择一款产品的考量因素之一,实际上,公司层级去选择一款HTAP产品时,还需要额外考量一些其他的因素,本篇文章,StoneDB首席架构师李浩给大家分享一下选择 HTAP 产品的六大关键考量因素。
在 TP 产品非常成熟的今天,各类 TP 类型数据库早已在各行各业中支撑着业务系统的高速发展。随着业务系统越来越复杂,所产生的数据量也在飞速增长。同时,对于这些数据的实时分析需求也日益迫切。然而,当前的解决方案却无法满足实时分析的需求。例如:如果直接在TP数据库上进行分析,虽然可以满足实时性要求,但其分析的性能基本无法满足要求,并且在进行分析时会占用大量的计算资源和 IO 资源,从而影响到 TP 性能。因此,传统的做法是将分析任务放在业务低峰时候(通常是半夜进行,因此大家经常会看见 T+1的说明情况)。
HTAP 的出现则解决了这个实时数据分析的痛点。HTAP,即Hybrid Transaction/Analytical Processing,一套系统可以同时解决 TP 需求和 AP需要。如果你的业务对于 TP 业务所产生的数据需要进行实时的 AP 分析,那么 HTAP 将会是你很好的选择。
Gartner 预计在 2024 年左右,HTAP 市场将会走向成熟。 从最早 2014 年概念的提出到最近这几年,国内外对于 HTAP 已经从概念走向具体的产品落地。早期大家炒炒概念还可以接受,但显而易见,现在的市场越来越明确地走向产品质量和方案落地的竞争。
无论国内外的 SnowFlake(Unistore)、Google(AlloyDB)、Oracle( HeatWave )还是国内的 TiDB、OceanBase、StoneDB 等都推出了其各自的 HTAP 产品并且在积极的落地到生产系统。那么面对越来越多的 HTAP 产品,我们该如何选择一款适合自己业务的 HTAP 数据库产品呢?我们选择一款 HTAP 数据库又需要从那些方面进行考察呢? 本篇文章中,StoneDB将给出一些自己的思考,需要说明的是,本篇作为产品选择篇,我们不从技术架构和具体的实现上进行讨论,而是主要从业务需求端的角度来作分析。 对于硬核的技术实现角度,我们将在《什么是真正的 HTAP?实践篇》的下一章进行讨论。
业务场景
首先,我们从业务场景的角度来讨论如何选择一款HTAP数据库,主要有以下四个维度:
1.1、业务类型
业务所在的领域决定了产品底层技术栈的选择。这个很好理解,比如电商这个业务场景所需要的技术栈和产品特点与传统制造、CRM 等所关注的侧重点就完全不一样——电商关注高并发、低延时、 数据一致性和秒杀场景等等,而传统制造商则对海量多样化数据的处理和如何有效挖掘数据价值这些方面更加关注。
在不同的业务类型下,选择一款 HTAP 产品需要重点考察的是——这个业务类型需要哪一部分能力为主:TP 能力为主亦或是 AP 能力为主。
对于电商系统需要更加注重其在 TP 方面的关键能力,例如:事务、数据一致性等等;而对于CRM系统,经销存等等对TP能力则不会那么严苛,其可能更加看重AP的能力,在 TP 能力满足其基本业务需求的情况下,哪款产品的 AP 能力更强,业务侧可能会更倾向于选择该款产品。
而现有 HTAP 产品从技术实现路线上,基本可以分为这么两类路线,其决定产品的基因:即侧重于 TP 还是 AP?
路线1: 以成熟的TP系统为基础,在其上进行AP能力的扩展。现有大部分 HTAP 数据库产品均采用该种策略。为什么采用该种策略?其原因是显而易见的,TP 系统发展到现在其相较于 AP 系统,更加成熟。例如:国内外的 OB,StoneDB,TiDB,Oracle MySQL Heatwave 和 Google AlloyDB 等; 路线2: 在 AP 系统的基础上扩展其处理 TP 的能力。例如:Snowflake 等。这种路线,比较困难,但是成熟的科技公司会有更多的资源去做这个事儿,难度大,但是做出来了,也会是一大利器。
1.2、端到端的解决方案能力:
对于业务开发相关人员,一个新产品或者解决方案的引入,自然希望不会给其带来额外的工作负担,并且最好能够与其原有的技术栈相兼容,这样对于原有业务系统的改动要求最少 。但也不完全就是为了让干的活儿更轻松一些,因为,对于一个在线运行的系统,其对于稳定性的要求非常高,而新组件的引入往往会让整个业务的不稳定因素增大。因此,如果不能够保持原有的技术栈,则需要提供端到端的解决方案。例如: 原系统采用的 ClickHouse 或者 ElasticSearch, 如果需要替换为 OB 或者StoneDB ,那么需要考虑原系统 ClickHouse 或者 ElasticSearch 上下游相关模块接口兼容性,数据同步 到 CK 或者 ES 的方式等等,这些解决方案都要提供出来。
1.3、数据实时性要求:
数据实时性的高低同样也会影响到产品的选择。 当前现有的 HTAP 数据库在 TP和 AP 之间的数据同步策略实现机制不尽相同。例如:有些云厂商通过 MySQL+Binlog+ClickHouse 的组合方式提供 HTAP 服务,从用户的角度看似乎该服务具备了HTAP的能力,但实际上完全不是那么回事儿——因为通过 Binlog 这种方式会有很多弊端,这里可以参考我们之前的两篇文章;又如有厂商通过 TP+Redo+Raft+AP 这样的组合构成 HTAP 产品,其相较于前一种在数据的实时性上有了较大的提升,但也只是提供数据的最终一致性,同样数据的实时性还是得不到保证;有的厂商则采用了基于 LSM-tree 实现的行列混存,这种可以基本保证对于数据实时性的要求;而像 MySQL Heatwave 和 StoneDB 则提供了基于内存计算的强实时性的方案。
HTAP 数据库在产品具体实现的时候,其选择的存储方案会直接到影响架构的选择:是一体化的架构?还是 TP 系统叠加 AP 系统的方案?架构的选择则会直接决定数据同步策略和数据实时性的高低。
1.4、技术能力:
产品背后其公司所代表的技术实力也是业务方选择一款产品的考量因素,例如:我们在下文第六点中给出的观点。
性能
考量完业务场景相关的因素后,接下来需要考量的一个重要因素就是性能。不同于TP系的 Benchmark TPC-C 或者 AP 系统的 Benchmark TPC-H,对于HTAP 的性能测评一般不再使用这两个传统的方式来进行衡量。
当前大家更多地使用 TPC-H 来对其 AP 的能力进行评估,该种方法可以对其系统有一定的评价作用,但也存在着一定的弊端,那就是 TPC-H 无法全面地衡量一款 HTAP——因为 HTAP 数据库的系统中会同时存在两类负载:TP负载和AP负载 。两类负载需要同时使用系统的CPU资源、IO 资源和网络资源等等。对资源的竞争会导致两类负载的相互干扰。因此,为了更好的衡量 HTAP 数据库,无论是学术界还是工业界,都逐渐提出了一些适用于HTAP数据库的 Benchmark 系统,具体可以参考我们之前的文章: 《 如何给一个 HTAP 数据库做基准测试? 》
这里也简单提一下,除了具体的性能指标,例如:TPS、 QPS、吞吐量等等,资源隔离性也是我们的重要考量。而资源隔离通常有两种方式: (1) 通过系统手段(软件)隔离。 例如,通过 Cgroup 的方式进行资源的管理; (2) 通过物理手段进行隔离。 例如,依据不同的负载类型 Route 到不同引擎上,将 AP 查询路由到列存引擎节点上,这样可将 TP 负载和 AP 负载运行于不同的节点上,从而做到真正的物理隔离。
运维
运维的难度也需要我们认真考量。 数据库的运维不同于其它基础系统,其对于 DBA 的综合素质有比较高的要求。在系统长时间运行的过程中会遇到各种数据库的使用、功能、性能等等问题。解决这些问题除了需要数据库、 操作系统和业务等多方面的知识,同样也需要相关运维工具的支持。运维手段和运维工具可以高效的支持 DBA 的运维工作。复杂的系统形态,会导致 DBA 的运维工作量增大,最直接的影响就是难以快速定位问题,增加了解决问题的耗时。
生态
生态是选择一款 HTAP 数据库的一个重要因素。 当前有两类生态:PostgreSQL 和 MySQL。选择哪一种生态,会直接影响到后续围绕数据库所构成的整个技术栈。同时,业务也会从其自身的特点选择相应的技术路线。例如:如果业务系统是基于 JSON 和 GIS 能力的话,那么多数的业务开发者可能更倾向于选择 PostgreSQL 生态;如果是电商业务则更多的会选择 MySQL 生态。
具体来讲,生态中的周边工具、中间件和解决方案的完整性和丰富性非常重要。除工具、方案外,社区参与的人数(不管是对开源的 HTAP 数据库,还是对于商业或云上的 HTAP 服务,都需要考量该使用该服务的人群数量),更多的社区参与人数往往意味着社区比较活跃,那么,我们使用者遇到的一些问题就可以得到快速的响应。
生态的繁荣也从另外一个侧面反映出该技术路线获得了相当多的上下游厂商的支持。
成本
成本是一个无法绕过的话题,一般企业/组织内的管理者对于成本的关注度往往是多于其他项的。 如果想要使用一款 HTAP,需要考量的成本主要包括以下几个方面:硬件成本、替换(迁移)成本、运维成本等:
5.1、硬件成本:
其中最主要包括: 计算成本和存储成本。 在 StoneDB 实际的产品 POC 过程中,遇到很多客户实际的业务数据量在 100GB-1TB 内。如果采用一些现有的其他国产 HTAP 产品,由于这些产品对最小集群有要求,从而使得这些小厂商在使用 HTAP 服务时,必须付出比较高的集群硬件成本,这个是他们不愿意接受的。特别地,当需要替换现有MySQL数据库的时候,目前的一些国产 HTAP 数据库,基本都存在 MySQL 语法兼容性的问题,这导致迁移到新的业务系统上需要进行大量的修改,从而造成整体成本的飙升。如果厂商比较在乎这一部分的成本的话,StoneDB 就是很好的选择了。
5.2、替换成本:
需要能够提供对于原系统的 平滑迁移 能力。对于业务侵入改动最小,业务无需做修改即可平滑迁移到新的数据库平台。
5.3、运维成本:
在第三点中我们讨论运维问题,这里就不再详细讨论了。运维成本将会是系统稳定后,最主要的支出成本。
LTS 支持性
对于LTS(Long Term Support,长期支持版)支持性,这里又可以从两个方面来讨论。 (1)商业 HTAP 数据库 (2)开源 HTAP 数据库 无论对于商业数据库还是开源数据库都面临某个版本的生命周期问题。
商业数据库相对来说,其售后服务有保障,但同时商业数据库又面临闭源和售后服务需要支付昂贵的服务费用等问题。而 开源数据库,其 LTS 的支持除了需要社区支持以外,也需要由其背后的公司来进行保证。我们也很容易发现, 一个成功的开源数据库项目背后,通常都有一个成功的商业公司支撑。
因此,无论是选择哪类 HTAP 数据库,都需要注意所选择的产品的 LTS 支持性的问题。
好了,以上就是我们总结的选择一款 HTAP 数据库需要考量的六大因素,也即:业务场景、性能、运维、生态、成本和 LTS 支持性,希望对于这六点的分析能给大家在做 HTAP 产品选型时提供帮助。
StoneDB 的 2.0 架构完全对标 Oracle MySQL MDS(HeatWave),目前,我们的架构设计方案的RFC文档也完全公布在了 Github 上: https://github.com/stoneatom/stonedb/issues/436 如果您想了解更多,也可以关注我们的 Github 仓库: https://github.com/stoneatom/stonedb 本周五(12月9号)下午,StoneDB 开源社区PMC、StoneDB 首席架构师李浩老师也将参与由 ITPUB 社区举办的开源小秀场线上 Meetup 活动,欢迎大家前往官网 http://os.itpub.net/ 关注:
以上就是本次的分享,欢迎大家批评指正。如果您还有其他疑问,欢迎添加StoneDB小助手,加入StoneDB开源社区技术交流群,在群里您可以随时提问,我们会认真为您解答。
WebStorm激活2022.3.4
WebStorm激活2022.3.4扫码添加小助手
加入StoneDB开源社区用户群
讨论交流,共同进步
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/171626.html