kubernetes高性能存储-piraeus简介

news2024/11/24 2:04:09

piraeus简介

Piraeus 是面向 Kubernetes 的高性能、高可用性、简单、安全且与云无关的云原生存储解决方案,号称性能和稳定性都优于 Ceph/OpenEBS/Longhorn 等项目。Piraeus 对应的商业产品为LINSTOR 。

众所周知,本地存储具有高性能的优势,但它将应用程序绑定到特定节点,从而使应用程序难以调度,如果该节点或本地卷遇到故障并变得不可访问,则该容器也将变得不可访问。有了piraeus的加持,使高性能的本地存储同时具备高可用的能力,在kubernetes集群中运行数据库、大数据等对性能要求高的有状态应用不再令人望而生畏。

Piraeus 项目成长路径:

  • 2019 年 5 月由浦发银行、DaoCloud 道客联合奥地利 LINBIT 公司共同孵化,致力于为 Kubernetes
    的本地持久卷实现全局管理,动态分配,高可用,和压缩备份等企业级功能。
  • 2020 年 7 月在 KuberCon China 被首次分享。
  • 2021 年 1 月通过 CNCF TOC 投票入选云原生计算基金会(CNCF)Sandbox 项目。
  • 2021 年 5 月注册成为LF/CNCF 资产,并在 2021 年7 月世界人工智能大会上正式宣布被 CNCF 接纳为沙盒项目。

官方网站:https://piraeus.io/
项目地址:https://github.com/piraeusdatastore/piraeus

Piraeus核心技术为基于操作系统内核的DRBD数据块复制技术来实现本地卷可高用。
在这里插入图片描述

Piraeus 项目能够具备高可用,高性能,丰富的企业级存储特性,有以下原因:

  • 复用成熟的 Linux 内核 Distributed Replicated Block Device (分布式复制块,简称 DRBD) 数据技术,没有新写的数据层
  • 邀请 DRBD 作者 Phil Reisner 亲自督导
  • 控制流和数据流完全分离
  • 100% 开源, Apache 开源许可,支持商业开发
  • DaoCloud 道客 和 LINBIT 合作提供企业级技术支持
  • 性能和稳定性都优于 Ceph/OpenEBS/Longhorn等项目

在这里插入图片描述

Piraeus 与其他存储对比

Piraeus vs. 专业NAS

特点PiraeusNAS
动态分配
数据隔离块级别无 (都在一个母路径下)
OLTP数据库小IO性能
本地数据访问
易用性K8S集群内即插即用购买专业NAS设备
成本
延展度高(和k8s节点数匹配)

Piraeus vs. 本地盘

特点Piraeus本地盘
动态分配
数据多节点高可用单点故障
数据远程访问
数据隔离块级别无 (都在一个母路径下)
安全性差(暴露OS路径给租户)
容量管理
超量分配(thin)
快照克隆
压缩去冗

和同类别项目对比

存储技术数据技术数据同步技术开源商业许可
PiraeusLVM, ZvolLinux 内核原生 DRBD 技术开源自主掌控 和代码作者合作
LonghornSparse file自研未知开源属于 Rancher
Rook(ceph)Sparse fileCeph开源属于 Redhat
PortworxBtrfs商业自研纯商业属于 PureStorage

Piraeus 案例

博客链接:https://piraeus.io/site/blog/

传统的大数据平台是一种保存大量数据并对其进行流式计算的基础设施。典型的大数据平台包括Hadoop、Spark、Flume、Flink、Kafka等组件。这些组件的容器化和编排催生了云原生大数据平台。

在研究了Cloudera CDP等主流大数据平台,充分了解采用云原生工作流程的优势和挑战后,浦发银行认识到存储技术是云原生大数据平台建设成功的关键。为此,浦发银行与合作伙伴合作开展云原生存储项目Piraeus Datastore的研究和实验,最终浦发银行的工程师采用了Piraeus云原生存储,并将其应用到大数据生产中。

