当前位置: 首页 > news >正文

ClickHouse 存算分离改造:小红书自研云原生数据仓库实践

ClickHouse 作为业界性能最强大的 OLAP 系统,在小红书内部被广泛应用于广告、社区、直播和电商等多个业务领域。然而,原生 ClickHouse 的 MPP 架构在运维成本、弹性扩展和故障恢复方面存在较大局限性。为应对挑战,小红书数据流团队基于开源 ClickHouse 自主研发了云原生实时数据仓库 RED ClickHouse(以下简称“REDck”)。

在保持 ClickHouse 原有超高性能的基础上,我们对其进行深度的云原生改造,实现了计算和存储层的弹性扩缩容能力,从而有效减轻运维负担并降低成本。REDck 具备支持 PB 级别数据的用户交互式分析能力,能够灵活满足各类数据分析需求,以满足小红书日益增长的业务和数据分析需求。

目前,REDck 已成功在公司电商、广告、社区、直播等 10+ 个业务场景上落地,总存储规模达到 30+PB。它在降本增效方面取得显著成效,特别是在实验平台和用户行为分析平台等典型场景中。以实验平台为例,在过去 2 年里,实验平台的数据存储周期从 2 个月增长到 2 年,实验指标数量和分析场景也增长 10 倍以上。在如此快速的业务增长下,REDck 为实验平台提供了 99.9% 的可用性保障,其强大的可扩展性成为了业务扩展的有力支撑。

图片

1.1 小红书实时 OLAP 的发展

小红书从诞生之日起,整个基建体系全部搭建在公有云之上,是云上的原住民。

图片

如上图所示,小红书的云原生大数据架构体系,自上而下分别是应用层、计算引擎层、计算资源层、数据层和存储层。

● 存储层核心是各大云厂商提供的对象存储服务,数据层采用通用的数据格式如 Parquet、ORC、Avro 等,并通过 Hive Metastore 提供统一的元信息服务。

● 在计算层,小红书利用 Kubernetes、YARN 等计算资源框架提供资源池化和弹性扩展能力。

● 在计算引擎层,借助 Spark、Flink 等技术实现离线和实时 ETL 链路,并通过 Presto、SparkSQL 等工具对外提供离线报表和数据分析功能。

这种典型的云原生架构为小红书的数据处理提供了高度的灵活性和可扩展性。然而,在此架构体系中,实时 OLAP 引擎的缺失限制了小红书数据分析业务的发展;亟需引入拥有强大分析性能的实时 OLAP 引擎,以满足不断增长的数据分析需求。

图片

ClickHouse 作为一款高性能的实时 OLAP 数据库,以其出色的极致性能、快速稳定的更新迭代、积极响应的开源社区等优势,受到各大公司的青睐。为了实现更快速的查询和分析,小红书数据流团队为公司的实验平台构建了 ClickHouse 集群。

1.2 面临的问题

在初期阶段 ClickHouse 展示了出色的性能,具备极快的查询响应速度,提供了灵活性和实时性,为小红书的数据分析服务提供了更强大的 Ad-Hoc 分析能力。但随着数据的累积,集群规模不断膨胀,现有的实时 OLAP 系统在使用中遇到以下问题:

● 弹性扩展困难

随着小红书业务的快速发展,扩容成为团队频繁进行的运维操作。ClickHouse 采用 Share-Nothing 架构, 每个节点的计算和存储资源强绑定,导致集群扩容受限于机器的调度周期。同时,扩容过程中会引入以周甚至以月为单位的数据迁移工作,对用户的查询产生影响,包括稳定性和一致性问题。

● 资源利用率低

ClickHouse 通过多副本机制来提高整体的可靠性,但也导致资源几何倍增。由于存储和计算比例失调, 在大多数场景下,数据存储量的需求远大于计算需求,却因为存算绑定而造成算力严重浪费。此外,许多业务存在明显的波峰和波谷,缺乏弹性扩展能力导致严重的资源冗余。

● 稳定性问题

ClickHouse 在资源隔离能力方面较弱,容易引发用户查询体验的不稳定性问题。在查询高峰期,资源紧张会导致查询失败率和查询时延显著增加。另外,ClickHouse 的多副本机制重度依赖 Zookeeper,当集群规模达到一定程度时,Zookeeper 的故障频率增高,限制了集群的扩展能力。

● 数据同步问题

