Khronos: 面向万亿规模时间线的性能监控引擎建设实践

news2024/9/24 15:29:15

作者:余文清

阿里巴巴智能引擎事业部自研的 Khronos 系统是阿里内部接入规模最大的性能数据存储引擎。Khronos 支持动态生命周期的存储计算分离架构,采用 schemaless 的 data model 设计,在万亿数据规模下为业务提供易用、高效、经济的服务,团队近期的优化工作也被国际学术会议 CIKM2023 收录。本⽂总结了 Khronos 在性能监控领域遇到的技术挑战,以及在这个场景下的一些价值判断。

一、背景

时序数据管理系统(Time series DBMS)近年来受到较多的关注,这是受到多方面因素推动的结果,包括:云原生可观测性的要求逐渐标准化,DevOps/AIOps 的发展,IoT 技术、车联网、智能⾦融等技术趋势对时序数据的存储需求。从图 1 左侧 DB-Engines 网站[1]的趋势可以看出,从 2013 年开始,Time series DBMS 受到的关注就在逐渐上升。

另一方面,时序数据库产品形态也呈现出多元化趋势。图中右侧列出的是 DB-Engines 根据时序数据库产品热度的 top10 排名。在这个榜单中,有的是为业务场景设计的专业时序数据库产品(例如 InfluxDB、Prometheus、Graphite),有的是基于关系型数据库的架构,针对业务场景进行了专门的设计(例如 Kdb+,TimescaleDB), 也有的面向更通用的大数据分析场景,时序分析是它能满⾜的⼀个子场景(例如 Druid)。

在我们对业内产品的调研过程中发现,⽬前没有产品能够很好的满⾜大规模性能监控中台对时序数据库的要求。因此在 2019 年,阿里智能引擎团队就基于 AIOS 技术栈体系[2]和 Havenask 开源搜索引擎[3],自研了⼀款面向大规模性能监控场景的时序存储引擎 Khronos。

经过几年的持续建设,它已经成为阿里内部两大性能监控平台 Kmonitor 和 Sunfire 的底层时序数据存储引擎。2023 年是 Khronos 上线生产系统的第 4 年,从数据接入量上看,它俨然已成长为阿里巴巴内部规模最大的性能数据存储引擎。

二、技术挑战

在性能监控场景,TSDB 的主要的使用场景有大盘展示、系统问题调查、根因分析、异常检测和报警等。随着内部业务逐渐向云上环境迁移,基于云上的性能监控,面临以下几大挑战:

2.1 写入规模巨大

随着 DevOps 概念、云原生概念、系统可观测性概念的普及,集团内部应用大量使用指标、日志等手段实时反馈系统的性能状态和业务状态。

以 Kmonitor 业务平台为例,指标接入量从 2019 年的每秒写入 46Million/second 增长到 2022 年的 255 Million/second,每年都有 1 倍左右的写入量增长。这些数据需要被 Khronos 实时消费、索引并且存储起来,这对数据的接入 pipeline 是⼀个巨大的压力。另⼀方面,业务层面对指标数据的保留时间限制(time-to-live) 存在需求,大部分的指标数据保留 1-3 个月,但是也有⼀定比例的指标要求永久保留。

2.2 维度诅咒

我们用时间线的基数(cardinality)来衡量性能监控场景的规模。这里先简单介绍⼀下时间线的概念。性能监控数据通常被建模为多维时间序列(multi-dimensional time series),  每⼀个 time series 包含⼀个 metric、⼀组 tags(其中,每个 tag 由 tag key 和 tag value 构成)和⼀组带时间戳的样本值(timestamped samples)。⼀条时间线可以由 SeriesKey 进行唯⼀标识,SeriesKey =  metric + tags。

以下表为例,包含了 4 个 series(红、绿、蓝、黄):

(表 1)

在 Kmonitor 业务场景中,我们在多个租户都观察到时间线的基数逐渐膨胀。图 2 给出了 4 个典型租户时间线基数的变化趋势。可以看出,他们的时间线规模都在持续增长,个别租户(HI) 的时间线规模甚至超过万亿级别(1e12)。另一个值得注意的统计特征是 60%以上的时间线生命周期并不长,在⼀个小时以内。

(图 2)