Piraeus 数据卷是块设备,使用 ext4 或 xfs 文件系统本地安装。Piraeus Kubernetes-CSI 驱动程序和 DRBD Transport 远程挂载技术使容器能够从集群中的任何节点访问数据卷。Piraeus多副本卷采用DRBD同步复制技术,在保证高可用性的同时,提供堪比本地磁盘的高吞吐量和低延迟。

在成功使用 Piraeus 支持节点管理器后,还配置了 MySQL 容器来挂载 Piraeus 副本卷,这也取得了非常令人满意的结果。

在这里插入图片描述

piraeus-operator部署

项目地址:https://github.com/piraeusdatastore/piraeus-operator

准备1至多个kubernetes节点,这里以3个节点为例,测试场景下节点无需挂盘等额外任何操作。

root@node1:~# kubectl get nodes -o wide
NAME    STATUS   ROLES           AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
node1   Ready    control-plane   7d4h   v1.26.7   192.168.72.30   <none>        Ubuntu 22.04.2 LTS   5.15.0-78-generic   containerd://1.6.22
node2   Ready    control-plane   7d4h   v1.26.7   192.168.72.31   <none>        Ubuntu 22.04.2 LTS   5.15.0-78-generic   containerd://1.6.22
node3   Ready    control-plane   7d4h   v1.26.7   192.168.72.32   <none>        Ubuntu 22.04.2 LTS   5.15.0-78-generic   containerd://1.6.22

所有节点配置内核参数

echo fs.inotify.max_user_instances=8192 | tee -a /etc/sysctl.conf && sudo sysctl -p

下载helm chart

wget https://github.com/piraeusdatastore/piraeus-operator/archive/refs/tags/v2.1.1.tar.gz
tar -zxvf v2.1.1.tar.gz
cd piraeus-operator-2.1.1/charts/

使用helm安装piraeus-operator

helm upgrade --install piraeus-operator ./piraeus \
--create-namespace -n piraeus-datastore \
--set installCRDs=true

查看部署的pods

root@node1:~# kubectl -n piraeus-datastore get pods 
NAME                                                    READY   STATUS        RESTARTS   AGE
piraeus-datastore-controller-manager-6f6b8f48c4-st7zb   2/2     Running       0          14m

部署Piraeus数据存储

创建storage cluster

$ kubectl apply -f - <<EOF
apiVersion: piraeus.io/v1
kind: LinstorCluster
metadata:
  name: linstorcluster
spec: {}
EOF

查看部署的pods

root@node1:~# kubectl -n piraeus-datastore get pods 
NAME                                                   READY   STATUS    RESTARTS   AGE
ha-controller-bmz2w                                    1/1     Running   0          66s
ha-controller-rn54t                                    1/1     Running   0          66s
ha-controller-x6sh9                                    1/1     Running   0          66s
linstor-controller-97cd7495c-rqgzd                     1/1     Running   0          67s
linstor-csi-controller-7f85967cd9-8dq7t                7/7     Running   0          67s
linstor-csi-node-dxpc4                                 3/3     Running   0          67s
linstor-csi-node-p9f62                                 3/3     Running   0          67s
linstor-csi-node-q8dwv                                 3/3     Running   0          67s
node1                                                  2/2     Running   0          59s
node2                                                  2/2     Running   0          66s
node3                                                  2/2     Running   0          65s
piraeus-operator-controller-manager-6f8974c495-fk5ql   2/2     Running   0          2m2s

使用linstor客户端检查已部署的 LINSTOR集群的状态:

root@node1:~# kubectl -n piraeus-datastore exec deploy/linstor-controller -- linstor node list
+--------------------------------------------------------+
| Node  | NodeType  | Addresses                 | State  |
|========================================================|
| node1 | SATELLITE | 100.64.0.82:3366 (PLAIN)  | Online |
| node2 | SATELLITE | 100.64.1.173:3366 (PLAIN) | Online |
| node3 | SATELLITE | 100.64.2.178:3366 (PLAIN) | Online |
+--------------------------------------------------------+

配置存储

我们尚未为卷配置任何存储位置。这可以通过创建LinstorSatelliteConfiguration新资源来完成 。

查看支持的存储池类型:

kubectl explain linstorsatelliteconfigurations.spec.storagePools