ClickHouse 一直被用户诟病的问题就是缺乏成熟的分布式事务系统,数据同步时经常出现数据不一致的现象。

● 可维护性问题

ClickHouse 分布式表和底层复制表模式大大增加了表管理的难度,同时缺少必要的分布式管理功能,如节点加入、节点退出和副本均衡等,使得一旦集群数量变多,维护代价巨大。

基于上述原因,社区开源版的 ClickHouse 难以满足公司在广告、社区、直播、电商等业务需求方面的大规模应用。解决集群岌岌可危的存储上限和运维等问题,对团队来说迫在眉睫。

1.3 解决方案选型

方案1:集群扩容

集群扩容是一种常见解决存储瓶颈问题的方案。然而,社区开源版的 ClickHouse 没有内置支持自动平衡数据负载的功能,因此新加入的节点需要手动平衡负载,并同步其他集群的表结构。此外,扩容无法真正地解决海量数据业务的挑战,最终仍需要添加 TTL 来删除历史数据。同时,扩容后的集群在可用性方面存在风险,需要投入双倍机器资源以避免单点故障导致的数据丢失,增加了成本和复杂性。

综上,集群扩容方案不仅大大增加了运维难度,而且未能从根本上解决存储瓶颈问题。存储问题依然是一把时刻悬在团队头上的“达摩克利斯之剑“。

方案2:存算分离

另一个方案则是更困难的路,即自研云原生实时数仓。尽管该方案面临诸多挑战,如元信息中心化、存算分离改造、容器化等,需要团队从运维能力转向自主研发,但它能从根本上解决扩展性问题。

在传统数据库系统中,存储与计算通常强绑定,即共用相同机器资源。得益于当下云原生技术的飞速发展,越来越多的数据库系统选择拥抱存算分离架构,将存储层与计算层解耦,使得存储资源和计算资源分别弹性扩展成为可能。存算分离架构带来诸多益处:首先,将数据存储到云厂商提供的对象存储中,使数据存储拥有了近乎无限扩展的能力。其次,根据需求动态调整计算资源,满足高频实时计算的性能需求并控制成本。最后,在面对故障时,可以快速迁移和恢复外部数据存储,从而极大提高数据的可靠性。

如今,云原生数据库大多是基于存算分离架构实现,如 SnowFlake、Redshift、TiDB 等。可以说,存算分离已成为分布式数据库的主流方向。

1.4 我们的选择

最终我们选择了正确但困难的道路,希望通过自研存算分离架构,从根本上解决实时 OLAP 引擎在扩容和运维方面的问题,更好地支撑小红书分析业务的快速发展。自研使我们能快速响应业务需求,并有利于成本控制。

基于社区开源版 ClickHouse,我们打造了基于对象存储的存算分离版 Red ClickHouse,简称 REDck

图片

图片

小红书自研云原生分析型数据库的整体设计图,如上图所示。REDck 具备在海量数据下提供秒级的实时复杂分析能力,在公司内广泛支撑了非常多的业务场景,如A/B测试分析、用户行为分析和广告用户分群等。

2.1 存算分离架构

REDck 的存算分离架构如下图,具体包括三层:

图片

● 统一的元信息中心

在开源 ClickHouse中,元信息存储在各个节点的本地磁盘目录下,并通过读取目录列表构建对应的元信息。而 REDck 构建的统一元信息服务是一个无状态的中心化服务,包括内部存储和外部存储等多种存储方式;内部存储模型选择关系型数据库(如 MySQL)或健值数据库(如 Redis),外部存储模式可以与 Hive 数仓以及 Iceberg 数据湖进行深度集成。

构建统一元信息服务层的好处是集群整体信息可以集中掌握,而不是离散到各个机器节点上。集中化的信息管理能力使得数据库引擎,更方便地实现存算分离和事务机制。目前每个集群拥有自己独立的元信息服务,未来可进一步实现多集群的元数据服务,即元数据服务只有一份,可以多个集群共享。

● 计算层

以计算组为基本单位,每个计算组内是一个多节点的分布式计算集群,用户通过网关对计算仓库进行访问,无需关心底层的 Server Node 和 Worker Node 等细节信息。计算任务将由 Server Node 按需调度至 Worker Node 上执行。在此之上集群还有 Master 角色负责管理协调集群中心状态。得益于存算分离的实现,集群能够轻松进行横向和纵向扩展。

● 存储层

