Trip.com 如何从 Elasticsearch 迁移到 ClickHouse 并构建了 50PB 的日志解决方案

图片

本文字数:8721;估计阅读时间:22 分钟

审校:庄晓东(魏庄)

本文在公众号【ClickHouseInc】首发

图片

在 Trip.com,我们为用户提供广泛的数字产品,包括酒店和机票预订、景点、旅游套餐、商务旅行管理和与旅行相关的内容。正如你所猜的那样,我们需要一个可扩展、可靠且快速的日志平台,这对于我们的运营至关重要。

在我们开始之前,为了激起你的好奇心,让我展示一些我们在 ClickHouse 上构建的平台的关键数据:

图片

这篇博客文章将讲述我们日志平台的故事,包括为什么我们最初构建它、我们使用的技术,以及我们在 ClickHouse 上利用 SharedMergeTree 等功能对其未来的规划。

以下是我们在旅程中将讨论的不同主题:

  • 我们如何构建一个集中的日志平台

  • 我们如何扩展日志平台并从 Elasticsearch 迁移到 ClickHouse

  • 我们如何改进我们的运营体验

  • 我们如何在阿里云上测试 ClickHouse Cloud

为了简化,让我们把这些内容放在一个时间线上:

图片

构建一个集中的日志平台

每个伟大的故事都始于一个巨大的挑战。在我们的案例中,这个项目起源于 2012 年之前,因为 Trip.com 没有统一或集中的日志平台。每个团队和业务单元(BU)各自收集和管理自己的日志,这带来了许多不同的问题:

  • 需要大量人力来开发、维护和操作所有这些环境,不可避免地导致了大量重复工作。

  • 数据治理和控制变得复杂。

  • 公司内部没有统一的标准。

基于这些问题,我们意识到需要构建一个集中和统一的日志平台。

2012 年,我们推出了第一个平台。它建立在 Elasticsearch 之上,开始定义 ETL、存储、日志访问和查询的标准。

尽管我们不再使用 Elasticsearch 作为我们的日志平台,但值得探讨我们当初是如何实现这个解决方案的。它驱动了我们后来的许多工作,这是我们在后续迁移到 ClickHouse 时必须考虑的。

存储

我们的 Elasticsearch 集群主要由主控节点、协调节点和数据节点组成。

主控节点

每个 Elasticsearch 集群至少由三个主控节点组成。其中一个将被选为主节点,负责维护集群状态。集群状态是包含有关各种索引、分片、副本等信息的元数据。任何修改集群状态的操作都会由主控节点执行。

数据节点

数据节点存储数据并用于执行增删改查(CRUD)操作。它们可以分为多个层次:热层、暖层等。

协调节点

这种类型的节点没有其他功能(如主控、数据、摄取、转换等),并通过考虑集群状态作为智能负载均衡器。如果协调节点接收到带有 CRUD 操作的查询,它会被发送到数据节点。相反,如果接收到添加或删除索引的查询,它会被发送到主控节点。

图片

可视化

基于 Elasticsearch 我们使用 Kibana 作为可视化层。你可以在下方看到一个可视化示例:

图片

日志插入

我们的用户有两种方式将日志发送到平台:通过 Kafka 和通过代理。

通过 Kafka

第一种方法是使用公司的框架 TripLog 将数据导入 Kafka 消息代理(使用 Hermes)。


private static final Logger log = LoggerFactory.getLogger(Demo.class);public void demo (){TagMarker marker = TagMarkerBuilder.newBuilder().scenario("demo").addTag("tagA", "valueA").addTag("tagA", "valueA").build();log.info(marker, "Hello World!");
}

这为用户提供了一个轻松将日志发送到平台的框架。

通过代理工具

另一种方法是使用代理工具,如 Filebeat、Logstash、Logagent 或定制客户端,直接写入 Kafka。你可以在下面看到一个 Filebeat 配置示例:


filebeat.config.inputs:enabled: truepath: "/path/to/your/filebeat/config"
filebeat.inputs:- type: logenabled: truepaths:- /var/log/history.log- /var/log/auth.log- /var/log/secure- /var/log/messagesharvester_buffer_size: 102400max_bytes: 100000tail_files: truefields:type: osignore_older: 30mclose_inactive: 2mclose_timeout: 40mclose_removed: trueclean_removed: true
output.kafka:hosts: ["kafka_broker1", "kafka_broker2"]topic: "logs-%{[fields.type]}"required_acks: 0compression: nonemax_message_bytes: 1000000
processors:- rename:when:equals:source: "message"target: "log_message"

​​​​​​​

ETL

无论用户选择哪种方法,数据最终都会进入 Kafka,然后可以通过 gohangout 管道传输到 Elasticsearch。

Gohangout 是由 trip.com 开发和维护的开源应用程序,作为 Logstash 的替代方案。它旨在从 Kafka 获取数据,执行 ETL 操作,最终将数据输出到各种存储介质中,如 ClickHouse 和 Elasticsearch。Filter 模块中的数据处理包括常见的数据清洗功能,如 JSON 处理、Grok 模式匹配和时间转换(如下所示)。在下面的示例中,GoHangout 使用正则表达式匹配从 Message 字段提取 num 数据,并将其存储为单独的字段。

图片

达到瓶颈

许多人使用 Elasticsearch 进行可观测性,在处理较小数据量时表现出色。它提供易于使用的软件、无模式体验、广泛的功能和流行的 Kibana 界面。然而,当我们这种大规模部署时,它存在一些众所周知的挑战。

当我们在 Elasticsearch 中存储 4PB 数据时,我们开始面临集群稳定性的多个问题:

  1. 集群上的高负载导致许多请求被拒绝、写入延迟和查询缓慢

  2. 每日将 200 TB 数据从热节点迁移到冷节点导致显著的性能下降

  3. 分片分配是一个挑战,导致一些节点过载

  4. 大查询导致内存不足 (OOM) 异常

关于集群性能

  1. 查询速度受到整体集群状态的影响

  2. 由于摄取过程中高 CPU 使用率,我们难以提高插入吞吐量

最后,关于成本

  1. 数据量大、数据结构复杂且缺乏压缩导致需要大量存储空间

  2. 较弱的压缩率对业务产生影响,迫使我们缩短保留期

  3. Elasticsearch 的 JVM 和内存限制导致更高的 TCO(总体拥有成本)

所以,在意识到以上所有问题后,我们寻找替代方案,于是 ClickHouse 出现了!

ClickHouse vs Elasticsearch

Elasticsearch 和 ClickHouse 之间存在一些基本差异;让我们来看看它们。

查询 DSL vs SQL

Elasticsearch 依赖于一种特定的查询语言,称为查询 DSL(领域专用语言)。尽管现在有更多的选项,但这仍然是主要语法。另一方面,ClickHouse 依赖于 SQL,这是一种非常主流且非常用户友好的语言,并且与许多不同的集成和 BI 工具兼容。

内部机制

Elasticsearch 和 ClickHouse 在内部行为上有一些相似之处,Elasticsearch 生成段,而 ClickHouse 写入部分。虽然两者都会随着时间的推移异步合并,创建更大的部分和段,但 ClickHouse 通过列式模型区分自己,其中数据通过 ORDER BY 键排序。这允许构建稀疏索引,从而实现快速过滤和高效的存储使用,因为压缩率很高。你可以在这篇出色的指南中了解更多关于此索引机制的信息。

索引 vs 表

Elasticsearch 中的数据存储在索引中,并分解为分片。这些需要保持在相对较小的大小范围内(在我们使用时,推荐的是大约 50GB 的分片)。相比之下,ClickHouse 的数据存储在显著更大的表中(在 TB 范围内,如果不受磁盘大小限制的话,还可以更大)。除此之外,ClickHouse 允许你创建分区键,这会将数据物理上分隔到不同的文件夹中。如果需要,可以高效地操作这些分区。