时间线基数膨胀的主要原因是时间线存在⼀定的流动率(churn rate):active 的时间线停⽌接受指标样本,变为 inactive 状态。同时,又不断有新的 active 时间线进入系统。

在具体业务中,series churn 的来源是多方面的,例如:

  • 在线系统会在电商大促活动期间进行弹性扩缩容操作,扩容操作发生时,新启动的业务进程就会产生大量新的时间线;而缩容操作发生时,大量的进程消亡,对应的时间线变成 inactive 状态。

  • 随着大规模混布技术和容器技术的应用,云上部署的服务进程会在物理机之间进行迁移。如果某些指标以物理机 IP 作为 tag key,那么每当进程迁移到新的物理机时,就会产生⼀批新的 active 的时间线集合(IP 的 tag value 发生更新)。

表 2 对来自不同租户的 30 分钟区间的汇报指标进行了统计。可以看出时间线基数(#series)就达到百万级别(1e7)。例如 ASI 租户,时间线基数到了 4100 万+。主要原因是 tags 的平均维度(#tags)超过 31 个,tag values 的基数(tag values 列)超过 446 万。我们把 tags 维度太多导致的时间线基数膨胀问题,称作时序场景的“维度诅咒”。

(表 2 )

2.3 及时可见性

线上业务对于监控数据的时效性要求越来越高。我们把可见性延迟(Visible-Delay)定义为时序数据产生的时间(event-time)到它可以被检索到的时间(visible-time)的 gap。部分时效性敏感的业务要求可见性延迟在维持在几秒之内。举个例子,弹性扩缩容服务可能会基于某个应用最近 5 分钟的聚合 QPS 指标进行弹性扩缩决策,如果 QPS 指标的 visible-delay 达到分钟级别,那么弹性扩缩容服务就⽆法做出及时的决策,甚至可能基于部分聚合结果,产生错误的决策。

指标数据从产生到被存储,大致上要经历 SDK 收集、agent 采集、引擎消费这么几个阶段。其中前两个步骤运行在端上(容器、物理机),第三步通过中心化的时序引擎进行处理。因此 visible-delay 可以细分为端延迟和引擎构建延迟。

上述的三个挑战对 TSDB 意味着什么呢?

首先,高写入压力要求引擎提供极高吞吐的写入 pipeline,同时业务场景要求数据能够被长期保留下来,意味着引擎需要提供高可靠、低成本和低访问延迟的存储方案;第二,秒级的及时可见性要求系统具备实时索引(realtime-indexing)的能力;

最后,高维度高基数的数据特点对实时索引性能带来巨大的挑战,TSDB 在设计上需要能控制时间线规模,且提供高吞吐的索引方案。

三、系统架构介绍

3.1 整体架构设计

指标数据采集的入口是部署在各个物理机上的指标采集模块 kmon-agent。kmon-agent 会将本地采集的原始指标降精度(down-sample)为 4 个精度:20 秒、1 分钟、10 分钟、60 分钟,并将降精度后的数据,写入该租户对应的 4 个消息队列(MessageQueue)中。

Khronos 会直接消费消息队列中的数据。如图 3 所示,Khronos 整体架构采用了类似 lambda 架构的设计,分为在线和离线两个模块:

  • 在线模块:使用 Havenask 引擎(以下简称 Ha3)作为在线模块,提供实时数据的消费和查询服务。Ha3 分为 QRS 和 Searcher 两种角色。QRS 模块接受用户的查询请求,进行 SQL 解析、生成查询计划、将查询计划转发给 searcher 并对 searcher 返回的结果进行全局聚合和排序。Searcher 是查询计划的执行者,在时序场景,它召回符合查询条件(Metric, Tags, TimeRange)的所有时间线,并根据 group by 条件进行数据的本地聚合。为了提供高时效性的服务, searcher 会在内存中构建时序索引,并将内存中的索引定期刷写到本地磁盘上。查询时,searcher 会从内存、本地磁盘和分布式⽂件系统盘古这三种存储介质中进行数据召回。其中本地磁盘和离线盘古中的数据,会通过 BlockCache 的方式缓存(LRU)在内存中。

  • 离线模块:使用 BuildService 引擎作为离线模块,提供离线数据的产出和整理服务。BuildService 会周期性启动分布式构建进程,消费 MessageQueue 中的数据,将时序索引产出到盘古系统上。BuildService 还会周期性调度分布式的索引整理进程,对时序索引进行整理、优化。优化后的索引版本信息会被推送到在线模块,用于替换 Ha3 searcher 本地内存中和本地磁盘上的时序索引。

(图 3)

采用 lambda 架构的好处在于,在线模块通过直接消费消息队列,  能够保障时序数据的时效性。而消耗 CPU 计算资源的索引整理优化逻辑可以放在离线模块进行,避免了在线服务的 CPU 抖动。但是目前的架构版本中,存在在线模块和离线模块消费两遍消息队列的构建 CPU 成本浪费,后续考虑将 Ha3 Searcher 产出的实时索引直接刷写到盘古上来节省这部分资源。

3.2 基于数据动态生命周期的存储计算分离架构

在存储结构设计上,Khronos ⽀持了在线直接访问离线盘古的存储计算分离架构:BsWorker 将离线优化后的索引直接产出到盘古(HDD) 上,在线 searcher 通过网络直接访问,省去了分发巨量索引到 searcher 本地的过程。⼀方面离线盘古提供了数据的可靠存储保障和理论上⽆限制的存储空间,另⼀方面 searcher 本地状态很小,利于其弹性扩缩容。

在业务场景中,时序场景的数据有明显的冷热特征,但这种冷热变化并不是静态的。比如:场景 A 建⽴了数据大盘,希望能快速召回最近 3 天的数据查询;场景 B 希望能进行 2021、2022 年大促期间的性能对比和业务数据聚合分析;场景 C 希望将基于 blink 流式聚合报警任务下线,有 30 万条报警规则需要直接从 khronos 实时聚合进行计算,要求最近 1 分钟的数据能够提供秒级的构建时效性和毫秒级的查询延迟。

(图 4)

我们通过为引擎增加“动态生命周期管理” 能力来解决这部分需求。

具体而⾔,Khronos ⽀持将⼀张表内的数据分为 N 个冷热层级。我们可以为每一层定义多个时间窗口和一个存储介质。以图 4 为例配置了 3 阶段的生命周期:Hot Layer 配置为最近 12 小时,访问介质配置为内存(Ram);Warm Layer 配置了两个时间窗口:一个是最近 3 天至最近 12 小时,另一个是去年双十一当天(用于业务上支持同期数据对比);访问介质配置为本地 SSD 磁盘;Cold Layer 的时间窗口配置为最近一年至最近 3 天,介质配置为 DFS。在这种配置下,时序数据进入引擎的 12 小时内。它会被加载到全内存中提供高速访问;当数据的 eventTime 和当前时间差值在 3 天到 12 小时之间时,或者命中去年双十一当天的时间区间,这部分时序数据会被迁移至本地磁盘介质(SSD),以更经济的方式提供访问。

当数据的 eventTime 和当前时间的差值超过 3 天时,它就被存放在分布式文件系统上,通过网络 IO 的形式提供访问。

四、Data-Model 设计

data-model 被认为是时序数据管理系统的核心“世界观”,它代表了数据库是如何对数据进行建模的。按照建模方式是否需要预定义 schema, 可以将 TSDB 的建模方案大致分类为 schematized 和 schemaless 两类。

4.1 Schematized Data Model

基本上采用类似关系数据库建模时序数据的产品中普遍需要预先定义 schema。

例如 TimescaleDB、QuestDB、Druid、TDEngine,我们称这类设计为 schematized data model。在数据写入引擎前,定义 schema 可以带来⼀些明确的好处,包括利于查询引擎实现,尤其是提供 SQL 标准(或类似 SQL 语义)的查询引擎;其次它强制用户在写入数据前对数据建模进行仔细地设计,写入流程中可以根据 schema 对数据进行校验,从而避免异常数据进入引擎;另外,这也限制用户随意增加维度列,从⼀定程度上避免上文提到的“维度诅咒”。

以 TimescaleDB [4] 的数据写入为例。用户需要:

  • Step1.  定义⼀个表并关联到⼀个超表 (hyper table)

CREATE TABLE stocks_real_time (  time TIMESTAMPTZ NOT NULL,  symbol TEXT NOT NULL,  price DOUBLE PRECISION NULL,  day_volume DOUBLE PRECISION NULL);SELECT create_hypertable('stocks_real_time','time');
  • Step2. 定义索引

CREATE INDEX ix_symbol_time ON stocks_real_time (symbol, time DESC);

  • Step3. 写入数据

INSERT INTO stocks_real_time(time, symbol, price, day_volumn)  VALUES (NOW(), 'product', 22.2, 3300.0);

  • Step4. 如果需要增加⼀个维度列的话,需要显式修改表结构

ALTER TABLE stocks_real_time ADD COLUMN week_volumn DOUBLE PRECISION NULL;

4.2 Khronos 的选择:Schemaless Data Model

从上述的过程中可以看出, schematized data model 的缺点就是使用体验上不够灵活。Khronos 对接的业务指标的数量超过百万规模,为每个指标都定义⼀个 schema 将会带来巨量的表管理成本,且同⼀个业务存在多个代码版本,对同⼀个指标的建模也不尽相同。增减 metrics、tags 和 fields 都是相对高频的操作。例如代码版本升级、开发人员临时的问题调查等场景都可能更新 metrics、 tags 和 fields。总之如果用户需要在汇报指标前先定义 schema,并显式地为某些 tag 列建⽴索引的话,恐怕产品就要收到很多吐槽投诉了。

考虑到业务上灵活多变的指标数据建模需求,Khronos 采用了完全 schemaless 的 data model。上述流程中的 Step1、Step2 都可以省略,用户只需描述数据本⾝,并推送到系统的消息队列中就行了。这是⼀个 Khronos 的消息示例:

{Metric=stocks_real_time, time=1668417257, tags={symbol=product}, fields={day_volumn=3300.0, price=22.2}}{Metric=stocks_real_time, time=1668417258, tags={symbol=product}, fields={day_volumn=3300.0, price=23.2}}{Metric=stocks_real_time, time=1668417259, tags={symbol=pre}, fields={day_volumn=3300.0, price=24.2}}

Khronos 会自动为所有 tags 建⽴合适的索引。当用户想要修改数据建模时,也不需要上面 Step4、Step2 的 AlterTable/CreateIndex 过程,仍然只需要描述新数据本⾝的变化就可以。例如用户想为指标新增一个 tag: "market" 和一个 field: "week_volumn",直接推送下面的消息即可:

{Metric=stocks_real_time, time=1668417259, tags={symbol=product,market=shanghai}, fields={day_volumn=3300.0, price=22.1,week_volumn=26400.0}}{Metric=stocks_real_time, time=1668417260, tags={symbol=product,market=shanghai}, fields={day_volumn=3300.0, price=23.2,week_volumn=26401.0}}

Khronos 采用了 schema-on-read 的设计理念,这种数据建模的变化是即刻生效的。当执行查询{Metric=stocks_real_time, symbol=product, field=week_volumn}时, 将召回以下数据:

而执行查询{Metric=stocks_real_time, market=shanghai, field=price} 时,只有第⼆批数据被召回:

Khronos 的 data model 可以服务于两种主流的指标数据建模方式:

Model by Metric

按照指标建模的方式下,tags 是用来描述指标的属性的,fields 用来存储指标对应的⼀个或多个值,知名的开源时序监控引擎 Prometheus[5] 也是采用这种方式。表 3 给了⼀个具体的例子,metric 列标识了指标的名称,tags 则表明对应的指标的属性。例如 http_requests_total 包含 method 和 handler 两个维度的属性,而 api_http_requests_client 则包含 method、url、ip 3 个维度的属性。

(表 3)

Model by Data Source

这种建模方案下,Data Source 代表产生数据的⼀类任务或者进程。metric 标识 data source 的名称,tags 用于描述数据源的属性,field names 用于存储指标名称,field values 用于存储指标数值。集团⼴泛使用的 sunfire 平台[9] 可以认为采用了按照 data source 建模的方案。表 4 给了⼀个具体的例子:  

(表 4)

这两种建模方式各有千秋,但对于 Khronos 来说没有差别,即每个 sample 包含⼀个 metric 字段、⼀个 timestamp、多个 tags 和多个 fields。相比于其它时序产品,Khronos 在设计上不需要预先定义的 schema,它相信每个 sample 都可以自解释,且允许模型发生变化。

五、索引方案设计

5.1 Sample-Oriented vs. Series-Oriented

时序数据的索引策略按照索引对象来划分,可以被分类为 Sample-Oriented 方案和 Series-Oriented 方案。Druid、TimescaleDB 是采用 Sample-Oriented 策略的典型数据库。以 Druid 为例,它为每⼀列的每个 distinct value 建⽴⼀个倒排索引。倒排链表指向了包含这个 token 的所有 samples 所在的行号。

下图给了⼀个具体的例子:Justin Bieber 的倒排链指向了 row 0 和 row 1。

(图 5)

但在性能监控场景,sample-oriented 策略的⼀个大问题就是 sample 的数量太大,索引每个 samples 会带来巨大的计算和存储成本。通常,点数量和时间线数量的比值大约是 30 ~ 100 倍,意味着为时间线建⽴索引就比为 sample 建⽴索引要轻的多。

因此 series-oriented 索引策略也越来越成为监控领域的主流,InfluxDB、Prometheus、Google Monarch 等都采用了这样的方案。扩展来说,在⽇志分析领域, ElasticSearch 可以被认为采用了 sample-oriented 方案,而 Loki 采用了 series-oriented 方案。

5.2 时间线索引的构建性能瓶颈分析

时间线索引的构建过程可以被抽象成下面的算法过程,简单描述⼀下:当时间线进入引擎时,先判断⼀下是否已经被索引过。如果没有索引过,那么进入索引构建流程。如果已经被索引过,即只需把它的点数据插入对应的 sample buffer 中。

(图 6)

⽬前,倒排索引和基于树的索引被⼴泛应用在 TSDB 系统中。下图展示了⼀个具体的索引构建流程:  时间线的 SeriesKey ⾸先被分配⼀个 seriesId 作为它的标识符,然后它被分词为 metric-token 和⼀组 tagk-tagv token。seriesId 会被插入到这些 token 对应的倒排链表中,Metric 和 tagk-tagv token 也会被插入到前缀树中用来⽀持时间线的模糊匹配和 meta 查询。

(图 7)

在超高基数的时间线写入负载下,该算法的容易出现以下两个方面的问题:

  • 时间线索引构建性能达到瓶颈:主流的时间线索引方案包括倒排索引、前缀树索引等,构建开销正比于时间线基数(#series)和每个时间线包含的 tags 个数(#tags),从表 2 可以看出,两个数字都不是小数⽬。

  • 冷启动问题:这指的是时间线索引刚创建时,索引构建吞吐会剧烈下降,索引构建延迟会迅速上升,索引构建性能要经历较长的时间才能恢复平稳的现象。这是由于时间线索引的内存不能能⽆限制增长,需要周期性地序列化到磁盘上,并重新创建空索引。空索引创建时,进入系统的大部分的时间线会进入开销昂贵的索引构建分⽀。图 8(b) 画出了⼀个 Khronos 老版本下的周期性冷启动现象。可以看出,⽆论是数据写入吞吐还是索引构建延迟,都会发生周期性的抖动,这对前面章节提到的“及时可见性”造成严重影响。

(图 8)

图 8(a)中,我们对比了两种索引方案在 igraph 性能监控数据集下的峰值写入吞吐能力对比,InfluxDB(series-oriented) 的峰值吞吐能力是 TimescaleDB(sample-oriented) 的 3 倍左右,但是冷启动问题发生时,性能就会严重下降。

5.3 构建性能优化

今年,Khronos 针对上述的索引构建性能瓶颈问题进行了专门的优化。设计了⼀个新的“补集索引构建算法” 。这部分⼯作的细节我们总结为了⼀篇 paper 发表在 CIKM2023[6] 上:"Khronos: A Real-time Indexing Framework for Time Series Databases on Large-Scale Performance Monitoring Systems" [7]。在高基数时间序列负载下,该算法表现要显著优于 InfluxDB。

下图对比了 Khronos、InfluxDB、TimescaleDB 在不同基数的数据集下的单实例峰值写入吞吐能力。

(图 9)

随着数据集的时间线基数从 0.6Million 增长到 9 Million,InfluxDB 的写入性能下降了约 66%。而 Khronos 的构建性能⼀直稳定保持在 1Million samples/second 以上,是 InfluxDB 的 18 倍以上。在和 TimescaleDB 对比时,我们进行两种配置: TimeSNon 表示不对 tag 列配置索引,TimeSInd 表示对所有 tag 列都配置索引。显而易见,即使对比 TimeSNon 方案,Khronos 仍然有很高的性能表现(x4.5)。

在优化构建延迟方面,Khronos 新版本解决了周期性的冷启动问题,下图给出了新老两个版本在 ASI 数据集下的单实例构建性能和构建延迟对比。可以看出,新版本在均值 250K 的写入压力下,索引构建延迟仍稳定在 2s 以内。

(图 10)

六、总结和展望

以上是 Khronos 团队在应对超大规模性能监控场景的⼀些实践经验。后续引擎会在完善可观测数据模型体系上持续发力,例如接入⽇志、trace、event、profiling、用户行为序列数据等。⽬前行业内还没有⼀款产品称得上是可观测性领域的“六边形”战⼠,还有很多机会可以挖掘。

参考资料

[01] DB-engiens ranking

https://db-engines.com/en/ranking

[02] AIOS 技术栈

https://developer.aliyun.com/article/674167

[03] Havenask 搜索引擎

https://github.com/alibaba/havenask

[04] TimescaleDB Docs

https://docs.timescale.com/

[05] Prometheus data model

https://prometheus.io/docs/concepts/data_model/

[06]  CIKM2023 Accepted Papers

https://uobevents.eventsair.com/cikm2023/accepted-papers 

[07] Khronos 论文原文

https://dl.acm.org/doi/10.1145/3583780.3614944#

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1131382.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自媒体创业秘籍:视频号视频下载助你打造热门账号

​自媒体创业者们都知道,视频号已经成为拓展影响力和吸引更多用户的热门平台之一。然而,要想在这个竞争激烈的市场中脱颖而出,并打造一个热门账号,你需要掌握一些技巧和秘籍。在本文中,我将分享关于视频号视频下载的方…

ModelSim【紫光】

这软件是查看波形的。 如果ModelSim频繁弹窗,关闭电脑杀毒软件和电脑管家。 尤其是荣耀管家

Python学习8

前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…

UMMKD

方法 对于“Y”形模型,绿线之前的层是分开的,绿线之后的层在模态之间共享。对于“X”形模型,第一条蓝线之前和第二条蓝线之后的层是分开的,蓝线之间的层在模态之间共享 作者未提供数据

shell脚本中循环语句(极其粗糙版)

分界点:以下内容需要更改,正常放假更改 循环语句: 循环:重复执行一段代码的结构,通过循环,可以在满足一定的条件情况下,多次的执行相同的代码 循环包括:循环体以及循环条件&#…

第二证券:macd指标如何使用?

MACD方针是一种用于技术分析的方针,被广泛应用于股票、期货和外汇市场。本文将从什么是MACD,MACD的原理,怎样运用MACD和MACD的优缺点四个方面分析MACD方针怎样运用。 一、什么是MACD MACD是Moving Average Convergence Divergence的缩写&…

第二证券:股指预计维持蓄势震荡格局 关注证券、计算机设备等板块

第二证券指出,增发1万亿国债、自2000年以来首度年内调整预算传递财务积极发力的信号,估量会对四季度及明年GDP将产生显著带动作用,有利于股市整体情绪的提振。对于债市而言,在支撑信贷增加和实体经济批改的目标下,我们…

在线客服系统源码 客服系统源码

在线客服系统源码 客服系统源码 框架:Thinkphp5workerman,环境:nginxphp7.3mysql5.6 多商户客服、不限坐席、独立系统--数据存储自己服务器上,支持开启SSL、支持离线对话。 新款在线客服系统全开源无加密:多商户、国…

IN动态|小达智能科技领导一行莅临英码科技调研,携手打造时代特色的AI教学平台

近日,小达智能科技CEO何方明领导一行莅临英码科技进行走访调研,我司业务中心总监刘力搏及电商运营经理潘怡霏等一同热情接待,并展开深入的座谈交流。 01 广州小达智能科技有限公司 广州小达智能科技有限公司是于2023年融合砺锋信息科技有限公…

探索 VChart 图表库:简单、易用、强大、高性能、炫酷的可视化利器

声明: 本文标题由ChatGpt 生成 导读 VChart不只是开箱即用的多端图表库,更是生动灵活的数据故事讲述者。 VChart是字节跳动开源可视化解决方案 VisActor 的核心图表组件库。它基于可视化语法库VGrammar和渲染引擎VRender进行封装,在满足数据…

android 如何判断已配对的蓝牙是否打开了互联网访问开关

最近遇到一个需求,要判断已配对的蓝牙是否打开了互联网访问的开关。 经查看源码,得出以下方法。 1. 首先要判断蓝牙是否打开 2. 已打开的蓝牙是否已配对 3. 验证是否真正打开 /*** 是否打开蓝牙互联网访问*/SuppressLint("MissingPermission&quo…

STM32 定时器介绍

STM32F103系列单片机定时器主要有:系统定时器SysTick,2个高级定时器TIM1和TIM8,4个通用定时器TIM2/3/4/5,2个基本定时器TIM6和TIM7。下面先简单介绍一下: 基本定时器:基本定时器只能计时,不能产…

进一步了解视频美颜SDK:美颜SDK的技术原理

美颜技术在当今的数字世界中变得越来越流行,尤其是在视频直播、社交媒体和视频通话应用中。用户寻求通过美颜效果增强自己的外观,这种需求催生了众多美颜SDK(软件开发工具包)的出现。这些SDK使开发者能够轻松地将美颜功能集成到他…

PHP 数据库交互优化,根据传参查询

接上文 修改以下内容 将查询的 uid 改为 username,同时在 user 和 message 两张表中查询 $sql "select m.id,u.username,m.title,m.content from user u,message m where u.idm.uid;"根据 message 中的 id 查询,形式为 http://127.0.0.1/m…

k8s-----亲和力Affinity

1、应用场景 pod和节点间的关系: 某些Pod优先选择有ssdtrue标签的节点,如果没有在考虑部署到其它节点;某些Pod需要部署在ssdtrue和typephysical的节点上,但是优先部署在ssdtrue的节点上; pod和pod间的关系: 同一个应用的Pod不…

13 结构性模式-装饰器模式

1 装饰器模式介绍 在软件设计中,装饰器模式是一种用于替代继承的技术,它通过一种无须定义子类的方式给对象动态的增加职责,使用对象之间的关联关系取代类之间的继承关系. 2 装饰器模式原理 //抽象构件类 public abstract class Component{public abstract void operation(); }…

挑战没有免费的午餐定理?南洋理工提出扩散模型增强方法FreeU

论文名称:FreeU: Free Lunch in Diffusion U-Net 文章链接:https://arxiv.org/abs/2309.11497 代码仓库:https://github.com/ChenyangSi/FreeU 项目主页:https://chenyangsi.top/FreeU 机器学习领域中一个著名的基本原理就是“没…

搜维尔科技:伦敦艺术家利用Varjo头显捕捉盲人隐藏的梦想

在伦敦举行的弗里泽艺术博览会上,与专业级虚拟现实/XR硬件和软件领域的全球领先者Varjo合作,展示一个突破性的混合现实艺术装置, 皇家国家盲人学会 (rnib),英国领先的视力丧失慈善机构。 这个名为"公共交通的私人生活"的装置是一个互动的声音和图像雕塑,旨在让有眼光…

配置中心那些事

闲着也是闲着,就看看过往是在没有时间来折腾的东西,这不,最近2天看了看配置中心。 比较有代表性的有老牌的apollo,新贵 nacos,再就是出身也很好的Spring cloud config,网上比较这3者的文章多余牛毛&#x…

一文了解企业云盘和大文件传输哪个更适合企业传输

文件传输是企业工作中必不可少的环节,无论是内部协作还是外部沟通,都需要高效、安全、稳定地传输各种类型和大小的文件。然而,市面上的文件传输工具众多,如何选择合适的工具呢?本文将从两种常见的文件传输工具——企业…