存储层实现了分布式文件系统、对象存储等多种低成本存储方式,为数据库提供高效、可扩展的存储能力,以满足海量数据处理需求。

2.2 统一元数据服务

将数据存储在云上的对象存储后,确保每个节点都能够访问数据的元信息是一项具有挑战性的任务。在开源 ClickHouse 中,元信息来源于磁盘的目录,通过读取目录列表构建相应的元信息。然而元信息分散在每个节点内部,每个节点都有独一无二的状态,当有节点宕机时,整个集群就无法使用。为了实现每个节点共享统一的元数据信息并提高可靠性,REDck 引入了统一元信息库和 Metastore 角色。Metastore 负责统一管理集群的元信息。每个计算节点启动后,只需要访问 Metastore 获取最新的元信息即可。

统一元信息库存储分为内部存储外部存储两种方式,我们使用 MySQL 作为内部存储来存储元数据,并利用 MySQL 的事务特性确保整体一致性。Metastore 接管并维护整个集群的信息,使得集群无需再通过 Zookeeper 进行管理,从而解除了 Zookeeper 对 ClickHouse 的束缚。同时,对于元信息的存储,我们使用内部自研的 REDkv(类比开源 Redis)实现了一套文件系统映射,使集群完全脱离磁盘文件系统的限制,实现真正的云原生。在外部存储方面,我们积极与 Hive 数仓以及 Iceberg 数据湖进行深度集成,使得 REDck 可以直接从外部存储中读取元信息。

Metastore 与 REDck 之间的通信流程如下图所示,首先部署好的 MetaStore 会向注册中心发送注册请求,对服务进行注册。当 REDck 集群部署好后,会向注册中心请求进行服务发现,并访问发现的服务以获取元数据信息。

图片

2.3 对象存储访问优化

对象存储具有无限扩展、低成本、可靠性极高的特点。通过使用对象存储来存储数据,我们能够从根本上解决不断增长的数据存储需求,从此告别传统数据存储带来的烦恼。对象存储的可靠性使我们能够摒弃副本机制,从而解决了副本一致性、资源浪费、Zookeeper 稳定性等一系列棘手问题,为 REDck 节点的无状态化提供了基础。

但对象存储也并不是十全十美,引入对象存储之后,我们碰到了如下问题:

● 访问速度:对象存储的总吞吐上限理论上只受带宽限制,但是单线程访问速度较低,远低于磁盘。

● 延迟:目前对象存储访问主要通过 HTTP 协议,延迟较高(包括建立连接等操作的延迟可达到 20 毫秒级别),对部分小文件极其不友好。

● 稳定性:如何减轻多家云厂商对象存储稳定性问题对计算层的影响。

对象存储作为 REDck 的基石,它的性能问题将成为整个数据库系统的瓶颈。为此,我们针对对象存储的读写问题进行了以下优化:

● 提升缓存机制:通过缓存机制提升对象存储的访问速度,从而实现查询性能的百倍提升(详见缓存策略)。针对非缓存的数据,采用并行化手段提升数据下载速度,实现十倍的性能提升。

● 优化查询计算过程:通过查询执行计划重排序、多线程自适应优化等手段,将 HTTP 延迟降低到用户可以忽略的程度。

● 重构访问模块:对对象存储访问模块进行优化和重构,添加数据检查、超时检测和失败重试机制,提升访问的稳定性。

具体流程如下图所示:

1.  客户端将查询发送至服务端,服务端根据查询选择需要读取的 Parts,同时对 Parts 的 markRanges 进行重排序,使每个连接线程读取相同 Part 的 Mark,减少连接次数,从而降低 HTTP 延迟。

2.  将重排序后的 Ranges 传给对应的 Part 类,Part 根据 Ranges 的大小,动态选择下载方式(分为三种),可减少下载压力。

a.  对于大型的 Part,采用多线程多段下载的方式,最后将多段合并成一个 Part。

b.  对于小型的 Part,采用先缓存到内存,再下载到本地的方式。

c.  对于其他的 Part,选择直接下载到本地的方式。

3.  服务端获取到下载的 Part,并计算查询结果,返回给客户端。

图片

2.4 缓存优化

对象存储为我们实现存算分离提供了基础,但同时也带来了查询时必须从云上拉取而导致延迟的问题。尽管通过对象存储的优化手段解决了大部分场景下的拉取问题,但对于部分频繁访问的热数据,反复从云端拉取并不高效。为此我们提出了缓存策略,利用机器的磁盘用作对象存储的缓存盘,为高频查询需求提供高性能保障。