总体而言,我们对 ClickHouse 的功能和特性印象深刻:它的列式存储、向量化查询执行、高压缩率和高插入吞吐量。这些满足了我们对日志解决方案在性能、稳定性和成本效益方面的需求。因此,我们决定使用 ClickHouse 来替换我们的存储和查询层。

下一个挑战是如何无缝地从一种存储迁移到另一种存储而不中断服务。

日志平台 2.0:迁移到 ClickHouse

在决定迁移到 ClickHouse 之后,我们确定了需要完成的几个任务:

图片

表设计

这是我们当时确定的初始表设计(请记住,那是几年前的事了,当时 ClickHouse 还没有现在的所有数据类型,例如 maps):


CREATE TABLE log.example
(`timestamp` DateTime64(9) CODEC(ZSTD(1)),`_log_increment_id` Int64 CODEC(ZSTD(1)),`host_ip` LowCardinality(String) CODEC(ZSTD(1)),`host_name` LowCardinality(String) CODEC(ZSTD(1)),`log_level` LowCardinality(String) CODEC(ZSTD(1)),`message` String CODEC(ZSTD(1)),`message_prefix` String MATERIALIZED substring(message, 1, 128) CODEC(ZSTD(1)),`_tag_keys` Array(LowCardinality(String)) CODEC(ZSTD(1)),`_tag_vals` Array(String) CODEC(ZSTD(1)),`log_type` LowCardinality(String) CODEC(ZSTD(1)),...INDEX idx_message_prefix message_prefix TYPE tokenbf_v1(8192, 2, 0) GRANULARITY 16,...
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/example', '{replica}')
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY (log_level, timestamp, host_ip, host_name)
TTL toDateTime(timestamp) + toIntervalHour(168)
  • 我们使用双数组方法来存储动态变化的标签(我们计划未来使用 maps),即有两个数组分别存储键和值。

  • 按天分区以便于数据操作。对于我们的数据量,每日分区是合适的,但大多数情况下,较高的粒度如每月或每周更好。

  • 根据你在查询中使用的过滤器,你可能希望有一个与上表不同的 ORDER BY 键。上面的键是针对使用 log_level 时间的查询进行优化的。例如,如果你的查询不使用 log_level,那么在键中只包含时间列是有意义的。

  • Tokenbf_v1 布隆过滤器用于优化关键词查询和模糊查询。

  • _log_increment_id 列包含一个全局唯一的增量 ID,以实现高效的滚动分页和精确的数据定位。

  • ZSTD 数据压缩方法,节省了超过 40% 的存储成本。

集群设置

鉴于我们在 Elasticsearch 上的历史设置和经验,我们决定复制一个相似的架构。我们的 ClickHouse-Keeper 实例充当主节点(类似于 Elasticsearch)。部署了多查询节点,这些节点不存储数据,而是持有指向 ClickHouse 服务器的分布式表。这些服务器托管数据节点,存储和写入数据。以下显示了我们最终的架构:

图片

数据可视化

在迁移到 ClickHouse 后,我们希望为用户提供无缝体验。为此,我们需要确保所有的可视化和仪表板都能使用 ClickHouse。这带来了一个挑战,因为 Kibana 是一个最初在 Elasticsearch 上开发的工具,不支持其他存储引擎。因此,我们必须对其进行自定义,以确保它能够与 ClickHouse 接口。这需要我们在 Kibana 中创建新的数据面板,可以与 ClickHouse 一起使用:chhistogramchhitschpercentileschrangeschstatschtablechterms 和 chuniq

然后,我们创建了脚本,将 95% 的现有 Kibana 仪表板迁移到使用 ClickHouse。最后,我们增强了 Kibana,使用户可以编写 SQL 查询。

图片

Triplog

我们的日志管道是自助服务,允许用户发送日志。这些用户需要能够创建索引并定义所有权、权限和 TTL 策略。因此,我们创建了一个名为 Triplog 的平台,为用户提供管理表、用户和角色的接口,监控其数据流,并创建警报。

图片

回顾

现在一切都已迁移完毕,是时候看看我们平台的新性能了!尽管我们自动化了 95% 的迁移并实现了无缝过渡,但回顾我们的成功指标并查看新平台的表现仍然很重要。两个最重要的指标是查询性能和总体拥有成本(TCO)。

TCO

我们最初成本的一个重要组成部分是存储。让我们比较一下 Elasticsearch 和 ClickHouse 在相同数据样本上的存储情况:

图片

存储空间节省超过 50%,使现有的 Elasticsearch 服务器能够支持 4 倍的数据量增加。

查询性能

图片

查询速度比 Elasticsearch 快 4 到 30 倍,P90 小于 300 毫秒,P99 小于 1.5 秒。

日志 3.0:改进基于 ClickHouse 的平台

自从我们在 2022 年完成从 Elasticsearch 的迁移以来,我们在平台上增加了更多日志用例,使其从 4PB 增长到 20PB。随着它继续增长并扩展到 30PB,我们遇到了新的挑战。

性能和功能瓶颈

  1. 在这种规模下管理单个 ClickHouse 集群是具有挑战性的。在部署时,没有 ClickHouse-Keeper 或 SharedMergeTree,我们面临着 Zookeeper 的性能瓶颈,导致 DDL 超时异常。

  2. 用户的不良索引选择导致查询性能不佳,需要使用更好的模式重新插入数据。

  3. 未优化的查询导致性能问题。

操作挑战

  1. 集群构建依赖于 Ansible,导致长部署周期(数小时)。

  2. 我们当前的 ClickHouse 实例版本落后于社区版本,当前的集群部署模式不便于进行更新。

为了解决上述性能挑战,我们首先放弃了单集群的架构。在我们的规模下,没有 SharedMergeTree 和 ClickHouse Keeper,元数据的管理变得困难,由于 Zookeeper 的瓶颈,我们会遇到 DDL 语句的超时问题。因此,我们创建了多个集群,而不是保留一个单一的集群,如下所示:

图片

这种新架构帮助我们扩展并克服了 Zookeeper 的限制。我们将这些集群部署到 Kubernetes,使用 StatefulSets、反亲和和 ConfigMaps。这将单个集群的交付时间从 2 天减少到 5 分钟。同时,我们标准化了部署架构,简化了全球多个环境中的部署流程。这种方法显著降低了我们的运营成本,并有助于实施上述方法。

查询路由

尽管上述方案解决了一些挑战,但它引入了新的复杂性,即如何将用户的查询路由到特定的集群。

让我们举个例子来说明:

假设我们有三个集群:集群1、集群2和集群3,以及三个表:A、B和C。在我们实施下面描述的虚拟表分区方法之前,一个表(如A)只能存在于一个数据集群中(例如集群1)。这种设计限制意味着当集群1的磁盘空间用满时,我们没有快速的方法将表A的数据迁移到集群2的空闲磁盘空间。相反,我们不得不使用双写操作,同时将表A的数据写入集群1和集群2。然后,在集群2中的数据过期后(例如七天后),我们可以从集群1中删除表A的数据。这个过程繁琐且缓慢,需要大量手动工作来管理集群。

图片

为了解决这个问题,我们设计了一个类似类的分区架构,使表A能够在多个集群(集群1、集群2和集群3)之间来回移动。如右侧所示,转换后,表A的数据基于时间间隔进行分区(可以精确到秒,但这里为了简单起见使用天作为例子)。例如,6月8日的数据写入集群1,6月9日的数据写入集群2,6月10日的数据写入集群3。当查询命中6月8日的数据时,我们只查询集群1的数据。当查询需要6月9日和10日的数据时,我们同时查询集群2和集群3的数据。

我们通过建立不同的分布式表实现了这一功能,每个分布式表表示特定时间段的数据,并且与多个集群(如集群1、集群2和集群3)的逻辑组合相关联。这种方法解决了跨集群表的问题,使不同集群之间的磁盘使用更加平衡。

图片

如上图所示,每个查询会根据其 WHERE 子句由代理智能重定向到包含所需表的正确集群。

这种架构有助于模式的演变。由于可以添加和删除列,有些表可以有更多或更少的列。上述路由可以在列级别应用,代理可以过滤不包含查询所需列的表。

此外,这种架构帮助我们支持演变的 ORDER BY 键——通常在 ClickHouse 中,无法动态更改表的 ORDER BY 键。通过上述方法,你只需更改新表上的 ORDER BY 键,并让旧表过期(得益于 TTL)。

Antlr4 SQL 解析

在查询层,我们使用 Antlr4 技术将用户的 SQL 查询解析为抽象语法树(AST)。通过 AST 树,我们可以快速获取 SQL 查询中的表名、过滤条件和聚合维度等信息。利用这些信息,我们可以轻松实现针对 SQL 查询的实时策略,例如数据统计、查询重写和流量控制。

图片

我们为所有用户的 SQL 查询实现了一个统一的查询网关代理。该程序基于元数据信息和策略重写用户的 SQL 查询,实现精确路由和自动性能优化等功能。此外,它记录了每个查询的详细上下文,用于统一管理集群查询,限制 QPS、大表扫描和查询执行时间,从而提高系统稳定性。

我们平台的未来是什么?

我们的平台在 40PB+ 规模下已经得到验证,但仍有许多需要改进的地方。我们希望能够更加动态地扩展,以便在假期等高峰期间更优雅地应对高峰需求。为了应对这种扩展需求,我们开始探索 ClickHouse 企业服务(通过阿里云),引入了 SharedMergeTree 表引擎。这一新架构提供了存储和计算的原生分离。通过这种新架构,我们可以提供几乎无限的存储,以支持 trip.com 内部更多的日志用例。

阿里云上提供的 ClickHouse 企业服务与 ClickHouse Cloud 使用相同版本的 ClickHouse。

在阿里云上测试 ClickHouse 企业服务

为了测试 ClickHouse 企业服务,我们首先将数据双写,插入到现有部署和利用 SharedMergeTree 的新服务中。为了模拟真实的工作负载,我们:

  • 将 3TB 数据加载到两个集群中,然后继续插入负载。

  • 收集各种查询模板用作测试集。

  • 使用脚本构建查询,这些查询将在特定值保证非空结果集的情况下查询随机的 1 小时时间间隔。

关于使用的基础设施:

  • 3 个节点,每个节点 32 个 CPU 和 128 GiB 内存,使用对象存储用于 ClickHouse 企业版(带 SMT)

  • 2 个节点,每个节点 40 个 CPU 和 176 GiB 内存,使用 HDD 用于社区版(开源)

为了执行我们的查询工作负载,我们使用了 clickhouse-benchmark 工具(ClickHouse 自带)对两种服务进行测试。

  1. 企业版和社区版都配置为使用文件系统缓存,因为我们希望重现生产环境的条件(生产环境中数据量更大,缓存命中率较低)

  2. 我们将以 2 的并发运行第一次测试,每个查询执行 3 次。

Testing RoundP50P90P99P9999Avg
Alicloud Enterprise Edition1st0.260.627.222.990.67
2nd0.240.464.420.610.52
3rd0.240.4816.7521.710.70
Avg0.246
40.3%
0.52
22.2%
7.05
71.4%
21.77
90.3
0.63
51.6%
Alicloud Community Edition1st0.633.411.0629.501.39
2nd0.641.929.3523.501.20
3rd0.581.609.2319.31.07
Avg0.61
100%
2.31
100%
9.88
100%
24.1
100%
1.07
100%

ClickHouse 企业服务的结果显示为黄色,阿里云社区版的结果显示为红色。相对于社区版的性能百分比显示为绿色(越低越好)。

随着并发增加,社区版很快无法处理工作负载并开始返回错误。这实际上意味着企业版能够有效地处理三倍的并发查询。

尽管 ClickHouse 企业服务使用对象存储作为数据存储方式,但它在高并发工作负载方面表现更好。我们认为这种无缝的就地升级可以大大减轻我们的运营负担。

因此,我们决定开始将业务指标迁移到企业服务。这包括支付完成率、订单统计等信息。我们建议所有社区用户试用企业服务!

征稿启示

面向社区长期正文,文章内容包括但不限于关于 ClickHouse 的技术研究、项目实践和创新做法等。建议行文风格干货输出&图文并茂。质量合格的文章将会发布在本公众号,优秀者也有机会推荐到 ClickHouse 官网。请将文章稿件的 WORD 版本发邮件至:Tracy.Wang@clickhouse.com

图片

​​联系我们

手机号:13910395701

邮箱:Tracy.Wang@clickhouse.com

满足您所有的在线分析列式数据库管理需求

 

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

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

相关文章

电脑复制按哪个键?还不会操作的赶紧来看!

当我们提到“电脑复制按哪个键”时,实际上是在讨论电脑键盘上用于执行复制操作的快捷键。复制功能在日常的电脑操作中极为常用,无论是文本编辑、文件处理还是图片操作,都离不开复制这一基本功能。以下,我们将深入探讨电脑复制操作…

【环境搭建】windows下MySQL8与5共存

目录 一、安装MySQL81.官网下载2.初始化mysql文件夹中my.ini文件3.初始化data文件夹,并记录初始密码4.安装服务,指定服务名称5.启动服务6.测试登录并修改密码 二、安装MySQL51.mysql5文件夹中初始化my.ini文件2.初始化data文件夹,并记录初始密…

GraphQL:简介

GraphQL 图片来源: 我们将探索GraphQL 的基础知识,并学习如何使用Apollo将其与 React 和 React Native 等前端框架连接起来。这将帮助您了解如何使用 GraphQL、React、React Native 和 Apollo 构建现代、高效的应用程序。 什么是 GraphQL?…

春秋云境:CVE-2022-25411[漏洞复现]

根据题目提示和CNNVD优先寻找后台管理地址 靶机启动后,使用AWVS进行扫描查看网站结构 在这里可以看到后台管理的登录地址:/admin/,根据题目提示可知是弱口令 尝试admin、123456、admin666、admin123、admin888...等等常见弱口令 正确的账户…

地理空间数据格式GeoJSON扫盲,在CesiumJS中如何加载。

Hi,我是贝格前端工场,GIS已经越来越多的应用在可视化大屏中了,开发GIS类应用就少不了地理空间数据,本文介绍一下数据GeoJSON数据格式。 一、什么是GeoJSON数据格式,在GIS开发中有什么作用 GeoJSON是一种基于JSON&…

【MySQL】数据库——备份与恢复,日志管理1

一、数据备份的重要性 1.备份的主要目的是灾难恢复 在生产环境中,数据的安全性至关重要 任何数据的丢失都可能产生严重的后果造成数据丢失的原因: 程序错误人为,操作错误运算错误磁盘故障灾难(如火灾、地震)和盗窃 2.数据库备份…

小窗口大魔力,实况窗服务实时掌控重要信息变化

移动互联网时代,各种以用户为中心的App如春笋般涌现,满足了用户在购物、导航、娱乐等不同场景下的需求,不同程度上丰富了用户的日常生活。然而,随着App种类的激增,用户在享受多样化服务的同时,也面临着多任…

26.4 Django 视图层

1. 视图函数 视图函数是Django框架中用于处理Web请求并返回Web响应的重要组件. 以下是对Django视图函数的详细解释: * 1. 视图函数与URL的映射.为了让Django能够知道哪个URL对应哪个视图函数, 需要在应用的urls.py文件中定义URL模式.使用path或re_path函数来定义URL模式, 并将…

Linux安装frp实现内网穿透

Linux运维工具-ywtool 目录 一. 简介二.代理类型三.frp支持的Linux的架构四.安装1.准备工作2.配置frp服务器端(a)下载安装包(b)解压安装包(c)修改配置文件(d)启动服务端 3.配置frp客户端(a)下载安装包并修改配置文件(b)启动客户端 4.测试连接 五.其他1.多端口穿透(a)服务端(b)客…

【AI】存储自定义色板库

点击左上角色板,弹出色板框; 色板框的左下角有一个“色板库” 菜单,点击色板库菜单,弹出色板库; 色板库弹窗的第一条数据【存储色板】,点击存储色板,出现自定义色板所在文件路径; 找…

计算机毕业设计Thinkphp/Laravel校园体育器材管理系统

校园体育器材管理系统在流畅性,续航能力,等方方面面都有着很大的优势。这就意味着校园体育器材管理系统的设计可以比其他系统更为出色的能力,可以更高效的完成最新的体育器材、器材借用、器材归还、器材损坏、采购入库、器材报废、维修记录等…

Spring Boot整合RocketMQ实现延迟消息消费

导包 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.0.3</version></dependency>添加配置信息 application配置文件 # rocketMq地址 rocketmq.name…

Ubuntu+Apache2 搭建Gerrit 环境

一、前言 时隔多年&#xff0c;好久没有更新CSDN 博客了&#xff0c;主要原因有如下两点&#xff1a; 1、平时工作繁忙&#xff0c;无暇更新。 2、工作内容涉及信息安全&#xff0c;一些工作经验积累不便更新到互联网上。 最近一直在折腾搭建Gerrit 环境&#xff0c;最开始是…

基于Transformer的自监督学习在NLP中的前沿应用

1. 引言 自然语言处理&#xff08;NLP&#xff09;领域正经历一场由自监督学习&#xff08;Self-Supervised Learning, SSL&#xff09;和Transformer架构共同驱动的革命。自监督学习通过巧妙地利用未标注数据&#xff0c;大大减少了对人工标注的依赖&#xff0c;而Transforme…

基于IM948(Low-cost IMU+蓝牙)模块的高精度PDR(Pedestrian Dead Reckoning)定位系统 — 可以供模块和配套代码

一、背景与意义 行人PDR定位系统中的PDR&#xff08;Pedestrian Dead Reckoning&#xff0c;即行人航位推算&#xff09;背景意义在于其提供了一种在GPS信号不可用或不可靠的环境下&#xff0c;对行人进行精确定位和导航的解决方案。以下是关于PDR背景意义的详细描述&#xff1…

Shopee、Lazada测评,是找服务商呢?还是建议自己养号补单呢?

目前大部分Shopee、Lazada的卖家由于运营成本的增加&#xff0c;都会找服务商测评来打造权重&#xff0c;但是找服务商有很多不靠谱&#xff0c;建议还是自行精养一批号&#xff0c;账号在手里比较安全可控&#xff0c;随时随地可以送测&#xff0c;精准搜索关键词货比三家下单…

【日记】希望文竹长得越来越好吧(856 字)

正文 为什么昨天给老师提早说了今天上课…… 今天都要忙死了。不论上午下午都手忙脚乱。上午之前的存量客户来开新账户&#xff0c;流程卡在客户经理尽调那里。恰好那个客户经理还是部门主管&#xff0c;我们没一个人敢催。向副行长汇报情况&#xff0c;又跟客户说。客户跟他们…

【Android】android studio简单实现图书馆借阅管理系统

希望文章能给到你启发和灵感&#xff5e; 点赞收藏关注 支持一下吧&#xff5e; 阅读指南 序幕一、基础环境说明1.1 硬件环境1.2 软件环境 二、整体设计2.1 数据库逻辑处理&#xff1a;2.2 登录/注册模块2.3 功能界面初始化&#xff1a;2.4 图书管理模块2.5 图书租借服务2.6 读…

Java25年还有更多的工作岗位适合二本学生就业吗?

Java作为一种广泛使用的编程语言。尽管技术领域不断发展和变化&#xff0c;Java依然在许多行业中占据重要地位。以下是一些原因&#xff0c;刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「JAVA的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区…

基于Java的软件测试管理系统【附源码】

毕业&#xff08;设计&#xff09;论文 题 目&#xff1a; 软件测试管理系统 学 号&#xff1a; 姓 名&#xff1a; 院 部&#xff1a; 专 业&#xff1a; 班 级&#xff1a; 指导教师&#xff1a; 职 称&#xff1a; 完成日期&#xff1a; 年 月 日 摘要 随着信息技术的不断…