支持的存储池类型如下

  • filePool 配置基于文件系统的存储池,为每个卷分配一个常规文件
  • fileThinPool 配置基于文件系统的存储池,为每个卷分配稀疏文件
  • lvmPool 将LVM卷组配置为存储池
  • lvmThinPool 将LVM精简池配置为存储池。

我们将在每个节点上创建一个fileThinPool type 的存储池。我们选择fileThinPool它是因为它不需要在主机上进行进一步配置,直接使用根磁盘路径,无需额外准备磁盘。

$ kubectl apply -f - <<EOF
apiVersion: piraeus.io/v1
kind: LinstorSatelliteConfiguration
metadata:
  name: storage-pool
spec:
  storagePools:
    - name: pool1
      fileThinPool:
        directory: /var/lib/piraeus-datastore/pool1
EOF

这将导致一些 Pod 被重新创建。发生这种情况时linstor node list会暂时显示节点离线,再等一会儿,节点又会出现Online。一旦节点再次连接,我们就可以验证存储池是否已配置:

root@node1:~# kubectl -n piraeus-datastore exec deploy/linstor-controller -- linstor storage-pool list
+------------------------------------------------------------------------------------------------------------------------------------------------+
| StoragePool          | Node  | Driver    | PoolName                         | FreeCapacity | TotalCapacity | CanSnapshots | State | SharedName |
|================================================================================================================================================|
| DfltDisklessStorPool | node1 | DISKLESS  |                                  |              |               | False        | Ok    |            |
| DfltDisklessStorPool | node2 | DISKLESS  |                                  |              |               | False        | Ok    |            |
| DfltDisklessStorPool | node3 | DISKLESS  |                                  |              |               | False        | Ok    |            |
| pool1                | node1 | FILE_THIN | /var/lib/piraeus-datastore/pool1 |    23.17 GiB |     96.90 GiB | True         | Ok    |            |
| pool1                | node2 | FILE_THIN | /var/lib/piraeus-datastore/pool1 |    72.38 GiB |     96.90 GiB | True         | Ok    |            |
| pool1                | node3 | FILE_THIN | /var/lib/piraeus-datastore/pool1 |    70.57 GiB |     96.90 GiB | True         | Ok    |            |
+------------------------------------------------------------------------------------------------------------------------------------------------+

使用Piraeus Datastore

支持的所有参数:https://linbit.com/drbd-user-guide/linstor-guide-1_0-en/#s-kubernetes-sc-parameters

我们现在已经成功部署和配置了 Piraeus 数据存储,并准备 PersistentVolume在 Kubernetes 中创建我们的第一个数据存储。

首先,我们将为我们的卷设置一个新的StorageClass。在StorageClass 中,我们指定上面的存储池:

$ kubectl apply -f - <<EOF
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: piraeus-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: linstor.csi.linbit.com
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
parameters:
  linstor.csi.linbit.com/placementCount: "2"
  linstor.csi.linbit.com/storagePool: pool1
  csi.storage.k8s.io/fstype: xfs
EOF

参数说明:

  • placementCount: 支持1/2/3副本,默认为1
  • fstype:支持ext4和xfs,默认为ext4

查看创建的storageclass

root@node1:~# kubectl get sc
NAME                        PROVISIONER              RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
piraeus-storage (default)   linstor.csi.linbit.com   Delete          WaitForFirstConsumer   true                   16s

接下来,我们将创建一个PersistentVolumeClaim,从新创建的StorageClass 中请求 1G 的存储空间。

$ kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-volume
spec:
  storageClassName: piraeus-storage
  resources:
    requests:
      storage: 1Gi
  accessModes:
    - ReadWriteOnce
EOF

当我们检查创建的 PersistentVolumeClaim 时,我们可以看到它仍然处于Pending状态。

$ kubectl get persistentvolumeclaim
NAME          STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS      AGE
data-volume   Pending                                      piraeus-storage   14s

首先需要创建一个“消费者”,在本例中只是一个Pod. 对于我们的消费者,我们将为一个简单的 Web 服务器创建一个部署,从我们的卷中提供文件。

$ kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: web-server
  template:
    metadata:
      labels:
        app.kubernetes.io/name: web-server
    spec:
      containers:
        - name: web-server
          image: nginx
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: data-volume
EOF

短暂等待后,Pod 已完成Running,我们的PersistentVolumeClaim现在已完成Bound

$ kubectl wait pod --for=condition=Ready -l app.kubernetes.io/name=web-server
pod/web-server-84867b5449-hgdzx condition met

$ kubectl get persistentvolumeclaim
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
data-volume   Bound    pvc-9e1149e7-33db-47a7-8fc6-172514422143   1Gi        RWO            piraeus-storage   1m

检查正在运行的容器,我们看到该卷已安装在我们预期的位置:

$ kubectl exec deploy/web-server -- df -h /usr/share/nginx/html
Filesystem      Size  Used Avail Use% Mounted on
/dev/drbd1000   973M   24K  906M   1% /usr/share/nginx/html

查看客户端linstor,我们可以看到该卷已在 LINSTOR 中列出并由InUsePod 标记为。经过短暂的等待,可以看到 LINSTOR 将卷放在两个节点上,当一个节点故障后,pod会调度到第二个节点并挂载卷:

root@node1:~# kubectl -n piraeus-datastore exec deploy/linstor-controller -- linstor resource list-volumes
+---------------------------------------------------------------------------------------------------------------------------------------------+
| Node  | Resource                                 | StoragePool          | VolNr | MinorNr | DeviceName    | Allocated | InUse  |      State |
|=============================================================================================================================================|
| node1 | pvc-62bdaf29-188f-4e88-9c04-db7b7f6cca95 | DfltDisklessStorPool |     0 |    1000 | /dev/drbd1000 |           | Unused | TieBreaker |
| node2 | pvc-62bdaf29-188f-4e88-9c04-db7b7f6cca95 | pool1                |     0 |    1000 | /dev/drbd1000 | 10.58 MiB | InUse  |   UpToDate |
| node3 | pvc-62bdaf29-188f-4e88-9c04-db7b7f6cca95 | pool1                |     0 |    1000 | /dev/drbd1000 |  2.39 MiB | Unused |   UpToDate |
+---------------------------------------------------------------------------------------------------------------------------------------------+

我们现在已经成功设置了 Piraeus 数据存储,并使用它在 Kubernetes 集群中配置持久卷。

kubectl-linstor安装

kubectl-linstor是一个通过 kubectl 命令行执行 LINSTOR 命令的插件。要使用 kubectl linstor 需要使用Piraeus Operator。

wget https://github.com/piraeusdatastore/kubectl-linstor/releases/download/v0.2.1/kubectl-linstor-v0.2.1-linux-amd64.tar.gz
tar -zxvf kubectl-linstor-v0.2.1-linux-amd64.tar.gz kubectl-linstor
mv kubectl-linstor /usr/local/bin/
chmod +x /usr/local/bin/kubectl-linstor

查看节点

root@node1:~# kubectl linstor node list
╭────────────────────────────────────────────────────────╮
┊ Node  ┊ NodeType  ┊ Addresses                 ┊ State  ┊
╞════════════════════════════════════════════════════════╡
┊ node1 ┊ SATELLITE ┊ 100.64.0.83:3366 (PLAIN)  ┊ Online ┊
┊ node2 ┊ SATELLITE ┊ 100.64.1.175:3366 (PLAIN) ┊ Online ┊
┊ node3 ┊ SATELLITE ┊ 100.64.2.179:3366 (PLAIN) ┊ Online ┊
╰────────────────────────────────────────────────────────╯

查看存储池