图片

整个多级缓存架构如图所示:内存缓存 -> 本地磁盘缓存 -> 分布式缓存。从上到下,缓存的性能由高到低,可用性和容量由低到高,分别适用于不同类型和热度的数据。这种多级缓存架构帮助我们以最少的成本为用户提供极致的查询性能体验。针对数据的特征,我们提供了两种缓存策略:

● 被动缓存:适用于不可预知的数据,在用户查询时,临时缓存对应的数据,以提高后续查询的性能。

● 主动缓存:适用于可以预知会被频繁访问的数据。集群启动后,系统会在后台主动根据用户设定的规则和用户的查询历史,智能推算用户今天可能会查询的数据,并将这些数据预先从对象存储缓存到本地磁盘,用户查询时直接从本地读取,性能与本地磁盘相当。

同时,由于本地磁盘空间有限,我们提供了两种缓存淘汰策略:LRU 和 Clock Sweep。为进一步优化缓存清理的速度,我们在内存中构建了磁盘的 Catalog,以便快速筛选需要淘汰的缓存数据。

图片

2.5 分布式任务调度

通过对象存储和缓存策略,REDck 的集群节点能够共享存储在云厂商的数据,从而减轻了本地磁盘的压力,但同时带来了任务执行冲突的挑战。这里的任务类型包括 Compaction、Mutation、Insert 以及缓存任务等。在原有架构中,每个实例相互独立,无需考虑任务调度冲突。而实现存算分离后,不同节点之间的任务调度需要进行规划,实现有序调度,以避免冲突。这对我们有两个核心挑战点:

1.  如何统一调度全局的任务计划;

2.  在集群扩缩容过程中,如何自动调整调度计划,以确保没有任务冲突。

为实现统一调度,我们引入了全局选举唯一的 Master 角色,Master 指定特定的 Server 作为整表的全局任务协调者。该协调者根据预设的调度策略(例如按 bucket 进行调度),将不同的任务进行分配,以确保所有任务有序执行。但在集群异常情况下,可能会出现脑裂、任务分配重复等问题,为了解决这些问题,我们在整个任务执行的过程中增加了事务管理和异常检测逻辑,以保证不会有任务冲突,维护数据准确性。

图片

2.6 数据分桶

如前所述,为了实现分布式任务调度,我们引入一个全局选举的 Master 角色。然而在执行分配任务过程中,如果没有合适的调度策略,数据分布可能过于分散,导致聚合和多表连接的性能下降,并经常会伴随机器内存溢出(OOM)和计算倾斜等问题。为了解决这些问题,我们在 REDck 中引入了桶 (Bucket) 的概念。

桶是指将表或分区中指定列的值为 Key 进行 Hash,将其 Hash 到指定的桶中,例如实验平台中将用户 ID 指定为 Bucket 划分的 Key。通过数据分桶,我们获得以下几个优化效果:

● 在单点查询时,可以通过分桶键进行快速过滤,实现高速索引的功能,从而减少数据读取量。

● 通过分桶优化聚合和多表连接查询的性能,避免数据 Shuffle。

通过将数据按 Bucket 划分,我们在任务调度过程中以 Bucket 为单位,灵活调度 Bucket 和节点之间的映射关系,为弹性扩缩容提供了基础。

图片

2.7 分布式事务

经过一系列优化措施,如对象存储的优化、增加缓存策略、添加分布式任务调度、引入 Bucket 的概念等,REDck 的基本使用已经比较稳定。然而,在大规模部署集群后,我们发现从 Hive/Spark 导入数据到 ClickHouse 的过程中,由于不支持事务机制,经常会发生写入重复数据的问题。这是由于开源的 ClickHouse 本身缺少成熟的事务机制,也一直是众多用户所诟病的点。虽然 ClickHouse 内有一套 Transaction 机制,但仅适用于单机模式,无法应用于我们部属的分布式集群。因此,为了实现 REDck 的 Exactly-Once 功能,减少数据导入过程中的失败和数据不一致,提高系统导数的稳定性,带来的收益是很可观的。