root@node1:~# kubectl linstor storage-pool list
╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
┊ StoragePool          ┊ Node  ┊ Driver    ┊ PoolName                         ┊ FreeCapacity ┊ TotalCapacity ┊ CanSnapshots ┊ State ┊ SharedName ┊
╞════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╡
┊ DfltDisklessStorPool ┊ node1 ┊ DISKLESS  ┊                                  ┊              ┊               ┊ False        ┊ Ok    ┊            ┊
┊ DfltDisklessStorPool ┊ node2 ┊ DISKLESS  ┊                                  ┊              ┊               ┊ False        ┊ Ok    ┊            ┊
┊ DfltDisklessStorPool ┊ node3 ┊ DISKLESS  ┊                                  ┊              ┊               ┊ False        ┊ Ok    ┊            ┊
┊ pool1                ┊ node1 ┊ FILE_THIN ┊ /var/lib/piraeus-datastore/pool1 ┊    23.14 GiB ┊     96.90 GiB ┊ True         ┊ Ok    ┊            ┊
┊ pool1                ┊ node2 ┊ FILE_THIN ┊ /var/lib/piraeus-datastore/pool1 ┊    72.24 GiB ┊     96.90 GiB ┊ True         ┊ Ok    ┊            ┊
┊ pool1                ┊ node3 ┊ FILE_THIN ┊ /var/lib/piraeus-datastore/pool1 ┊    70.45 GiB ┊     96.90 GiB ┊ True         ┊ Ok    ┊            ┊
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

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

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

相关文章

基于Python 简易实现接口测试自动化

目录 实现思路 统筹脚本 请求封装 日志封装 结果比对 结果邮件 用例获取及数据格式化 请求url转换 测试用例excel结构 测试报告 邮件接收结果 资料获取方法 实现思路 使用excel管理用例用例信息&#xff0c;requests模块发送http请求&#xff0c;实现了记录日志&…

科聪控制系统六大行业典型应用案例合集

01. 纺织行业 科聪移动机器人通用控制系统赋能无人接丝AGV实现丝盘自动化上下料 应用难点&#xff1a;无人接丝AGV是纺织行业无人工厂重要环节之一&#xff0c;这个环节对机器人到点精度要求非常高&#xff0c;无人接丝AGV的到位精度&#xff0c;必须确保“丝级”的准确无误&…

geeemap学习总结(2)——地图底图应用

1. 加载库中已有图层 import os os.environ[HTTP_PROXY] http://127.0.0.1:8001 os.environ[HTTPS_PROXY] http://127.0.0.1:8001 # 设置中心位置/地图层级/图层加载高度&#xff0c;加载图层 import geemap Mapgeemap.Map(center[40, 100], zoom4, height600) Map# 添加已经…

Javascript 正则

基本语法 定义 JavaScript种正则表达式有两种定义方式 构造函数 var regnew RegExp(<%[^%>]%>,g);字面量 var reg/<%[^%>]%>/g;g&#xff1a; global&#xff0c;全文搜索&#xff0c;默认搜索到第一个结果接停止i&#xff1a;ingore case&#xff0c;忽略…

Linux(进程地址空间)

进程地址空间 程序地址空间进程地址空间 程序地址空间 在Linux环境下&#xff0c;我们可以对上述程序空间地址进行验证&#xff1a; 运行程序&#xff0c;可以看到&#xff0c;我们就可以很好看出程序的地址空间的排布了&#xff1a; 进程地址空间 严格来说&#xff0c;我们…

免费商用图片素材网站,4K高清无水印。

推荐6个图片素材网站&#xff0c;免费下载&#xff0c;还可以商用&#xff0c;希望对大家有帮助。 菜鸟图库 美女图片|手机壁纸|风景图片大全|高清图片素材下载网 - 菜鸟图库 网站主要是为新手设计师提供免费素材的&#xff0c;素材的质量都很高&#xff0c;类别也很多&#x…

NGINX组件(rewrite)

一、location匹配的规则和优先级&#xff08;*&#xff09; URI&#xff1a;统一资源标识符&#xff0c;是一种字符串标识&#xff0c;用于标识抽象的或者是物理资源&#xff1b;如&#xff1a;文件、图片、视频等 nginx中的URI匹配的是&#xff1a;网址”/“后的路径 如&…

17 spring项目——登录拦截器

经实验发现&#xff0c;当访问拦截器拦截的地址的时候都会经过拦截器。在拦截器中&#xff0c;返回true则放行&#xff0c;允许访问该地址&#xff1b;返回false&#xff0c;则拦截&#xff0c;不允许访问该地址&#xff0c;但可以在return前去设置要跳转的地址。 拦截器可以拦…