基于统一管理的元数据中心,我们实现了 REDck 的事务机制,对数据摄入进行事务管理,并通过 Metastore 角色统一管理全局的数据可见性,从而实现两阶段事务提交功能。这一改进使得我们能够确保数据写入的一致性和可靠性,避免重复数据的产生。

图片

在实现了 REDck 的两阶段提交之后,我们进一步和 Flink 的 Checkpoint 机制打通,实现了Flink -> REDck 数据链路的 Exactly-Once 语义,提高数据处理的准确性和可靠性。

2.8 离线同步链路优化

在离线数据摄入方面,我们使用 Spark 离线导入方式代替了原有的 Flink 小批导入方式,从而降低导入链路的复杂度,提升导数的效率,并消除由额外的 Compaction 工作引入的写放大问题。同时,该离线导入方式天然支持 insert overwrite 语义,用户不会读取到正在导入的的数据,提供了更好的查询体验。

图片

经两年多的发展,REDck 已全面上线,覆盖公司广告、电商、直播等多个领域的 10+ 条业务线,取得了显著效果:

● 降低成本:通过存算分离改造,解决了实验平台集群窘迫资源上限的问题。改造前,集群的存储空间仅为 TB 级别,改造后,理论上可以存储无限的数据,实际上我们存储了 PB 级别的数据,其中最大的计算组规模达到万 Core 规模,单个集群最大存储量达十 PB。此外,用户的查询时间范围也从以月为单位增长到以年为单位。相比于原本的 ClickHouse,REDck 单位 CPU 能处理的数据量增长了 10 倍之多,大幅度减少了 CPU 资源浪费。同时基于存算分离的架构,我们节省了多副本机制带来的成本压力,单位存储成本也降低了 10 倍之多。

● 提高效率:在写入性能方面,通过使用 Spark 对离线链路进行全面改造,离线导入性能提升了一倍。在查询性能方面,尽管引入了分布式元数据服务和性能较慢的对象存储,但 REDck 通过对象存储读优化多级缓存预热等技术手段,优化单机查询性能,查询性能媲美原生ClickHouse。同时存算分离带来了弹性扩展方面的优势,可以在业务高峰期进行分钟级别的动态扩容,用户再也不用担心高峰期的查询拥堵问题。

● 高可用性:摒弃原生 ClickHouse 冗余且难以管理的多副本模式,REDck 依托对象存储,通过多种优化手段使数据可靠性达到 99.9%。实现存算分离后,数据存储在云端,单个节点的宕机不会影响整个集群的正常执行,整体的可用性能达到 99.9%

● 可扩展性:REDck 的云原生特性显著降低了集群扩展的运维压力,集群扩容的时间周期由周级别降低为分钟级别。这得益于通过统一的元信息服务消除了 Zookeeper 这个明显的中心化瓶颈,横向无限扩展虚拟仓库以支持不同业务的环境部署,纵向可随需扩展虚拟仓库的节点以增强抗压能力,实现负载均衡。目前,最大虚拟仓库可以扩展到 100+ 节点规模。此外,REDck 采用统一的表引擎,将分布式表、Zookeeper、Replica 等概念对用户屏蔽,使运维管理更加便捷。

图片

白桦

小红书数据平台部 OLAP 研发专家,负责小红书 OLAP 方向的架构和研发工作,主要包括云原生实时数仓、湖仓一体化方向的研发与落地,有丰富的 OLAP 架构和实践经验。

庞博

小红书数据平台部 LakeHouse 团队负责人,负责 OLAP 及数据湖方向。

铜须

小红书数据平台部 OLAP 研发,负责小红书 OLAP 方向的研发工作,主要包括 REDck 的研发与落地。

相关文章:

ClickHouse 存算分离改造:小红书自研云原生数据仓库实践

ClickHouse 作为业界性能最强大的 OLAP 系统,在小红书内部被广泛应用于广告、社区、直播和电商等多个业务领域。然而,原生 ClickHouse 的 MPP 架构在运维成本、弹性扩展和故障恢复方面存在较大局限性。为应对挑战,小红书数据流团队基于开源 C…...

STM32-DMA

1 DMA简介 DMA(Direct Memory Access),中文名为直接内存访问,它是一些计算机总线架构提供的功能,能使数据从附加设备(如磁盘驱动器)直接发送到计算机主板的内存上。对应嵌入式处理器来说,DMA可…...

1065 A+B and C (64bit)

题&#xff1a;点我 题目大意&#xff1a; 这题虽然看着像签到&#xff0c;然鹅签不过去。 因为我最初写的沙雕代码是&#xff1a; #include<iostream> #include<cstdio> using namespace std; int main(void) {int t;scanf("%d", &t);for (int i …...

阿里云效和阿里在线idea使用

阿里云效 https://flow.aliyun.com/all?page1 阿里在线idea&#xff1a;https://ide.aliyun.com/ 在云效中创建的项目可以在在线idea 打开 运行中的项目 设置ssh 设置以后可以使用云效率的代码构建来构建代码 设置 添加自有云或者体验5h...

[git] 删除分支中的内容 -> 空分支

git branch 分支名1 #创建一个新分支git checkout 分支名1 #切换到刚创建的分支上git rm -rf . #删除所有文件内容 -> 空分支&#xff08;注意&#xff1a;命令后面有个.&#xff09; 也可以 git checkout --orphan 分支名1 #创建一个分支&#xff0c;其包含父分支…...

git 配置

vi ~/.gitconfig 安装开源命令行对比工具 delta: https://github.com/dandavison/delta 详细设置delta&#xff1a;https://www.5axxw.com/wiki/content/xrx4vf [user]name xxemail xxxxxx.com[core]attributesfile ~/.gitattributespager deltaquotepath false[credentia…...

vue router进行路由跳转并携带参数(params/query)

在使用router.push进行路由跳转到另一个组件时&#xff0c;可以通过params或query来传递参数。 1. 使用params传参&#xff1a; // 在路由跳转时传递参数 router.push({ name: targetComponent, params: {paramName: paramValue // 参数名和值 } });// 在目标组件中通过$r…...

Mysql触发器

文章目录 1. 简介2. 触发器语法 1. 简介 触发器是与表有关的数据库对象&#xff0c;指在insert/update/delete之前或之后&#xff0c;触发并执行触发器中定义的sql语句集合。触发器可以协助应用在数据库端确保数据的完整性&#xff0c;日志记录&#xff0c;数据校验等操作。使…...

认识doubbo和rpc

开个新坑&#xff0c;和大家一起学习Dubbo 3.X。我们按照一个由浅入深顺序来学习&#xff0c;先从使用Dubbo开始&#xff0c;再深入Dubbo的核心原理。 今天我们就从认识Dubbo开始&#xff0c;整体的内容可以分为3个部分&#xff1a; Dubbo是什么RPC是什么Dubbo的架构 正式开…...

get_views中list的arch格式

1 日历 -> 会议 <tree string"会议" sample"1" multi_edit"1"><header><button name"action_open_composer" type"object" context"{composition_mode:mass_mail}" string"发送邮件"…...

淘宝商品销量接口API更新(总销+精准月销API)

不少客户有获取淘宝商品销量的需求&#xff0c;淘宝商品销量接口主要用于以下业务场景。有不齐全的欢迎大家补充。 库存管理&#xff1a;商家可以通过接口获取到实时的销量信息&#xff0c;更好地进行库存管理。供应链计划&#xff1a;商家可以通过接口了解到商品的销售趋势&a…...

Android 11编译第三弹 ADB开启ROOT权限

一、为什么需要adb root权限 问题&#xff1a;Relese版本&#xff0c;默认adb访问会降级到shell权限&#xff0c;一些敏感操作不能进行&#xff0c;远程调试比较麻烦。且Release版本没有su模块&#xff0c;不能切换Root用户。 开启adb调试以后&#xff0c;默认进入adb是syste…...

《TCP/IP网络编程》--基于TCP实现字符串对话和文件传输

1--基于TCP实现字符串对话 主要需求&#xff1a; 服务器端和客户端各传递 1 次字符串&#xff0c;基于 TCP 协议&#xff0c;传递字符串前先以 4 字节整数型方式传递字符串长度&#xff0c;剩余部分为字符串数据&#xff1b; 注&#xff1a;下面的代码基于 Windows 系统实现&am…...

Feign负载均衡写法

Feign主要为了面向接口编程 feign是web service客户端&#xff0c;是接口实现的&#xff0c;而ribbon是通过微服务名字访问通过RestTemplate调用的&#xff0c;如下&#xff1a; 在Feign的实现下&#xff0c;我们只需要创建一个接口并使用注解的方式来配置它&#xff08;类似…...

OpenCV(二十八):连通域分割