【二分】CF1623 C

Problem - 1623C - Codeforces 题意&#xff1a; 思路&#xff1a; 肯定是二分&#xff0c;我们去二分最小值&#xff0c;然后check的时候最小值要大于mid check的时候要让最小值尽可能大 注意到我们不需要去管最大值&#xff0c;只需要最小值尽可能大就好了&#xff0c;因…

Creo散热处理结构设计--阵列操作

问题描述&#xff1a; 在某一平面掏孔以散热&#xff0c;如何快速的绘制多孔并掏空处理 解决方式&#xff1a; 采用阵列操作。 1&#xff09;绘制圆、拉伸处理 2&#xff09;选择需要阵列的单元&#xff0c;选择阵列操作&#xff0c;在弹出的界面选择方向&#xff0c;按照…

BigDecimal(double)和BigDecimal(String)有什么区别?

面试回答 有区别&#xff0c;而且区别很大。 因为double是不精确的&#xff0c;所以使用一个不精确的数字来创建 BigDecimal&#xff0c;得到的数字也是不精确的。如 0.1 这个数字&#xff0c;double 只能表示他的近似值。 所以&#xff0c;当我们使用 new BigDecimal(0.1) 创建…

SwiftUI 兼容 Light Dark

1. Assets 右键 New Color Set 2. 起个合适的颜色名称&#xff0c;修改一下 demo_bgcolordemo_card_bgcolordemo_text_color 3. Show Me The Code // // light_dark_demo.swift // bill2 // // Created by 朱洪苇 on 2023/8/10. //import SwiftUIstruct light_dark_demo: …

机器学习---自编码器

自编码器过程 输入一个图片&#xff0c;经过encoder变成一个向量&#xff0c;再通过decoder将这个向量反向生成输入的图片。 这里我们希望输入和输出越接近越好。这个过程我们称为重建。 特点&#xff1a;不需要任何的标注资料。 在2006年这个思想就被提出来了&#xff1a; …

消息队列比较

、ActiveMQ 优点&#xff1a;单机吞吐量万级&#xff0c;时效性ms级&#xff0c;可用性高&#xff0c;基于主从架构实现高可用性&#xff0c;消息可靠性较低的概率丢失数据。 缺点&#xff1a;官方社区现在对ActiveMQ5.X维护越来越少了&#xff0c;高吞吐量场景较少使用。 2、K…

《Linux从练气到飞升》No.10 冯洛依曼体系结构

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

rust关于项目结构包,Crate和mod和目录的组织

rust 最近开始学习rust语言。感觉这门语言相对java确实是难上很多。开几个文章把遇到的问题记录一下 rust关于包&#xff0c;Crate 关于包&#xff0c;Crate这块先看看官方书籍怎么说的 crate 是 Rust 在编译时最小的代码单位。如果你用 rustc 而不是 cargo 来编译一个文件…

Opencv实战(银行卡识别)

目录 模版匹配不同方法对比一个模板匹配多个 直方图及直方图均衡化Mask操作直方图均衡化自适应直方图均衡化 模版匹配 公式 import cv2 #opencv读取的格式是BGR import numpy as np import matplotlib.pyplot as plt#Matplotlib是RGB %matplotlib inline def cv_show(img,nam…

win10 + VS2022 安装opencv C++

最近需要用到C opencv&#xff0c;看了很多帖子都需要自己编译opencv源码。为避免源码编译&#xff0c;可以使用VS来配置opencv C。下面是主要过程&#xff1a; 目录 1. 从官网下载 opencv - Get Started - OpenCV 2. 点击这个exe文件进行安装 3. 配置环境变量 4. VS中的项…

【数据结构与算法】多路查找树

多路查找树 二叉树的问题分析 二叉树的操作效率较高&#xff0c;但也存在问题。 二叉树需要加载到内存的&#xff0c;如果二叉树节点少&#xff0c;没什么问题&#xff0c;但是如果二叉树的节点很多&#xff08;比如 1 亿&#xff09;&#xff0c;就存在如下问题&#xff1a…

【信号生成器】从 Excel 数据文件创建 Simulink 信号生成器块研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…