目录 1.介绍连通域分割 2.像素领域介绍 3.两遍法分割连通域 4.连通域分割函数 1.介绍连通域分割 连通域分割是一种图像处理技术&#xff0c;用于将图像中的相邻像素组成的区域划分为不同的连通域。这些像素具有相似的特性&#xff0c;如相近的灰度值或颜色。连通域分割可以…...

达梦控制台还原报错“管道失败”

达梦数据库控制台还原报错“管道失败” 环境 主机操作系统&#xff1a;windows10 profession 达梦数据库版本&#xff1a;达梦7 问题背景 全新安装达梦7数据库后&#xff0c;创建数据库实例&#xff0c;需要恢复往期bat备份。在控制台配置指定搜索目录后&#xff0c;获取备份时…...

[杂谈]-快速了解直接内存访问 (DMA)

快速了解直接内存访问 (DMA) 文章目录 快速了解直接内存访问 (DMA)1、使用 DMA 需要什么&#xff1f;2、DMA介绍3、DMA 中的数据传输如何进行&#xff1f;4、DMA接口5、DMAC 控制器寄存器6、DMA 控制器编程模式6.1 突发模式&#xff08;Burst Mode&#xff09;6.2 循环窃取模式…...

java八股文面试[设计模式]——23种设计模式

设计模式&#xff08;Design pattern&#xff09;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结 在GOF编写的设计模式(可复用面向对象软件的基础)一书中说道: 本书涉及的设计模式并不描述新的或未经证实的设计&#xff0c;我们只收录那些在不同系统中…...

mysql(十)mysql主从复制--主库切换

概述 可能为了更迭升级服务器&#xff0c;或者主库出现问题&#xff0c;又或者只是希望重新分配容量&#xff0c;此时需要切换主库。 如果这是计划内的切换&#xff0c;会相对容易点。只需要在从库上使用CHANGE MASTER TO命令&#xff0c;并设置合适的值。大多数的值都是可选…...

vue3项目的src下的各个文件夹介绍

在Vue 3项目中&#xff0c;通常的目录结构如下所示&#xff1a; src/|- assets/ # 存放静态资源文件&#xff0c;如图片、字体等|- components/ # 存放可复用的Vue组件|- views/ # 存放页面级别的Vue组件|- router/ # 存放路由相关的配置文件|- store…...

五、编译预处理

源程序编译预处理命令一律以‘#’开头 5.1宏定义 不带参数的宏定义 # define 宏名 字符串 宏命令之后&#xff0c;出现宏名的地方均用其对应的字符串来替换。 宏替换是一种”机械替换“&#xff0c;宏定义语句后一般不加分号&#xff0c;因为它仅具有替换功能&#xff0c;…...

应用出海,Google 分享如何让数字营销素材再上层楼

数字营销广告要想取得理想的效果&#xff0c;广告素材是最关键的决定因素之一。 事实上米贸搜谷歌推广发现&#xff0c;在广告给品牌带来的销售额增量中&#xff0c;有 47% 都归功于广告素材。在当今自动化时代&#xff0c;广告素材的作用尤其重要&#xff1a;固然机器可以完成…...

酱香咖啡喝了没?用数据分析揭秘瑞幸咖啡的7500万用户增长策略

瑞幸 X 茅台 这波联名赢麻了&#xff0c;不仅狂卖 542 万杯&#xff0c;甚至带动茅台市值飙升200亿。 瑞幸这几年联名搞了不少&#xff0c;又是线条小狗的爱情故事&#xff0c;又是椰树、维密、周大福、足球的&#xff0c;下面老李就从数据分析角度&#xff0c;带大家来看一下…...

Grafana之魔法:揭秘数据可视化的艺术

在数据驱动的时代&#xff0c;如何有效地呈现和理解数据成为了每个组织和个人的核心任务。Grafana作为一个领先的开源数据可视化工具&#xff0c;为我们提供了强大的功能和灵活性。本文将深入探讨Grafana的魔法&#xff0c;以及它如何帮助我们更好地理解数据。 Grafana简介 G…...

c高级day2作业

写一个1.sh脚本&#xff0c;将以下内容放到脚本中&#xff1a; 在家目录下创建目录文件&#xff0c;dir 在dir下创建dir1和dir2 把当前目录下的所有文件拷贝到dir1中&#xff0c; 把当前目录下的所有脚本文件拷贝到dir2中 把dir2打包并压缩为dir2.tar.xz 再把dir2.tar.xz…...

第3章 【MySQL】字符集和比较规则

3.1 字符集和比较规则简介 3.1.1 字符集简介 如何存储字符串&#xff1f;需要建立字符与二进制数据的映射关系。建立这个关系需要&#xff1a; 1.把哪些字符映射成二进制数据&#xff1f; 2.怎么映射&#xff1f; 将一个字符映射成一个二进制数据的过程也叫做 编码 &#…...

2023 年全国大学生数学建模D题目-圈养湖羊的空间利用率

D题目应该是专科题目&#xff1f;&#xff1f;&#xff1f;不确定了 感觉类似一个细胞分裂问题一样&#xff0c;1&#xff0c;2&#xff0c;4&#xff0c;8&#xff0c; 题目1中规中矩 按照前面说的分配方法&#xff0c;一步一步计算进行 缺口的问题考虑反推回去&#xff0c…...

攻防世界-WEB-ics-05

打开靶机 只有设备维护中心可以点开 点标签得到新的url pageindex 想到文件包含漏洞&#xff08;URL中出现path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼 利用php伪协议查看源码 出现一段base64源码&#xff0c;进行转码得出源码 ?pagephp://filter…...

typedef的四种用法

目录 前言 1&#xff09;为基本数据类型定义类型名 2&#xff09;为自定义数据类型&#xff08;结构体、枚举、共用体&#xff09;定义别名 3&#xff09;为数组定义简易的别名 4&#xff09;为指针定义简洁的名称 前言 在看工程的过程中发现typedef的如下用法&#xff0c…...

Rstudio开不开了怎么办?R is taking longer to start than usual

Rstudio Server 启动时卡死 在使用 linux 服务器版 RstudioServer 的过程中&#xff0c;发现出现了一个问题&#xff0c;导致没有办法正常载入工作页面&#xff0c;网页提示信息是“R is taking longer to start than usual”&#xff0c;直接翻译过来就是“这次启动 R 会比平…...

黃冈建设厅官方网站/国外产品推广平台

SQL Server 的子查询给人的感觉一向不是很好用&#xff0c; IN 子查询无法实现多列的子查询&#xff0c;很多情况下又需要进行自我的子查询操作&#xff0c;比如取员工的最新订单之类的问题。以下 SQL 和案例来之于 <SQLServer2005 技术内幕 T-SQL 查询 > 一书&#xff0…...

青岛做网站的/营销 推广

本题解不一定正确&#xff0c;欢迎大家指正 A&#xff1a;2023 【问题描述】 请求出在 12345678 至 98765432 中&#xff0c;有多少个数中完全不包含 2023 。 完全不包含 2023 是指无论将这个数的哪些数位移除都不能得到 2023 。 例如 20322175&#xff0c;33220022 都完全不包…...

哈尔滨网站搭建/熊猫关键词工具官网

创建新的Models介绍model/view组件之间功能的分离&#xff0c;允许创建model利用现成的views。这也可以使用标准的功能 图形用户接口组件像QListView,QTableView和QTreeView来显示来自各种数据源的数据为。QAbstractListModel类提供了非常灵活的接口&#xff0c;允许数据源以层…...

利用百度图片做网站外链/深圳竞价托管公司

2019独角兽企业重金招聘Python工程师标准>>> 查看版本信息: uanme -a 查看开机机系统信息: dmesg 包括rc.conf和rc.local里程序运行信息的dmesg: dmesg -a 查看某种程序的所有进程,这里以python为例: ps -ax | grep python 查看cpu,硬盘控制器以及网卡的情况 vmstat…...

汕头网站建设网站建设/会计培训班要多少钱一般要学多久

常用的两种解决方案&#xff1a; 第一&#xff1a;使用IE滤镜解决 关键代码&#xff1a; css代码 _background:none;_filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(srccss/images/png24.png,sizingMethodcrop); 有几点注意点&#xff1a; 1&#xff1a;这里对…...

轻量级服务器wordpress/教育培训网站模板

1 问题定位 windows下面无问题&#xff0c;在linux下面出现问题&#xff0c;中文变成方框&#xff0c;经过排查发现linux下缺少字体&#xff0c;只需将widows字体上传到linux服务器进行配置加载就好 2 解决方案 2.1 方案一 2.1.1 安装字体库 [rootlocalhost ~]# yum -y inst…...